splice ws2_32

Тема в разделе "WASM.WIN32", создана пользователем 63F45EF45RB65R6VR, 9 ноя 2011.

  1. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    shchetinin
    > А как на счет того что в момент патчей либа выгрузилась?

    При патче jmp short -> jmp far выгрузиться ничего не может?
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    deLight
    Я имею ввиду что потоки должны быть остановлены ... А не какой джамб выбрать... Не говоря уже от том что не для каждого же патча проверять а не выгрузили ли либу?
     
  3. 63F45EF45RB65R6VR

    63F45EF45RB65R6VR New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2011
    Сообщения:
    70
    хм ну а допустим такая ситуация если запускается софт который устраивает цепочки хуков тоесть есть например плагин в opera.exe который всегда сплайсит ws2_32.dll но в это время запускается другая программа которая аттачится к opera.exe и тоже ставит хуки на ws2_32.dll то в случае с push ret в прологе я просто копировал push ret предыдущего перехватчика в трамплин в итоге сначало вызывалсЯ мой перезхватчик я вызывал трамлин попадал в старый перехватчик из него вызывалась настоящая апи в итоге софт друг другу не мешал сплайсить одни и теже функции софт разный например плагин всегда модифицирует пакеты opera.exe во время работы но если надо подцепить некую программу сниффер то нет проблем цепочка хуков прекрасно работает а как быть в случае с хот патчиногм ? получится ли так же делать ?
     
  4. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Почему система будет деградировать? Просто код будет в памяти висеть, это конечно не по фен шую, зато просто.

    Не совсем врубился что имелось ввиду под "расщепленными страницами"?

    Помоему вы сильно усложнили все. Тормозим все потоки, смотрим какие из них выполняются в нашем обработчике либо трамплине. Ставим флаг unhook и (любым удобным способом, например в TEB) и отпускаем этот поток.
    MainUnhookLoop()
    {
    SuspendAllThreadsWithoutMe(); //тормозим все кроме нас =))
    HOOKED_FUNCTOINS hf[NumberOfFunction];
    for(int i=0; i<RTL_NUMBER_OF(hf); i++)
    {
    if(!IsEipInTramp(Thread.eip)
    && !IsEipInDispatcher(Thread.eip)) //проверяем не находится ли поток в данный момент в нашем коде
    {
    RestoreOriginalBytes();
    }
    else
    {
    //если нам не повезло))
    SetThreadUnhookFlag(Thread.TEB) // устанавливаем флаг любым удобным способом
    WaitForEvent(Unhook_Event);
    }
    }
    UnloadHookDll();
    }
    В конце каждого обработчика должна быть вставка типа
    if(CheckUnhookFlag()) // проверяем надо ли анхукать
    {
    CloseHandle(CreateThread(UnhookThread,PARAMS{FuncBegin,OriginalBytes})); //создаем поток который просто восстановит байты а этот усыпляем, проснется он уже на точке входа ф-ции которую анхукаем. передаем ему все необходимое для этого
    while(TRUE) {nop;} // подвешиваем чтобы никуда не убежал))
    }
    UnhookThread()
    {
    RestoreOriginalBytes();
    SuspendThread;
    SetThreadContext(eip=FuncBegin);
    SignalizeToUnhookLoop();
    CloseThread();
    }

    Вроде бы должно работать, если что предупреждаю: писал засыпая, возможно где-то глупые ошибки, но мне кажется вполне рабочий вариант, не нравится только создание потока для каждой ф-ции.
     
  5. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    shchetinin
    Так схватить LoaderLock, запатчить, отдать. Проще чем ловить все в хендлере.
     
  6. 63F45EF45RB65R6VR

    63F45EF45RB65R6VR New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2011
    Сообщения:
    70
    вот как обычно программы накатывали патчи друг на друга и работали в цепочке придумать бы еще как замарозить процесс перед патчингом что бы ни один поток не был замарожен в DllMain тогда создать новый поток и можно проверять в нем что
    Eip != ws2_32.dll!for_each_func_entry + diasm(min(6)) и патчить
    Код (Text):
    1. #include <windows.h>
    2.  
    3. // SLESH
    4.  
    5. #define _SALC   0xD6
    6. #define _AAM    0xD4
    7. #define NRM_TAB_LEN 53
    8.  
    9. #define DB __asm _emit
    10.  
    11. __declspec(naked) int _cdecl MDAL_GetOpcodeLen(BYTE* opcode)
    12. {
    13.     _asm
    14.     {
    15.         mov esi, [esp + 4]
    16.         pushad
    17.         push    000001510h
    18.         push    0100101FFh
    19.         push    0FFFFFF55h
    20.         push    0FFFFFFF8h
    21.         push    0F8FF7FA0h
    22.         push    00F0EC40Dh
    23.         push    007551004h
    24.         push    001D005FFh
    25.         push    0550D5D55h
    26.         push    0555F0F88h
    27.         push    0F3F3FFFFh
    28.         push    00A0C1154h
    29.        
    30.         mov edx, esi
    31.         mov esi, esp
    32.  
    33.         push    11001b
    34.         push    10110000101011000000101110000000b
    35.         push    10111111101100011111001100111110b
    36.         push    00000000000100011110101001011000b
    37.         mov ebx, esp
    38.         sub esp, 110
    39.         mov edi, esp
    40.  
    41.         cld
    42.         push    100
    43.         pop ecx
    44.     xa_nxtIndx:
    45.         bt  [ebx], ecx
    46.         DB _SALC
    47.            
    48.         jnc xa_is0
    49.         lodsb
    50.     xa_is0:
    51.         stosb
    52.         loop    xa_nxtIndx
    53.         mov esi, edx
    54.  
    55.         push    2
    56.         pop ebx
    57.         mov edx, ebx
    58.     xa_NxtByte:
    59.         lodsb
    60.         push    eax
    61.         push    eax
    62.         cmp al, 66h
    63.         cmove   ebx, ecx
    64.         cmp al, 67h
    65.         cmove   edx, ecx
    66.         cmp al, 0EAh
    67.         je  xa_jmp
    68.         cmp al, 09Ah
    69.         jne xa_nocall
    70.  
    71.         inc esi
    72.     xa_jmp:
    73.         lea esi, [esi+ebx+3]
    74.     xa_nocall:
    75.         cmp al, 0C8h
    76.         je  xa_i16
    77.         and al, 0F7h
    78.         cmp al, 0C2h
    79.         jne xa_no16
    80.     xa_i16:
    81.         inc esi
    82.         inc esi
    83.  
    84.     xa_no16:
    85.         and al, 0E7h
    86.         cmp al, 26h
    87.         pop eax
    88.         je  xa_PopNxt
    89.         cmp al, 0F1h
    90.         je  xa_F1
    91.         and al, 0FCh
    92.         cmp al, 0A0h
    93.         jne xa_noMOV
    94.         lea esi, [esi+edx+2]
    95.     xa_noMOV:
    96.         cmp al, 0F0h
    97.         je  xa_PopNxt
    98.     xa_F1:
    99.         cmp al, 64h
    100.     xa_PopNxt:
    101.         pop eax
    102.         je  xa_NxtByte
    103.  
    104.         mov edi, esp
    105.         push    edx
    106.         push    eax
    107.         cmp al, 0Fh
    108.         jne xa_Nrm
    109.         lodsb
    110.     xa_Nrm:
    111.         pushfd
    112.         DB _AAM
    113.         DB 10h
    114.         xchg    cl, ah
    115.         cwde
    116.         cdq
    117.         xor ebp, ebp
    118.         popfd
    119.         jne xa_NrmGroup
    120.  
    121.         add edi, NRM_TAB_LEN
    122.         jecxz   xa_3
    123.     xa_1:
    124.         bt  [edi], ebp
    125.         jnc xa_2
    126.         inc edx
    127.     xa_2:
    128.         inc ebp
    129.         loop    xa_1
    130.         jc  xa_3
    131.         DB _SALC
    132.         cdq
    133.     xa_3:
    134.         shl edx, 1
    135.         jmp xa_ProcOpcode
    136.  
    137.     xa_NrmGroup:
    138.         sub cl, 4
    139.         jns xa_4
    140.         mov cl, 0Ch
    141.         and al, 7
    142.     xa_4:
    143.         jecxz   xa_4x
    144.     xa_5:
    145.         adc dl, 1
    146.         inc ebp
    147.         bt  [edi], ebp
    148.         loop    xa_5
    149.         jc  xa_ProcOpcode
    150.     xa_4x:
    151.         shr al, 1
    152.  
    153.     xa_ProcOpcode:
    154.         xchg    cl, al
    155.         lea edx, [edx*8+ecx]
    156.         pop ecx
    157.         pop ebp
    158.         bt  [edi+2], edx
    159.         jnc xa_noModRM
    160.  
    161.         lodsb
    162.         DB _AAM
    163.         DB 8
    164.         shl ah, 4
    165.         jnc xa_isModRM
    166.         js  xa_enModRM
    167.     xa_isModRM:
    168.         pushfd
    169.         test    ebp, ebp
    170.         jnz xa_addr32  
    171.         sub al, 6
    172.         jnz xa_noSIB
    173.         mov al, 5
    174.     xa_addr32:
    175.         cmp al, 4
    176.         jne xa_noSIB
    177.         lodsb
    178.         and al, 7
    179.     xa_noSIB:
    180.         popfd
    181.         jc  xa_iWD
    182.         js  xa_i8
    183.         cmp al, 5
    184.         jne xa_enModRM
    185.     xa_iWD:
    186.         add esi, ebp
    187.         inc esi
    188.     xa_i8:
    189.         inc esi
    190.  
    191.     xa_enModRM:
    192.         test    ah, 60h
    193.         jnz xa_noModRM
    194.         xchg    eax, ecx
    195.         cmp al, 0F6h
    196.         je  xa_ti8
    197.         cmp al, 0F7h
    198.         jne xa_noModRM
    199.         add esi, ebx
    200.         inc esi
    201.     xa_ti8:
    202.         inc esi
    203.  
    204.     xa_noModRM:
    205.         shl edx, 1
    206.         bt  [edi+2+17], edx
    207.         jnc xa_Exit
    208.         inc edx
    209.         bt  [edi+2+17], edx
    210.         jnc xa_im8
    211.         adc esi, ebx
    212.     xa_im8:
    213.         inc esi
    214.  
    215.     xa_Exit:
    216.         add esp, 110+64
    217.         sub esi, [esp+4]
    218.         mov [esp+7*4], esi
    219.         popad
    220.         ret
    221.     }
    222. }
    223.  
    224. int MDAL_GetOpcodesLenByNeedLen(BYTE* opcode, int NeedLen)
    225. {
    226.     int FullLen = 0;
    227.     int len;
    228.  
    229.     do
    230.     {
    231.         __asm push esi
    232.         len = MDAL_GetOpcodeLen(opcode + FullLen);
    233.         __asm pop esi
    234.         if (!len)
    235.         {
    236.             return 0;
    237.         }
    238.         FullLen += len;
    239.     }
    240.     while (FullLen < NeedLen);
    241.  
    242.     return FullLen;
    243. }
    244.  
    245. typedef struct TRAMPOLINE
    246. {
    247.     BYTE CodeBuf[0x1A];
    248.     DWORD cbSaved;
    249.  
    250. }*PTRAMPOLINE;
    251.  
    252. VOID SpliceUp(PVOID WinApi, PTRAMPOLINE Jmp, PVOID HookSub)
    253. {
    254.     /*
    255.      * \x68\xFF\xFF\xFF\xFF\xC3  
    256.      */
    257.     DWORD cb = MDAL_GetOpcodesLenByNeedLen((PBYTE)WinApi, 6);
    258.    
    259.     memcpy(Jmp->CodeBuf, WinApi, cb);
    260.  
    261.     /*
    262.      * jmp rel32
    263.      */
    264. #include <pshpack1.h>
    265.     struct
    266.     {
    267.         BYTE jmp;
    268.         DWORD rel32;
    269.     } sub;
    270. #include <poppack.h>
    271.     sub.jmp = 0xE9;
    272.     sub.rel32 = ((PBYTE)WinApi + cb) - ((PBYTE)Jmp->CodeBuf + cb + 5);
    273.    
    274.     memcpy(Jmp->CodeBuf + cb, &sub, sizeof(sub));
    275.     Jmp->cbSaved = cb;
    276.  
    277.     /*
    278.      * push imm32
    279.      * ret
    280.      */
    281. #include <pshpack1.h>
    282.     struct
    283.     {
    284.         BYTE push;
    285.         PVOID imm32;
    286.         BYTE ret;
    287.     } obj;
    288. #include <poppack.h>
    289.     obj.push = 0x68;
    290.     obj.imm32 = HookSub;
    291.     obj.ret = 0xC3;
    292.     WriteProcessMemory(GetCurrentProcess(), WinApi, &obj, sizeof(obj), 0);
    293. }
    294.  
    295. VOID SpliceDown(PVOID WinApi, PTRAMPOLINE Jmp)
    296. {
    297.     WriteProcessMemory(GetCurrentProcess(), WinApi, Jmp, Jmp->cbSaved, 0);
    298. }
    299.  
    300. #pragma data_seg(push, r1, ".text")
    301. BYTE xxx[16];
    302. #pragma data_seg(pop, r1)
    303.  
    304. #define pk1 __asm{__emit 0xCC}
    305. #define pk4 pk1 pk1 pk1 pk1
    306. #define pk16 pk4 pk4 pk4 pk4
    307. #define pk64 pk16 pk16 pk16 pk16
    308. #define pk256 pk64 pk64 pk64 pk64
    309.  
    310. TRAMPOLINE jmp1, jmp2;
    311. #include <boost/typeof/typeof.hpp>
    312.  
    313. static int
    314. WINAPI
    315. hook1(
    316.     __in_opt HWND hWnd,
    317.     __in_opt LPCSTR lpText,
    318.     __in_opt LPCSTR lpCaption,
    319.     __in UINT uType)
    320. {
    321.     return ((BOOST_TYPEOF(hook1)*)&jmp1)(hWnd,lpText,lpCaption,uType);
    322. }
    323. static int
    324. WINAPI
    325. hook2(
    326.     __in_opt HWND hWnd,
    327.     __in_opt LPCSTR lpText,
    328.     __in_opt LPCSTR lpCaption,
    329.     __in UINT uType)
    330. {
    331.     return ((BOOST_TYPEOF(hook2)*)&jmp2)(hWnd,lpText,lpCaption,uType);
    332. }
    333.  
    334. int main()
    335. {
    336.     MessageBox(0, 0, 0, 0);
    337.     SpliceUp(&MessageBoxA, &jmp1, &hook1);
    338.     MessageBox(0, 0, 0, 0);
    339.     SpliceUp(&MessageBoxA, &jmp2, &hook2);
    340.     MessageBox(0, 0, 0, 0);
    341.     SpliceDown(&MessageBoxA, &jmp2);
    342.     MessageBox(0, 0, 0, 0);
    343.     SpliceDown(&MessageBoxA, &jmp1);
    344.     MessageBox(0, 0, 0, 0);
    345. }
     
  7. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    63F45EF45RB65R6VR
    Саспенд после захвата кс загрузчика.
    Но не спеши открывать папку "Counter-Strike" (ровно как и пдфник с последним ксакепом), речь о критической секции.
    Смесь asm-листенгов, буста и тотального винегрета в голове - это конечно ахтунг. Надо фиксить.

    Еще пару таких постов и делайт необратимо о*уеет. Ставь хоть запятые иногда.
     
  8. 63F45EF45RB65R6VR

    63F45EF45RB65R6VR New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2011
    Сообщения:
    70
    так эта она ж ведь в другом процессе !!
     
  9. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    onSide
    Рассщипление страницы - это случай когда либо грузится в не сколько процессов. Физичиская память будет одна, но после того как её модифицируют , то происходит расщепления страницы дабы избежать изменения во всех процессах(Это когда мы ставим патч). После того как мы сделаем анпатч кто это страницы вернет в норлмаьное состояние то и есть в изначальное?


    Очень не проще, а точнее намного:
    1) Менее прозрачно + Версии а архитектура.
    2) Нельзя стартовать потоки.
    3) Не чего нельзя вгрузить(У меня например случай на некоторые патчи вгружалась специльная либа так сказать база данных )
     
  10. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    shchetinin
    2), 3) - не сталкивался. согласен.
    хоть и тут решаемо, но уже из области извращений.
     
  11. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    deLight
    Я согласен это давно специфичные пункты, но все таки решение с локом инвалидно, особенно подумав о факте если туды поподет человек без знания локов загрузчика( А такие есть, например у меня сейчас в проекте ).
     
  12. 63F45EF45RB65R6VR

    63F45EF45RB65R6VR New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2011
    Сообщения:
    70
    вот например по адресу 0x0000000F есть такой код
    0x0000000F 8B FF mov edi,edi
    теперь представим что поток был вытеснен со значением
    eip == 0x0000000F теперь другой поток хочет пропатчить эти два байта и записать туда
    0x0000000F EB F9 jmp short $ - 5
    и например выполняет для этого такой код
    mov eax, 0x0000000F
    mov word ptr [eax], 0xF9EB
    возможно ли расщепление записи т.е запись только 1 байта EB
    потом переключение контекста и второй поток увидит в итоге
    0x0000000F EB FF ??
    или запись будет гарантированно атомарной и любой поток никак
    не прочтет разрезанные опкоды ? вообще во всех этих случаях атомарность гарантируется
    mov byte ptr[eax], AA
    mov word ptr[eax], AABB
    mov dword ptr[eax], AABBCCDD
    ?
     
  13. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    63F45EF45RB65R6VR
    Не такого не будет, если его что то вытеснит то это прирывание, в этом случае не будет работать другой поток.
     
  14. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    63F45EF45RB65R6VR
    Такого, как Вы описали, быть не может, потому что процессор исполняет инструкции целиком, и не может прерваться на середине инструкции (полслова записал, полслова — нет).
    Но это не означает, что запись будет атомарной. Если адрес записываемого слова попадает на границу линейки кэша, то в многопроцессорной системе теоретически может запись одним процессором может быть разбита на две транзакции, между которыми может влезть читающий другой процессор. Хотя в случае, когда под чтением понимается выборка инструкций (кроссмодифицируемый код), тут всё может быть немного сложнее.
     
  15. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    Думать.
     
  16. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    l_inc
    Я немного запутался, кто на что и кому отвечает, но вот это хочется уточнить:
    Только ли при пересечении границы кэша? Как я себе представлял, чтение/запись объекта по некратному ему размеру адресу может быть разбито на несколько транзакций. Т.е. например при

    proc0:
    mov eax, [0x1]

    proc1:
    mov [0x1], eax

    может произойти перемешивание. Я в таких случаях использую простое правило: записывающая инструкция должна использовать префикс LOCK. С другой стороны, проверить такую ситуацию довольно сложно, может это и не совсем правильно. В общем, где лучше почитать насчет "дробления" операций?
     
  17. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
  18. 63F45EF45RB65R6VR

    63F45EF45RB65R6VR New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2011
    Сообщения:
    70
    клерк ты классный специалист и многие из за этого к тебе относятся с уважением например я но своим поведением ты нивелируеш себя прежде всего как человека вот посмотри со стороны это похоже на поведение школьника и это только портит твою репутацию

    P.S я совершенно беспристрастный человек так что моим словам можеш доверять

    насчет Mika0x65 помоему классный специалист в моих темах не троллил да и вообще замечен не был зачем его оскорблятъ ?
     
  19. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    63F45EF45RB65R6VR
    Да, точно. Вы правы :)
     
  20. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Mika0x65
    Нет никаких транзакций, если доступ к памяти целиком попадает в подгруженную линейку кэша. Если же попадает целиком в неподгруженную линейку, то под транзакциями понимается сброс/подгрузка всей линейки целиком.
    Ну правило-то может и простое, но по lock mov будет #UD, что указано в документации.
    Более подробно мне известен только один надёжный источник: leo. :)