елаю запуск файла с памяти,при заполнение импорта возникает проблема. Первым в Import descriptor'e kernel32 идет, он грузится нормально. все ок. Затем переходим к user32 , и LoadLibrary возвращает ERROR_DLL_INIT_FAILED. вот код процедуры заполнения импорта. Код (Text): proc FillImport pImportTable,pAllocedMemory pusha mov edx,[pImportTable] add edx,[pAllocedMemory];edx - IMAGE_IMPORT_DSCRIPTOR. _loop: push edx mov edi,[edx+IMAGE_IMPORT_DESCRIPTOR.FirstThunk] mov esi,[edx+IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk] test edi,edi;Если последний IMAGE_IMPORT_DESCRIPTOR jz end_it test esi,esi;если OriginalFirstThunk нулевой jnz __ok mov esi,edi;То присвоить ему значение из FirstThunk __ok: mov eax,[edx+IMAGE_IMPORT_DESCRIPTOR.Name1] add eax,[pAllocedMemory];eax имя длл add edi,[pAllocedMemory];сюда будем писать адреса функций add esi,[pAllocedMemory];esi - VA массива IMAGE_THUNk_DATA xcall LoadLibraryA,eax push eax load_func_addres: lodsd;eax - RVA IMAGE_IMPORT_BY_NAME test eax,eax jz _goto_next_ImportDescriptor bt eax,31;если этот бит установлен,то импорт по ординалу jnz .no_ord and eax,0ffffh;Выделем из eax ординал функции jmp .getproc .no_ord: add eax,[pAllocedMemory];eax - VA IMAGE_IMPORT_BY_NAME add eax,2;VA имени функции .getproc: ;push ebp mov ecx,[esp] xcall GetProcAddress,ecx,eax ;pop ebp stosd;Пишем адрес в FirstThunk jmp load_func_addres _goto_next_ImportDescriptor: pop eax pop edx add edx,20 jmp _loop end_it: ;pop eax pop edx popa ret endp подскажите,пожалуйста где косяк. PS xcall вызывает функу с учетом дельта смещения,оно в ebx
совсем не понятно откуда берется массив структур IMAGE_IMPORT_DESCRIPTOR STRUCT если это просто PE файл как есть то :RVA и смещение в файле не одно и тоже
ну в pImportTable передается указатель на таблицу импорта,из DataDirectory. ну я это знаю как бы.. И потом если kernel32 нормально грузится,функции в нем ищутся, значит все норм. Где-то еще ошибку допустил,но не могу понять где. msvcrt.dll тоже нормально загружается,а вот user32 почему то не хочет.
dyn попробовал,длл вроде грузится,но GetProcAddress возвращает не тот адерс. Функция (MessageBox не вызвается). Код такойже как и в первом посте,поменял только LoadLibraryEx на LoadLibrary. Может стоит добавить,что процедура во время работы переносится за ImageBase+SizeofImage файла который загружаем
Код (Text): mov esi,_file;esi указывает на файл add esi,[esi+3ch] ;peheader mov ecx,[esi+34h] ;ecx=image base mov edx,[esi+50h] ;edx=SizeOfImage lea edi,[edx+ecx];edi - imagebase+SizeOfImage mov esi,iSizeToAlloc;Размер загрузчика add esi,10000h and esi,0ffff0000h;округляем @@: add edi,10000h invoke VirtualAlloc,edi,esi,MEM_RESERVE+MEM_COMMIT,PAGE_EXECUTE_READWRITE;размещаем загрузчие за SizeofImage+ImageBase test eax,eax jz @b mov ebp,eax mov esi,krnl32 mov edi,ebp @@:;копируем адреса апи функций,необходимых загрузчику lodsd test eax,eax jz @f mov eax,[eax] stosd jmp @b @@: ;push ebp mov esi,Execute mov edi,ebp mov ecx,iSizeToAlloc rep movsb ;копируем загрузчик вместе с файлом ;pop ebp jmp ebp
боюсь даже спрашивать, но любопытно это как ? GetProcAddress возвращает либо 0 либо правильный адрес Код (Text): .... add esi,10000h and esi,0ffff0000h;округляем @@: add edi,10000h ;<----------------- я так понимаю что виртуальный адрес новоиспеченного PE отличается от задуманного при компиляции короче есть туманное предположение и "выложу его сразу" (очень надеюсь что не обидишься) посмотри на опкоды этих знакомых переходов через которые ползают все вызовы, в секции кода (по крайний мере у меня по умолчанию все эгзешники так собираются) Код (Text): 0040104A .- FF25 10204000 JMP DWORD PTR DS:[<&kernel32.ExitProcess>] 00401050 $- FF25 00204000 JMP DWORD PTR DS:[<&kernel32.GetLastError>] 00401056 $- FF25 04204000 JMP DWORD PTR DS:[<&kernel32.GetModuleHandleA>] 0040105C $- FF25 08204000 JMP DWORD PTR DS:[<&kernel32.GetProcAddress>] 00401062 $- FF25 0C204000 JMP DWORD PTR DS:[<&kernel32.LoadLibraryExA>] это же жестко прописанные виртуальные адреса, и их тоже правишь ?