能力值:
( LV2,RANK:10 )
|
-
-
2 楼
可能我说的不准确
比如 一个目标程序已经和服务器连接了tcp连接,并通过了身份验证,
是不是我的dll注入这个目标程序后,直接调用用ws2_32 的send就可以发送服务器到服务器了?
不需要connect什么的?
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
你直接INLINE HOOK WS2_32.send这个函数,做一下过滤就好了。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
果然很新手啊。。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
首先要注入到目标进程,然后hook api。。
注入目标进程方式很多。。
hook api方式也很多。。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
各位达人,可否扔点简单的参考代码给瞧瞧啊。。。
谢谢先!
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
另外请教:如果自己准备数据的话,是否不需要hook了,直接注入目标进程,send即可?
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
按照逆向逻辑分析,你在send下断点后,一层一层返回,直到出现明文数据包时候,那么相应的取得这个明文数据包参数的函数,就是所谓的游戏明文发包函数。
最后,你直接注入dll,自己按游戏明文包格式填写好,然后调用这个明文发包函数,其实很简单,考的是你的汇编和编程功底。祝你好运!!!!!
|
能力值:
( LV4,RANK:50 )
|
-
-
9 楼
同样初学,前几天写了一个简单的demon,比较原始,在多线程的时候调用send时候会有bug(但是足够简单可以说明原理了),lz可以看明白这个自己写个完善的,把多线程的问题解决掉,共享到这里,帮助后来更多的人
//定义的全局变量和类型
typedef int (WINAPI *FunSend)(
__in SOCKET s,
__in_bcount(len) const char FAR * buf,
__in int len,
__in int flags
);
//
BYTE byOldCode[5] = {0};
BYTE byNewCode[5] = {0};
FunSend lpOldFunSend = NULL;
//自己的函数定义
int WINAPI MySend(
__in SOCKET s,
__in_bcount(len) const char FAR * buf,
__in int len,
__in int flags
);
//在初始化时候
HMODULE hMod = ::LoadLibrary(_T("ws2_32.dll"));
lpOldFunSend = (FunSend)::GetProcAddress(hMod,"send");
memcpy(byOldCode, lpOldFunSend, 5);
// 当前函数地址 + 5 + 跳转距离 = 跳转的地方 => 跳转的地方 - 当前函数地址 - 5
DWORD dwJmpDiff = (DWORD)MySend - (DWORD)send - 5;
byNewCode[0] = 0xe9;
*(DWORD*)&byNewCode[1] = dwJmpDiff;
//
DWORD dwOldProtect, dwTmp;
VirtualProtect(lpOldFunSend, 5, PAGE_READWRITE, &dwOldProtect);
memcpy(lpOldFunSend, byNewCode, 5);
VirtualProtect(lpOldFunSend, 5, dwOldProtect, &dwTmp);
//跳到我的send
int WINAPI MySend(
__in SOCKET s,
__in_bcount(len) const char FAR * buf,
__in int len,
__in int flags
)
{
DWORD dwOldProtect, dwTmp;
VirtualProtect(lpOldFunSend, 5, PAGE_READWRITE, &dwOldProtect);
memcpy(lpOldFunSend, byOldCode, 5);
VirtualProtect(lpOldFunSend, 5, dwOldProtect, &dwTmp);
//
int nRet= send(s, buf, len, flags);
DWORD dwLastError = GetLastError(),
SOCKADDR_IN skAddr;
int nLen=sizeof(skAddr);
getpeername(s, (struct sockaddr *)&skAddr, &nLen);//得到远程IP地址和端口号
char *szIP = inet_ntoa(skAddr.sin_addr);
short sPort = ntohs(skAddr.sin_port);
CString strLog;
strLog.Format(_T("port:%d, ip:%s"), sPort, szIP);
//
VirtualProtect(lpOldFunSend, 5, PAGE_READWRITE, &dwOldProtect);
memcpy(lpOldFunSend, byNewCode, 5);
VirtualProtect(lpOldFunSend, 5, dwOldProtect, &dwTmp);
SetLastError(dwLastError);
return nRet;
}
|
能力值:
( LV13,RANK:240 )
|
-
-
10 楼
提出两点建议
1不确定你使用关键段是不是为了想保护 写的时候不被打乱。如果是这样想的,那么在你的关键段起不到任何效果。
假设你初始化的时候未发生崩溃 当前send的地址上的数据是JMP XXX
第一个call send进入了你的Mysend 调用了EnterCS进入关键段,你正在进行memcpy前四个字节的时候,突然另外一个线程调用了一个call send,此时就会发生崩溃,call send的行为不是发生在你进入关键段之后,而是之前。
2调用send之后记得先funcerr=GetLastError()然后ret之前记得SetLastError(funcerr)
例如WSASend这类函数,有可能返回error,此时的状态为Pending
GetLastError可以得到PENDING状态。由于你函数在send之后执行了某些操作。比如getpeername函数会setlasterror将之前可能的PENDING状态清除掉。后续函数判断WSASend返回错误,调用GetLastError得到的却不是PENDING而是getpeername设置的OK。就会错误。
|
能力值:
( LV13,RANK:240 )
|
-
-
11 楼
大清早为何总是会有特别想要回答问题的欲望呢?奇怪。。。
|
能力值:
( LV4,RANK:50 )
|
-
-
12 楼
谢谢热心人,
1. 的确临界区没啥用,所以可以删掉
2. 第二点真没有注意到这些细节,因为不是商业程序写的很随意,也就懒得改了,不过谢谢指正
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
我也在写辅助框架 楼主求交流 q:84476063
|
能力值:
( LV4,RANK:50 )
|
-
-
14 楼
持续关注中~~
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
32位下面的话,直接找到这个函数挂钩子就行了,只是要注意堆栈平衡;64位下的应用层hook没有搞过,不知道如何整,话说回来,为什么要去hook send函数呢,这个函数你hook住,我觉得分析起来要累死人啊,为什么不直接hook最上层的调用,我的意思是hook游戏本身的函数。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
是不是64位下注入特麻烦啊,折腾了半天了,就是不成功
OpenProcess
VirtualAllocEx
WriteProcessMemory
GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA")
hThreadHandle=CreateRemoteThread(。。。
各个环节,包括最后 hThreadHandle的值都正常,dll就是一个测试的
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA (0,"I'am a dll!","Dll_Inj",MB_OK |MB_ICONINFORMATION );
while (1) {
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
死活看不到效果。
我是64位win7,vs2012,有人说 64位下注入,自己的程序必须是64位的,dll文件也必须是64位的
可是我测试了,还是不行。
是不是有什么特别需要注意的地方啊。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
呃,你不能在send这hook。。游戏在send之前是要加密的。你要找到明文包的发包地址。
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
谢谢各位大佬热心的回复。
我是学习阶段啊,想先把整个流程走一下,根本还没有到达“实用”的阶段。
新问题:
现在我已经把自己的dll注入目标进程了,如何调用目标进程已经加载的WS2_32 的send啊。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
自己脑补了一个思路,
hook send,然后程序调用他的时候,就可以得到socket 的句柄,
然后自己直接send(socket,,,) 就可以了?
|
能力值:
( LV4,RANK:50 )
|
-
-
20 楼
我贴的代码不就是这样么!
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
找到明文包再HOOK,而且8楼说的根本不可行,现在的游戏都是线程循环发包,那样做永远都是在一个死循环中,永远找不到明文发包
|
|
|