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

是否可以执行存放在数据区的代码
我想问:如果我把代码的机器指令存放在的数据区,那要如何执行这些代码呢?

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

下面给出一个具体的例子,在数组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 model
option casemap :none  ; case sensitive

WriteFile   PROTO        STDCALL:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CloseHandle PROTO        STDCALL:DWORD
ExitProcess PROTO        STDCALL:DWORD
wsprintfA    PROTO       C:DWORD,:VARARG 

includelib user32.lib
includelib 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, 0c3h
align        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, 0
end _start

------解决方案--------------------
API函数说明,
本程序使用了3个Windows API 函数,WriteFile,wsprintfA和ExitProcess。说明如下

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