能力值:
( LV13,RANK:400 )
2 楼
jmp指令需要一个操作数,OffSet
jmp OffSet
这个OffSet是当前指令地址和目标函数地址的差值,需要计算出来
RelocateJumps(NtOpenProcess, (ULONG)FuckNtOpenProcess - (ULONG)NtOpenProcess, uCodeLen);
这条语句的作用就是计算这个OffSet
能力值:
( LV3,RANK:20 )
3 楼
不是吧 那个writejump函数是这样的
VOID WriteJump(PVOID FuncPtr, PVOID JumpPtr)
{
KIRQL OldIrql;
UCHAR Buffer[5];
Buffer[0] = 0xe9;
*(PULONG)&Buffer[1] = (ULONG)JumpPtr - ((ULONG)FuncPtr + 5);
OldIrql = KeRaiseIrqlToDpcLevel();
__asm
{
cli;
push eax;
mov eax, cr0;
and eax, 0FFFEFFFFh;
mov cr0, eax;
pop eax;
}
// *(PUSHORT)FuncPtr = 0xfeeb;
// RtlMoveMemory((PUCHAR)FuncPtr + 2, (PUCHAR)Buffer + 2, 3);
// *(PUSHORT)FuncPtr = *(PUSHORT)Buffer;
RtlMoveMemory((PUCHAR)FuncPtr, (PUCHAR)Buffer, 5);//我修改了一下
__asm
{
push eax;
mov eax, cr0;
or eax, 10000h;
mov cr0, eax;
pop eax;
sti;
}
KeLowerIrql(OldIrql);
}
我怎么看这个才是计算跳转的地址啊。。。
能力值:
( LV4,RANK:50 )
4 楼
他是看被替换的指令 里面有JMP的 做特殊处理
能力值:
( LV3,RANK:20 )
5 楼
原函数前面如果有 jmp 跳转 就是已经被 HOOk了 那么直接改写 跳转目的地址 到我们的HOOK函数 楼主这几个函数的调用还是做下判断吧 不是;一连串下来的
能力值:
( LV3,RANK:20 )
6 楼
还想说的是 原先作者
// *(PUSHORT)FuncPtr = 0xfeeb;
// RtlMoveMemory((PUCHAR)FuncPtr + 2, (PUCHAR)Buffer + 2, 3);
// *(PUSHORT)FuncPtr = *(PUSHORT)Buffer;
这样写 也是有用意的 先修改前面的指令为死循环 这样即使后面的修改被打断 (当然中断都关了 这有点不可能)也不会出错
能力值:
( LV13,RANK:400 )
7 楼
[QUOTE=dancebaby;1162503]不是吧 那个writejump函数是这样的
VOID WriteJump(PVOID FuncPtr, PVOID JumpPtr)
{
KIRQL OldIrql;
UCHAR Buffer[5];
Buffer[0] = 0xe9;
...[/QUOTE]
擦。。。。我的错,我只看了一眼下面的代码
如楼上所说,那个函数是判断目标函数入口是否已经有jmp指令了
至于你的整体代码片段看不出来是干什么用的。
能力值:
( LV3,RANK:20 )
8 楼
这个意思是说他是想检测一下前面是不是jmp?如果不是就不写了么?
*(PULONG)((ULONG)FuncPtr + Offset + 1) -= Reloc; 我看这个赋值像是 如果检测到第一个是E8或者E9的话,就直接往他后面写一个地址,但是这个地址这么计算 我实在想不明白呢。。。
这个代码是不是应该判断一下reloc这个函数,如果返回是真的就不再直接把前5个字节写入了呢。。
能力值:
( LV2,RANK:10 )
9 楼
E8,E9操作码后跟一个4字节ULONG值,该值的计算方法为:
设E8或E9操作码所在内存地址为uE8E9,要跳转到(E9-jmp)或要调用函数(E8-Call)的绝对地址为uDecAdr,则E8,E9操作码后跟一个4字节ULONG值
uSize=uDecAdr-uE8E9-5
即相对跳转(调用)距离=目的地址-当前操作码所在地址-5
能力值:
( LV3,RANK:20 )
10 楼
我知道这个是这么算的关键是 我想知道这个
RelocateJumps(NtOpenProcess, (ULONG)FuckNtOpenProcess - (ULONG)NtOpenProcess, uCodeLen);
这个的第二个参数传递的是(ULONG)FuckNtOpenProcess - (ULONG)NtOpenProcess,
后面写入的时候是在e8或者e9的后面写了一个 xx -=reloac,也就是xx = xx -reloac
= xx - ((ULONG)FuckNtOpenProcess - (ULONG)NtOpenProcess)=NtOpenProcess+1-(yy) = NtOpenProcess + NtOpenProcess - FuckNtOpenProcess +1 这是个啥玩意啊。。。
能力值:
( LV5,RANK:60 )
11 楼
通过MeasureCodeLength找到一段>=5字节的完整指令后,需要检查下这段指令里是否有分支、跳转、子例程等指令,如果有则找到的指令段不适合inline hook即case break返回FALSE的(因为这几个字节的指令是你要保存好在你的hook函数里执行的,然后再跳回来执行原函数剩下的代码,由于你hook函数的地址和原函数的地址肯定不一样,相关指令在hook函数里执行时地址偏移也就不一样了),但如果是e8和e9还可以直接把e8/e9的地址减去这样一个相对地址来得到新的偏移完成正确执行,也就是这里的*(PULONG)((ULONG)FuncPtr + Offset + 1) -= Reloc;这个赋值。
能力值:
( LV3,RANK:20 )
12 楼
能力值:
( LV5,RANK:60 )
13 楼
假设原函数在0x400000也就是你inline hook的几个指令处有个xx跳转,跳转的相对地址是n。由于你现在inline hook掉了,所以0x400000处的指令可能被你的jmp破坏了。你会在你的hook函数处做些处理后调回原函数,有一种做法是在你的hook函数里先执行被你的jmp破坏的原函数代码,再跳转到原函数后面的地址继续。这时候会发现你hook函数里执行的原函数的代码里有相对于原函数的偏移,指令执行肯定就有问题了。这就是为什么某些地方不适合inline hook,至于为什么e8/e9这么处理后是可以的,建议LZ自己画个跳转图看看。
能力值:
( LV3,RANK:20 )
14 楼
噢 我大概明白了,就是说如果要覆盖原来的JMP的话,之后我的函数里面不能直接把原来的JMP给写上去,要计算出一个值来跳过去,这个就是先计算出来后我们自己去执行的。。是这个情况咯?
我再画画看。。。
能力值:
( LV5,RANK:60 )
15 楼