Cнова сплайсинг API функций

Тема в разделе "WASM.WIN32", создана пользователем ASMatik, 3 ноя 2008.

  1. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    Пишу программу, в которой требуется перехватывать API функции. Просмотрел кучу статей, но так и не нашел ничего на асме, в результате чего переписал на асм код из статьи http://rsdn.ru/article/baseserv/IntercetionAPI.xml
    Вот код:
    Код (Text):
    1. .386
    2.     .model flat,stdcall
    3.     option casemap:none
    4.     include \masm32\include\windows.inc
    5.     include \masm32\include\user32.inc
    6.     include \masm32\include\kernel32.inc
    7.  
    8.     includelib \masm32\lib\user32.lib
    9.     includelib \masm32\lib\kernel32.lib
    10.    
    11.     jmp_far struct
    12.         push_op     db  0
    13.         arg     dd  0
    14.         ret_op      db  0      
    15.     jmp_far ends
    16.  
    17. .data
    18.     hInstance   dd      0
    19.     hProcess    dd      0
    20.    
    21.     NewCode     jmp_far <> 
    22.     OldCode     db      6 dup(0)
    23.    
    24.     ProcAddr    dd      0
    25.    
    26.     LibName     db  "kernel32.dll",0
    27.     ProcName    db  "GetSystemTime",0
    28.        
    29.     mbError     db  "Can't get 'GetSystemTime' address",0
    30.     mbTitle     db  "Error",0  
    31.        
    32. .code
    33. NewGetSystemTime proc lpSystemTime:DWORD
    34.     LOCAL bytes :DWORD
    35.    
    36.     invoke  WriteProcessMemory, hProcess, ProcAddr, addr OldCode, 6, bytes
    37.     invoke  GetSystemTime, lpSystemTime
    38.     invoke  WriteProcessMemory, hProcess, ProcAddr, addr NewCode, 6, bytes
    39.     ret    
    40. NewGetSystemTime endp
    41.  
    42. SetHook proc
    43.     LOCAL bytes :DWORD
    44.        
    45.     invoke  GetModuleHandle, addr LibName
    46.     invoke  GetProcAddress, eax, addr ProcName
    47.     mov     ProcAddr, eax
    48.     .if (eax == 0)
    49.         invoke MessageBox, 0, addr mbError, addr mbTitle, MB_OK+MB_ICONERROR
    50.         ret
    51.     .endif
    52.    
    53.     mov     NewCode.push_op, 68h
    54.     mov     NewCode.arg, offset NewGetSystemTime
    55.     mov     NewCode.ret_op, 0C3h
    56.        
    57.     invoke  ReadProcessMemory, hProcess, ProcAddr, addr OldCode, 6, bytes
    58.     invoke  WriteProcessMemory, hProcess, ProcAddr, addr NewCode, 6, bytes
    59.        
    60.     ret
    61. SetHook endp
    62.  
    63. Unhook proc
    64.     LOCAL bytes :DWORD
    65.    
    66.     invoke  WriteProcessMemory, hProcess, ProcAddr, addr OldCode, 6, bytes
    67.     ret
    68. Unhook endp
    69.  
    70. DllEntryPoint proc hinstDLL:DWORD,fdwReason:DWORD,lpvReserved:DWORD
    71.     push    hinstDLL
    72.     pop     hInstance
    73.     call    GetCurrentProcess
    74.     mov     hProcess, eax
    75.    
    76.     .if     (fdwReason == DLL_PROCESS_ATTACH)
    77.         call    SetHook
    78.     .elseif (fdwReason == DLL_PROCESS_DETACH)
    79.         call    Unhook
    80.     .endif
    81.    
    82.     ret
    83. DllEntryPoint endp
    84.  
    85. End DllEntryPoint
    Батник для компиляции:
    Код (Text):
    1. @echo off
    2.  
    3. if exist time.obj del time.obj
    4. if exist time.dll del time.dll
    5.  
    6. \masm32\bin\ml /c /coff time.asm
    7.  
    8. \masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL time.obj
    9.  
    10. dir time.*
    11.  
    12. pause
    Итак, ошибки (их пока всего 2):
    1. Скомпиленная либа не загружается через LoadLibrary до тех пор, пока в DllEntryPoint в DLL_PROCESS_ATTACH не поставить invoke Sleep или invoke MessageBox перед "SetHook"
    2. Допустим, я вызвал MessageBox или Sleep перед "SetHook". Все заработало, но в этом случае при вызове GetSystemTime из программы, в которую внедрена библиотека, вылетает ексепшн.

    Вопрос: что я делаю не так?
     
  2. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Советую воспользоваться отладчиком, а вообще первое что бросается в глаза:

    invoke WriteProcessMemory, hProcess, ProcAddr, addr OldCode, 6, bytes

    Последний параметр должен быть указателем, и снимать перехват для вызова оригинальной функции как минимум плохой метод лучше использовать дизасм длин инструкций сохранить в буфер старые байты и сделать переход на продолжение функции. Читай статьи по перехвату от Ms-Rem'a, да и довольно много в инете готовых сорсов на эту тему мог хотябы поискать.
     
  3. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    О! Точно! Спасибо тебе, blast. Действительно забыл проставить addr перед bytes))) Блин. Ночью мозг отключается)))
     
  4. barton

    barton New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2008
    Сообщения:
    164
    Адрес:
    Czechoslovakia
    invoke ReadProcessMemory, hProcess, ProcAddr, addr OldCode, 6, bytes
    invoke WriteProcessMemory, hProcess, ProcAddr, addr NewCode, 6, bytes

    addr bytes, а не bytes

    там указатель куда записать кол-во прочитаных/записаных байт

    чорт.
    написал месагу а там уже ответит висит)
    сорри)