8

アセンブリ命令に変換される16進コードの配列があり、これらを実行できるプログラムを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
4

5 に答える 5

8

x86なら可能です。

ここに小さなサンプルがあります。ページに書き込み/実行権限を割り当て、そこにオペコードをコピーします。

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

POSIX システムでは、mmap() 呼び出しを使用します。

トランポリンについてもお読みください。リンクを参照してください: http://pages.cs.wisc.edu/~weinrich/papers/method_dispatch.pdf

これが完全なプログラムなのか単一の関数なのかはわかりませんでした。相対/絶対アドレッシングに問題がある可能性があります。

ちょっとした注意: このコードは、MMU が有効になっている PowerPC および ARM でも動作します。

于 2012-06-28T22:09:11.537 に答える
4

一部のプラットフォームでは、次のように宣言することはできません。

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

そして試してみてください

f(); 

16 進コードを実行します。

データページは実行できない可能性があるため。関数の内容を気にせずに関数を定義する便利な方法は.s、プロジェクトにファイルを追加することです。

GNU as でコンパイルし、そのオブジェクト ファイルを最終的なプログラムにリンクします。

例えば:

main.c

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

xs

コードは C ステートメントのように機能します。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 x.s -o x.o
gcc main.c x.o -o main
./main
Hello ASM!

さらに、16 進コード配列が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"
于 2012-06-29T07:02:47.523 に答える
4

関数ポインタを宣言してから関数を呼び出します。

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

もちろん、これは未定義の動作であり、動作する保証はありません。

于 2012-06-28T20:56:15.527 に答える
1

ヘッダー ファイル elf.h を見てください。

これらの構造体のフィールドに OPCode を入力する必要があります。

x86 には、実行可能ファイルをロードするためのプロトコルがあります。そうしないと、リンカがロードされたコードに制御を渡すと、クラッシュします。

有効な実行可能ファイルを作成する方法は次のとおりです。

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

于 2012-06-28T21:12:53.440 に答える
-1

system()それらをファイルに出力して呼び出しを使用することはできませんか? そうすれば、その配列が C 呼び出し規則に従っているかどうかを心配する必要がなくなります。

于 2012-06-28T20:56:23.897 に答える