我在使用Virtualprotect()api时遇到问题。 我从学校得到一份任务,我的老师告诉我们,过去当记忆稀less而昂贵。 程序员不得不创build先进的algorithm,在运行中自行修改以节省内存。 所以你有它,我们现在必须写这样一个algorithm,它不一定是有效的,但它必须修改自己。
所以我开始这样做,而且我想,在寻求任何帮助之前,我做了很多。
我的程序是这样的:
我有一个函数和一个内置堆栈溢出循环。 该堆栈获取溢出的代码所在的内存位置的地址是在循环过程中构build的。 控制传递给内存中的代码。 该代码加载一个DLL然后退出,但在退出之前,必须修复该循环。 这是我们任务的条件之一,在原来的循环中改变的一切都必须得到恢复。
批量游戏退出,而不是去下一行
将variables的结果保存在Windows批处理中
崩溃转储意味着顺序指令之间的寄存器值发生了变化
问题是,我没有写访问循环,只有READ_EXECUTE,所以改变我的访问我想,我使用virtualprotect。 但是那个函数返回了一个错误:
ERROR_NOACCESS,关于这个错误的文档是非常苗条的,windows只说:有效的访问内存地址。 自从我首先想要改变访问权限后,哪些数字是可以接受的。 那么怎么了? 下面是在内存中构build的代码:我的代码中的所有数据名称都有点模糊,所以我提供了一些注释
Size1: TrapData proc jmp pLocals LocalDllName db 100 dup(?) ; name of the dll to be called ebx-82h RestoreBuffer db 5 dup(?) ; prevIoUs bytes at the overflow location LoadAddress dd 0h ; ebx - 19h ; address to kernel32.loadlibrary RestoreAddress dd 0h ; ebx - 15h ; address to restore (with the restore buffer) AddresstoRestoreBuffer dd 0h ; ebx - 11h ; obsolete,I don't use this one AddresstoLea dd 0h ; ebx - 0Dh Changed,address to kernel32.virutalprotect AddresstoReturnTo dd 0h ; ebx - 9h address to return execution to(the same as RestoreAddress pLocals: call Refpnt Refpnt: pop ebx ; get current address in ebx push ebx mov eax,ebx sub ebx,82h push ebx ; dll name sub eax,19h ; load lib address mov eax,[eax] call eax pop ebx ; Current address push ebx ;BOOL WINAPI VirtualProtect( ; __in LPVOID lpAddress,; __in SIZE_T dwSize,; __in DWORD flNewProtect,; __out PDWORD lpflOldProtect ;); mov eax,ebx mov esi,ebx sub eax,82h push eax ; overwrite the buffer containing the dll name,we don't need it anymore push PAGE_EXECUTE_READWRITE push 5h sub esi,15h mov esi,[esi] push esi sub ebx,0Dh mov ebx,[ebx] call ebx ; Returns error 998 ERROR_NOACCESS (to what?) pop ebx push ebx sub ebx,1Eh mov eax,ebx ; restore address buffer pointer pop ebx push ebx sub ebx,15h ; Restore Address mov ebx,[ebx] xor esi,esi ; counter to 0 @0: push eax mov al,byte ptr[eax+esi] mov byte ptr[ebx+esi],al pop eax inc esi cmp esi,5 jne @0 pop ebx sub ebx,9h mov ebx,[ebx] push ebx ; address to return to ret Size2:
那么怎么了? 你们能帮我吗?
编辑,工作代码:
Size1: jmp pLocals LocalDllName db 100 dup(?) RestoreBuffer db 5 dup(?) LoadAddress dd 0h ; ebx - 19h RestoreAddress dd 0h ; ebx - 15h AddresstoRestoreBuffer dd 0h ; ebx - 11h AddresstoLea dd 0h ; ebx - 0Dh AddresstoReturnTo dd 0h ; ebx - 9h pLocals: call Refpnt Refpnt: pop ebx ; get current address in ebx push ebx mov eax,; __out PDWORD lpflOldProtect ;); mov esi,ebx push 0 push esp push PAGE_EXECUTE_READWRITE push 5h sub esi,[ebx] call ebx pop ebx pop ebx push ebx sub ebx,[ebx] push ebx ; address to return to ret Size2:
也许有点马虎,但我不这么做;)
为什么CALL SET在CMD Windows和.CMD文件中的工作方式不同?
如何修剪存储在std :: set中的string?
使用Windows安装程序启动依赖于并行程序集的服务
如何设置 – 一些工作?
您正在尝试使VirtualProtect将lpflOldProtect写入只读内存位置,也就是您当前的代码部分,这正是您想要首先取消保护的部分! 我的猜测是这是什么给你的ERROR_NO_ACCESS 。 既然你正在使用堆栈,那就让它把lpflOldProtect写入堆栈位置。
这并不像过去那么容易, 读取访问用来暗示执行访问,而且大量的映射映射是可写的。
这些天,如果有很多(任何?)内存映射是可写和可执行的,我会感到惊讶。 (现代cpu支持PAE即使是32位内核也能提供不可执行的可读映射。)
首先要说的是,找到一个较旧的Windows系统,Win2k或更早版本, 然后开始尝试解决这个问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。