当前位置: 代码迷 >> 汇编语言 >> windows2000里winapi是不是没有对edi、ebx、esi进行保护解决思路
  详细解决方案

windows2000里winapi是不是没有对edi、ebx、esi进行保护解决思路

热度:2875   发布时间:2013-02-26 00:00:00.0
windows2000里winapi是不是没有对edi、ebx、esi进行保护
我用VC编译一个多线程的c程序,发现release模式的时候总是出现0地址非法访问。
加   /FA选项查看汇编代码,发现使用了ebx,它是这样用的:
mov ebx,   DWORD   PTR   __imp__WaitForSingleObject@8
push 1000 ;   000003e8H
push esi
call         ebx

可是我查看ebx的值竟然是0,于是我在网上找到两篇文章:
1.“根据我的试验,在win2000以上操作系统对于ebx,esi,edi好像是拿来就用,没有进行保护和恢复,如果你的程序中使用了这几个寄存器,请一定先压栈,用完后恢复。否则会使程序在win98下正常,在win2000下出现莫名其妙的非法操作,一般是提示某个地址不能进行读写操作,而这个地址并不在你的程序的控制下。”

2.“如果你的程序98正常,而xp非法操作,进来看看
我经常玩游戏,特别喜好小游戏.经常把小游戏改动一下使之容易通关,或者汉化容易操作,以博女友欢心.我基本用winme,最近进XP发现玩改动后的小游戏时,出现莫名其妙的非法操作.说某某地址不能进行读写操作.

百思不得其解,辛苦很久才发现XP对ebx没有保护和恢复,如果你的程序也使用了ebx寄存器,请一定先压栈,用完后恢复
esi,edi好像也是.”

最后我在程序中加入以下代码:
                        __asm
                        {
                                mov   ebx,   123
                        }
目的就是不让编译器使用ebx,问题解决了。
但是我觉得这是一个隐患,以前编程从来没有想到过还有这种问题,请各们大大来说说看。

------解决方案--------------------------------------------------------
这个要看具体的api大多数都作了:

push esi
push edi
push ebx

等的操作,但也有例外,这个要结合反汇编实际来看。
------解决方案--------------------------------------------------------
不能一概而论,具体函数具体对待,不过相信Windows的分层体制,这些地层操作也应该在地层实现,估计可以访问到edi、ebx、esi寄存器的只有个别的API而已。
------解决方案--------------------------------------------------------
win9x以及winme都是允许应用程序直接操纵硬件的,但是为了系统的稳定和安全,WinNT、2000、xp以及后继版本都对系统实行了一些保护措施,不再允许应用程序直接操作硬件,而只能通过调用API来安全的使用硬件。所以在windows9x在运行的程序未必可用在Win2000及其后续版本中运行。