问题
I have an array of hex codes that translate into assembly instructions and I want to create program in C that can execute these.
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
回答1:
With the x86 it is possible.
Here's a small sample. Allocate the page with write/exec privileges and copy your opcodes there.
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
#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;
}
For POSIX systems use the mmap() call.
Also read about trampolines. See the link: http://pages.cs.wisc.edu/~weinrich/papers/method_dispatch.pdf
You didn't tell if this is a complete program or a single function. There might be problems with relative/absolute adressing.
Small remark: this code works also with PowerPC and ARMs with MMU enabled.
回答2:
Declare a function pointer then call the function.
void (*f)(void) = (void (*)(void)) rawData;
f();
Of course this is undefined behavior and not guaranteed to work.
回答3:
On some platform, you can not just declare:
void (*f)(void) = (void (*)(void)) rawData;
and try
f();
to run the hexed code.
As the data page may NOT executable. A convenient way to define a function without caring about the content of it is to add a .s
file to your project.
Compile it with GNU as, and link it's object file to your final program.
for example:
main.c
int main()
{
helloasm();
return 0;
}
x.s
the code works like C statment: 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
Compile & run
as x.s -o x.o
gcc main.c x.o -o main
./main
Hello ASM!
In addtion, if your hexed code array is in a binary file, like 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
Then your x.s may be:
.global helloasm
helloasm:
.incbin "a.bin"
回答4:
Look at the header file elf.h .
You need to complete the fields from these structures with OPCodes.
In x86 there is a protocol to load the executable, othewise after the linker passes the control to the loaded code, it crashes.
Look here how to create a valid executable :
http://bellard.org/otcc/otccelfn.c
回答5:
Couldn't you just output those to a file and then use the system()
call? That way you don't have to worry about whether that array follows C calling convention.
来源:https://stackoverflow.com/questions/11252707/how-to-make-a-c-program-that-can-run-x86-hex-codes