关于P版的RTApiHook32使用中遇到的难题求助(已解决)
本帖最后由 gto250 于 2010-9-8 21:43 编辑今天利用P版的RTApiHook32.au3实验了一下hook api。实现对ie浏览器的抓包。
Hook的api是 ws2_32.dll中的send,recv,WSASend,recvfrom,WSARecv,还有一个
Sendto没有hook。
函数的原型如下:
send(SOCKET s, const char FAR * buf, int len, int flags);
sendto( SOCKET s,
const char FAR * buf,
int len,
int flags,
const struct sockaddr FAR * to,
int tolen);
WSASend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
recv( SOCKET s, char FAR * buf, int len, int flags);
recvfrom(
SOCKET s,
char FAR * buf,
int len,
int flags,
struct sockaddr FAR * from,
int FAR * fromlen
);
WSARecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
代码如下:
#include <RTApiHook32.au3>
$hCallBack = DllCallBackRegister("_ApiHookCallBack", "dword", "handle;ptr")
$pCallBack = DllCallBackGetPtr($hCallBack)
$hProcess = _RTOpenProcess("iexplore.exe")
$psend = _RTGetProcAddress("ws2_32.dll", "send")
$precv = _RTGetProcAddress("ws2_32.dll", "recv")
$pWSASend = _RTGetProcAddress("ws2_32.dll", "WSASend")
$precvfrom = _RTGetProcAddress("ws2_32.dll", "recvfrom")
$pWSARecv = _RTGetProcAddress("ws2_32.dll", "WSARecv")
$tHooksend = _RTApiHookEx($hProcess,$psend,4,$pCallBack,$APIHOOK_Flags_Default)
$tHookrecv = _RTApiHookEx($hProcess,$precv,4,$pCallBack,$APIHOOK_Flags_Default)
$tHookwsasend = _RTApiHookEx($hProcess, $pWSASend, 7, $pCallBack, $APIHOOK_Flags_Default)
$tHookrecvfrom = _RTApiHookEx($hProcess,$precvfrom,6,$pCallBack,$APIHOOK_Flags_Default)
$tHookwsaRecv = _RTApiHookEx($hProcess, $pWSARecv, 7, $pCallBack, $APIHOOK_Flags_Default)
; 用于程序在退出时,恢复目标进程的系统函数。
HotKeySet("^{f5}", "_Close")
OnAutoItExitRegister("_Close")
While 1
Sleep(100)
WEnd
Func _ApiHookCallBack($hProcess, $pCallInfo)
Switch _RTApiHookReadProcedure($hProcess, $pCallInfo)
Case $psend
$pFileName = _RTApiHookReadParam($hProcess, $pCallInfo, 2) ;获取sendto中第二个参数 const char FAR*buf的指针
$sFileName = _RTReadProcessMemory($hProcess, $pFileName, "", 1024, "str")
MsgBox(48 + 4, "send", "发送内容:" & $sFileName )
Case $pWSASend
$pFileName2 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
$sFileName2= _RTReadProcessMemory($hProcess, $pFileName2, "", 1024, "str")
MsgBox(48 + 4, "WSAsend", "发送内容:" & $sFileName2 )
Case $precv
$pFileName3 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
$sFileName3= _RTReadProcessMemory($hProcess, $pFileName3, "", 1024, "str")
MsgBox(48 + 4, "recv", "接收内容:" & $sFileName3 )
Case $precvfrom
$pFileName4 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
$sFileName4= _RTReadProcessMemory($hProcess, $pFileName4, "", 1024, "str")
MsgBox(48 + 4, "recvfrom", "接收内容:" & $sFileName4 )
Case $pWSARecv
$pFileName5 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
$sFileName5= _RTReadProcessMemory($hProcess, DllStructGetData($pFileName5,2), "", 1024, "str")
MsgBox(48 + 4, "pWSARecv", "接收内容:" & $sFileName5 )
EndSwitch
EndFunc ;==>_ApiHookCallBack
Func _Close()
_RTApiUnhook($hProcess, $psend, DllStructGetData($tHooksend, 6))
_RTApiUnhook($hProcess, $pWSASend, DllStructGetData($tHookwsasend, 6))
_RTApiUnhook($hProcess, $precv, DllStructGetData($tHookrecv, 6))
_RTApiUnhook($hProcess, $precvfrom, DllStructGetData($tHookrecv, 6))
_RTApiUnhook($hProcess, $pWSARecv, DllStructGetData($tHookrecv, 6))
exit
EndFunc ;==>_Close运行的结果是:ie中发送包是用send函数,接收包是WSARecv函数。
但是这个程序可以截获send中的数据包,对WSARecv中的数据包却无法获得。
现在需要寻求帮助的是
1、 怎么获得WSARecv中的数据包
2、 怎么获得数据包是从哪个ip地址哪个端口发送或接收的
(虽然还没有解决,但是还是先好好消化一下) 你用的是哪个版本的IE啊?我测试不会有任何提示,也截取不到send发送的数据,我用的是IE8。
看了一下,有以下几个错误:
_Close()函数中
_RTApiUnhook($hProcess, $precvfrom, DllStructGetData($tHookrecv, 6))
_RTApiUnhook($hProcess, $pWSARecv, DllStructGetData($tHookrecv, 6))
恢复两个不同的函数时,都是使用了recv函数的代码数据。
回调函数中,Case $pWSARecv那里,
$pFileName5 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
$pFileName5是WSARecv的第2个参数lpBuffers,指针类型,结构定义为:
u_long len;
char FAR *buf;
len为*buf的缓存区数据长度,*buf为缓存区指针。
DllStructGetData($pFileName5,2)这里就出现问题了,$pFileName5是指针,而非结构,DllStructGetData的第一个参数必须是DllStruct结构。
应该改为:
; 读取WSARecv第2个参数lpBuffers。
$pFileName5 = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
; 读取lpBuffers.len。
$iLen = _RTReadProcessMemory($hProcess, $pFileName5, 0, 4, "ulong*") ; len
; 读取lpBuffers.buf。
$pBuffer = _RTReadProcessMemory($hProcess, $pFileName5 + 4, 0, 4, "ptr*") ; *buf
$sFileName5 = _RTReadProcessMemory($hProcess, $pBuffer, "", $iLen, "str")
MsgBox(0, "", $sFileName5) 我用的ie6,能够收到send和$pWSARecv,之前也是因为WSARecv的第二个参数结构才写成那样,想不到还是错了。
谢谢p版,我下午回公司试试 我家里的电脑装的是ie7,xp sp3,同样不能使用,奇怪了。难不成只能在ie6中使用?
还是下午回公司试试再说 回复 4# gto250
看来IE7、IE8的确安全许多啊。
除了上面说的几个错误,其余代码是没问题的。
在IE7、IE8中截取不到,只是因为挂钩了错误的系统函数,找对函数之后再对其挂钩,一定没问题的。
- - 根据P版的代码修改后,WSARecv的确有了数据,但是显示的是乱码,而且只是一部分数据!
用BinaryToString的函数转换也不行 回复 6# gto250
- -|||
显示乱码,是因为你用了错误的数据类型。关键要看*buf是什么结构,指定为str当然是将*buf作为字符串看待,而*buf实际可能是个dword或者wstr。 的确,换成wstr有着不同的结果,但是最终的结果都是一样,都是乱码,用BinaryToString转换一下,乱码多一点,不转换,乱码少一点 那就把wstr改成别的试试,*buf指针指向的并不一定是一个字符串,可能是一个DWORD、也可能是INT64、也可以是多个int、ushort,当然也不必区分数据类型,直接用"binary"返回一串2进制数据。
最关键的是要知道*buf指针所指的区域到底是怎样的数据结构,明白了结构才能对内存中的数据进行解码,在不知结构的情况下,只靠猜解或单纯地认为*buf就是指向一字符串,这样的做法不可取。 我再试试!
数据结构什么的还是不清楚! - -!!看不懂!!观望中! 赞啊。。。。。。。。。。。。。。
页:
[1]