比如我们用一个messagebox来弹出一个信息,说明该程序即将打开一个某谋路径的文件句柄。但是有一个要注意的是,如果你想拦截远程进程的话,对于那个拦截函数中所使用到的任何函数或者以任何形式的相对地址的调用都要停止。因为每个进程中的地址分配都是独立的,比如上面的CALL MessageBoxA改成直接地址的调用。对于使用messagebox,我们应该定义一个函数指针,然后把这个指针的值赋值为user32.dll中导出该函数的直接地址。然后利用这个指针来进行函数调用。对于messagebox函数的调用可以这样,在源程序中定义一个参数结构体,参数中包含一个导出函数的地址,把这个地址设为MessageBoxA的直接地址,获取地址的方法就不说了。然后把这个参数传给拦截函数,就可以使用拉。这也是利用一个参数的原因。类似代码如下:
typedef struct _RemoteParam {
DWORD dwMessageBox;
} RemoteParam, * PRemoteParam;
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);//定义一个函数指针
//拦截函数
void HookCreateFile(LPVOID lParam)
{
RemoteParam* pRP = (RemoteParam*)lParam;//获取参数地址
char* PFileName = NULL;//定义一个指针
__asm{
MOV EAX,[EBP+16]
MOV [szFileName], EAX //把CreateFile第一个参数的值,文件的路径的地址传 //给szFileName
}
//定 义一个函数指针
PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, PFileName, PFileName, MB_ICONINformATION |MB_OK);
//输出要打开的文件的路径
//..
}
对于你要使用的其他函数,都是使用同样的方式,利用这个参数来传递我们要传递的函数的绝对地址,然后定义这个函数指针,就可以使用了。
好了,接下来我们该让被拦截的api正常工作了,这个不难,把他原来的数据恢复一下就可以了。那入口的10个字节。我们在改写他们的时候应该保存一下,然后也把他放在参数中传递给拦截函数,呵呵,参数的作用可多了。接着我们就可以用WriteProcessMemory函数来恢复这个api的入口了,代码如下:
PFN_GETCURRENTPROCESS pfnGetCurrentProcess = (PFN_GETCURRENTPROCESS)pRP->dwGetCurrentProcess;
PFN_WRITEPROCESSMEMORY pfnWriteProcessMemory = (PFN_WRITEPROCESSMEMORY)pRP->dwWriteProcessMemory;
if(!pfnWriteProcessMemory(pfnGetCurrentProcess(),
(LPVOID)pfnConnect,
(LPCVOID)pRP->szOldCode,
&n