标 题: 【分享】西裤哥的 Hook Api Lib 0.2 For C
作 者: 海风月影
时 间: 2007-03-21,15:11:30
链 接: http://bbs.pediy.com/showthread.php?t=41387
对xIkUg的hook lib for delphi研究了一番,尤其是里面的GetOpCodeSize是好东西
![狂笑](http://www.cnblogs.cc2/images/smilies/biggrin.gif)
,但不太会用delphi,因此转成 VC代码 共享出来。
转好后发现GetOpCodeSize()有点小BUG,草草修正后发上来
先贴代码,然后再说明
GetOpCodeSize()对某些命令会算错,经多次试验,排查,发现问题在这里
代码:
if ((dh & 0x10) == 0)
{
dh ^= 6; // 这里不能异或6,是异或1,而且不是所以情况都要异或
t &= 0xFFFFFF00;
t |= dh;
}
改成这个,就可以了(我没研究到底为什么,反正能用就行)
代码:
if (dh & 0x40) //是否是 0x6x
dh ^= 1; // 当dh = 0x2x 这里计算多2,当=62的时候却是 异或1
还有一个问题,应该是GetOpCodeSize本身的问题了
/*
一旦OpCode以Prefix 66 开头,会出问题
如,第一个例子
66:814D E4 0103 or word ptr ss:[ebp-1C], 301
计算出来是8,其实是 814D E4 01030000 的7位 加上66一个字节
而,第二个例子
66:8906 mov word ptr ds:[esi], ax
正确,是3
原因是这样的
引用老罗的Learningopcode:
//////////////////////////////////////////////////////////////////////////
现在我们将要学习剩下的几个Prefixes,它们可以被划分为5个集合,分别是:
Change DEFAULT operand size. (66)
Change DEFAULT address size. (67)
Repeat prefixes. (F2, F3)
Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)
LOCK prefix. (F0)
prefix 66的作用是切换默认的操作数大小。请注意我们并没有说“指定”,
而是“切换”!反映到这个例子中,就是“切换默认的32位操作数到16位”
,而不是“指定操作数的大小为16位”。
也许并不是所有情况下的操作数大小都可以随意改变的。
假如这个改变是不允许的,那么它就会被忽略。
//////////////////////////////////////////////////////////////////////////
因此,第一个例子操作数从32位变成了16位,第二个例子无法改变,所以就没变
因此,此算法没有考虑prefix 66开头的变化,要加上66开头的处理
66也占一个字节,因此,第一个其实是 8
*/
这里我是在最后进行修正的,前面那些分支就没去管它
修正如下:
/*
单独处理 66 开头的问题
1字节66 ,1字节操作码,4字节操作数,因此至少要大于等于6以上
如
0040A339 66:B8 FF00 mov ax, 0FF
0040A33D 0000 add byte ptr ds:[eax], al
★我们这里假设windows 32位系统中没有单独操作16位的OpCode(事实估计也是这样的
![狂笑](http://www.cnblogs.cc2/images/smilies/biggrin.gif)
)
*/
代码:
if (((*(char*)Start) & 0x000000FF) == 0x66) // 单独处理 66 开头的问题
if ( OpCodeSize >= 6) //1字节66 ,1字节操作码,4字节操作数,因此至少要大于等于6以上
OpCodeSize -= 2; //减2处理 ,将 dword 型转成 word 型
上面的代码里有个main(),我测试了一下GetVolumeInformationW这个API函数,一共500+个字节,用OD反汇编对照了一下,OpCode长度没判断错,暂且认为它已经正确了吧,下面就可以用GetOpCodeSize干点坏事了,哈哈
thx to xIkUg,luocong