Нужно это перевести на делфи: Код (Text): __declspec(naked) int __find_address(DWORD base, DWORD hash) { __asm{ /*****************************************/ /* -2- FIND FUNCTION BY HASH */ /* -2- */ pushad /* -2- */ mov ebp, esp /* -2- */ mov eax, [ebp + 0x28] /* -2- */ mov ebp, eax /* -2- */ mov eax, [ebp + 0x3c] /* -2- */ mov edx, [ebp + eax + 0x78] /* -2- */ add edx, ebp /* -2- */ mov ecx, [edx + 0x18] /* -2- */ mov ebx, [edx + 0x20] /* -2- */ add ebx, ebp __find_function_loop: /* -2- */ jecxz __find_function_finished /* -2- */ dec ecx /* -2- */ mov esi, [ebx + ecx * 4] /* -2- */ add esi, ebp /* -2- */ xor edi, edi /* -2- */ xor eax, eax /* -2- */ cld __compute_hash_again: /* -2- */ lodsb /* -2- */ test al, al /* -2- */ jz __compute_hash_finished /* -2- */ ror edi, 0xd /* -2- */ add edi, eax /* -2- */ jmp __compute_hash_again __compute_hash_finished: /* -2- */ cmp edi, [esp + 0x24] /* -2- */ jnz __find_function_loop /* -2- */ mov ebx, [edx + 0x24] /* -2- */ add ebx, ebp /* -2- */ mov cx, [ebx + 2 * ecx] /* -2- */ mov ebx, [edx + 0x1c] /* -2- */ add ebx, ebp /* -2- */ mov eax, [ebx + 4 * ecx] /* -2- */ add eax, ebp /* -2- */ mov [esp + 0x1c], eax __find_function_finished: /* -2- */ popad /* -2- */ ret 0x0C /*****************************************/ } } делаю так: Код (Text): function find_address(base: DWORD; hash: DWORD): DWORD;cdecl; asm pushad mov ebp, esp mov eax, [ebp + $28] mov ebp, eax mov eax, [ebp + $3c] mov edx, [ebp + eax + $78] add edx, ebp mov ecx, [edx + $18] mov ebx, [edx + $20] add ebx, ebp @__find_function_loop: jecxz @__find_function_finished dec ecx mov esi, [ebx + ecx * 4] add esi, ebp xor edi, edi xor eax, eax cld @__compute_hash_again: lodsb test al, al jz @__compute_hash_finished ror edi, $d add edi, eax jmp @__compute_hash_again @__compute_hash_finished: cmp edi, [esp + $24] jnz @__find_function_loop mov ebx, [edx + $24] add ebx, ebp mov cx, [ebx + 2 * ecx] mov ebx, [edx + $1c] add ebx, ebp mov eax, [ebx + 4 * ecx] add eax, ebp mov [esp + $1c], eax @__find_function_finished: popad ret $0C end; Но почему-то все время аксесс виолейшен на этой строчке: mov edx, [ebp + eax + $78]
>> Но почему-то все время аксесс виолейшен на этой строчке посмотри код ф-ции под дебаггером, я в делфе не спец, но возможно она вставляет свой пролог
Конечно не попадает - компилер свой пролог добавил. Надо делать что-то типа: function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;assembler;
Конечно не попадает - компилер свой пролог добавил. Надо делать что-то типа: function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;assembler; не помогло проверь точно ли в eax на строчке mov eax, [ebp + 0x28] попадает значение переданное в base в eax с самого начала находится значение base, после этого mov eax, [ebp + 0x28] значение eax не изменилось
user32 В сишных declspec я ни бум-бум, но судя по ret 0x0C используется вызов stdcall со стандартным прологом - соответственно ret 12 снимает со стека 4 байта от push ebp и 8 байт входных праметров. Поэтому (по всей видимости) нужно просто заменить cdecl на stdcall
дык а толку, если в eax все равно правильная база образа? user32, может ты файл недопрочитал? Я смотрю уже 15 раз - код вроде бы правильный. Еще, посмотри атрибуты страниц (VirtualProtect) - может твой делфи где- закрывает доступ на чтение.
может это поможет: Код (Text): base=2088763392 function find_address(base: DWORD; hash: DWORD): DWORD;cdecl; asm pushad mov ebp, esp //ebp=1242504 esp=1242472 mov eax, [ebp + $28]//eax=2088763392 ebp=1242472 mov ebp, eax//ebp=1242472 eax=2088763392 mov eax, [ebp + $3c]//eax=2088763392 ebp=2088763392 mov edx, [ebp + eax + $78]//edx=9787256 ebp=2088763392 eax=232
Great Дык это исходники, а не асм-листиги Автопролог, вставляемый компилятором - и ret 12 на это указывает и первый параметр читается как [ebp+40] - 32 байта на pushad, 4 байта на push ebp и 4 на адрес возврата MSoft Угу, [ebp+3Ch] читается нормально, а [ebp+eax+78h] из той же страницы валится - чудеса, да и только Это она при первом вызове правильная, а при втором из-за неверного вызова cdecl указатель стека смещается на 8 байт и последующие push могут изгадить локальную переменную base user32 В приведенном выше куске кода вроде все правильно за исключением cdecl - замени на stdcall, тогда видно будет. Проблемы нужно решать по мере их выявления, а не гадать на кофейной гуще
leo и как ты вернешь стек от push ebp через RET xx ? это делается ведь через leave/ret ну при желании такое можно усторить, если на странице стоит PAGE_NOACCESS и обработчик access violation сам раздает доступ )
impossible Код верный, комменты моих рук дело, я его не один день тестил на всем чем можно, поэтому stdcall верный выход из проблемы. Его вообще valeryno написал. В коде выпоняются довольно простые операции - поиск экспорта, перечисление имен - все проверено. P.S. user32 Не забывай обнулить eax перед вызовом, чтобы потом проверить результат.
Great Мда, похоже я чушь сморозил ( Похоже тут вообще pascal-вызовом попахивает с третьим параметром, т.к. base = esp+28h, а hash = esp+24h, т.е. параметры идут в обратном порядке
Ес-но погибает, но но есть выход через одно место - перед вызовом функции поместить в ebp адрес возврата Но вместо того, чтобы извращаться и блуждать в 3-х соснах проще подправить функцию для нормального stdcall-вызова Код (Text): function find_address(base: DWORD; hash: DWORD): DWORD; stdcall; asm //скрытый пролог //push ebp //+4 //mov ebp,esp //---------------- pushad //+32 mov eax, [esp+40] //base = esp+40 = 32+4+4 mov ebp, eax ............... @__compute_hash_finished: cmp edi, [esp+44] //hash = esp+44 ............... @__find_function_finished: popad //скрытый эпилог //mov esp,ebp //pop ebp //retn 8 end;
Код (Text): function find_address(base: DWORD; hash: DWORD): DWORD;stdcall; asm pushad mov eax, [esp + 40] mov ebp, eax mov eax, [ebp + $3c] mov edx, [ebp + eax + $78] add edx, ebp mov ecx, [edx + $18] mov ebx, [edx + $20] add ebx, ebp @__find_function_loop: jecxz @__find_function_finished dec ecx mov esi, [ebx + ecx * 4] add esi, ebp xor edi, edi xor eax, eax cld @__compute_hash_again: lodsb test al, al jz @__compute_hash_finished ror edi, $d add edi, eax jmp @__compute_hash_again @__compute_hash_finished: cmp edi, [esp + 44] jnz @__find_function_loop mov ebx, [edx + $24] add ebx, ebp mov cx, [ebx + 2 * ecx] mov ebx, [edx + $1c] add ebx, ebp mov eax, [ebx + 4 * ecx] add eax, ebp mov [esp + $1c], eax @__find_function_finished: popad end; Так вроде как работает, в конце в eax находится нужный адрес, только после вызова этой функции почему-то возвращает 0.
А не проще ли эту ф-цию переписать на Дельфи и не париться ? Что там переводить-то... Не знаю как в Дельфи, но компилятор VC сгенерил бы существенно лучший код, чем в приведённом "шедевре" ручной оптимизации.