2012-06-28 42 views
8

Tôi có một chuỗi các mã hex dịch thành các hướng dẫn lắp ráp và tôi muốn tạo chương trình trong C có thể thực thi các mã này.Cách tạo chương trình C có thể chạy mã hex x86

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 
+2

là bài tập về nhà này? Đây không thực sự là một câu hỏi, nhưng là một bài tập. Bạn nên cho chúng tôi biết những gì bạn đã thử và nơi bạn bị lạc. – carmenism

+2

** Bạn đã thử ** để khai báo một con trỏ hàm đến rawData (gọi quy ước chăm sóc, xin vui lòng) và sau đó gọi hàm đó ??? Hơn nữa điều này có thể bị từ chối bởi Windows (nếu bạn đang sử dụng Windows) vì DEP (chỉ cần vô hiệu hóa nó). –

+0

Tôi làm cách nào để tắt tính năng này? – Iowa15

Trả lời

8

Với x86 nó là có thể.

Đây là một mẫu nhỏ. Phân bổ trang với đặc quyền ghi/exec và sao chép mã của bạn ở đó.

#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; 
} 

Đối với hệ thống POSIX sử dụng cuộc gọi mmap().

Cũng đọc về trampolines. Xem liên kết: http://pages.cs.wisc.edu/~weinrich/papers/method_dispatch.pdf

Bạn không biết đây có phải là một chương trình hoàn chỉnh hay một chức năng duy nhất. Có thể có vấn đề với địa chỉ tương đối/tuyệt đối.

Nhận xét nhỏ: mã này cũng hoạt động với PowerPC và ARM với MMU được bật.

+1

+1 Giải pháp tuyệt vời! Tôi đoán nó không phải là một thực thi nhưng chỉ là một hàm, nó không bắt đầu với bất kỳ dấu hiệu đã biết nào. –

4

Khai báo con trỏ hàm, sau đó gọi hàm.

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

Tất nhiên đây là hành vi không xác định và không được bảo đảm hoạt động.

+0

Cảm ơn, vì vậy tôi chỉ chu kỳ thông qua cho mảng – Iowa15

+1

Đây là lý do tại sao họ gọi C một bước lên từ lắp ráp! –

+2

Vâng, điều này là chính xác. Tuy nhiên, có những biến chứng có thể xảy ra. 1) cho dù lắp ráp thực sự theo quy ước gọi điện thoại C (bạn có thể gọi nó, nhưng nó có thể không trở lại). 2) Bạn có thể không làm được điều đó vì các hệ thống hiện đại cau mày khi chuyển đổi những gì có vẻ bề ngoài "chỉ là dữ liệu" trong mã thực thi. Đoạn dữ liệu mà mảng có thể ở trong có thể được đánh dấu là không thực thi được. Điều đó phụ thuộc vào tất cả các loại (nền tảng, os, biên dịch và liên kết tùy chọn, vv) –

-1

Bạn không thể chỉ xuất những tệp đó vào một tệp và sau đó sử dụng cuộc gọi system()? Bằng cách đó bạn không phải lo lắng về việc liệu mảng đó có tuân thủ quy ước gọi điện của C hay không.

+0

Điều đó sẽ chỉ hoạt động nếu các mã hex tạo thành một chương trình thực thi đúng và không chỉ là một hàm. – JAB

+1

hệ thống không dành cho hex. Nó dành cho các lệnh hệ điều hành (DOS hoặc UNIX). – ST3

1

Nhìn vào tệp tiêu đề elf.h.

Bạn cần hoàn thành các trường từ các cấu trúc này bằng OPCodes.

Trong x86 có một giao thức để tải tệp thực thi, thay thế sau khi trình liên kết chuyển điều khiển đến mã đã tải, nó bị treo.

Nhìn đây làm thế nào để tạo ra một thực thi hợp lệ:

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

4

Trên một số nền tảng, bạn không thể chỉ tuyên bố:

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

và thử

f(); 

để chạy mã hexed.

Do trang dữ liệu có thể KHÔNG thực thi được. Một cách thuận tiện để xác định một hàm mà không quan tâm đến nội dung của nó là thêm một tệp .s vào dự án của bạn.

Biên dịch nó bằng GNU và liên kết tệp đối tượng của nó với chương trình cuối cùng của bạn.

ví dụ:

main.c

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

x.s

mã hoạt động giống như 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 & chạy

as x.s -o x.o 
gcc main.c x.o -o main 
./main 
Hello ASM! 

Trong addtion, nếu mã mảng hexed bạn đang ở trong một tập tin nhị phân, như 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 

Sau đó x.s của bạn có thể là:

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