当前位置: 代码迷 >> 汇编语言 >> 是否可以执行存放在数据区的代码解决思路
  详细解决方案

是否可以执行存放在数据区的代码解决思路

热度:584   发布时间:2013-02-26 00:00:00.0
是否可以执行存放在数据区的代码
我想问:如果我把代码的机器指令存放在的数据区,那要如何执行这些代码呢?

------解决方案--------------------------------------------------------

下面给出一个具体的例子,在数组bytecode填充一些指令码,实现2个整数相加的功能。将函数指针g_fn_add指向这个数组,并调用函数指针g_fn_add指向的指令码计算整数a和b的值。

C/C++ code
#include <stdio.h>#include <stdlib.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;    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;}
------解决方案--------------------------------------------------------
g_fn_add= (lpfn_add_c)(bytecode);
此句强转编译报错
 error C2440: “类型转换”: 无法从“char [16]”转换为“lpfn_add_c”
------解决方案--------------------------------------------------------
VC++中可以这样过渡一下:

int *func_ptr = (int *)bytecode;
...
g_fn_add= (lpfn_add_c)func_ptr;

------解决方案--------------------------------------------------------
探讨
下面给出一个具体的例子,在数组bytecode填充一些指令码,实现2个整数相加的功能。将函数指针g_fn_add指向这个数组,并调用函数指针g_fn_add指向的指令码计算整数a和b的值。


C/C++ code

#include <stdio.h>
#include <stdlib.h>

typedef int (*lpfn_add_c)(int a, int b);

……

------解决方案--------------------------------------------------------
探讨

只是想了解下,所以希望能有代码,试试

------解决方案--------------------------------------------------------
好久没有写汇编程序了,现在给出上面c程序的等价masm32汇编版本。
Assembly code
.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个字符        invoke  ExitProcess, 0end _start
------解决方案--------------------------------------------------------
API函数说明,
本程序使用了3个Windows API 函数,WriteFile,wsprintfA和ExitProcess。说明如下

1. WriteFile
第一个参数是7,7是标准输出文件的句柄。对于输出的字节数,这里简单的设为32,更好的方法应该先算出字符串的长度,传给WriteFile
2. wsprintfA 是一个windows API函数,类似于c语言库函数的sprintf
3. ExitProcess,退出进程。没有什么好讲的。
  相关解决方案