分享
 
 
 

二、防火墙原理及实现 (3)

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

有了上面的知识,让我们回顾一下先前讨论的问题,首先,用户调用API的recv函数,程序运行到recv的入口地址处,此时堆栈中拥有用户调用recv的参数和用户代码中CALL [recv]的下一条指令的地址。堆栈如下图:

堆栈指针

[ESP]

堆栈的内容

堆栈内容的含义

0x00000100

0

参数

0x000000fc

len

参数

0x000000f8

buf

参数

0x000000f4

S

参数

0x000000f0

RetUserAddress

用户调用recv的下一条指令的地址

然后程序指针EIP被修改为recv入口处的地址,而入口地址处有一条简单的CALL指令,它使程序将recv的第6个字节的地址压入栈中(因为CALL XXXX占用5个字节,第六个字节被认为为返回地址),然后跳转到我们的无参数无返回值的通用替换函数中去了,好了看看现在堆栈中都有些什么?如图:

堆栈指针

[ESP]

堆栈的内容

堆栈内容的含义

0x00000100

0

参数

0x000000fc

len

参数

0x000000f8

buf

参数

0x000000f4

s

参数

0x000000f0

RetUserAddress

用户调用recv的下一条指令的地址

0x00000ec

RetrecvAddress

recv的第六个字节的地址

首先是参数,其次是用户调用recv后的返回值,然后是recv调用我们的替换函数中的返回值,紧接着就像刚才提到的那样,程序将EBP当前内容压入栈中。如图

堆栈指针[ESP]

堆栈的内容

堆栈内容的含义

0x00000100

0

参数

0x000000fc

len

参数

0x000000f8

buf

参数

0x000000f4

S

参数

0x000000f0

RetUserAddress

用户调用recv的下一条指令的地址

0x00000ec

RetrecvAddress

recv的第六个字节的地址

0x000000e8

OldEBP

保存的旧的EBP的内容,然后[EBP]= 0x000000e8

0x000000e4

OldEBX

保存的旧的EBX的内容

0x000000e0

OldESI

保存的旧的ESI的内容

0x000000dc

OldEDI

保存的旧的EDI的内容,此时[ESP]=0x000000dc

此时我们可以看到,[EBP]为保存的ebp的值,现在对我们没有用处,函数返回前用于恢复EBP的值,[EBP+4]是recv函数的CALL XXXX后面指令的地址(也就是第六个字节的地址),我们可以通过将此值减去5来得到recv的入口地址,这样在我们所有hook的api函数的列表中进行检索,就可以匹配出用户调用的是哪一个API函数,从而为后面恢复和再次改变该API的入口5字节做准备,因为调用任何我们需要HOOK的API程序都会进入到这个无返回值无参数的函数,所以通过这种方法找到当前HOOK的是哪一个API,从而可以区分不同的API进行特殊的处理。[EBP+8]保存的是用户调用recv后的返回地址,由于我们执行完替换函数后,应该返回到这个地址,而不应该返回到recv的第6个字节处执行,所以我们还是需要保存下这个值,以便在我们用ret返回前把它压栈从而使程序返回到用户调用recv的下一条指令处继续运行。

我们先定义如下函数:

void CommonFunc(void);

我们现在实现它,请注意参考上面堆栈表格。

void CommonFunc(void)

{

DWORD pdwCall; // recv入口地址

DWORD dwRtAddr; // 我们的函数真正要返回的地址

DWORD* pdwParam; // 第一个参数的地址

DWORD dwParamCount; // 参数个数

DWORD dwParamSize; // 所有参数所占用的大小应该=4* dwParamCount

DWORD dwRt; // 返回值

_asm

{

lea EAX,[EBP+4] // recv入口处第6个字节的地址

mov [pdwCall],EAX

mov EAX,[EBP+8] // 用户调用recv(即call XXXX)后面一条指令的地址

mov [dwRtAddr],EAX

lea EAX, [EBP+12] // 第一个参数的地址!

mov [pdwParam],EAX

}

(*pdwCall) -= 5; // 获得recv入口地址

HOOKINFO *hi = findHookInfo(pdwCall); // 通过原始API的入口地址获得此API的相关信息

memcpy(pdwCall,hi->OrgApi5bytes,5); // 恢复被调用API的前5个字节,使下面的代码可以正常调用

// 下面准备进入用户针对此API的替换函数,现准备参数

dwParamCount = hi->ParamCount; // 得到本API的参数个数

dwParamSize = 4*dwParamCount; // 计算参数所占用大小

DWORD pdwESP;

_asm

{

sub esp,[dwParamSize] // 将栈增加,可以容纳参数

mov [pdwESP],esp // 保存当前栈的地址

}

memcpy(pdwESP,pdwParam,dwParamSize);//将用户传递的参数拷贝到栈中

hi->myAPIFunc(); // 调用用户针对此API的替换函数

_asm

{

mov [dwRt],eax // 保存返回值

}

// 如果是CreateProcess,那么继续hook它

pPi = (PROCESS_INFORMATION*)pdwParam[9];

if(strcmpi(pai->szOrgApiName,"CreateProcessA") != 0 || strcmpi(pai->szOrgApiName,"CreateProcessW") != 0)

{

InjectDll(pPi->dwProcessId,m_szDllPathName);

}

// 下面再次修改原始API的前5个字节

memcpy(pdwCall,JMPCODE,5); // #define JMPCODE 0xE8

DWORD* pdwapi = pdwCall[1];

pdwapi[0] = (DWORD) CommonFunc – (DWORD)pdCall – 5; // CommonFunc函数地址的偏移

// 下面准备返回的操作

_asm

{

add esp,[dwParamSize] // 清理我们为了调用真正的替换函数而分配的堆栈里的参数

// 下面弹出所有保存的寄存器值(按照入栈的逆顺序)

pop EDI // 恢复EDI

pop ESI // 恢复ESI

pop EBX // 恢复EBX

// 我们没有改动过EBP的值,所以EBP指向堆栈中OldEBP的位置

mov ESP,EBP

pop EBP // 恢复EBP

// 由于堆栈中还剩下参数和两个返回地址(我们真正要返回的地址和原始API中的第6个字节的地址),所以我们把这些数据也清除出堆栈

add ESP,8 // 清除两个返回地址

mov ECX,[dwParamSize] // 获得参数的大小

add ESP,ECX // 清除参数

mov EAX,[dwRt] // 设置返回值

// 由于调用ret返回时,程序先从堆栈中取出返回地址,所以我们把要真正返回的地址压入堆栈中

mov EDX,[dwRtAddr] // 设置返回地址

push EDX

ret // 返回

}

}

最后要注意得一点是,如果要执行得API函数是CreateProcess,那么应该把它新开启得进程也HOOK掉。以上我们了解了通用替换函数的原理,那么让我们深入的讨论CHookApi类,并且实现它。

--------------------------------------联系我(liutao_free@sohu.com)

--------------------------------------联系我(liutao_free@sohu.com)

联系我(liutao_free@sohu.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有