void HookpIofCallDriver()
{
KIRQL oldIrql;
ULONG addr = (ULONG)IofCallDriver;
__asm
{
mov eax,addr
mov esi,[eax+2]
mov eax,[esi]
mov old_piofcalldriver,eax
}
oldIrql = KeRaiseIrqlToDpcLevel();
__asm
{
mov eax,cr0 //什么意思
mov oData,eax //oData 已有定义
and eax,0xffffffff //什么意思
mov cr0,eax
mov eax,addr
mov esi,[eax+2]
mov dword ptr [esi],offset NewpIofCallDriver //什么意思 要详细注释
mov eax,oData
mov cr0,eax
}
KeLowerIrql(oldIrql);
return ;
}
以上代码有表明注释的地方请加注释!
cr0是系统内的控制寄存器之一。控制寄存器是一些特殊的寄存器,它们可以控制CPU的一些重要特性。
控制寄存器最初出现于低级的286处理器中,以前称之为机器状态字(machine status word),在386以后它们被重命名为控制寄存器(control register)。cr0寄存器直到486的处理器版本才被加入了“写保护”(Write Protect,WP)位,WP位控制是否允许处理器向标记为只读属性的内存页写入数据,如果我们将WP位设置为0,就可以禁用写保护的功能。
mov eax,cr0 // 这行和下面一行的意思是 将cr0 的值保存下来,避免它受到下面操作的影响.
mov oData,eax //oData 已有定义
and eax,0xffffffff // 影响一些标志位, 但是看不出有什么实际目的.
...
mov eax,addr
mov esi,[eax+2]
mov dword ptr [esi],offset NewpIofCallDriver // 将NewpIofCallDriver 函数的地址放到 addr+2的地址
这段代码应该是用于Hook IofCallDriver 函数的, addr+2的地方放自己的函数地址, addr应该原函数的地址,
addr+0, addr+1 应该是 jmp 命令的汇编码. 这样当 IofCallDriver 被调用的时候就会跳到 NewpIofCallDriver 去.
更改所有函数地址都不可改该地址的前一两个吗???
不是, hook函数时怎么更改还要看具体情况的. 有一些改函数地址的前8个字节, 有一些像你例子中的只改4个字节的函数地址(因为这里有个跳转表).
mov dword ptr [esi],offset NewpIofCallDriver
把变量NewpIofCallDriver 的偏移量放到由esi指向的双字地址中。
mov eax,cr0 //cr0应该是某全局变量
mov oData,eax //oData 这两行加起来相当于oData=cr0;
and eax,0xffffffff //和全为1的数进行与运算对本身毫无影响,但是可以影响到状态寄存器的某些标志位。
.....
mov eax,addr
mov esi,[eax+2]
mov dword ptr [esi],offset NewpIofCallDriver
//这个NewpIofCallDriver应该是某函数吧,把它的入口地址赋值给一个"addr"变量(可能是一个结构)中偏移2的地方。