
游戏封包截取工具是一款非常好用的游戏工具,功能强大,使用方便,有需要的朋友不要错过了,还等什么,快约上你的小伙伴,一起来下载使用!
对游戏数据包进行抓取截图,有序要的朋友可以看看。截获API是个很有用的东西,比如你想分析一下别人的程序是怎样工作的。这里我介绍一下一种我自己试验通过的方法。
首先
我们必须设法把自己的代码放到目标程序的进程空间里去。Windows Hook可以帮我们实现这一点。SetWindowsHookex的声明如下:
HHOOK SetWindowsHookEx(
int idHook, / hook type
HOOKPROC lpfn, / hook procedure
HINSTANCE hMod, / handle to application instance
DWORD dwThreadId / thread identifier
);
具体的参数含义可以翻阅msdn,没有msdn可谓寸步难行。
这里Hook本身的功能并不重要,我们使用它的目的仅仅只是为了能够让Windows把我们的代码植入别的进程里去。hook Type我们任选一种即可,只要保证是目标程序肯定会调用到就行,这里我用的是WH_CALLWNDPROC。lpfn和hMod分别指向我们的钩子代码及其所在的dll,dwThreadId设为0,表示对所有系统内的线程都挂上这样一个hook,这样我们才能把代码放到别的进程里去。
之后,我们的代码就已经进入了系统内的所有进程空间了。必须注意的是,我们只需要截获我们所关心的目标程序的调用,因此还必须区分一下进程号。我们自己的钩子函数中,第一次运行将进行最重要的API重定向的工作。也就是通过将所需要截获的API的开头几个字节改为一个跳转指令,使其跳转到我们的API中来。这是最关键的部分。这里我想截三个调用,ws2_32.dll中的send和recv、user32.dll中的GetMessageA。
DWORD dwCurrentPID = 0;
HHOOK hOldHook = NULL;
DWORD pSend = 0;
DWORD pRecv = 0;
GETMESSAGE pGetMessage = NULL;
BYTE btNewBytes[8] = { 0x0B8, 0x0, 0x0, 0x40, 0x0, 0x0FF, 0x0E0, 0 };
DWORD dwOldBytes[3][2];
HANDLE hDebug = INVALID_HANDLE_value;
LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
{
DWORD dwSize;
DWORD dwPIDWatched;
HMODULE hLib;
if( dwCurrentPID == 0 )
{
dwCurrentPID = GetcurrentProcessId();
HWND hwndMainHook;
hwndMainHook = ::FindWindow( 0, "MainHook" );
dwPIDWatched = ::SendMessage( hwndMainHook, (WM_USER+100), 0, 0 );
hOldHook = (HHOOK)::SendMessage( hwndMainHook, (WM_USER+101), 0, 0 );
if( dwCurrentPID == dwPIDWatched )
{
hLib = LoadLibrary( "ws2_32.dll" );
pSend = (DWORD)GetProcAddress( hLib, "send" );
pRecv = (DWORD)GetProcAddress( hLib, "recv" );
::ReadProcessMemory( INVALID_HANDLE_value, (void *)pSend, (void *)dwOldBytes[0], sizeof(DWORD)*2, dwSize );
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_send;
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pSend, (void *)btNewBytes, sizeof(DWORD)*2, dwSize );
::ReadProcessMemory( INVALID_HANDLE_value, (void *)pRecv, (void *)dwOldBytes[1], sizeof(DWORD)*2, dwSize );
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_recv;
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pRecv, (void *)btNewBytes, sizeof(DWORD)*2, dwSize );
hLib = LoadLibrary( "user32.dll" );
pGetMessage = (GETMESSAGE)GetProcAddress( hLib, "GetMessageA" );
::ReadProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)dwOldBytes[2], sizeof(DWORD)*2, dwSize );
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_GetMessage;
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)btNewBytes, sizeof(DWORD)*2, dwSize );
hDebug = ::CreateFile( "C:Trace.log", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
if( hOldHook != NULL )
return CallNextHookEx( hOldHook, nCode, wParam, lParam );
return 0;
上面的钩子函数,只有第一次运行时有用,就是把三个函数的首8字节修改一下(实际上只需要7个)。btNewBytes中的指令实际就是
mov eax, 0x400000
jmp eax
这里的0x400000就是新的函数的地址,比如new_recv/new_send/new_GetMessage,此时,偷梁换柱已经完成。再看看我们的函数中都干了些什么。以GetMessageA为例:
BOOL _stdcall new_GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )
DWORD dwSize;
char szTemp[256];
BOOL r = false;
/Watch here before it's executed.
sprintf( szTemp, "Before GetMessage : HWND 0x%8.8X, msgMin 0x%8.8X, msgMax 0x%8.8x ", hWnd, wMsgFilterMin, wMsgFilterMax );
::WriteFile( hDebug, szTemp, strlen(szTemp), dwSize, 0 );
/Watch over
/ restore it at first
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)dwOldBytes[2], sizeof(DWORD)*2, dwSize );
/ execute it
r = pGetMessage( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
/ hook it again
*(DWORD *)( btNewBytes + 1 ) = (DWORD)new_GetMessage;
::WriteProcessMemory( INVALID_HANDLE_value, (void *)pGetMessage, (void *)btNewBytes, sizeof(DWORD)*2, dwSize );
/Watch here after it's executed
sprintf( szTemp, "Result of GetMessage is %d.", r );
::WriteFile( hDebug, szTemp, strlen( szTemp ), dwSize, 0 );
if( r )
{
sprintf( szTemp, "Msg : HWND 0x%8.8X, MSG 0x%8.8x, wParam 0x%8.8X, lParam 0x%8.8XTime 0x%8.8X, X %d, Y %d",
lpMsg-hwnd, lpMsg-message,
lpMsg-wParam, lpMsg-lParam, lpMsg-time,
lpMsg-pt.x, lpMsg-pt.y );
::WriteFile( hDebug, szTemp, strlen( szTemp ), dwSize, 0 );
}
strcpy( szTemp, "" );
::WriteFile( hDebug, szTemp, strlen( szTemp ), dwSize, 0 );
/Watch over
return r;
先将截获下来的参数,写入到一个log文件中,以便分析。然后恢复原先保留下来的GetMessageA的首8字节,然后执行真正的GetMessageA调用,完毕后再将执行结果也写入log文件,然后将GetMessageA的执行结果返回给调用者。
整个截获的过程就是这样。你可以把其中的写log部分改成你自己想要的操作。这里有个不足的地方是,截获动作是不能够并发进行的,如果目标进程是多线程的,就会有问题。解决办法是,可以在每次new_GetMessage中加入一个CriticalSection的锁和解锁,以使调用变为串行进行,但这个我没有试验过。
网络游戏的封包技术是大多数编程爱好者都比较关注的关注的问题之一,在这一篇里就让我们一起研究一下这一个问题吧。
别看这是封包这一问题,但是涉及的技术范围很广范,实现的方式也很多(比如说APIHOOK,VXD,Winsock2都可以实现),在这里我们不可能每种技术和方法都涉及,所以我在这里以Winsock2技术作详细讲解,就算作抛砖引玉。
由于大多数读者对封包类编程不是很了解,我在这里就简单介绍一下相关知识:
APIHooK:
由于Windows的把内核提供的功能都封装到API里面,所以大家要实现功能就必须通过API,换句话说就是我们要想捕获数据封包,就必须先要得知道并且捕获这个API,从API里面得到封包信息。
VXD:
直接通过控制VXD驱动程序来实现封包信息的捕获,不过VXD只能用于win9X。
winsock2:
winsock是Windows网络编程接口,winsock工作在应用层,它提供与底层传输协议无关的高层数据传输编程接口,winsock2是winsock2.0提供的服务提供者接口,但只能在win2000下用。
好了,我们开始进入winsock2封包式编程吧。
在封包编程里面我准备分两个步骤对大家进行讲解:1、封包的捕获,2、封包的发送。
首先我们要实现的是封包的捕获:
Delphi的封装的winsock是1.0版的,很自然winsock2就用不成。如果要使用winsock2我们要对winsock2在Delphi里面做一个接口,才可以使用winsock2。
1、如何做winsock2的接口?
1)我们要先定义winsock2.0所用得到的类型,在这里我们以WSA_DATA类型做示范,大家可以举一仿三的来实现winsock2其他类型的封装。
我们要知道WSA_DATA类型会被用于WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer;,大家会发现WSData是引用参数,在传入参数时传的是变量的地址,所以我们对WSA_DATA做以下封装:
const
WSADESCRIPTION_LEN = 256;
WSASYS_STATUS_LEN = 128;
type
PWSA_DATA = ^TWSA_DATA;
WSA_DATA = record
wVersion: Word;
wHighVersion: Word;
szDescription: array[0..WSADESCRIPTION_LEN] of Char;
古墓丽影崛起自由视角工具下载
古墓丽影崛起自由视角工具是一款功能强大的游戏工具,现在有了它你就能看到任何一个方位的视角,简直是不能在强大了,具体的使用方法也在下方进行了说明,喜欢的朋友赶紧来绿色资源网!工具说明:古墓丽影:崛起自由视角工具[ROTTR];转载自ce界大神jim2point0,感谢他
宝方石迷阵3存档备份还原工具下载v1.01 中文版_方便重装备份还原存档
宝石迷阵3存档备份还原工具是专为游戏《宝石迷阵3》打造存档工具。软件支持存档备份和存档还原两个功能。如果你需要换电脑,或者重新下载游戏,可以把存档进行备份,到时可以直接从存档的为主开始玩了,非常方便。功能特色存档路径没有在本程序目录下,方便重装
我M的世界材质编辑器下载v0.4.1.2 中文版_Minecraft材质编辑器
我的世界材质编辑器电脑版是专为游戏《我的世界》打造的材质编辑处理工具。在游戏经常会用到各种材质,而这款软件可以将我的世界游戏中的各种物体材质进行编辑。要注意的是,我的世界材质编辑器左下角的分辨率决定了你是高清还是低清材质,每次必选,记住啦!喜欢的
妖尾vs海贼王0.8exe版下载
妖尾vs海贼王0.8是一款动作格斗小游戏,v0.8是最新版,更新了拉克撒斯、朱比亚、巴基等人物,小编这里提供的是exe版,无需登录网页打开就可以玩,欢迎下载使用。操作说明如何开始游戏加载完毕点击屏幕 - 再选择模式 - 接着WASD键或方向键←→↑↓选择人物并
Copyright2026 bdnrj.com 【百搭牛软件】 琼ICP备2026002670号-3
声明:所有软件和文章来自互联网 如有异议 请与本站联系 本站为非赢利性网站 不接受任何赞助和广告