#include #include > #include #include /* * Como usarlo (caso intel): * ./loader suma.bin * * donde suma.bin contiene los raw opcodes a ejecutar: * * objdump -d suma.o * suma.o: file format elf64-x86-64 * Disassembly of section .text: * 0000000000000000 : * 0: 55 push %rbp * 1: 48 89 e5 mov %rsp,%rbp * 4: b8 ff 00 00 00 mov $0xff,%eax * 9: c9 leaveq * a: c3 retq * * * El archivo suma contiene el codigo raw a ejecutar * /home/soporte/vi6x877/src/loader % hexdump suma.bin *0000000 4855 e589 c3c9 9090 9090 *000000a */ int main( int argc, char *argv[] ){ unsigned char (*proc)(); unsigned int i =1 ; unsigned int fdprog=0; unsigned char *rcode=0; unsigned char *exec_code=NULL; unsigned char *ptr=NULL; unsigned long salida=0x0; exec_code=(char *) malloc( sizeof(unsigned char) * 100 ); ptr=exec_code; fdprog=open(argv[1], S_IRUSR ); printf("Opcodes to exec:\n"); while( read(fdprog, ptr, sizeof(unsigned char)) ){ printf(" %02x ", *ptr ); ptr++; i++; } printf("\nEnd opcodes\n"); printf("direccion de exec_code =%p \n",exec_code); proc=(unsigned char (*)() ) exec_code; printf("direccion de proc = %p \n",proc); /* Ejecutamos los opcodes cargados en el buf al que apunta el apuntador a funcion proc el fichero cargado contiene una funcion que hace un return devolviendo el valor en el registro acomulador, el compilador se encarga de generar codigo para copiar contenido del registro anterior en la variable salida, en este caso producto de la asignacion (igual = ) */ /* toda la preparacion del stack frame, la carga del valor en el registro y la restauracion del stack frame anterior queda a cargo del codigo ejecutable escrito en el fichero de carga */ salida= (*proc)(); /* * la comunicacion entre las variables y las funciones cuando *se realiza una asignacion del tipo var= myfunction() *se realiza atraves del registro eax ( en Intel ) o en el registro acumulador en alguna otra arquitectura */ printf("output :[eax, Intel],[ r3, PPC] %lx \n",salida); return 0; } /* En Mac OS X para extraer el codigo a ejecutar : $ otool sum.o -td|sed -n '3,$p'|awk '{ print $0}' 00000000 bfc1fff8 9421ffd0 7c3e0b78 38000000 <--opcodes, valor en hex 00000010 6000aaff 7c030378 80210000 bbc1fff8 00000020 4e800020 Para generar el fichero en formato binario: otool sum.o -td|sed -n '3,$p'|awk '{ print $0}'|xxd -r > fff (xxd -r transforma la salida a formato binario) El fichero a cargar seria : ./loader fff $ otool sum.o -tv sum.o: (__TEXT,__text) section _sum: 00000000 stmw r30,0xfff8(r1) 00000004 stwu r1,0xffd0(r1) 00000008 or r30,r1,r1 0000000c li r0,0x0 00000010 ori r0,r0,0xaaff <--- a cargar el valor inmediato 0xaaff 00000014 or r3,r0,r0 00000018 lwz r1,0x0(r1) 0000001c lmw r30,0xfff8(r1) 00000020 blr Tambien se puede obtener un vector con el hexdump en formato C: otool sum.o -td|sed -n '3,$p'| awk '{ print $0}' | xxd -i |awk 'BEGIN{print "shell[]={ "} {print $0} END{ print "\};" }' shell[]={ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x62, 0x66, 0x63, 0x31, 0x66, 0x66, 0x66, 0x38, 0x20, 0x39, 0x34, 0x32, 0x31, 0x66, 0x66, 0x64, 0x30, 0x20, 0x37, 0x63, 0x33, 0x65, 0x30, 0x62, 0x37, 0x38, 0x20, 0x33, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x20, 0x36, 0x30, 0x30, 0x30, 0x61, 0x61, 0x66, 0x66, 0x20, 0x37, 0x63, 0x30, 0x33, 0x30, 0x33, 0x37, 0x38, 0x20, 0x38, 0x30, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x20, 0x62, 0x62, 0x63, 0x31, 0x66, 0x66, 0x66, 0x38, 0x20, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x20, 0x34, 0x65, 0x38, 0x30, 0x30, 0x30, 0x32, 0x30, 0x20, 0x0a }; */