purebasic.info

PureBasic forum
Текущее время: Пт янв 19, 2018 4:45 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 57 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Загрузка виртуальной DLL из exe
СообщениеДобавлено: Пт авг 12, 2011 11:30 am 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Интро:
Года полтора назад я заинтересовался, как бы загрузить Dll из ресурсов exe файла. Нашел на просторах интернета статью (по моему на rsdn) Портировал на PB начал отлаживать и тут в библиотеке PBOSL обнаружил, что все уже сделано до меня. Естественно забил на это дело.
Тело:
Вчера в теме "Вопросы новичков" Петр предложил выложить для примера. Выкладываю. Прошу ногами не пинать, т.к. это был мой первый опыт портации с делфей на PB. Сильно я не тестировал по выше указанной причине. Но тот пример что в аттаче - рабочий


Вложения:
DllFromMemory.rar [365.57 KiB]
Скачиваний: 505

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение
Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт авг 12, 2011 3:04 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб май 21, 2011 10:27 pm
Сообщений: 246
Откуда: Брест , Беларусь
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
хорошее оформление , но с программкой плохо понял . Буду разбираться :)

_________________
Выпьем ещё раз - чтобы выпить в следущий раз! (С) Иван Пашкевич


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб авг 13, 2011 12:51 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Вс ноя 07, 2010 12:19 pm
Сообщений: 281
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
indy-vx.narod.ru/
/Bin/Ldr.zip
/Bin/LdrExts.zip
/Bin/LdrUpd.zip
/Bin/cws.zip
/Bin/AVrf.zip
/Bin/Ij.zip

_________________
Materia Lucida


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб авг 13, 2011 1:27 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб июл 18, 2009 8:25 am
Сообщений: 810
Откуда: Нерезиновая
Благодарил (а): 21 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Цитата:
ногами не пинать

Вполне неплохо сделано, как я уже писал, "кривую" либу распакованную из аспака, он грузит, в отличии от PBOSL и иже с ним, работающих с одного исходника, что уже говорит в ползу "первого опыта", а не цэшной статики :wink:

Indy, за исходники спасиб, но коменты бы по линкам не помешали.
Иначе приходится качать все, да еще и просматривать каждый сорец для выяснения зачем он собственно нужен :)
Ну и сразу предупреждаю остальных - все исходники на асме, кто ждал пурика, может сэкономить время и не составлять ссылки.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб авг 13, 2011 8:18 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Вот статья по которой писал код
http://rsdn.ru/article/baseserv/peloader.xml

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вс авг 14, 2011 12:40 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Пётр писал(а):
Есть либа PurePROCS (где скачать, хз, не помню, в портабельной версии 4.51 есть).

