We need to write our program like this:
$echo 0000000: 55 48 89 e5 b8 ff aa 00 00 c9 c3 |xxd -r > sum2.bin
Here we have the SAME little program in C: $ cat sum.c int sum(void){ return 0x00ff + 0xaa00; }
We can getLook at the results: $ gcc -c sum.c -o sum.o (get the raw opcodes in osx, intel arch )
$ otool sum.o -td|sed -n '3,$p'| awk '{ print $0}'|xxd -r > sum.bin
Now you can look at asm level your code: $ ndisasm -b 32 sum.bin 00000000 55 push ebp 00000001 48 dec eax 00000002 89E5 mov ebp,esp 00000004 B8FFAA0000 mov eax,0xaaff <-- gcc put our 'sum' final product here at compilation time 00000009 C9 leave 0000000A C3 ret
So your program is now reduced to this code: $ hexdump sum.bin 0000000 55 48 89 e5 b8 ff aa 00 00 c9 c3 000000b
Test your 2 files md5 sum.bin sum2.bin MD5 (sum.bin) = a0ccc94bcdc860a81ff28252f56c2257 MD5 (sum2.bin) = a0ccc94bcdc860a81ff28252f56c2257
We could probe our code with a selfmade userland loader: $./uloader sum2.bin Display Opcodes to exec: 55 48 89 e5 b8 ff aa 00 00 c9 c3 End opcodes code to exec address: exec_code =0x100100080 new crafted Proc : address = 0x100100080 returned value ==>aaff
----BEGIN Code--- #include <stdio.h> #include <stdlib.h>> #include <unistd.h> #include <fcntl.h>
int main( int argc, char argv[] ){ unsigned int (proc)(); unsigned int fdprog=0; unsigned int exec_code=NULL; unsigned char ptr=NULL; unsigned int returned_value=0x0; exec_code=(int ) malloc( 100 ); ptr=( char )exec_code; fdprog=open(argv[1], S_IRUSR ); printf("Display Opcodes to exec:\n"); while( read(fdprog, ptr, sizeof(unsigned char)) ){ printf(" %02x ", ptr ); ptr++; }
printf("\nEnd opcodes\n");
printf("code to exec address: exec_code =%p \n",exec_code);
proc=(unsigned int (*)() ) exec_code;
printf("new crafted Proc : address = %p \n",proc);
returned_value= (*proc)(); //here is the magic bro! :)
printf("returned value ==>%lx \n",returned_value); return 0; }
----END Code ---Saludos! Jorge A. Garcia.