1、
向指定地址写入代码
A、JMP地址转换公式推导
B、计算实际地址函数RealJmp_Addr
C、测试
【240】JMP指令 -> 机器码 --> 0xE9
【260】指令"JMP 88881234" --> 翻译成机器码 --> "E9 88881234"
【328】打开 OD 看一下,JMP指令是否如我们上面猜想的那样翻译的
【440】我们自己改几条指令(把它们改成JMP指令),发现 机器码后面的立即数是不同的:
后面3个byte是相同的,第1个byte的值不同
ZC: 应该是 JMP指令 跳转的是相对位置?
【645】十六进制0x88881234
【695】指令所在的地址为: 0x010073BB
它们的差为: 0x87879E79
【815】0x87879E79 - 0x5 ==> 0x87879E74 ==> 这就是 OD中显示的地址
ZC: 其实 E9 后面的立即数 就是 0x88881234 与 下一条指令地址 的差,它的相对地址是 通过下一条指令 计算得来的。(想象这样一个情景,有时用OD断下(内存断点?)的时候,我们观察的是此时EIP的上面一条指令,此处应该也是这个道理?当CPU在执行A指令的时候 EIP实际已经指向了下一条指令了?EIP实际指向的是将要执行现在还没执行的指令?稍微查了一下 貌似是这样子的。于是 段内偏移 应该 是相对EIP指向的地址来计算?)
【825】OD中的 立即数 的高地位是倒着的
【905】看一下"dd 10073BB+1",这里 "+1"是为了跳过字节"E9"
【1035】"db 10073BB+1"
ZC: 饶了半天,连 CPU 小端存储格式/大端存储格式 都讲不出来么...
【1185】
定义JMP结构
typedef struct _JMPCODE
{
BYTE E9;
ULONG JMPADDR;
} JMPCODE,*PJMPCODE;
ZC: (x86)公式 应该是: 机器码相对地址=段内绝对地址 - JMP的下一条指令的地址
【1720】把 第19课 的代码复制过来
【1910】
NTSTATUS DriverEntry(PDRIVER_OBJECT _pDrvierObject, PUNICODE_STRING B)
{
ULONG cur, old;
cur = GetNt_CurAddr() ;
old = GetNt_OldAddr();
if (cur != old)
{
// 【2830】写入 我们的 JMP指令
KdPrint(("NtOpenProcess被Hook了"));
}
else
KdPrint(("NtOpenProcess没有被Hook"));
_pDrvierObject->DriverUnload = DDK_Unload;
return 1;
}
A B C
C-A-5=B //实际要写入地址
// 5B 52 65 DC
if (cur!=old)
{
JCode.E9=0xE9;
JCode.JMPADDR=cur-old-5;
KdPrint(("需要写入的地址是%X",JCode.JMPADDR));
_asm
{
mov ebx,cur
lea ecx,JCode
mov ax,byte ptr [ecx]
mov byte ptr[ebx],ax //jmp
mov eax,[ecx+1] //B
mov [ebx+1],eax
}
//写入JMP
KdPrint(("NtOpenProcess被HOOK了"));
}
2、