如何制作一个可以运行x86hex代码的C程序

我有一个hex代码数组转换成汇编指令,我想在C中创建可以执行这些的程序。

unsigned char rawData[5356] = { 0x4C, 0x01, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0C, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x05, 0x00, 0x00, 0xA4, 0x01, 0x00, 0x00, 0x68, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x60, 0x2E, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0xC0, 0x2E, 0x62, 0x73, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x30, 0xC0, 0x2F, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x58, 0x07, 0x00, 0x00, 0x32, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x10, 0x30, 0x60, 0x2F, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6C, 0x07, 0x00, 0x00,...and so on 

使用x86是可能的。

这是一个小样本。 使用write / exec权限分配页面并在那里复制您的操作码。

 #ifdef _WIN32 #include  #else #include  #include  #endif int main(){ char opcodes[] = { ..... }; #ifdef _WIN32 HANDLE mem_handle = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, length, NULL); void* mem_map = MapViewOfFile( mem_handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0x0, 0x0, length); #else // posix void* mem_map = mmap(NULL, sizeof(opcodes), PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); #endif memcpy(mem_map, opcodes, sizeof(opcodes)); (( void(*)() )mem_map)(); return 0; } 

对于POSIX系统,请使用mmap()调用。

还阅读有关蹦床的信息。 请参阅链接: http : //pages.cs.wisc.edu/~weinrich/papers/method_dispatch.pdf

您没有告诉这是完整的程序还是单个函数。 相对/绝对地址可能存在问题。

小注:此代码也适用于启用了MMU的PowerPC和ARM。

声明一个函数指针然后调用该函数。

 void (*f)(void) = (void (*)(void)) rawData; f(); 

当然这是未定义的行为,并不能保证工作。

在某些平台上,您不能只声明:

 void (*f)(void) = (void (*)(void)) rawData; 

并尝试

 f(); 

运行hexed代码。

由于数据页面可能无法执行。 定义函数而不关心其内容的便捷方法是将.s文件添加到项目中。

用GNU as编译它,并将它的目标文件链接到你的最终程序。

例如:

main.c中

 int main() { helloasm(); return 0; } 

XS

代码就像C语句一样: printf("Hello ASM\n"); exit(11); printf("Hello ASM\n"); exit(11);

 .global helloasm helloasm: .byte 0x48, 0xc7, 0xc7, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x0b, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c .byte 0x6f, 0x20, 0x41, 0x53, 0x4d, 0x21, 0x0a, 0x5e, 0x48, 0xc7, 0xc2, 0x0b, 0x00, 0x00, 0x00, 0xb8 .byte 0x01, 0x00, 0x00, 0x00, 0x0f, 0x05, 0xbf, 0x0b, 0x00, 0x00, 0x00, 0xb8, 0x3c, 0x00, 0x00, 0x00 .byte 0x0f, 0x05 

编译并运行

 as xs -o xo gcc main.c xo -o main ./main Hello ASM! 

另外,如果你的hexed代码数组是二进制文件,比如a.bin

 hexdump -C a.bin 00000000 48 c7 c7 01 00 00 00 e8 0b 00 00 00 48 65 6c 6c |H...........Hell| 00000010 6f 20 41 53 4d 21 0a 5e 48 c7 c2 0b 00 00 00 b8 |o ASM!.^H.......| 00000020 01 00 00 00 0f 05 bf 0b 00 00 00 b8 3c 00 00 00 |............<...| 00000030 0f 05 |..| 00000032 

那你的xs可能是:

 .global helloasm helloasm: .incbin "a.bin" 

查看头文件elf.h。

您需要使用OPCodes完成这些结构中的字段。

在x86中有一个加载可执行文件的协议,在链接器将控件传递给加载的代码之后,它会崩溃。

在这里看看如何创建有效的可执行文件:

http://bellard.org/otcc/otccelfn.c

难道你不能只将它们输出到文件然后使用system()调用吗? 这样您就不必担心该数组是否遵循C调用约定。