实现 MU 窗口化 过程 窗口化 的确可以实现 可能很多人都以实现了 我在这里抛砖引玉了 但是 登陆 30 秒后 出现 GameGuard 出错 实在不知原因 又找不到 加密解密 的代码 听说 99 可以和 +11 装备 100% 成功 太 nb 自愧不如了 现在决定放弃了 把我的这些垃圾 贴到这 谁愿意继续搞 谁搞去把 < 1 > 调试 : 工具 OllDbg 系统 xp 忽略所有异常 菜单 文件/打开 选择 main.exe 在参数框中 添入 conn44ect /u210.51.27.96 /p44405 // 这是模仿 MU.exe 启动 Main.exe // MU.exe 使用了命令行 // 显然不同的区 IP 不同 bp 77FB172C ecx == 0c6d39cf // 这是第26次 SEH 断下后按 F7 到这里 0C6D39CF 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C] 0C6D39D3 8380 B8000000 0>ADD DWORD PTR DS:[EAX+B8],2 0C6D39DA C740 18 0000000>MOV DWORD PTR DS:[EAX+18],0 0C6D39E1 31C0 XOR EAX,EAX 0C6D39E3 C3 RETN 0C6D39E4 31C0 XOR EAX,EAX 0C6D39E6 64:FF30 PUSH DWORD PTR FS:[EAX] 0C6D39E9 64:8920 MOV DWORD PTR FS:[EAX],ESP 0C6D39EC 3100 XOR DWORD PTR DS:[EAX],EAX 0C6D39EE 64:8F05 0000000>POP DWORD PTR FS:[0] // 这里下断点 0C6D39F5 58 POP EAX 0C6D39F6 833D B07E6D0C 0>CMP DWORD PTR DS:[C6D7EB0],0 然后 bp 0C6D39EE 断下后 我们先 看一下 启动 GameGuard.des 的代码 d 5A2470 // 这个地址我也忘记我是如何找到的了 我可能用了 SoftICE 或者 我一直跟踪到此 // ASProtect壳 的HookAPI挺恶心 // 可能要 BP CreateProcessA + 一个大一点的数 数据窗口 点右键 反汇编 看到下面代码
005A2470 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18] 005A2474 8D4424 40 LEA EAX,DWORD PTR SS:[ESP+40] 005A2478 8D8C24 B0030000 LEA ECX,DWORD PTR SS:[ESP+3B0] 005A247F 52 PUSH EDX 005A2480 50 PUSH EAX 005A2481 6A 00 PUSH 0 005A2483 6A 00 PUSH 0 005A2485 6A 00 PUSH 0 005A2487 6A 01 PUSH 1 005A2489 6A 00 PUSH 0 005A248B 6A 00 PUSH 0 005A248D 8D9424 C8010000 LEA EDX,DWORD PTR SS:[ESP+1C8] 005A2494 51 PUSH ECX 005A2495 52 PUSH EDX 005A2496 FF15 04915B00 CALL DWORD PTR DS:[5B9104] // 这里 调用 CreateProcessA 005A249C 85C0 TEST EAX,EAX 005A249E 75 46 JNZ SHORT main.005A24E6 005A2496 行 调用 CreateProcessA 。 修改 地址 5B9104 的内容可以 HOOK CreateProcessA ; 向下 按 F7 或 F8 有几个 跳转指令 然后 启动了 GameMon.des // 也是 CALL CALL DWORD PTR DS:[5B9104] 注意 一下 OD 中显示出的字符串 可以 发现这些 跳转 多数 跳到了 GameMon failure ; 我把他们 统统 改了 // 见后面的 C 代码 ////////////////////////////////////////////////// 调试就到这里了 谁喜欢调自己调去把 < 2 > 注入 DLL 可以很简单的 使用 远程线程 的 方法 照搬 <<winndows 核心编程>> 里的代码就行了
////////////////////////////////////////////////////////////////////////////// < 3 > 启动 main.exe 向其代码空间中写入 指令 首先启动 Main // 不要忘了传递命令行 connect /u210.51.27.96 /p44405 // 各区的 IP 与 端口 在 partition.inf 文件里 当然以调试器的身份启动 Main 是非常好的 // 但先要躲过 IsDebuggerPresent() 在 26 次 异常后断下 ,修改 Main 的代码 ,一切那么自然 但我不知 如何躲过 IsDebuggerPresent() 所以启动之后产生了 千万次异常 我只好不用 "调试" 那参数了,这样修改 Main.exe 代码的时机很难掌握了 我用了 这样一个循环 只是延时了 其实没准的 很 while (dwBuf != GREAYE_PROCESS_V && j < 1110000) { BOOL fRead = ReadProcessMemory (GetCurrentProcess(), (LPCVOID)GREAYE_PROCESS_A , (LPVOID) &dwBuf, 4, NULL) ; _ASSERTE (fRead) ; j ++ ; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 下面是 被注入的 DLL 的全部代码 // 注意 : 我从来没搞过任何项目 写过的代码也有限 // 下面的代码 写的不好 请原谅 // 比如 里面有一些 曾经用过 但现在不用的变量 没有删掉 // 还有注释 写的不好请原谅 // MuDll.cpp 文件 #include "MU_DLL.h" #pragma data_seg ("sharedID") HANDLE m_hMuThread = NULL ; HANDLE m_hMuProcess = NULL ; static int m_iNumLoad = 0 ; static char m_szMuMsg[1024] ; #pragma data_seg () #pragma comment (linker, "/SECTION:sharedID,rws")
WNDPROC m_wpMuOldProc ; HINSTANCE m_hThis ; HWND m_hwndInsert ; LPPROCESS_INFORMATION m_lpProcessInfoMon ; HWND m_hwndMu ; char m_lpsSend [302700] ; UINT m_strSendLen = 0 ;
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { m_hThis = hInstance ; m_iNumLoad ++ ;
if (m_iNumLoad > 1) { m_hwndInsert = FindWindow ("InsertDll", NULL) ; SetProcessPriorityBoost (m_hMuProcess, TRUE) ; DWORD dwRun = ResumeThread (m_hMuThread) ; if ( -1 == dwRun) { char szShowNum[1024] ; sprintf (szShowNum, "hThread %x load time %d\n", m_hMuThread, m_iNumLoad) ; MessageBox (NULL, szShowNum , " shibai MUdll", MB_OK) ; FreeLibrary (m_hThis) ; } else { unsigned dwTreadID = 0; HANDLE hThread = NULL ; hThread = (HANDLE)_beginthreadex (NULL, 0, &ThreadReadWrite , NULL, 0, &dwTreadID) ;
} } } return TRUE; } unsigned __stdcall ThreadReadWrite (PVOID pvoid) { int i = 0 ; int j = 0 ; DWORD dwBuf = 0 ; while (dwBuf != GREAYE_PROCESS_V && j < 1110000) // 如果出现保护错误或其他错误 尝试 修改循环次数 这个“dwBuf != GREAYE_PROCESS_V” 没用 { BOOL fRead = ReadProcessMemory (GetCurrentProcess(), (LPCVOID)GREAYE_PROCESS_A , (LPVOID) &dwBuf, 4, NULL) ; _ASSERTE (fRead) ; j ++ ; } SuspendThread (m_hMuThread); char FalseNpCode[] = "\xB8\x01\x00\x00\x00" // mov eax, 0x00000001 "\xB9\xE2\x33\xE5\x77" // mov ecx, 0x77E533E2 "\xBA\x08\x06\x14\x00" // mov edx, 0x00140608 "\x90\x90\x90\x90\x90" // nop "\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90" "\x90\x90\x90\x90" ; // 跳过 Create GameGuard BOOL fOKe = WriteProcessMemory (m_hMuProcess, (LPVOID)NP_ADDRESS, FalseNpCode, 44, FALSE) ; // 跳过 GameGuard 后 的后续工作 // 一些跳转 char chrJMP[] = "\xeb" ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A256C, chrJMP, 1, FALSE) ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A2b4b, chrJMP, 1, FALSE) ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A2d5b, chrJMP, 1, FALSE) ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A2dcc, chrJMP, 1, FALSE) ; // 一个函数我不知道他的用途,运行他会出错 干脆 NOP 掉了 char chrNOP[] = "\x90\x90\x90\x90\x90\x90\x90" ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A2cd9, chrNOP, 7, FALSE) ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005A2ceb, chrNOP, 4, FALSE) ; // 下面这些函数的地址 也没什么用 用 SofICE 下断 很容易找到 // 钩挂 CreateProcess () 函数 LPVOID lpMyFunc ; lpMyFunc = (LPVOID)MyCreateProcess ; BOOL fOKa = WriteProcessMemory (m_hMuProcess, (LPVOID)0x005b9104, (LPCVOID)&lpMyFunc, 4, FALSE) ;
// 改变 MU 窗口类风格 //char cClssStyle[] = "\x03" ; //BOOL fOKb = WriteProcessMemory (m_hMuProcess, (LPVOID)0x0045D313, cClssStyle, 1, FALSE) ;
// 钩挂 CreateWindow 函数 改变窗口风格 lpMyFunc = (LPVOID)MyCreateWindowEx ; BOOL fOKc = WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B93DC, (LPCVOID)&lpMyFunc, 4, FALSE) ;
// 钩挂 ChangeDisplaySetting 函数 lpMyFunc = (LPVOID)MyChangeDisplay ; BOOL fOKd = WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B9410, (LPCVOID)&lpMyFunc, 4, FALSE) ; // 钩挂 send 函数 lpMyFunc = (LPVOID)MySend ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B9470, (LPCVOID)&lpMyFunc, 4, FALSE) ; // 钩挂 recv () lpMyFunc = (LPVOID)MyRecv ; WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B9494, (LPCVOID)&lpMyFunc, 4, FALSE) ;
// 钩挂 SetTimer () //dwMyFunc = (DWORD)MySetTimer ; //WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B93cc, (LPCVOID)&dwMyFunc, 4, FALSE) ; // 钩挂 TextOut 函数 //dwMyFunc = (DWORD)MyTextOut ; //WriteProcessMemory (m_hMuProcess, (LPVOID)0x005B9068, (LPCVOID)&dwMyFunc, 4, FALSE) ;
//if (fOKa && fOKb && fOKc) // MessageBox (NULL, " 代码改好了 要出错了吗?", ":(", 0) ;
ResumeThread (m_hMuThread) ;
CloseHandle (m_hMuThread) ; CloseHandle (m_hMuProcess) ; _endthreadex(0) ; return 0 ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MU 子类化窗口过程 LRESULT CALLBACK MuSubclassProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HANDLE hFile ; DWORD dwActBytes ;
switch (message) { case WM_CREATE :
m_hwndMu = hwnd ; break ; case WM_TIMER : if ((int)wParam == 1000) { KillTimer (hwnd, (int)wParam) ; // 不知道他是什么 但是必须 Kill return 0 ; } break ; case WM_ACTIVATE : // 解决了Mu窗口不放弃焦点的问题 wParam = 1 ; break ; case WM_DESTROY : // 顺便把 Mon 结束掉 TerminateProcess (m_lpProcessInfoMon -> hProcess, 0) ;
//// 将 m_lpsSend串写到磁盘 他们是 Send Recv 包 if (!m_lpsSend) break ; hFile = CreateFile ("e:\\Mu Msg.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ; WriteFile (hFile, m_lpsSend, m_strSendLen, &dwActBytes, NULL) ; CloseHandle (hFile) ; break ; case 0x2B11 : // 看Main.exe 的代码 好象有这个 用户消息 但是从没接收到过他 MessageBox (NULL, "0x2B11 Msg", "WndProc", 0) ; break ; } return CallWindowProc (m_wpMuOldProc, hwnd, message, wParam, lParam); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CreateWindowEx() EXPORT HWND WINAPI MyCreateWindowEx (DWORD dwExStyle,LPCTSTR lpClassName, LPCTSTR lpWindowName,DWORD dwStyle, int x,int y,int nWidth,int nHeight, HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { HWND hwnd = NULL ; if ( strcmp(lpClassName, "MU") == 0) { hwnd = CreateWindowEx (/*dwExStyle*/0, lpClassName, // window class name lpWindowName, // window caption WS_OVERLAPPEDWINDOW & (~WS_THICKFRAME ) & (~WS_MINIMIZEBOX) & (~WS_MAXIMIZEBOX), // window style 0, // initial x position 0, // initial y position 640, // initial x size 480, // initial y size hWndParent, // parent window handle hMenu, // window menu handle hInstance, // program instance handle lpParam) ; // creation parameters // 子类化 MU 窗口 m_wpMuOldProc = (WNDPROC)SetWindowLong (hwnd, GWL_WNDPROC, (LONG) MuSubclassProc); } else { hwnd = CreateWindowEx (dwExStyle, lpClassName, // window class name lpWindowName, // window caption dwStyle, // window style x, // initial x position y, // initial y position nWidth, // initial x size nHeight, // initial y size hWndParent, // parent window handle hMenu, // window menu handle hInstance, // program instance handle lpParam) ; // creation parameters } return hwnd ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CreateProcess() EXPORT BOOL WINAPI MyCreateProcess (LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { CreateProcess (lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, // 挂起 进程 GameMon.des lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) ; m_lpProcessInfoMon = lpProcessInformation ;
return TRUE ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // SetTime() 没必要 HOOK EXPORT UINT_PTR WINAPI MySetTimer (HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) { if (nIDEvent == 1003) { MessageBox (NULL, m_szMuMsg, "mu", 0); } return (SetTimer (hWnd, nIDEvent, uElapse, lpTimerFunc)) ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // send() EXPORT int WINAPI MySend (SOCKET s, const char* buf, int len, int flags) { char szSendHex[3072] ; int i = 0 ; BYTE byte ; BYTE * pByte = (BYTE*)buf ; for (int j = 0 ; j < len ; j++) { byte = *pByte >> 4 ; if (byte < 10) byte += 48 ; else byte += 55 ; szSendHex[i++] = byte ; byte = *pByte & 0x0F ; if (byte < 10) byte += 48 ; else byte += 55 ; szSendHex[i++] = byte ; szSendHex[i++] = ' ' ; pByte ++ ; } szSendHex = 0 ; static int iNumSend = 0 ; iNumSend ++ ;
m_strSendLen += sprintf (m_lpsSend + m_strSendLen, TEXT("%s %d PackLen : %d: \n %s\n"), "Send", iNumSend, len, szSendHex) ;
return send (s, buf, len, flags) ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // recv () EXPORT int WINAPI MyRecv (SOCKET s, char* buf, int len, int flags) { int iRetn = recv (s, buf, len, flags) ; char szRecvHex[3072] ; int i = 0 ; BYTE byte ; BYTE * pByte = (BYTE*)buf ; // Get revc data len int iPackLen = (int)pByte[1] ; if ( (! iPackLen) || iPackLen == 1 ) iPackLen = 2 ; for (int j = 0 ; j < iPackLen ; j++) { byte = *pByte >> 4 ; if (byte < 10) byte += 48 ; else byte += 55 ; szRecvHex[i++] = byte ; byte = *pByte & 0x0F ; if (byte < 10) byte += 48 ; else byte += 55 ; szRecvHex[i++] = byte ; szRecvHex[i++] = ' ' ; pByte ++ ; } szRecvHex = 0 ; static int iNumRecv = 0 ; iNumRecv ++ ;
m_strSendLen += sprintf (m_lpsSend + m_strSendLen, TEXT("%s %d PackLen : %d iRetn : %d : \n %s\n"), "Recv", iNumRecv, iPackLen, iRetn, szRecvHex) ; return iRetn ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TextOut() 没必要 HOOK
EXPORT BOOL WINAPI MyTextOut (HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString) { if (*lpString == 'G') { MessageBox (NULL, m_szMuMsg, "GameGaurd ?", 0) ; } return TextOut (hdc, nXStart, nYStart, lpString, cbString) ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ChangeDisplay() 直接返回 不出现黑屏了 EXPORT LONG WINAPI MyChangeDisplay (LPDEVMODE lpDevMode, DWORD dwflags) { return 0 ; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXPORT void SetMuHandle(HANDLE hProcess, HANDLE hThread) { m_hMuProcess = hProcess ; m_hMuThread = hThread ; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // MuDll.h 文件
#pragma once #include <Winsock2.h> #pragma comment(lib, "Ws2_32") #include <windows.h> #include <stdio.h> #include <process.h> #include <Dbghelp.h> #pragma comment(lib, "Dbghelp") #include <Crtdbg.h> #ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif #define NP_ADDRESS 0x005A2470 #define NP_ADDRESS_V 0x1824448D #define NP_ADDRESS_END_A 0x005A2498 #define GREAYE_PROCESS_A 0x0C6E0374 #define GREAYE_PROCESS_V 0x6AEC8B55 LRESULT CALLBACK MuSubclassProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ;
// 读写 MU.exe进程空间 代码 的 线程 unsigned __stdcall ThreadReadWrite (PVOID pvoid) ; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 下面函数导出 给 InsertDll.exe 使用 EXPORT void SetMuHandle (HANDLE hProcess, HANDLE hThread) ; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 下面定义 HOOK API 都以 My 开头 // Hook CreateWindowEx Func EXPORT HWND WINAPI MyCreateWindowEx ( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) ; EXPORT LONG WINAPI MyChangeDisplay (LPDEVMODE lpDevMode, DWORD dwflags) ; EXPORT BOOL WINAPI MyCreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); EXPORT UINT_PTR WINAPI MySetTimer (HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc); EXPORT DWORD WINAPI MyWaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); EXPORT BOOL WINAPI MyTextOut (HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString); EXPORT int WINAPI MySend (SOCKET s, const char* buf, int len, int flags); EXPORT int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags); |