23.03.2013 Views

Quick introduction to reverse engineering for beginners

Quick introduction to reverse engineering for beginners

Quick introduction to reverse engineering for beginners

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

jge SHORT $LN1@main<br />

mov ecx, DWORD PTR _i$[ebp]<br />

mov edx, DWORD PTR _i$[ebp] ; that insruction is obviously redundant<br />

mov DWORD PTR _a$[ebp+ecx*4], edx ; ECX could be used as second operand here instead<br />

jmp SHORT $LN2@main<br />

$LN1@main:<br />

xor eax, eax<br />

mov esp, ebp<br />

pop ebp<br />

ret 0<br />

_main ENDP<br />

Run compiled program and its crashing. No wonder. Let’s see, where exactly it’s crashing.<br />

I’m not using debugger anymore, because I tired <strong>to</strong> run it each time, move mouse, etc, when I need just <strong>to</strong><br />

spot some register’s state at specific point. That’s why I wrote very minimalistic <strong>to</strong>ol <strong>for</strong> myself, tracer 5.0.1,<br />

which is enough <strong>for</strong> my tasks.<br />

I can also use it just <strong>to</strong> see, where debuggee is crashed. So let’s see:<br />

generic tracer 0.4 (WIN32), http://conus.info/gt<br />

New process: C:\PRJ\...\1.exe, PID=7988<br />

EXCEPTION_ACCESS_VIOLATION: 0x15 (),<br />

ExceptionIn<strong>for</strong>mation[0]=8<br />

EAX=0x00000000 EBX=0x7EFDE000 ECX=0x0000001D EDX=0x0000001D<br />

ESI=0x00000000 EDI=0x00000000 EBP=0x00000014 ESP=0x0018FF48<br />

EIP=0x00000015<br />

FLAGS=PF ZF IF RF<br />

PID=7988|Process exit, return code -1073740791<br />

So, please keep an eye on registers.<br />

Exception occured at address 0x15. It’s not legal address <strong>for</strong> code — at least <strong>for</strong> win32 code! We trapped<br />

there somehow against our will. It’s also interesting fact that EBP register contain 0x14, ECX and EDX — 0x1D.<br />

Let’s study stack layout more.<br />

After control flow was passed in<strong>to</strong> main(), EBP register value was saved in<strong>to</strong> stack. Then, 84 bytes was<br />

allocated <strong>for</strong> array and i variable. That’s (20+1)*sizeof(int). ESP pointing now <strong>to</strong> _i variable in local<br />

stack and after execution of next PUSH something, something will be appeared next <strong>to</strong> _i.<br />

That’s stack layout while control is inside _main:<br />

ESP 4 bytes <strong>for</strong> i<br />

ESP+4 80 bytes <strong>for</strong> a[20] array<br />

ESP+84 saved EBP value<br />

ESP+88 returning address<br />

Instruction a[19]=something writes last int in array bounds (in bounds yet!)<br />

Instruction a[20]=something writes something <strong>to</strong> the place where EBP value is saved.<br />

Please take a look at registers state at the crash moment. In our case, number 20 was written <strong>to</strong> 20th<br />

element. By the function ending, function epilogue res<strong>to</strong>re EBP value. (20 in decimal system is 0x14 in<br />

hexadecimal). Then, RET instruction was executed, which is equivalent <strong>to</strong> POP EIP instruction.<br />

RET instruction taking returning adddress from stack (that’s address in some CRT 40 -function, which was<br />

called _main), and 21 was s<strong>to</strong>red there (0x15 in hexadecimal). The CPU trapped at the address 0x15, but<br />

there are no executable code, so exception was raised.<br />

Welcome! It’s called buffer overflow 41 .<br />

40 C Run-Time<br />

41 http://en.wikipedia.org/wiki/Stack_buffer_overflow<br />

50

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!