Допустим кто-то выполняет функцию Call из моей dll (см. код на Дельфи ниже) rundll32 mydll.dll,Call. Каким образом определить хендл/путь моей длл, если чел ее скопировал и переименовал как ему вздумается? Код (Text): library mydll; uses windows,sysutils; procedure Call; stdcall; begin end; var Buf: array[0..255] of Char; handle:cardinal; exports Call; begin //Как найти хендл(handle) длл? GetModuleFileName(handle, Buf, SizeOf(Buf)); MessageBox(0, Buf, PChar(IntToStr(handle))), 0); end.
В win32 handle PE файла = адресу загрузки (для EXE обычно 400000h). Поэтому на асме можно делать так: Код (Text): handle dd ? mov eax, handle ; адрес метки (можно другой) xor ax, ax ; выравниваем по PAGE mov [handle], eax ; сохраняем хэндл
по сути вопроса. цитата из МСДН: Код (Text): BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ); т.е. самый первый параметр при вызове дллмайн - это есть хендл дллки, далее делаем ему GetModuleFileName и вуаля
И куда его втыкать? По моему и так неплохо. Пасиб, S_T_A_S_ Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include '%fasminc%\win32a.inc' proc DllEntryPoint, hinstDLL,fdwReason,lpvReserved mov eax,TRUE return endp buf db ? handle dd ? proc Dure begin: mov eax,begin xor ax,ax mov [handle],eax invoke GetModuleFileName,[handle],buf,255 invoke MessageBox,HWND_DESKTOP,buf,buf,MB_OK invoke ExitProcess,0 endp section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleFileName,'GetModuleFileNameA' import user,\ MessageBox,'MessageBoxA' section '.edata' export data readable export 'MYDLL.DLL',\ Dure,'Dure' section '.reloc' fixups data discardable Тока вот не пойму две вещи. Если сделать так Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include '%fasminc%\win32a.inc' proc DllEntryPoint, hinstDLL,fdwReason,lpvReserved mov eax,TRUE return endp proc Dure return endp section '.code' code readable executable buf db ? handle dd ? begin: mov eax,begin xor ax,ax mov [handle],eax invoke GetModuleFileName,[handle],buf,255 invoke MessageBox,HWND_DESKTOP,buf,buf,MB_OK invoke ExitProcess,0 section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleFileName,'GetModuleFileNameA' import user,\ MessageBox,'MessageBoxA' section '.edata' export data readable export 'MYDLL.DLL',\ Dure,'Dure' section '.reloc' fixups data discardable то ничего не получается (хотя в дельфине и так и так канает, там кстати var handle:THandle; begin handle:= THandle(@handle) and $FFFF0000 ) И второе. Если imagebase у двух файлов одинакова, что они оба по одному адресу загружается (конечно, нет, но не пойму)? VA и реальный адрес в памяти - разные вещи?
ovod zed_0xff имел ввиду примерно так : Код (Text): ;======================================================== format PE GUI 4.0 DLL entry DllEntryPoint ;======================================================== include '%fasminc%\win32a.inc' ;======================================================== section '.code' code readable writeable executable ;======================================================== buf rb 255 ;======================================================== proc DllEntryPoint,hinstDLL,fdwReason,lpvReserved invoke GetModuleFileName,[hinstDLL],buf,255 xor eax,eax inc eax return endp ;======================================================== proc Dure invoke MessageBox,HWND_DESKTOP,buf,buf,MB_OK return endp ;======================================================== section '.idata' import data readable writeable ;======================================================== library kernel,'KERNEL32.DLL',user,'USER32.DLL' import kernel,GetModuleFileName,'GetModuleFileNameA' import user,MessageBox,'MessageBoxA' ;======================================================== section '.edata' export data readable export 'MYDLL.DLL',Dure,'Dure' section '.reloc' fixups data discardable ;========================================================
ovod Тут весь смысл в том, что в eax нужно загружать адрес метки находящейся в первой секции, и обязательно что бы fixup для неё происходил. Во 2м случае - код в другой секции, поэтому адрес вычисляется некорректно, нужно ещё и размер секции вычесть. А можно взять DllEntryPoint - он в первой секции. > Вот на то и fixup, загрузчик подправляет команды обращающиеся к меткам (релоцирует) так что модуль может работать по другому адресу. mov eax, label <- адрес label быдет скорректирован загрузчиком.