find_address

Тема в разделе "WASM.BEGINNERS", создана пользователем user32, 30 апр 2007.

  1. user32

    user32 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    Нужно это перевести на делфи:

    Код (Text):
    1. __declspec(naked) int __find_address(DWORD base, DWORD hash)
    2. {
    3.     __asm{
    4. /*****************************************/
    5. /* -2- FIND FUNCTION BY HASH    */
    6. /* -2- */       pushad
    7. /* -2- */       mov   ebp,  esp
    8. /* -2- */       mov   eax, [ebp + 0x28]
    9. /* -2- */       mov   ebp, eax
    10. /* -2- */       mov   eax, [ebp + 0x3c]
    11. /* -2- */       mov   edx, [ebp + eax + 0x78]
    12. /* -2- */       add   edx, ebp
    13. /* -2- */       mov   ecx, [edx + 0x18]
    14. /* -2- */       mov   ebx, [edx + 0x20]
    15. /* -2- */       add   ebx, ebp
    16. __find_function_loop:
    17. /* -2- */       jecxz __find_function_finished
    18. /* -2- */       dec   ecx
    19. /* -2- */       mov   esi, [ebx + ecx * 4]
    20. /* -2- */       add   esi, ebp
    21. /* -2- */       xor   edi, edi
    22. /* -2- */       xor   eax, eax
    23. /* -2- */       cld
    24. __compute_hash_again:
    25. /* -2- */       lodsb
    26. /* -2- */       test  al, al
    27. /* -2- */       jz    __compute_hash_finished
    28. /* -2- */       ror   edi, 0xd
    29. /* -2- */       add   edi, eax
    30. /* -2- */       jmp   __compute_hash_again
    31. __compute_hash_finished:        
    32. /* -2- */       cmp   edi, [esp + 0x24]
    33. /* -2- */       jnz   __find_function_loop
    34. /* -2- */       mov   ebx, [edx + 0x24]
    35. /* -2- */       add   ebx, ebp
    36. /* -2- */       mov   cx,  [ebx + 2 * ecx]
    37. /* -2- */       mov   ebx, [edx + 0x1c]
    38. /* -2- */       add   ebx, ebp
    39. /* -2- */       mov   eax, [ebx + 4 * ecx]
    40. /* -2- */       add   eax, ebp
    41. /* -2- */       mov   [esp + 0x1c], eax
    42. __find_function_finished:
    43. /* -2- */       popad
    44. /* -2- */       ret 0x0C
    45. /*****************************************/
    46.     }
    47. }
    делаю так:


    Код (Text):
    1. function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;
    2. asm
    3.  
    4.        pushad
    5.        mov   ebp,  esp
    6.        mov   eax, [ebp + $28]
    7.        mov   ebp, eax
    8.        mov   eax, [ebp + $3c]
    9.        mov   edx, [ebp + eax + $78]
    10.        add   edx, ebp
    11.        mov   ecx, [edx + $18]
    12.        mov   ebx, [edx + $20]
    13.        add   ebx, ebp
    14. @__find_function_loop:
    15.        jecxz @__find_function_finished
    16.        dec   ecx
    17.        mov   esi, [ebx + ecx * 4]
    18.        add   esi, ebp
    19.        xor   edi, edi
    20.        xor   eax, eax
    21.        cld
    22. @__compute_hash_again:
    23.        lodsb
    24.        test  al, al
    25.        jz    @__compute_hash_finished
    26.        ror   edi, $d
    27.        add   edi, eax
    28.        jmp   @__compute_hash_again
    29. @__compute_hash_finished:
    30.        cmp   edi, [esp + $24]
    31.        jnz   @__find_function_loop
    32.        mov   ebx, [edx + $24]
    33.        add   ebx, ebp
    34.        mov   cx,  [ebx + 2 * ecx]
    35.        mov   ebx, [edx + $1c]
    36.        add   ebx, ebp
    37.        mov   eax, [ebx + 4 * ecx]
    38.        add   eax, ebp
    39.        mov   [esp + $1c], eax
    40. @__find_function_finished:
    41.        popad
    42.        ret $0C
    43. end;
    Но почему-то все время аксесс виолейшен на этой строчке:
    mov edx, [ebp + eax + $78]
     
  2. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    >> Но почему-то все время аксесс виолейшен на этой строчке
    посмотри код ф-ции под дебаггером, я в делфе не спец, но возможно она вставляет свой пролог
     
  3. IMW11

    IMW11 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    проверь точно ли в eax на строчке
    mov eax, [ebp + 0x28]
    попадает значение переданное в base
     
  4. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Конечно не попадает - компилер свой пролог добавил.
    Надо делать что-то типа:
    function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;assembler;
     
  5. user32

    user32 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    Конечно не попадает - компилер свой пролог добавил.
    Надо делать что-то типа:
    function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;assembler;

    не помогло

    проверь точно ли в eax на строчке
    mov eax, [ebp + 0x28]
    попадает значение переданное в base

    в eax с самого начала находится значение base, после этого mov eax, [ebp + 0x28] значение eax не изменилось
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    user32
    В сишных declspec я ни бум-бум, но судя по ret 0x0C используется вызов stdcall со стандартным прологом - соответственно ret 12 снимает со стека 4 байта от push ebp и 8 байт входных праметров. Поэтому (по всей видимости) нужно просто заменить cdecl на stdcall
     
  7. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    дык а толку, если в eax все равно правильная база образа?

    user32, может ты файл недопрочитал? Я смотрю уже 15 раз - код вроде бы правильный. Еще, посмотри атрибуты страниц (VirtualProtect) - может твой делфи где- закрывает доступ на чтение.
     
  8. user32

    user32 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    может это поможет:

    Код (Text):
    1.                       base=2088763392
    2. function find_address(base: DWORD; hash: DWORD): DWORD;cdecl;
    3. asm
    4.  
    5.        pushad
    6.        mov   ebp,  esp //ebp=1242504 esp=1242472
    7.        mov   eax, [ebp + $28]//eax=2088763392 ebp=1242472
    8.        mov   ebp, eax//ebp=1242472 eax=2088763392
    9.        mov   eax, [ebp + $3c]//eax=2088763392 ebp=2088763392
    10.        mov   edx, [ebp + eax + $78]//edx=9787256 ebp=2088763392 eax=232
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а где ты видишь там push ebp?
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Great
    Дык это исходники, а не асм-листиги ;) Автопролог, вставляемый компилятором - и ret 12 на это указывает и первый параметр читается как [ebp+40] - 32 байта на pushad, 4 байта на push ebp и 4 на адрес возврата

    MSoft
    Угу, [ebp+3Ch] читается нормально, а [ebp+eax+78h] из той же страницы валится - чудеса, да и только ;)

    Это она при первом вызове правильная, а при втором из-за неверного вызова cdecl указатель стека смещается на 8 байт и последующие push могут изгадить локальную переменную base

    user32
    В приведенном выше куске кода вроде все правильно за исключением cdecl - замени на stdcall, тогда видно будет. Проблемы нужно решать по мере их выявления, а не гадать на кофейной гуще ;)
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    leo
    и как ты вернешь стек от push ebp через RET xx ?
    это делается ведь через leave/ret
    ну при желании такое можно усторить, если на странице стоит PAGE_NOACCESS и обработчик access violation сам раздает доступ )
     
  12. Guest

    Guest Guest

    Публикаций:
    0
    impossible

    Код верный, комменты моих рук дело, я его не один день тестил на всем чем можно, поэтому stdcall верный выход из проблемы. Его вообще valeryno написал. В коде выпоняются довольно простые операции - поиск экспорта, перечисление имен - все проверено.
    P.S. user32 Не забывай обнулить eax перед вызовом, чтобы потом проверить результат.
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Great
    Мда, похоже я чушь сморозил :dntknw:(

    Похоже тут вообще pascal-вызовом попахивает с третьим параметром, т.к. base = esp+28h, а hash = esp+24h, т.е. параметры идут в обратном порядке
     
  14. user32

    user32 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    stdcall помог, теперь аксесвиолейшен на этом ret $0C
     
  15. Guest

    Guest Guest

    Публикаций:
    0
    видать адрес возрата погибает, кинь асм-листинг пролога до
    mov ebp, esp
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ес-но погибает, но но есть выход через одно место - перед вызовом функции поместить в ebp адрес возврата ;)

    Но вместо того, чтобы извращаться и блуждать в 3-х соснах проще подправить функцию для нормального stdcall-вызова
    Код (Text):
    1. function find_address(base: DWORD; hash: DWORD): DWORD; stdcall;
    2. asm
    3.   //скрытый пролог
    4.   //push ebp                 //+4
    5.   //mov ebp,esp
    6.   //----------------
    7.   pushad                     //+32
    8.   mov   eax, [esp+40]        //base = esp+40 = 32+4+4
    9.   mov   ebp, eax
    10.   ...............
    11. @__compute_hash_finished:
    12.   cmp   edi, [esp+44]        //hash = esp+44
    13.   ...............
    14. @__find_function_finished:
    15.   popad
    16.   //скрытый эпилог
    17.   //mov esp,ebp
    18.   //pop ebp
    19.   //retn 8
    20. end;
     
  17. user32

    user32 New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    5
    Код (Text):
    1. function find_address(base: DWORD; hash: DWORD): DWORD;stdcall;
    2. asm
    3.        pushad
    4.        mov   eax, [esp + 40]
    5.        mov   ebp, eax
    6.        mov   eax, [ebp + $3c]
    7.        mov   edx, [ebp + eax + $78]
    8.        add   edx, ebp
    9.        mov   ecx, [edx + $18]
    10.        mov   ebx, [edx + $20]
    11.        add   ebx, ebp
    12. @__find_function_loop:
    13.        jecxz @__find_function_finished
    14.        dec   ecx
    15.        mov   esi, [ebx + ecx * 4]
    16.        add   esi, ebp
    17.        xor   edi, edi
    18.        xor   eax, eax
    19.        cld
    20. @__compute_hash_again:
    21.        lodsb
    22.        test  al, al
    23.        jz    @__compute_hash_finished
    24.        ror   edi, $d
    25.        add   edi, eax
    26.        jmp   @__compute_hash_again
    27. @__compute_hash_finished:
    28.        cmp   edi, [esp + 44]
    29.        jnz   @__find_function_loop
    30.        mov   ebx, [edx + $24]
    31.        add   ebx, ebp
    32.        mov   cx,  [ebx + 2 * ecx]
    33.        mov   ebx, [edx + $1c]
    34.        add   ebx, ebp
    35.        mov   eax, [ebx + 4 * ecx]
    36.        add   eax, ebp
    37.        mov   [esp + $1c], eax
    38. @__find_function_finished:
    39.        popad
    40.  
    41. end;
    Так вроде как работает, в конце в eax находится нужный адрес, только после вызова этой функции почему-то возвращает 0.
     
  18. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
  19. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    А не проще ли эту ф-цию переписать на Дельфи и не париться ? Что там переводить-то...

    Не знаю как в Дельфи, но компилятор VC сгенерил бы существенно лучший код, чем в приведённом "шедевре" ручной оптимизации.