执行存放在的数据区的机器指令的方法
来源:互联网 发布:博客ios优化 编辑:程序博客网 时间:2024/05/22 13:59
转载请标明是引用于 http://blog.csdn.net/chenyujing1234
编译工具:VS2005
最近在论坛上看到这个主题,想对此做些总结。
基本知识:
1. 在32bit flat模式,Windows对代码section是有保护的,一般不允许修改,对于数据section,可读可写可执行。所以执行数据section的代码是没有问题的,代码section和数据section是统一编址的。用一条call指令即可实现。
2. 在16bit dos 模式,dos对代码段没有保护,故代码段依然是可写的,你可以在代码段预留一块空间,将数据区的指令复制到代码段保留区,然后执行。如果你非要运行数据段的代码,则比较麻烦,需要修改cs寄存器。
我们的电脑是32 bit flat的,故数据段是可读可写可执行的,所以执行数据段的代码没有问题。
这里可以用下面的例子说明这一点:
#include <stdio.h>#include <stdlib.h>#include <Windows.h>typedef int (*lpfn_add_c)(int a, int b);char bin_pattern[]={0x8b, 0x44, 0x24, 0x08,0x8b, 0x4c, 0x24, 0x04,0x03, 0xc1,0xc3,};int main(int argc, char* argv[]){char bytecode[16];int a,b,c;lpfn_add_c g_fn_add;memset(bytecode,0,sizeof(bytecode));memcpy(bytecode,bin_pattern,sizeof(bin_pattern));a=3;b=5;// 用下面的方法做过渡int *temp = (int*)bytecode;g_fn_add= (lpfn_add_c)(temp);// 编译出错// error C2440: “类型转换”: 无法从“char [16]”转换为“lpfn_add_c”//g_fn_add= (lpfn_add_c)(bytecode);//接下来去执行在数据区的代码c=g_fn_add(a,b);printf("a=%d,b=%d,a+b=%d\n",a,b,c);return 0;}
.386.model flat ; 32 bit memory modeloption casemap :none ; case sensitiveWriteFile PROTO STDCALL:DWORD,:DWORD,:DWORD,:DWORD,:DWORDCloseHandle PROTO STDCALL:DWORDExitProcess PROTO STDCALL:DWORDwsprintfA PROTO C:DWORD,:VARARG includelib user32.libincludelib kernel32.lib .const_formatString db '%d+%d=%d',0dh,0ah,0 .data? ;非初值化的数据,不占可执行文件空间_buff db 128 dup (?)align 4_tmp1 dd ? _c dd ? .data ;初值化的数据fun_add db 8bh, 44h, 24h, 08h, 8bh, 4ch, 24h, 04h,03h, 0c1h, 0c3halign 4_a dd 3_b dd 5 .code_start: mov eax,_a mov edx,_b push eax push edx lea ebx, fun_add ;eax 执行函数的地址 call ebx mov _c, eax ;返回值 --> 全局变量 _c invoke wsprintfA, addr _buff, addr _formatString, _a, _b, _c add esp, 20 ;5 * dword? invoke WriteFile,7,OFFSET _buff,32,OFFSET _tmp1,0 ; 输出到控制台,输出32个字符 ; 7是标准输出文件的句柄 invoke ExitProcess, 0 ; 退出进程end _start
把上面的汇编保存为test.asm
编译test.asm成exe 的方法是:
编译ASM时得添加规则:
右击项目-> 自定义生成规则->
此时编译会提示:
1>LINK : fatal error LNK1221: 无法推导出子系统,必须定义它
这时要在工程属性->链接->命令行下添
/subsystem:console
再编译,产生exe了。
- 执行存放在的数据区的机器指令的方法
- 存放待执行指令的地址。
- 执行数值精度转换的机器指令
- 在C++中执行cmd指令的两种方法
- 在C++中执行cmd指令的两种方法
- 在C++中执行cmd指令的两种方法
- 在C++中执行cmd指令的两种方法
- opentsdb采集的数据存放在哪里
- 你的数据存放在哪
- NValue存放的数据
- 数据存放的位置
- 【Swift】数据的存放
- 在linux中执行可执行文件的指令
- android 执行monkey指令的方法
- react中将数据存放在缓存中的方法和将数据从缓存中取出的方法
- 关于数据区中存放的东西
- MTK机器的默认时间存放地
- 数据在程序中存放的位置[转]
- 第十周报告(二)
- java 的异常处理
- 第十周实验报告3(派生类+流输入输出-->求圆柱体的面积与体积)
- C# lock 锁的操作
- CSemaphore/CMutex/CCriticalSection/CEvent区别
- 执行存放在的数据区的机器指令的方法
- 求数组中子数组的最大和
- Visual Studio快捷键大全
- Java内部类简述总结
- 日语发音
- Android有用代码片段(二)
- 大学那点破事
- 客户端实现准确的服务器时间同步
- 键盘快捷键大全