hur.cn - 华软网

 热门搜索

Release版本下,我用VirtualProtect函数修改内存页属性返回1,WriteProcessMemory返回1,程序结果却并没有正确

  作者:未知    来源:网络    更新时间:2011/5/30
如下代码,Release版本下,我想用自己的MyMessageBox函数替换系统API函数MessageBox,在修改导入表的地址过程中,修改页属性为PAGE_READWRITE返回1,写入内存WriteProcessMemory也返回1.但是函数还是没被替换掉,但是在Debug下运行是可以成功的。找不出原因了。。 如下是代码
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr,&mbi,sizeof(mbi));    //lpAddr是函数在文件导入表中的地址,DEBUG下运行正确,所以地址应该是没问题的
VirtualProtect(lpAddr,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldProtect);

::WriteProcessMemory(GetCurrentProcess(),lpAddr,&lpNewProc,sizeof(DWORD),NULL);

VirtualProtect(lpAddr,sizeof(DWORD),dwOldProtect,0); //运行到这里把页属性改回去时返回0,原因是内存分配访问无效。但是我想应该不会影响前面的程序。
---华软 网友回答---
第二个VirtualProtect会失败,内存分配失败指的是lpflOldProtect为NULL
lpflOldProtect 
[out] Pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails. 

函数没替换成功,找个调试器,在WriteProcessMemory后边写个int 3,然后一步步跟这看看..
---华软网友回复---
贴完整代码上来~
---华软网友回复---
程序代码是不可写的,DEBUG版可能采取了特殊措施,把代码拷贝了出来执行的。要修改代码段,用VirtualProtect赋与PAGE_WRITECOPY权限
---华软网友回复---
VirtualProtect失败的原因mszjk已经说清楚了

至于为何WriteProcessMemory成功了却没有勾住,我猜你的代码是这样的

MessageBox(....);
HookIAT(...);
MessageBox(....);

然后发现第二次调用MessageBox未受影响,这是因为release下编译器有优化
它发现你要调用两次MessageBox,因此在调用第一次MessageBox前把MessageBox的地址从IAT中读取到一个稳定寄存器中,一般是esi,因为调用约定是esi等在函数调用前后不变
你的HookIAT函数修改的仅仅是IAT中的地址,然而第二次MessageBox调用是call esi,不从IAT中读取了,因此这次调用不受影响
---华软网友回复---
如果你的代码安排是我所说的,换成
HookIAT(...);
MessageBox(....);
就应该有效
---华软网友回复---
如果 debug 版本正确,把这段代码的编译全局优化关掉试一试

#pragma optimize("g", off)
...// 你的代码
#pragma optimize("", on)

---华软网友回复---
引用 1 楼 mszjk 的回复:
第二个VirtualProtect会失败,内存分配失败指的是lpflOldProtect为NULL
lpflOldProtect 
[out] Pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. I……



lpflOldProtect值为READONLY的值哈,这个是没问题的。

---华软网友回复---
引用 4 楼 lactoferrin 的回复:
VirtualProtect失败的原因mszjk已经说清楚了

至于为何WriteProcessMemory成功了却没有勾住,我猜你的代码是这样的

MessageBox(....);
HookIAT(...);
MessageBox(....);

然后发现第二次调用MessageBox未受影响,这是因为release下编译器有优化
它发现你要调用两次MessageBox,因此……




确实是这样!  现在好了。 非常感谢,高手!
---华软网友回复---
-
引用 7 楼 loverwlj520 的回复:
引用 1 楼 mszjk 的回复:
第二个VirtualProtect会失败,内存分配失败指的是lpflOldProtect为NULL
lpflOldProtect
[out] Pointer to a variable that receives the previous access protection value of the first page in the specified ……


MSDN说的很明白,lpfnOldProtect为NULL的话,函数VirtualProtect失败.========      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。