首页
社区
课程
招聘
如何处理E8指令的HooK
发表于: 2015-3-6 17:20 5370

如何处理E8指令的HooK

2015-3-6 17:20
5370
过JMP HOOK 是在JMP XXXX 后在XXXX做还原后HOOK跳转回来,这个没什么问题。但是CALL HOOK 如何处理才能正常跳回。

Hook后:
CALL XXXXX                 
NOP               
MOV ECX,ESI

原文如下:
PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH ESI
PUSH EDI
MOV ECX,ESI

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 261
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我觉得可以在XXXXX中先保存返回地址,然后返回地址出栈,还原指令,jmp 返回地址
2015-3-6 17:31
0
雪    币: 958
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
在hook的最后恢复原来的指令

PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH ESI
PUSH EDI

接着jmp到MOV ECX,ESI 指令的地址
2015-3-12 16:13
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
call的原理,是调用过程之前,会自动把下一条指令的地址,压入堆栈,不用担心跳回的问题
2015-3-18 18:14
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
来学习一下!
2015-3-19 13:47
0
雪    币: 223
活跃值: (94)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
真是一群假书呆子,书上说的都没领会,,,,,,哥直接上c++代码看哥的hook用几句汇编。:e9也能照抄
void MyWriteline(PCHAR Add,int Value)
{
        DWORD dwPro                                        = 0;
        if (Add!=0)
        {
                VirtualProtect(Add,4,PAGE_READWRITE,&dwPro);
                *(int *)Add =(int)Value;
                VirtualProtect(Add,4,dwPro,&dwPro);
        }
}

void myE8CovertInlineHook(DWORD inlineAdd,DWORD myFuctionADD,DWORD & OldAddContainer)
{
        if (inlineAdd != 0 && myFuctionADD != 0 )
        {
                OldAddContainer=inlineAdd+*(PDWORD)(inlineAdd+1)+5;
                MyWriteline((PCHAR)(inlineAdd+1),(int)(myFuctionADD-5-inlineAdd));
        }
}

void myE8CovertInlineUnHook(DWORD inlineAdd,DWORD & OldAddContainer)
{
        DWORD dwPro                                        = 0;
        if(inlineAdd!= 0 && OldAddContainer != 0)
        {
                MyWriteline((PCHAR)(inlineAdd+1),(int)(OldAddContainer-5-inlineAdd));
        }
}
例子:
myE8CovertInlineHook(要hook的地址,(DWORD)自己的函数地址,用来保存原始地址的全局变量);

// __declspec(naked)void 我的函数()
// {
//
// ……
// ……
// ……
// ……
//         __asm{
//                 jmp 原始地址
//
//                         }
// }
2015-3-20 13:58
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
7
返回时要还原现场,这就是原则。所以,HOOK的时候不要用
E8,不要用call xxxx,而要用jmp far xxxx,因为call的时候
把eip压入堆栈了,你返回的时候要恢复堆栈,这个很麻烦,
而用jmp,堆栈没有变, 你返回的时候,hook掉几行,就先
执行几行,再跳转回去就可以了,比如你的这个例子,
返回之前,先执行
先检查:
注意,这时,所有的寄存器应该都是原值,你用了几个,
就要恢复几个
再执行
PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH ESI
PUSH EDI
再跳转到hook的下一条语句:
MOV ECX,ESI,这样就可以了。
如果你用call,堆栈中有一个返回地址,但你又要操作
PUSH EBP...等等,这就不好操作,所以不如用jmp
2015-3-20 14:27
0
雪    币: 223
活跃值: (94)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
我的方法只要保证naked 堆栈是平衡的,被hook的地方用的是e8call就可以通杀,而且都是c代码写的别人一看就明白, 你这种方法一堆汇编,到时维护的时候一堆汇编混在一起, 你自己都分不清哪个是哪个了
2015-3-20 14:40
0
雪    币: 2832
活跃值: (1065)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习下学习学习
2015-3-21 20:59
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
OldAddContainer=inlineAdd+*(PDWORD)(inlineAdd+1)+5;
这句话的意思能讲的明白些么?   64位与32位的程序这些值都适应么?
2015-5-27 17:36
0
雪    币: 6
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
call 完了自己会回来
2015-6-17 13:11
0
游客
登录 | 注册 方可回帖
返回
//