Скачать можно тут
http://gnozal.ucoz.com/
Но на некоторых dll эта либа тоже валится с ошибкой доступа к памяти. К примеру на BASS.dll

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 17, 2011 11:58 am 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Допилил код, исправил ошибки. Теперь грузятся все библиотеки (почти), пакованые, запротекченные и т.д. в том числе и BASS.dll
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
; Author: Pablov 
 ; For PB 4.30 - 4.51
 ; Date: 17. 08.2011
 ; OS: Windows
 ; По мотивам  http://rsdn.ru/article/baseserv/peloader.xml
 ;########################################################################################
 ;###                                                                                  ###
 ;###                               АХТУНГ!!!!!!!                                      ###
 ;###          Имена функций вызываемых из DLL РЕГИСТРОЗАВИСИМЫ !!!!!!!!!!             ###
 ;###                                                                                  ###
 ;########################################################################################
 ; Если библиотека не упакована сторонними пакерами, ее можно упаковать
 ; средствами PureBasic, для уменьшения веса приложения. Распаковка предусмотрена
 
 #IMAGE_REL_BASED_ABSOLUTE = 0
 #IMAGE_ORDINAL_FLAG32     = $80000000
 ;{ Structures
 Structure IMAGE_SECTION_HEADER
   SecName.b[8]
   StructureUnion
     PhysicalAddr.l
     VirtualSize.l
   EndStructureUnion
   VirtualAddress.l
   SizeOfRawData.l
   PointerToRawData.l
   PointerToRelocations.l
   PointerToLinenumbers.l
   NumberOfRelocations.w
   NumberOfLinenumbers.w
   Characteristics.l
 EndStructure
 
 Structure IMAGE_SECTION_HEADERS
   ish.IMAGE_SECTION_HEADER[32]
 EndStructure
 
 Structure ImageBaseRelocation
     VirtualAddress.l
     SizeOfBlock.l
 EndStructure
 
 Structure _IMAGE_IMPORT_DESCRIPTOR
     OriginalFirstThunk.l
     TimeDateStamp.l                     ;  0, если импортирование осуществляется без привязки (binding)
                                         ;  При импортировании с привязкой содержит отметку времени файла, из которого
                                         ;  импортируем, но: Если -1, то здесь использовался новый стиль привязки
     ForwarderChain.l                    
     Name.l                              ;  Виртуальный адрес ASCIIZ-строки с именем файла, из которого импортируем
     FirstThunk.l                        ;  Виртуальный адрес подтаблицы импортируемых символов
 EndStructure
 
 Structure EXPORT_NAME_ORDINAL
   FunctionVA.l
   Ordinal.w
   NameFunction.s
 EndStructure
 
 Structure DLL_INFO                        ; Глобальные переменные
   BaseVirtDll.l
   EntryPoint.l
   loadDLL.l
   PExports.IMAGE_EXPORT_DIRECTORY
 EndStructure  
 ;}
 
 DataSection
   StartFile:
     IncludeBinary "SkinFeature.dll"               ; Измените на свою DLL          
   EndFile:
 EndDataSection
 
 Declare FreeLibraryEx()
 Global Dim LibraryLoad(0)         ; Сюда заносим хендлы библиотек загруженых для нашей вирт. DLL
 Global Dim tblFuncVA_Ordinal_Name.EXPORT_NAME_ORDINAL(0)
 Global DllInfo.DLL_INFO
 
 ProcedureDLL LoadLibraryEx(StartFile.l, EndFile.l)
   Protected *DOS_HEADER.IMAGE_DOS_HEADER              
   Protected *SECTION_HEADERS.IMAGE_SECTION_HEADERS  
   Protected *NT_HEADERS.IMAGE_NT_HEADERS
   Protected PImport._IMAGE_IMPORT_DESCRIPTOR
   Protected *PReloc.ImageBaseRelocation
   Protected BaseVirtDll.l
 SizeDll =  EndFile - StartFile
 If PeekW(StartFile) = $434A                               ; Если файл запакован средствами PureBasic(сигнатура "JC")
   *Source        = AllocateMemory(SizeDll)            
   *VirtMemOffset = AllocateMemory(SizeDll * 3)
 EnableASM
                   mov ecx, SizeDll
                   mov edi, *Source
                   mov esi, StartFile
                   rep movsb                               ; распакуем его и копируем в память
     UnpackMemory(*Source, *VirtMemOffset)                              
     If *Source : FreeMemory(*Source) : EndIf                      
 ElseIf PeekW(StartFile) = $5A4D                           ; Если не запакован (сигнатура "MZ")
     *VirtMemOffset = AllocateMemory(SizeDll)    
                   mov ecx, SizeDll
                   mov edi, *VirtMemOffset
                   mov esi, StartFile
                   rep movsb                               ; прямо копируем в память
 DisableASM    
 Else
   MessageRequester("Error", " No valid PE File  ", #MB_OK|#MB_ICONERROR)
   End
 EndIf    
 ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Загрузка образа DLL в выделенную память   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    ; Инициируем структуры ********************************************************************
    *DOS_HEADER      = *VirtMemOffset
    *NT_HEADERS      = *VirtMemOffset + *DOS_HEADER\e_lfanew            
    *SECTION_HEADERS = *NT_HEADERS\OptionalHeader + *NT_HEADERS\FileHeader\SizeOfOptionalHeader
    ;******************************************************************************************
  ;  BaseVirtDll = AllocateMemory(*NT_HEADERS\OptionalHeader\SizeOfImage)    ; Выделяем память под виртуальную DLL
  ; С AllocateMemory не всегда работает ???????????????????????????????????
    ; Выделяем память под виртуальную dll
    BaseVirtDll = VirtualAlloc_(#Null, *NT_HEADERS\OptionalHeader\SizeOfImage, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
 If BaseVirtDll  
    DllInfo\EntryPoint = *NT_HEADERS\OptionalHeader\AddressOfEntryPoint
    ; Грузим PE Header (заголовок)
    ; В большинстве случаев, заголовок можно не грузить, но в некоторых случаях грузить необходимо,
    ; т.к. присутствует проверка целостности образа в памяти. Как в примере с BASS.dll
    RtlMoveMemory_(BaseVirtDll, *VirtMemOffset, *NT_HEADERS\OptionalHeader\SizeOfHeaders)        
    ; Грузим секции на родину
    For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
      RtlMoveMemory_(BaseVirtDll + *SECTION_HEADERS\ish[i]\VirtualAddress, *VirtMemOffset  + *SECTION_HEADERS\ish[i]\PointerToRawData, *SECTION_HEADERS\ish[i]\SizeOfRawData)      
    Next i
    ImageBaseDelta = BaseVirtDll - *NT_HEADERS\OptionalHeader\ImageBase   ; Вычисляем дельту  
   
 ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           Правка релоков      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   If ImageBaseDelta     ; Если память под вирт. DLL выделена по ImageBase (дельта = 0), релоки править не надо
     RelocsSize.l = *NT_HEADERS\OptionalHeader\DataDirectory[5]\Size
     *PReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseVirtDll
     P.w
     j.l
     ModCount.l
     tempSize.l = 0
     startAdrReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseVirtDll + 8
     While tempSize < RelocsSize                                          
        ModCount = (*PReloc\SizeOfBlock - 8) / 2
        For j = 0 To ModCount-1
           P = PeekW(startAdrReloc)
           If P & $f000 <> #IMAGE_REL_BASED_ABSOLUTE
              RelocValue = PeekL(BaseVirtDll + *PReloc\VirtualAddress + (P & $0fff)) + ImageBaseDelta
              PokeL(BaseVirtDll + *PReloc\VirtualAddress + (P & $0fff), RelocValue)          ;  Исправляем ссылку
              startAdrReloc + 2
           Else
              startAdrReloc + 2
           EndIf
        Next j  
        tempSize        + *PReloc\SizeOfBlock
        *PReloc         + *PReloc\SizeOfBlock
        startAdrReloc  + 8
     Wend
   EndIf
 ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Заполнение таблицы импорта   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   If *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress  ; Если нет иморта, пропускаем
     SizeImportStruct.b = SizeOf(_IMAGE_IMPORT_DESCRIPTOR)
     RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseVirtDll , SizeImportStruct)
     While PImport\FirstThunk <> 0                 ; Пока не пройдем по всем библиотекам
 ;          Раскоментировав Debug, можно посмотреть заполненную таблицу импорта            
 ;          Debug PeekS(PImport\Name + BaseVirtDll)  
           LibsUsed.s = PeekS(PImport\Name + BaseVirtDll)
           hModule = GetModuleHandle_(LibsUsed)
           If hModule = 0                                      ; Если наше приложение не подгрузило нужных библиотек
             hModule = LoadLibrary_(LibsUsed)                  ; загрузим их сами
             ReDim LibraryLoad(DllInfo\loadDLL)
             LibraryLoad(DllInfo\loadDLL) = hModule
             DllInfo\loadDLL + 1
           EndIf
         While PeekL(PImport\FirstThunk + BaseVirtDll) <> 0  ; Пока не пройдем по всем импорируемым функциям из данной библиотеки
           If PeekL(PImport\FirstThunk + BaseVirtDll) & #IMAGE_ORDINAL_FLAG32 <> 0  ; Если импорт по ординалу
 ;          Debug  Hex(GetProcAddress_(hModule, PeekL(PImport\FirstThunk + BaseVirtDll) & $FFFF)) + "  Импорт по ординалу"
             PokeL(PImport\FirstThunk + BaseVirtDll, GetProcAddress_(hModule, PeekL(PImport\FirstThunk + BaseVirtDll) & $FFFF))
           Else                                                                    ; Иначе по имени
 ;          Debug  Hex(GetProcAddress_(hModule, PeekS(PeekL(PImport\FirstThunk + BaseVirtDll) + 2 + BaseVirtDll))) + "  " + PeekS(PeekL(PImport\FirstThunk + BaseVirtDll) + 2 + BaseVirtDll)
             PokeL(PImport\FirstThunk + BaseVirtDll, GetProcAddress_(hModule, PeekS(PeekL(PImport\FirstThunk + BaseVirtDll) + 2 + BaseVirtDll)))
          EndIf    
             PImport\FirstThunk + 4
         Wend
 ;          Debug  "------------------------------------------------ "
          RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseVirtDll + _step.w + SizeImportStruct, SizeImportStruct)
          _step + SizeImportStruct
     Wend
   EndIf
  _step = 0              
 ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Заполнение таблицы экспорта   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 ;      Заполняем массив -> виртуальный адрес функции, ее ординал и имя
        SizeExportStruct = SizeOf(IMAGE_EXPORT_DIRECTORY)
        RtlMoveMemory_(DllInfo\PExports, *NT_HEADERS\OptionalHeader\DataDirectory[0]\VirtualAddress + BaseVirtDll , SizeExportStruct)
        ReDim tblFuncVA_Ordinal_Name(DllInfo\PExports\NumberOfNames)
        NameAddr.l = DllInfo\PExports\AddressOfNames + BaseVirtDll
        OrdinalAddres = DllInfo\PExports\AddressOfNameOrdinals + BaseVirtDll
        FuncAddr.l = DllInfo\PExports\AddressOfFunctions + BaseVirtDll
 ;      Раскоментировав Debug, можно посмотреть заполненную таблицу экспорта            
