2012-06-28 9 views
8

Tengo una serie de códigos hexadecimales que se traducen en instrucciones de ensamblaje y deseo crear un programa en C que pueda ejecutarlos.Cómo hacer un programa en C que pueda ejecutar códigos hexadecimales 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

Es esta tarea? Esto no es realmente una pregunta, sino una tarea. Debería decirnos qué ha intentado ya y dónde se perdió. – carmenism

+2

** ¿Intentó ** declarar un puntero de función a rawData (convención de llamadas de cuidado, por favor) y luego invocar esa función ??? Además, esto puede ser negado por Windows (si está usando Windows) debido a DEP (simplemente deshabilítelo). –

+0

¿Cómo lo desactivo? – Iowa15

Respuesta

8

Con el x86 es posible.

Aquí hay una pequeña muestra. Asigne la página con privilegios de escritura/ejecución y copie sus códigos de operación allí.

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

Para sistemas POSIX, utilice la llamada mmap().

Lea también sobre trampolines. Vea el enlace: http://pages.cs.wisc.edu/~weinrich/papers/method_dispatch.pdf

No indicó si este es un programa completo o una función única. Puede haber problemas con la dirección relativa/absoluta.

Observación pequeña: este código también funciona con PowerPC y ARM con MMU habilitado.

+1

+1 ¡Buena solución! Supongo que no es un ejecutable sino solo una función, no comienza con ningún marcador conocido. –

4

Declarar un puntero a la función y llamar a la función.

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

Por supuesto, esto es un comportamiento indefinido y no está garantizada para trabajar.

+0

Gracias, así que solo voy a completar el ciclo para la matriz – Iowa15

+1

¡Es por eso que llaman a C un paso más arriba del ensamblador! –

+2

Sí, esto es correcto. Sin embargo, hay posibles complicaciones. 1) si el conjunto realmente sigue la convención de llamadas C (es posible que pueda llamarlo, pero puede no volver). 2) Es posible que no pueda hacerlo, ya que los sistemas modernos no toman en cuenta lo que aparentemente es "solo datos" en el código ejecutable. El segmento de datos en el que puede estar la matriz puede marcarse como no ejecutable. Eso depende de todo tipo de cosas (plataforma, sistema operativo, opciones de compilación y enlace, etc.) –

-1

¿No podría simplemente sacarlos a un archivo y luego usar la llamada system()? De esta forma, no tiene que preocuparse de si esa matriz sigue a la convención de llamadas de C.

+0

Eso solo funcionaría si los códigos hexadecimales forman un programa ejecutable correctamente y no solo, por ejemplo, una función. – JAB

+1

sistema no es para hex. Es para comandos del sistema operativo (DOS o UNIX). – ST3

1

Mire el archivo de encabezado elf.h.

Debe completar los campos de estas estructuras con OPCodes.

En x86 hay un protocolo para cargar el ejecutable, de lo contrario, una vez que el enlazador pasa el control al código cargado, se bloquea.

mira aquí cómo crear un ejecutable válido:

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

4

En algunas plataformas, no se puede simplemente declarar:

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

y tratar

f(); 

para ejecutar el código hexagonal.

Como la página de datos NO es ejecutable. Una forma conveniente de definir una función sin preocuparse por el contenido de la misma es agregar un archivo .s a su proyecto.

Compile con GNU como y vincule su archivo objeto a su programa final.

por ejemplo:

main.c

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

x.s

el código funciona como C DECLARACIÓN: 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 

Compilar & plazo

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

En voluminoso, si la matriz de código hexagonal está en un archivo binario, como 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 

A continuación, sus x.s pueden ser:

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