现在的位置: 首页 > 综合 > 正文

实现 MU 窗口化 过程

2013年10月11日 ⁄ 综合 ⁄ 共 15834字 ⁄ 字号 评论关闭
实现 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[i] = 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[i] = 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);

 

抱歉!评论已关闭.