c - Getting the exact position of a specific OpCode in a binary file -
our professor in computer-architecture gave sample program asks password. task change jump-opcode after compares entered password , decides if okay or not. wrote program can change byte @ specific place in given binary file.
here's code of pasword-program:
int main(int argc, char* argv[]){ char *pw = "12441233"; char pass[32]; printf("enter password:\n"); scanf("%s", pass); if(strncmp(pass,pw,8)) { printf("password wrong\n"); exit(-1); } printf("welcome\n"); }
so entered $ objdump -d task
in console , got this:
...
400703: || 48 8b 5d e8 || mov -0x18(%rbp),%rbx
400707: || 64 48 33 1c 25 28 00 || xor %fs:0x28,%rbx
40070e: || 00 00
400710: || 74 05 || je 400717
400712: || e8 29 fe ff ff || callq 400540 <__stack_chk_fail@plt>
400717: || 48 83 c4 58 || add $0x58,%rsp
40071b: || 5b || pop %rbx
...
74
byte je want change 75
jne. how can exact position of 74
byte in corresponding binary file can change new value?
as hans noted, memory location has nothing it. need find byte (or bytes) located in file. disassembler (this ida-pro) makes live easy. sadly, there steep price curve ida, stick tools can easily.
what follows done on linux machine, using gcc version 4.8.2 , gdb 7.7 running on ubuntu 14.04
compiled code using
gcc -g -ansi -pedantic -wall
. not issue,main
should have return value.loaded program gdb, put break point @ main , ran program. when hit break point, used gdb's
disass
command disassembly listing shown below:(gdb) disass dump of assembler code function main: 0x000000000040067d <+0>: push %rbp 0x000000000040067e <+1>: mov %rsp,%rbp 0x0000000000400681 <+4>: push %rbx 0x0000000000400682 <+5>: sub $0x58,%rsp 0x0000000000400686 <+9>: mov %edi,-0x54(%rbp) 0x0000000000400689 <+12>: mov %rsi,-0x60(%rbp) => 0x000000000040068d <+16>: mov %fs:0x28,%rax 0x0000000000400696 <+25>: mov %rax,-0x18(%rbp) 0x000000000040069a <+29>: xor %eax,%eax [ ... ] 0x00000000004006cc <+79>: mov $0x8,%edx 0x00000000004006d1 <+84>: mov %rcx,%rsi 0x00000000004006d4 <+87>: mov %rax,%rdi 0x00000000004006d7 <+90>: callq 0x400520 <strncmp@plt> 0x00000000004006dc <+95>: test %eax,%eax 0x00000000004006de <+97>: je 0x4006f4 <main+119> 0x00000000004006e0 <+99>: mov $0x4007c0,%edi 0x00000000004006e5 <+104>: callq 0x400530 <puts@plt> [ ... ] 0x0000000000400718 <+155>: retq end of assembler dump.
pretty ominous looking, know take second , around , notice few things; a. numbers in angle-brackets (i.e. <+97>) give number of bytes instruction located start of function. in case the op-code need 97 bytes beginning of function.
b. first 9 bytes (the first 4 instructions) have here, prolog function, , setting activation (or stack) frame function.now, need find main in executable. tends os , compiler specific. in case, working on linux host, know code stored in .text section of file, , can use tool
readelf
location shown below;readelf --wide -s task there 35 section headers, starting @ offset 0x1478: section headers: [nr] name type address off size es flg lk inf al [ 0] null 0000000000000000 000000 000000 00 0 0 0 [ 1] .interp progbits 0000000000400238 000238 00001c 00 0 0 1 [ 2] .note.abi-tag note 0000000000400254 000254 000020 00 0 0 4 [ 3] .note.gnu.build-id note 0000000000400274 000274 000024 00 0 0 4 [ 4] .gnu.hash gnu_hash 0000000000400298 000298 00001c 00 5 0 8 [ 5] .dynsym dynsym 00000000004002b8 0002b8 0000c0 18 [ .... ] [13] .text progbits 0000000000400590 000590 000202 00 ax 0 0 16 [14] .fini progbits 0000000000400794 000794 000009 00 ax 0 0 4 [15] .rodata progbits 00000000004007a0 0007a0 000037 00 key flags: w (write), (alloc), x (execute), m (merge), s (strings), l (large) (info), l (link order), g (group), t (tls), e (exclude), x (unknown) o (extra os processing required) o (os specific), p (processor specific)
from above, can see .text section start @ memory location of 0x400590 , ending location of 0x400792 (based on size of 0x202). additionally, can see the .text section has offset in file of 0x590. looking @ our disassembly, can see
main
starts @ 0x0040067d, in range of .text (just sanity check).we have entry point application (the starting memory address of .text section, , if subtract starting point of
main
entry point, should offset (in memory)main
relative code mapped. adding value offset of code in executable should give file location ofmain
:000067d: 5548 89e5 5348 83ec 5889 7dac 4889 75a0 uh..sh..x.}.h.u. 000068d: 6448 8b04 2528 0000 0048 8945 e831 c048 dh..%(...h.e.1.h 000069d: c745 b8a4 0740 00bf ad07 4000 e882 feff .e...@....@..... 00006ad: ff48 8d45 c048 89c6 bfbd 0740 00b8 0000 .h.e.h.....@.... 00006bd: 0000 e8ac feff ff48 8b4d b848 8d45 c0ba .......h.m.h.e.. 00006cd: 0800 0000 4889 ce48 89c7 e844 feff ff85 ....h..h...d.... 00006dd: c074 14bf c007 4000 e846 feff ffbf ffff .t....@..f...... 00006ed: ffff e88c feff ffbf cf07 4000 e832 feff ..........@..2.. 00006fd: ff48 8b5d e864 4833 1c25 2800 0000 7405 .h.].dh3.%(...t. 000070d: e82e feff ff48 83c4 585b 5d .....h..x[]
as quick sanity check, remember mentioned first few bytes of main disassembly of main boiler-plate, if @ them , assemble them machine get:
push %rbp 0x55 mov %rsp,%rbp 0x48 0x89 0xe5 push %rbx 0x53 sub $0x58,%rsp 0x48 0x83 0xec 0x58 mov %edi,-0x54(%rbp) 0x89 0x7d 0xac
given above sequences of bytes matches begging sequence of bytes step 5, safe assumption have found location of
main
in executable. left modify byte @ offset 0x6de 0x74 0x73.
n.b. ida have free version, number of restrictions on it, worth time grab , play it.
hope help, t
Comments
Post a Comment