;       Debug "   VA   | Ordinal | Name function"    
;       Debug "-------------------------------------"
          For index.l = 0 To DllInfo\PExports\NumberOfNames - 1
            NameAddr + _step
            OrdinalAddres + _step/2                   ; Делим на два, потому что Ordinal -> WORD
            With tblFuncVA_Ordinal_Name(index)
              \FunctionVA    = PeekL(FuncAddr + PeekW(OrdinalAddres)*4 ) + BaseVirtDll
              \Ordinal       = PeekW(OrdinalAddres) ;  + 1
              \NameFunction  = PeekS(PeekL(NameAddr) + BaseVirtDll)
            EndWith
;      Debug  RSet(Hex(tblFuncVA_Ordinal_Name(index)\FunctionVA),8,"0") +"   "+ RSet(Hex(tblFuncVA_Ordinal_Name(index)\Ordinal),4,"0") +"     "+ tblFuncVA_Ordinal_Name(index)\NameFunction        
            _step = 4                                 ; Увеличиваем на DWORD
        Next index
 ; @@@@@@@@@@@@@@@@@@@@@@@@@@  Выставляем секциям флаги доступа  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  
     For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
        SC.l = *SECTION_HEADERS\ish[i]\Characteristics
        protect.l = #PAGE_READONLY
        If  SC & $80000000 : protect = #PAGE_READWRITE  : EndIf            
        If  SC & $20000000 : protect = #PAGE_EXECUTE_READ : EndIf          
        If  SC & $20000000 And SC & $80000000 : protect = #PAGE_EXECUTE_READWRITE : EndIf
        VirtualProtect_(*SECTION_HEADERS\ish[i]\VirtualAddress + BaseVirtDll, *SECTION_HEADERS\ish[i]\VirtualSize, protect, @TempAddr.l)
     Next i
 ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     Инициируем DLL    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
     If DllInfo\EntryPoint <> 0     ; Если DllMain присутствует
       If CallFunctionFast(BaseVirtDll + *NT_HEADERS\OptionalHeader\AddressOfEntryPoint, BaseVirtDll, #DLL_PROCESS_ATTACH, 0)
       Else
         FreeLibraryEx()
         ProcedureReturn 0
       EndIf
     EndIf
 ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
     If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf    
     DllInfo\BaseVirtDll = BaseVirtDll              
     ProcedureReturn BaseVirtDll
  EndIf
     If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf  
     ProcedureReturn 0
 EndProcedure
 
 ProcedureDLL GetProcAddressEx(NameFunction.s)  ; Ищет VA адрес экспортируемой функции по ее имени в массиве tblFuncVA_Ordinal_Name
     For i = 0 To DllInfo\PExports\NumberOfNames - 1
       If tblFuncVA_Ordinal_Name(i)\NameFunction = NameFunction
         Break
       EndIf
     Next i
     ProcedureReturn tblFuncVA_Ordinal_Name(i)\FunctionVA  
 EndProcedure      
 
 ProcedureDLL FreeLibraryEx()    ; Выгружает dll и освобождает зааллоченую память    
     CallFunctionFast(DllInfo\BaseVirtDll + DllInfo\EntryPoint, DllInfo\BaseVirtDll, #DLL_PROCESS_DETACH, 0)
     For i.w = 0 To DllInfo\loadDLL - 1
        FreeLibrary_(LibraryLoad(i))
     Next i
     If DllInfo\BaseVirtDll : VirtualFree_(DllInfo\BaseVirtDll, 0, #MEM_RELEASE) :EndIf
 EndProcedure
 
 BaseDll.l = LoadLibraryEx(?StartFile, ?EndFile)      
 If BaseDll
   MessageRequester("Congratulation", "Библиотека загружена по адресу: " + RSet(Hex(BaseDll), 8, "0"), #MB_OK|#MB_ICONINFORMATION)
 Else
   MessageRequester("Error", "Не могу загрузить библиотеку", #MB_OK|#MB_ICONERROR)
   End
 EndIf  
 ;  Пример для BASS.dll  !!!!!!!!!!!!!!
 BASS_GetVersion.l = GetProcAddressEx("BASS_GetVersion")
 If BASS_GetVersion
   ver.s = Hex(CallFunctionFast(BASS_GetVersion))
   If ver
     While Right(ver, 1) = "0"
        ver = Mid(ver, 1, Len(ver)-1)
     Wend
     ver = ReplaceString(ver, "0", ".")
     MessageRequester("Version of BASS", "Version BASS.dll:  " + ver, #MB_OK|#MB_OK|#MB_ICONINFORMATION)
   EndIf
 EndIf
 FreeLibraryEx()


Прошу выкладывать библиотеки, которые не захотели загружаться
Да, и отпишитесь как на win7 работает, а то нету под рукой

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Последний раз редактировалось pablov Чт авг 18, 2011 10:29 am, всего редактировалось 4 раз(а).

Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 17, 2011 9:54 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб июл 18, 2009 8:25 am
Сообщений: 810
Откуда: Нерезиновая
Благодарил (а): 21 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Win7
\FunctionVA = PeekL(FuncAddr + PeekW(OrdinalAddres)*4 ) + BaseVirtDll
[ERROR] Invalid memory access. (read error at address 47769492)

Старая "недопиленная версия с ошибками" работает норм :wink:
Либа в личке.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 17, 2011 10:38 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Угу, буду смотреть. Спасибо за баг-репорт
Ытс, нашел баг. Ведь говорила мне Мама, лучшее - враг хорошего.
Волков, проверь. Должно работать. Исправил код в своем посте, который выше

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 17, 2011 11:22 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб июл 18, 2009 8:25 am
Сообщений: 810
Откуда: Нерезиновая
Благодарил (а): 21 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Все ок. Work like a charm )
Датасекцию ток я бы убрал\закоментил в pbi


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 17, 2011 11:53 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Volkoff писал(а):
Датасекцию ток я бы убрал\закоментил в pbi

Дык там же комент стоит "Измените на свою DLL " и на pbi еще не тянет
А вообще я был бы очень признателен, тому, кто подправил бы заполнение таблицы импорта. Тут не все гладко. По именам, все ок, а если по ординалам, я не уверен. Не на чем проверить. К слову user32.dll не хочет :?

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт авг 19, 2011 3:13 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
С импортом по ординалам разобрался. Исправил ошибки, "причесал" код. Можно пользовать.


Вложения:
DllFromMemorypy.pbi.rar [98.14 KiB]
Скачиваний: 307

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение
Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб сен 24, 2011 3:31 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Тут столкнулся с новой dll
и изменил код (разобрался с Bound import - это импорт с привязкой)
Вобчем тут новый вариант

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
; Author: Pablov (for PB4.30 - 4.51) 
; Date: 24. 09.2011
; OS: Windows
; По мотивам  http://rsdn.ru/article/baseserv/peloader.xml
;########################################################################################
;###                                                                                  ###
;###                               АХТУНГ!!!!!!!                                      ###
;###          Имена функций вызываемых из DLL РЕГИСТРОЗАВИСИМЫ !!!!!!!!!!             ###
;###                                                                                  ###
;########################################################################################
; Если библиотека не упакована сторонними пакерами, ее можно упаковать
; средствами PureBasic, для уменьшения веса приложения. Распаковка предусмотрена
 
#IMAGE_REL_BASED_ABSOLUTE = 0
#IMAGE_ORDINAL_FLAG32     = $80000000
;{ Structures
Structure IMAGE_SECTION_HEADER
  SecName.b[8]
  StructureUnion
    PhysicalAddr.l
    VirtualSize.l
  EndStructureUnion
  VirtualAddress.l
  SizeOfRawData.l
  PointerToRawData.l
  PointerToRelocations.l
  PointerToLinenumbers.l
  NumberOfRelocations.w
  NumberOfLinenumbers.w
  Characteristics.l
EndStructure
 
Structure IMAGE_SECTION_HEADERS
  ish.IMAGE_SECTION_HEADER[32]
EndStructure
 
Structure ImageBaseRelocation
    VirtualAddress.l
    SizeOfBlock.l
EndStructure
 
Structure _IMAGE_IMPORT_DESCRIPTOR
    OriginalFirstThunk.l
    TimeDateStamp.l                     ;  0, если импортирование осуществляется без привязки (binding)
                                        ;  При импортировании с привязкой содержит отметку времени файла, из которого
                                        ;  импортируем, но: Если -1, то здесь использовался новый стиль привязки
    ForwarderChain.l                    
    Name.l                              ;  Виртуальный адрес ASCIIZ-строки с именем файла, из которого импортируем
    FirstThunk.l                        ;  Виртуальный адрес подтаблицы импортируемых символов
EndStructure
 
Structure DLL_INFO                      ; Глобальные переменные
  BaseVirtDll.l
  EntryPoint.l
  loadDLL.l
EndStructure  
;}
 
Global Dim LibraryLoad(0)               ; Сюда заносим хендлы библиотек загруженых для нашей вирт. DLL
Global DllInfo.DLL_INFO
 
ProcedureDLL FreeLibraryEx()    ; Выгружает dll и освобождает зааллоченую память  
    CallFunctionFast(DllInfo\BaseVirtDll + DllInfo\EntryPoint, DllInfo\BaseVirtDll, #DLL_PROCESS_DETACH, 0)
    For i.w = 0 To DllInfo\loadDLL - 1
       FreeLibrary_(LibraryLoad(i))
    Next i
    If DllInfo\BaseVirtDll : VirtualFree_(DllInfo\BaseVirtDll, 0, #MEM_RELEASE) :EndIf
EndProcedure
 
ProcedureDLL GetProcAddressEx(BaseAddress.l, ProcName.s)
    PExports.IMAGE_EXPORT_DIRECTORY
    _step = 0
    *DOS_HEADER.IMAGE_DOS_HEADER            
    *NT_HEADERS.IMAGE_NT_HEADERS
    *DOS_HEADER      = BaseAddress
    *NT_HEADERS      = BaseAddress + *DOS_HEADER\e_lfanew          
    RtlMoveMemory_(PExports, *NT_HEADERS\OptionalHeader\DataDirectory[0]\VirtualAddress + BaseAddress , SizeOf(IMAGE_EXPORT_DIRECTORY))
    NameAddr.l = PExports\AddressOfNames + BaseAddress
    OrdinalAddres.l = PExports\AddressOfNameOrdinals + BaseAddress
    FuncAddr.l      = PExports\AddressOfFunctions + BaseAddress
    For index.l = 0 To PExports\NumberOfNames - 1
        NameAddr + _step
        OrdinalAddres + _step/2                   ; Делим на два, потому что Ordinal -> WORD
        If ProcName = PeekS(PeekL(NameAddr) + BaseAddress)
           ProcAddress.l = PeekL(FuncAddr + PeekW(OrdinalAddres)*4 ) + BaseAddress
           Break
        EndIf  
        _step = 4                                 ; Увеличиваем на DWORD
    Next index
 ProcedureReturn ProcAddress  
EndProcedure
 
ProcedureDLL ImportProc(BaseAddress.l, *NT_HEADERS.IMAGE_NT_HEADERS)
  PImport._IMAGE_IMPORT_DESCRIPTOR
  PRVA_Import.l
  n.w = 0
  If *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress  ; Если нет иморта, пропускаем
    SizeImportStruct.b = SizeOf(_IMAGE_IMPORT_DESCRIPTOR)
    RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseAddress , SizeImportStruct)
    While PImport\FirstThunk <> 0                             ; Пока не пройдем по всем библиотекам
          LibsUsed.s = PeekS(PImport\Name + BaseAddress)
          hModule = GetModuleHandle_(LibsUsed)
          If hModule = 0                                      ; Если наше приложение не подгрузило нужных библиотек
            hModule = LoadLibrary_(LibsUsed)                  ; загрузим их сами
            ReDim LibraryLoad(DllInfo\loadDLL)
            LibraryLoad(DllInfo\loadDLL) = hModule
            DllInfo\loadDLL + 1
          EndIf
          If PImport\TimeDateStamp = 0                        ; Привязка есть?          
               PRVA_Import = pImport\FirstThunk + BaseAddress
          Else
               PRVA_Import = pImport\OriginalFirstThunk + BaseAddress          
          EndIf
        While PeekL(PRVA_Import) <> 0  ; Пока не пройдем по всем импорируемым функциям из данной библиотеки
          If PeekL(PRVA_Import) & #IMAGE_ORDINAL_FLAG32 <> 0                       ; Если импорт по ординалу
             PokeL(PRVA_Import, GetProcAddress_(hModule, PeekL(PRVA_Import) & $FFFF))
          Else                                                                     ; Иначе по имени
             PokeL(pImport\FirstThunk + n + BaseAddress, GetProcAddress_(hModule, PeekS(PeekL(PRVA_Import) + 2 + BaseAddress)))
          EndIf
            n + 4
            PRVA_Import + 4
        Wend
        n = 0
         RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseAddress + _step.w + SizeImportStruct, SizeImportStruct)
         _step + SizeImportStruct
    Wend
  EndIf
EndProcedure
 
ProcedureDLL RelocProc(BaseAddress.l, *NT_HEADERS.IMAGE_NT_HEADERS)
  *PReloc.ImageBaseRelocation
  ImageBaseDelta = BaseAddress - *NT_HEADERS\OptionalHeader\ImageBase   ; Вычисляем дельту  
  If ImageBaseDelta     ; Если память под вирт. DLL выделена по ImageBase (дельта = 0), релоки править не надо
    RelocsSize.l = *NT_HEADERS\OptionalHeader\DataDirectory[5]\Size
    *PReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseAddress
    P.w
    j.l
    ModCount.l
    tempSize.l = 0
    startAdrReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseAddress + 8
    While tempSize < RelocsSize                                          
       ModCount = (*PReloc\SizeOfBlock - 8) / 2
       For j = 0 To ModCount-1
          P = PeekW(startAdrReloc)
          If P & $f000 <> #IMAGE_REL_BASED_ABSOLUTE
             RelocValue = PeekL(BaseAddress + *PReloc\VirtualAddress + (P & $0fff)) + ImageBaseDelta
             PokeL(BaseAddress + *PReloc\VirtualAddress + (P & $0fff), RelocValue)          ;  Исправляем ссылку
             startAdrReloc + 2
          Else
             startAdrReloc + 2
          EndIf
       Next j  
       tempSize        + *PReloc\SizeOfBlock
       *PReloc         + *PReloc\SizeOfBlock
       startAdrReloc   + 8
    Wend
  EndIf
EndProcedure
 
ProcedureDLL LoadLibraryEx(StartFile.l, EndFile.l)
  *DOS_HEADER.IMAGE_DOS_HEADER            
  *SECTION_HEADERS.IMAGE_SECTION_HEADERS  
  BaseVirtDll.l
  *NT_HEADERS.IMAGE_NT_HEADERS
SizeDll =  EndFile - StartFile
If PeekW(StartFile) = $434A                               ; Если файл запакован средствами PureBasic(сигнатура "JC")
  *Source        = AllocateMemory(SizeDll)          
  *VirtMemOffset = AllocateMemory(SizeDll * 5)
EnableASM
                  mov ecx, SizeDll
                  mov edi, *Source
                  mov esi, StartFile
                  rep movsb                               ; распакуем его и копируем в память
    UnpackMemory(*Source, *VirtMemOffset)                            
    If *Source : FreeMemory(*Source) : EndIf                    
ElseIf PeekW(StartFile) = $5A4D                           ; Если не запакован (сигнатура "MZ")
    *VirtMemOffset = AllocateMemory(SizeDll)  
                  mov ecx, SizeDll
                  mov edi, *VirtMemOffset
                  mov esi, StartFile
                  rep movsb                               ; прямо копируем в память
DisableASM    
Else
  MessageRequester("Error", " No valid PE File  ", #MB_OK|#MB_ICONERROR)
  End
EndIf  
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Загрузка образа DLL в выделенную память   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ; Инициируем структуры ********************************************************************
   *DOS_HEADER      = *VirtMemOffset
   *NT_HEADERS      = *VirtMemOffset + *DOS_HEADER\e_lfanew          
   *SECTION_HEADERS = *NT_HEADERS\OptionalHeader + *NT_HEADERS\FileHeader\SizeOfOptionalHeader
   ;******************************************************************************************
   ; Выделяем память под виртуальную dll
   BaseVirtDll = VirtualAlloc_(#Null, *NT_HEADERS\OptionalHeader\SizeOfImage, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If BaseVirtDll  
   DllInfo\EntryPoint = *NT_HEADERS\OptionalHeader\AddressOfEntryPoint
   ; Грузим PE Header (заголовок)
   ; В большинстве случаев, заголовок можно не грузить, но в некоторых случаях грузить необходимо,
   ; т.к. присутствует проверка целостности образа в памяти. Как в примере с BASS.dll
 
   RtlMoveMemory_(BaseVirtDll, *VirtMemOffset, *NT_HEADERS\OptionalHeader\SizeOfHeaders)      
   ; Грузим секции на родину
   For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
     RtlMoveMemory_(BaseVirtDll + *SECTION_HEADERS\ish[i]\VirtualAddress, *VirtMemOffset  + *SECTION_HEADERS\ish[i]\PointerToRawData, *SECTION_HEADERS\ish[i]\SizeOfRawData)      
   Next i
   RelocProc(BaseVirtDll, *NT_HEADERS)                           ; Правка релоков    
 
   ImportProc(BaseVirtDll, *NT_HEADERS)                          ; Заполнение таблицы импорта
   
; @@@@@@@@@@@@@@@@@@@@@@@@@@  Выставляем секциям флаги доступа  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  
    For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
       SC.l = *SECTION_HEADERS\ish[i]\Characteristics
       protect.l = #PAGE_READONLY
       If  SC & $80000000 : protect = #PAGE_READWRITE  : EndIf          
       If  SC & $20000000 : protect = #PAGE_EXECUTE_READ : EndIf        
       If  SC & $20000000 And SC & $80000000 : protect = #PAGE_EXECUTE_READWRITE : EndIf
       VirtualProtect_(*SECTION_HEADERS\ish[i]\VirtualAddress + BaseVirtDll, *SECTION_HEADERS\ish[i]\VirtualSize, protect, @TempAddr.l)
    Next i
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     Инициируем DLL    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    If DllInfo\EntryPoint <> 0                       ; Если DllMain присутствует
      If CallFunctionFast(BaseVirtDll + *NT_HEADERS\OptionalHeader\AddressOfEntryPoint, BaseVirtDll, #DLL_PROCESS_ATTACH, 0)
      Else
        FreeLibraryEx()
        ProcedureReturn 0
      EndIf
    EndIf
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf  
    DllInfo\BaseVirtDll = BaseVirtDll            
    ProcedureReturn BaseVirtDll
 EndIf
    If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf  
    ProcedureReturn 0
EndProcedure


_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб сен 24, 2011 8:56 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Вс ноя 07, 2010 12:19 pm
Сообщений: 281
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
pablov
А какже тлс, логгирование, верификатор, конфиг етц ?

С ручной настройкой импорта такое не канает, а значит техника не годна.

_________________
Materia Lucida


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб сен 24, 2011 10:21 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Indy
тлс, логгирование, верификатор, конфиг
К чему это. Или просто пишешь, что сказать больше не чего
Прошу в студию dll, которая не загрузится по моему способу
Епте гвозди, ты умный мужик, помоги. Подскажи где я ошибся в коде, что нужно добавить\убавить а....
PS С ручной настройкой импорта такое не канает, а значит техника не годна.
Вот здесь прошу поподробней. Что означает ручная настройка импорта?

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 57 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB