x64下SSDT表中值的含义

这是在win7 x64下查看ssdt表中数据:

kd> dd fffff800`03e83300
fffff800`03e83300  0f68d000 02f55c00 fff6ea00 02e87805
fffff800`03e83310  031a4a06 03116a05 02bb9901 02b4f200
fffff800`03e83320  0312cc40 03dd7400 02c84700 02e7d100
fffff800`03e83330  02f68100 02e02301 02dd0601 02d96100
fffff800`03e83340  02df4602 02f18600 02ad0500 02cefe01
fffff800`03e83350  02d01d02 02f69902 03101101 0323ca01
fffff800`03e83360  0455c305 02ed29c0 02b2e703 ffec1d00
fffff800`03e83370  043c2800 02f51040 02c52c01 03126c00

这里跟32位系统下的ssdt表直接存的是函数地址不同,这里存放的都是4字节的数据,通过反汇编可知,这些数据 比如02f55c00,将其右移4位再加上ssdt表地址即真实函数地址,02f55c00 >>4+ssdtbase。这个表中的数据是有符号的,如第三项 fff6ea00 ,这表示一个负值,我们在计算函数地址的时候要注意使用有符号的类型来计算,比如long,这样将其与ssdt地址相加的时候才能得到正确的地址,使用long来跟longlong相加时fff6ea00 才会变成ffffffff`fff6ea00 ,如果错误的使用了无符号类型如DWORD ,则会变成00000000`fff6ea00 ,这样计算是有问题的。

为什么要存偏移呢?一是可以节省内存,二是可以在一定程度上防止SSDT HOOK ,因为偏移用的28位的一个有符号整数来表示。这样ssdt表中函数只能在ssdt表地址上下256mb内存中间,一共也就是512mb。而nt加载的地址一般是fffff800`xxxxxxxx开头,而我们的驱动一般是fffff880`xxxxxxxx开头的加载地址。相差不止512mb,所以想要跟以前那样去直接修改ssdt表地址来进行hook是行不通了。

不过还是有办法,我一般是在ssdt表上下256mb内存中找到一块内存缝隙来执行我的跳转代码,我也见过修改系统例程的如KeBugCheckEx等。其实就是在ssdt表限制下加一段跳转代码来跳到我们的驱动中的函数中,多了这个步骤而已。

 

你可能感兴趣的:(C/C++,Windows,内核)