Board logo

标题: 请帮忙看看以下代码哪里出了问题: [打印本页]

作者: 武骧金星    时间: 2010-3-6 06:07     标题: 请帮忙看看以下代码哪里出了问题:

004CE7B6    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-4]
004CE7B9    8A51 01         MOV DL,BYTE PTR DS:[ECX+1]
004CE7BC    8BCA            MOV ECX,EDX
004CE7BE    6BC9 24         IMUL ECX,ECX,24
004CE7C1    81C1 502C4B00   ADD ECX,Ekd5.004B2C50
004CE7C7    E8 A40EF9FF     CALL Ekd5.0045F670

这段代码在CALL 45F670时会出现以下的问题:(以下是单步步过的结果)

0045F670  /$  55            PUSH EBP
0045F671  |.  8BEC          MOV EBP,ESP
0045F673  |.  51            PUSH ECX
0045F674  |.  894D FC       MOV DWORD PTR SS:[EBP-4],ECX
0045F677  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0045F67A  |.  8B00          MOV EAX,DWORD PTR DS:[EAX] //访问违规: 读取[0A94AE14]
0045F67C  |.  8BE5          MOV ESP,EBP
0045F67E  |.  5D            POP EBP
0045F67F  \.  C3            RETN

请问这可能是由于什么原因?谢谢。

[ 本帖最后由 武骧金星 于 2010-3-6 06:22 编辑 ]
作者: godtype    时间: 2010-3-6 07:59

在004CE7B9这里加一个断点(F2),看一下从[EBP-4]输出到ECX的值是多少。
作者: 武骧金星    时间: 2010-3-6 12:34

……真奇怪,这时ECX的值是004927F0,应该是没问题的……

可是接下去几步后ECX就变成那个违规调用的内存位置了……

[ 本帖最后由 武骧金星 于 2010-3-6 13:02 编辑 ]
作者: 武骧金星    时间: 2010-3-6 13:12

经过仔细研究发现:原来代码应该改成这个样子:

004CE7B6    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-4]
004CE7B9    8A51 01         MOV DL,BYTE PTR DS:[ECX+1]
004CE7BC    8BCA            MOV ECX,EDX
在这里插一条:                  AND ECX, 0FF
004CE7BE    6BC9 24         IMUL ECX,ECX,24
004CE7C1    81C1 502C4B00   ADD ECX,Ekd5.004B2C50

这样就行了……

不过,能不能在技术上解释一下这里出问题的原因呢?谢谢。
作者: godtype    时间: 2010-3-6 15:36

嗯,我开头也没有注意看。
因为 MOV DL,BYTE PTR DS:[ECX+1] 是单字节,而 MOV ECX,EDX 是四字节,所以要进行零扩展。
也可以改成以下几种方式:
1、在MOV DL,BYTE PTR DS:[ECX+1]的前面加一条XOR EDX,EDX
2、将MOV DL,BYTE PTR DS:[ECX+1]改成MOVZX EDX,BYTE PTR DS:[ECX+1]
以上两种都可以省去AND ECX,0FF
3、
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX ECX,BYTE PTR DS:[EDX+1]
这样还可以省多一条MOV ECX,EDX
4、将
AND ECX, 0FF
IMUL ECX,ECX,24
ADD ECX,Ekd5.004B2C50
写成一个自定义函数,直接CALL就是了,这样以后在其他地方修改也更方便一些。




欢迎光临 轩辕春秋文化论坛 (http://www.xycq.org.cn/forum/) Powered by Discuz! 5.0.0