Не работает перехват MessageBox

Тема в разделе "WASM.WIN32", создана пользователем ksu_ant, 13 ноя 2010.

  1. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Clerk
    За перепалками не заметил Вашего сообщения, содержащего конструктивную критику с указанием проблем. Спасибо большое.
    Постараюсь учесть то, что Вы сказали.
    Но, справедливости ради, необходимо заметить, что исходный код (ссылку на который я приводил) практически идентичен моему (возможно, я добавил некоторые ошибки перевода)... Это я к тому, что не всегда необходимы грубые слова при общении и оценке чужого кода, т.к. даже проверенные временем и очень уважаемые программисты (Ms-Rem, в данном случае) - не всегда пишут идеальный код (энума тредов и т.д. нет в исходном коде)...
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    n0name
    Я и не сомневался, что майкрософт непортабелен между своими версиями.
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    ksu_ant
    Для конкретных задач это вполне работоспособное решение, Clerk как всегда напускает тумана и поднимает своё ЧСВ. Вы отлаживать умеете или нет? Или натыкайте логов на худой конец.
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Booster
    Как же вы надоели с этим чсв. Я написал как оно есть. Проблема с переопределением ошибочным констант очень распространена между тех, кто юзает дельфи.
     
  5. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Booster
    Поправил, все, что увидел. Получилось вот это:
    Код (Text):
    1. #include "stdafx.h"
    2. #include "windows.h"
    3.  
    4. typedef struct _OldCode {
    5.     DWORD   One;
    6.     DWORD   Two;
    7. } OldCode;
    8.  
    9. typedef struct _far_jmp {
    10.     BYTE    PuhsOp;
    11.     DWORD   PushArg;
    12.     BYTE RetOp;
    13. } far_jmp;
    14.  
    15. typedef VOID (*MYPROCA)(HWND, LPCSTR, LPCSTR, UINT,WORD);
    16. typedef VOID (*MYPROCW)(HWND, LPCWSTR, LPCWSTR, UINT,WORD);
    17. HINSTANCE hDLL;
    18.  
    19.  
    20. OldCode OldMba, OldMbw;
    21. DWORD  MbaAdr;
    22. DWORD MbwAdr;
    23. far_jmp JmpMba, JmpMbw;
    24. BOOL WINAPI TrueMessageBoxExA(HWND hwnd, LPCSTR text, LPCSTR hdr, UINT utype,WORD wLanguageId)
    25. {
    26.   DWORD written;
    27.  
    28.   CHAR str[5] = "1234";
    29.   CHAR stdPath[30] = "C:\\tmp.txt";
    30.   DWORD d;
    31.   HANDLE hOut = CreateFile(stdPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    32.   CloseHandle(hOut);
    33.  
    34.   WriteProcessMemory(GetCurrentProcess(), (void*)MbaAdr,
    35.                      (void*)&OldMba, sizeof(OldCode), &written);
    36.   MessageBoxExA(hwnd, text, hdr, utype, wLanguageId);
    37.  
    38.   WriteProcessMemory(GetCurrentProcess(), (void*)MbaAdr,
    39.                      (void*)&JmpMba, 6,&written);
    40.   return true;
    41. }
    42.  
    43. BOOL WINAPI TrueMessageBoxExW(HWND hwnd, LPCWSTR text, LPCWSTR hdr, UINT utype,WORD wLanguageId)
    44. {
    45.   DWORD written;
    46.  
    47.   CHAR str[5] = "1234";
    48.   CHAR stdPath[30] = "C:\\tmp.txt";
    49.   DWORD d;
    50.   HANDLE hOut = CreateFile(stdPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    51.   CloseHandle(hOut);
    52.  
    53.   WriteProcessMemory(GetCurrentProcess(), (void*)MbwAdr,
    54.                      (void*)&OldMbw, sizeof(OldCode), &written);
    55.   MessageBoxExW(hwnd, text, hdr, utype, wLanguageId);
    56.  
    57.   WriteProcessMemory(GetCurrentProcess(), (void*)MbwAdr,
    58.                      (void*)&JmpMbw, 6,&written);
    59.   return true;
    60. }
    61.  
    62. BOOL WINAPI NewMessageBoxExA(HWND hwnd, LPCSTR text, LPCSTR hdr, UINT utype,WORD wLanguageId)
    63. {
    64.     CHAR str[5] = "1234";
    65.     CHAR stdPath[30] = "C:\\tmp.txt";
    66.     DWORD d;
    67.     HANDLE hOut = CreateFile(stdPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    68.     CloseHandle(hOut);
    69.     TrueMessageBoxExA(hwnd, text, hdr, utype, wLanguageId);
    70.     return TRUE;
    71. }
    72.  
    73. BOOL WINAPI NewMessageBoxExW(HWND hwnd, LPCWSTR text, LPCWSTR hdr, UINT utype,WORD wLanguageId)
    74. {
    75.     CHAR str[5] = "1234";
    76.     CHAR stdPath[30] = "C:\\tmp.txt";
    77.     DWORD d;
    78.     HANDLE hOut = CreateFile(stdPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    79.     CloseHandle(hOut);
    80.     TrueMessageBoxExW(hwnd, text, hdr, utype, wLanguageId);
    81.     return TRUE;
    82. }
    83.  
    84. LRESULT CALLBACK MessageProc(int code, WPARAM wParam, LPARAM lParam)
    85. {
    86.     CallNextHookEx(0, code, wParam, lParam);
    87.     return 0;
    88. }
    89.  
    90. DWORD WINAPI SetGlobalHookProc(LPVOID lpParam)
    91. {
    92.     SetWindowsHookEx(WH_GETMESSAGE, &MessageProc, hDLL, 0);
    93.     Sleep(INFINITE);
    94.     return 0;
    95. }
    96.  
    97. DWORD SetGlobalHook()
    98. {
    99.     HANDLE hMutex;
    100.     DWORD TrId;
    101.     hMutex = CreateMutex(NULL, false, "AdvareHook");
    102.     if (GetLastError() == 0)
    103.     {
    104.         CreateThread(NULL, 0, &SetGlobalHookProc, 0, 0, &TrId);
    105.     }
    106.     else
    107.     {
    108.             CloseHandle(hMutex);
    109.     }
    110.     return 0;
    111. }
    112.  
    113. DWORD SetHook()
    114. {
    115.     HINSTANCE hUser32;
    116.     ULONG Bytes;
    117.     hUser32 = GetModuleHandle("user32.dll");
    118.     MbaAdr  = (DWORD) GetProcAddress(hUser32, "MessageBoxExA");
    119.     MbwAdr  = (DWORD) GetProcAddress(hUser32, "MessageBoxExW");
    120.     ReadProcessMemory(GetCurrentProcess(), &MbaAdr, &OldMba, sizeof(OldCode), &Bytes);
    121.     ReadProcessMemory(GetCurrentProcess(), &MbwAdr, &OldMbw, sizeof(OldCode), &Bytes);
    122.     JmpMba.PuhsOp  = 0x68;
    123.     JmpMba.PushArg = (DWORD) NewMessageBoxExA;
    124.     JmpMba.RetOp   = 0xC3;
    125.     JmpMbw.PuhsOp  = 0x68;
    126.     JmpMbw.PushArg = (DWORD) NewMessageBoxExW;
    127.     JmpMbw.RetOp   = 0xC3;
    128.     WriteProcessMemory(GetCurrentProcess(), &MbaAdr, &JmpMba, sizeof(far_jmp), &Bytes);
    129.     WriteProcessMemory(GetCurrentProcess(), &MbwAdr, &JmpMbw, sizeof(far_jmp), &Bytes);
    130.     return 0;
    131. }
    132.  
    133.  
    134. DWORD UnHook()
    135. {
    136.     ULONG Bytes;
    137.     WriteProcessMemory(GetCurrentProcess(), (void*)MbaAdr, (void*)&OldMba, sizeof(OldCode), &Bytes);
    138.     WriteProcessMemory(GetCurrentProcess(), (void*)MbwAdr, (void*)&OldMbw, sizeof(OldCode), &Bytes);
    139.     return 0;
    140. }
    141.  
    142. BOOL APIENTRY DllMain( HINSTANCE hModule,
    143.                        DWORD  ul_reason_for_call,
    144.                        LPVOID lpReserved
    145.                      )
    146. {
    147.     switch (ul_reason_for_call)
    148.     {
    149.         case DLL_PROCESS_ATTACH:
    150.             hDLL = hModule;
    151.                           SetGlobalHook();
    152.                           SetHook();
    153.             MessageBoxExA(NULL,"Test me","Test Caption",MB_OK,0);
    154.                           break;
    155.         case DLL_THREAD_ATTACH:
    156.             break;
    157.         case DLL_THREAD_DETACH:
    158.             break;
    159.         case DLL_PROCESS_DETACH:
    160.             UnHook();
    161.             break;
    162.     }
    163.     return TRUE;
    164. }
    В результате выполнения этого кода длжен создаться файл C:\tmp.txt, но он не создается. По поводу отладки - при отладке в Visual C++ 6.0 - я попадаю на точку входа (DLL_PROCESS_ATTACH), попадаю в SetHook(), вроде хуки устанавливаются, но даже при проверочном вызове MessageBox - я не попадаю в функцию NewMessageBox... Думаю, что проблемы при установке хуков (адреса напутал или еще что)...
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    увы без матчасти (хотя бы основы - отладки приложений) эту задачу не решить.
    PS: первая встреченная ошибка в 11 строчке.
     
  7. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Еще нашел:
    Код (Text):
    1. typedef struct _OldCode {
    2.     DWORD    One;
    3.     DWORD    Two;
    4. } OldCode;
    Верно так:
    Код (Text):
    1. typedef struct _OldCode {
    2.     DWORD   One;
    3.     WORD    Two;
    4. } OldCode;
    Раньше были неверные размеры структур...
    По отладке: попадаю только на DLL_PROCESS_ATTACH, выполняется все, что указано в коде и все :dntknw: . В перехваченные функции не заходит...
     
  8. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    n0name
    Если можно - приведите содержание строки - не понятно как строки считать (с пустыми, с объявлениями структур и т.д.).
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Собрал этот чудо код.
    1) return CallNextHookEx(0, code, wParam, lParam);
    2)
    Код (Text):
    1. #pragma pack(1)
    2. typedef struct _OldCode {
    3.     DWORD    One;
    4.     DWORD    Two;
    5. } OldCode;
    6.  
    7. #pragma pack(1)
    8. typedef struct _far_jmp {
    9.     BYTE    PuhsOp;
    10.     DWORD    PushArg;
    11.     BYTE RetOp;
    12. } far_jmp;
    3)
    Код конечно своеобразно написан. ^)
     
  10. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    WriteProcessMemory(GetCurrentProcess(), MbaAdr, &JmpMba, sizeof(far_jmp), &Bytes);
    WriteProcessMemory(GetCurrentProcess(), MbwAdr, &JmpMbw, sizeof(far_jmp), &Bytes);
     
  11. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Booster punxer

    Спасибо Вам большое! Все заработало.
    Мне бы было тяжело найти эти проблемы самостоятельно.
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ksu_ant
    [modnote=Great]Предупреждение, что не юзали поиск.[/modnote]

    Booster
    Clerk
    ksu_ant
    [modnote=Great]Предупреждение за срач[/modnote]
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Great
    Какой есчо срач. Предложите ваше решение задачи в UM.
     
  14. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Great
    Поиск юзал. Работающего решения в User Mode (на С) - не нашел (хотя нашел множество других, но они не работали). Была попытка перевода того решения, которое работало, на нужный язык... И были, при этом, недопонимания.
    Про
    С моей стороны не было никакой агрессии (если это подразумевает Ваше определение), а было противодействие безосновательным нападкам не знающего меня человека.
     
  15. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    ksu_ant
    Формат инструкций не зависит от CPL. Не имеет значения в каком кольце защиты выполняется ваш код. Это тупой патч. Неужеле так трудно просто логически подумать, я на самом деле не понимаю.
     
  16. _Lamer

    _Lamer Petr

    Публикаций:
    0
    Регистрация:
    19 ноя 2010
    Сообщения:
    9
    Адрес:
    Vitebsk
    попробуй перед каждым вызовом WriteProcessMemory вазвать VirtualProtect а полсе каждого вызова WriteProcessMemory вазвать FlushInstructionCache.
    С параметрами для VirtualProtect и FlushInstructionCache думаю разберешься, как и с назначением этих функций.


    Совсем забыл, после вызова FlushInstructionCache желательно вызвать VirtualProtect и вернуть как было до первого вызова VirtualProtect.

    Код (Text):
    1. DWORD dwProtection = 0;
    2. DWORD dwWrite = 0;
    3. LPVOID pAdress; // адрес, значение которого надо изменить на значение по pNewAdress
    4. DWORD dwLength;
    5. LPVOID pNewAdress;
    6. DWORD dwNewLength;
    7.  
    8. VirtualProtect(pAdress, dwLength, PAGE_READWRITE, &dwProtection);
    9. WriteProcessMemory(hProcess, pAdress, pNewAdress, dwNewLength, &dwWrite);
    10. VirtualProtect(pAdress, dwLength, dwProtection, &dwProtection);
    11. FlushInstructionCache(g_hProcess, pAdress, dwLength);
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    _Lamer
    Мб попробовать разобраться в копипасте ?
     
  18. _Lamer

    _Lamer Petr

    Публикаций:
    0
    Регистрация:
    19 ноя 2010
    Сообщения:
    9
    Адрес:
    Vitebsk
    поясни, я ничего не понял из твоего сообщения
     
  19. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    И набуя в своём процессе юзать WriteProcessMemory - запись в память своего процесса легко делается например через RtlMoveMemory или напрямую асмом, тока VirtualProtect из WinAPI нужен и после модификций памяти не надо забывать выставлять предыдущие флаги для неё.
    Ещё можно напрямую вызывать NtFlushInstructionCache, но всё равно проблема атомарности и записи при многопоточности остаётся открытой в сплайсинге.