Lets see a really simple program you can explain all te assembly :)
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 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
#include >
#include
#include
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.