API сплайсинг.

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

  1. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    Здр. Перехватываю send в проложении, заменяю первые 5 байт ( по статье )
    Код (Text):
    1. // DLL внедряемая в АП Lotus Notes
    2. //
    3.  
    4. #include "stdafx.h"
    5.  
    6. #define __dbg 1
    7.  
    8. void *oldSend;
    9. void *newSend;
    10. UCHAR oldFunc[5];
    11.  
    12.  
    13.  
    14. void __debug(char *buff,int len){
    15.     FILE *fp;
    16.     int i;
    17.     if ((fp=fopen("c:\\__debug.txt","a+"))!=NULL){
    18.         // файл открыт, надо писать
    19.         fputs("\r\n--------------------------------- PACKET START ---------------------------------\r\n",fp);
    20.         for (i = 0; i<=len ; i++)
    21.         {
    22.             fputc(buff[i],fp);
    23.         }
    24.         fputs("\r\n--------------------------------- PACKET END ---------------------------------\r\n",fp);
    25.         fclose(fp);
    26.     } // if != NULL fopen
    27. }
    28.  
    29.  
    30.  
    31. bool SetSplicingHook(void* pfnDst, void* pfnHook, UCHAR buffer[5])
    32. {
    33.     memcpy(buffer, pfnDst, 5); // бекап начала функции
    34.  
    35.     // разрешаем запись в страницу с кодом
    36.     DWORD old = 0;
    37.    
    38.     VirtualProtect(pfnDst, 5, PAGE_READWRITE, &old);
    39.     // мы запрашиваем 5 байт, но на самом деле изменятся права доступа всей страницы сразу
    40.  
    41.     // ставим JMP FAR
    42.     DWORD offset = (DWORD) pfnHook - (DWORD) pfnDst - 5;
    43.     *(BYTE*)pfnDst = 0xE9; // JMP FAR
    44.     *(DWORD*)((DWORD)pfnDst+1) = offset;
    45.  
    46.     // восстанавливает старые атрибуты страницы
    47.     VirtualProtect(pfnDst, 5, old, &old);
    48.  
    49.     // ништяк
    50.     return true;
    51. }
    52.  
    53. // снимаем локальный хук
    54. void UnsetSplicingHook(void* pfnDst, UCHAR buffer[5])
    55. {
    56.     DWORD old = 0;
    57.     VirtualProtect(pfnDst, 5, PAGE_READWRITE, &old);
    58.     __asm int 3
    59.     memcpy(pfnDst, buffer, 5); // восстанавливаем первые 5 байт из бекапа
    60.    
    61.     VirtualProtect(pfnDst, 5, old, &old);
    62. }
    63.  
    64. int hsend(SOCKET s,const char* buf,int len,int flags){
    65.     int nRet;
    66.  
    67.     __debug((char*)buf,len);
    68.    
    69.     UnsetSplicingHook(oldSend,oldFunc);
    70.    
    71.     nRet = send(s,buf,len,flags);
    72.    
    73.     SetSplicingHook(oldSend,newSend,oldFunc);
    74.    
    75.     return nRet;
    76. }
    77.  
    78.  
    79. BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    80. {
    81.     HMODULE hMod_ws2_32dll;
    82.  
    83.     if(ul_reason_for_call == DLL_PROCESS_ATTACH )
    84.     {
    85.         _asm mov newSend,offset hsend // Get newSend addr
    86.  
    87.         hMod_ws2_32dll = LoadLibrary("Ws2_32.dll");
    88.         oldSend = GetProcAddress(hMod_ws2_32dll, "send");
    89.        
    90.         if (oldSend){
    91.             if (!SetSplicingHook(oldSend,newSend,oldFunc)){
    92.                 MessageBox(0,(char *)oldFunc,0,0);
    93.             }   // if SetSplicingHook
    94.         }   // if oldSend
    95.     }    
    96.     return TRUE;
    97. }
    Только вот после 2 вызова Lotus Notes падает, никак не мог отследить почему при востановлении 5 байтов в начало send ( в ws2_32 ) записывается всякое гавно....мож вы поможете.
     
  2. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    а hsend у тебя stdcall или cdecl?
     
  3. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    не знаю :dntknw:
     
  4. TanKisT

    TanKisT New Member

    Публикаций:
    0
    Регистрация:
    21 авг 2006
    Сообщения:
    8
    Попробуй так:
    Код (Text):
    1. int [b]WINAPI[/b] hsend(SOCKET s,const char* buf,int len,int flags){
     
  5. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    Да не в этом дело, всё нормально шлёт 2 раза, но потом какой-то мусор в начале функции send, щяс я по другому пробую сплайсить
     
  6. Guest

    Guest Guest

    Публикаций:
    0
    WIN32
    Многопоточное приложение точно упадет т.к. ты каждый раз восстанавливаешь 5 байт чего делать нельзя. Посмотри вот посты http://www.wasm.ru/forum/viewtopic.php?id=20203. Тебе придется еще дизассемблер длин использовать.
    То есть схема должна быть:

    до:

    void target_example(){ // цель
    push ebp
    mov ebp, esp
    mov eax, 123
    ........
    }

    после:

    void target_example(){ // цель
    jmp allocated_address
    __original:
    ........
    ........
    }
    allocated_address: // выделеный в памяти адрес
    push ebp
    mov ebp, esp
    mov eax, 123
    call _our_proc // вызов нужной процедуры, чтобы зарегать что-либо
    jmp __original

    - ничего не востанавливаем, просто несколько инструкций перенесли в другое место и выолнили свой код