Доброго времени суток. у меня такой вопрос: в ринг3 нахожу kernel32.dll таким образом Код (Text): function GetKernel : DWORD; assembler; asm mov eax, dword ptr fs:[30h] mov eax, dword ptr [eax+0ch] mov esi, dword ptr [eax+1ch] lodsd mov eax, dword ptr [eax+08h] end; каким образом я могу с помощью этого найти адрес функции в ринг3 ? что нибудь вроде myGetProcAddress(hModule: DWORD; szProcName: PChar) : Pointer; благодарю за внимание.
GeNeZiS Вот код yoda, оптимизированный мной. Код (Text): GetProcAddr proc uses esi edi ebx dwDllBase:DWORD, lpProcName:DWORD ; check PE Signature mov esi, dwDllBase cmp word ptr [esi], IMAGE_DOS_SIGNATURE jnz not_found add esi, [esi + 3ch] cmp word ptr [esi], IMAGE_NT_SIGNATURE jnz not_found ; get the length of the target proc name mov edi, lpProcName or ecx, -1 xor eax, eax repne scasb not ecx ; ecx -> ProcName length assume edx: ptr IMAGE_EXPORT_DIRECTORY ; trace the export table mov edx, [esi + 078h] ; edx -> Export table add edx, dwDllBase mov ebx, [edx].AddressOfNames ; ebx -> AddressOfNames array pointer add ebx, dwDllBase ; xor eax, eax ; eax -> AddressOfNames Index .repeat mov edi, [ebx] add edi, dwDllBase mov esi, lpProcName push ecx ; save ProcName length repe cmpsb je found ; found smth ? pop ecx ; restore ProcName length add ebx, 4 inc eax .until [edx].NumberOfNames == eax jmp not_found found: pop ecx mov ecx, dwDllBase mov esi, ecx ; find the corresponding ordinal add ecx, [edx].AddressOfNameOrdinals lea eax, [ecx + 2*eax] movzx eax, word ptr [eax] ; eax -> Api Ordinal ; get the address of the api lea eax, [esi + 4*eax] add eax, [edx].AddressOfFunctions mov eax, [eax] add eax, esi jmp return assume edx: nothing not_found: xor eax, eax return: ret GetProcAddr endp
огромная всем благодарность. особенно koderrу еще вопрос: assume edx: ptr IMAGE_EXPORT_DIRECTORY как нибудь можно это заменить аналогом, ато у меня делфа ругается на assume?
В Delphi и Builder когда делаешь lea в регистр, автоматически подключается контроль типов. Типа автоматической assume получается
GeNeZiS Что-то типа этого: Код (Text): var pt: TPoint; begin asm lea eax,pt // неявный ASSUME eax:TPoint mov ebx,[eax].x sub ebx,[eax].y end; end;
2 gilg попытался сделать так: Код (Text): function myGetProcAddress(hModule: DWORD; szProcName: PChar) : Pointer; assembler; const IMAGE_DOS_SIGNATURE = $5A4D; IMAGE_NT_SIGNATURE = $00004550; var IED : IMAGE_EXPORT_DIRECTORY; asm mov esi, hModule cmp word ptr [esi], IMAGE_DOS_SIGNATURE jnz @not_found add esi, dword ptr [esi + 3ch] cmp word ptr [esi], IMAGE_NT_SIGNATURE jnz @not_found lea edx, IED mov edx, [esi + 078h] add edx, hModule mov ebx, [edx].AddressOfNames add ebx, hModule @l00p: mov edi, [ebx] add edi, hModule mov esi, szProcName push ecx repe cmpsb je @found pop ecx add ebx, 4 inc eax cmp [edx].NumberOfNames, eax jne @l00p jmp @not_found @found: pop ecx mov ecx, hModule mov esi, ecx add ecx, [edx].AddressOfNameOrdinals lea eax, [ecx + 2*eax] movzx eax, word ptr [eax] lea eax, [esi + 4*eax] add eax, [edx].AddressOfFunctions mov eax, [eax] add eax, esi ret @not_found: xor eax, eax ret end; не получается. ((( пишет Undeclared identifier: 'AddressOfNames' то же самое и для NumberOfNames, AddressOfNameOrdinals, AddressOfFunctions. просто уж не знаю что и сделать. очень нужна помощь.
Код (Text): lea edx, IED mov edx, [esi + 078h] ; mov после lea все сбрасывает add edx, hModule mov ebx, [edx].AddressOfNames Попробуй изменить так: Код (Text): lea edx, IED mov ebx, [edx].AddressOfNames Если скомпилится, посмотрим дальше. ЗЫ: А чем не устраивает целиком на Delphi? Посмотри здесь: http://www.wasm.ru/forum/viewtopic.php?id=11349 и здесь http://www.wasm.ru/forum/viewtopic.php?id=12479 Думаю, с СИшными исходниками будет проще разобраться, как это работает, чем с асмовыми
Код (Text): function xGetProcAddress(hMod: HMODULE; ProcName: PChar): Pointer; stdcall; var ExportDir: PImageExportDirectory; i, IndInAddr: DWORD; begin result:=nil; ExportDir:=PImageExportDirectory(PImageNtHeaders(hMod+DWORD(PImageDosHeader(hMod).e_lfanew)).OptionalHeader. DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+hMod); for i:=0 to ExportDir.NumberOfNames-1 do begin if ComparePCharStrings(PChar(PDWORD(DWORD(ExportDir.AddressOfNames)+hMod+i*4)^+hMod), ProcName) then begin IndInAddr:=PWORD(DWORD(ExportDir.AddressOfNameOrdinals)+hMod+i*2)^; result:=Pointer(PDWORD(DWORD(ExportDir.AddressOfFunctions)+hMod+IndInAddr*4)^+hMod); exit; end; end; end; Код писал лет 5 назад, но работать должен и сейчас =)
Вот это круче =) Код (Text): PInt(PInt(ListEntry+4)^)^:=PInt(PInt(PInt(ListEntry+4)^)^)^; PInt(PInt(ListEntry+4)^+4)^:=PInt(PInt(PInt(ListEntry+4)^+4)^+4)^;
GeNeZiS, gilg В дельфях это делается так Код (Text): //объявим тип покороче, чтобы не возиться с длинным именем type IED = IMAGE_EXPORT_DIRECTORY; asm //равнозначные варианты mov ebx, IED[edx].AddressOfNames mov ebx, [edx].IED.AddressOfNames mov ebx, [edx+IED.AddressOfNames]
leo Наконец, пришли к истине Нашел мануал по инлайн-ассемблеру в Делфи: http://info.borland.com/techpubs/delphi/delphi5/oplg/assemblr.html ЗЫ: Странно, но про билдер на всем сайте почти что ни одного умного слова нет. Все больше про создание на нем текстового редактора
доброго времени суток. всем огромная благодарность. получился такой код: Код (Text): function myGetProcAddress(hModule: DWORD; szProcName: PChar) : Pointer; assembler; type IED = IMAGE_EXPORT_DIRECTORY; const IMAGE_DOS_SIGNATURE = $5A4D; IMAGE_NT_SIGNATURE = $00004550; asm mov esi, hModule cmp word ptr [esi], IMAGE_DOS_SIGNATURE jnz @not_found add esi, dword ptr [esi + 3ch] cmp word ptr [esi], IMAGE_NT_SIGNATURE jnz @not_found mov edx, [esi + 078h] add edx, hModule mov ebx, [edx].IED.AddressOfNames add ebx, hModule @l00p: mov edi, [ebx] add edi, hModule mov esi, szProcName push ecx repe cmpsb je @found pop ecx add ebx, 4 inc eax cmp [edx].IED.NumberOfNames, eax jnz @l00p jmp @not_found @found: pop ecx mov ecx, hModule mov esi, ecx add ecx, [edx].IED.AddressOfNameOrdinals lea eax, [ecx + 2*eax] movzx eax, word ptr [eax] lea eax, [esi + 4*eax] add eax, [edx].IED.AddressOfFunctions mov eax, [eax] add eax, esi ret @not_found: xor eax, eax ret end; все удачно скомпилировалось, только вылетает окно с ошибкой и программа не работает. что я делаю не правильно? или код не рабочий?