Reverse Engineering for Beginners

(avery) #1

CHAPTER 7. SCANF() CHAPTER 7. SCANF()


AJNEconditional jump follows theCMPinstruction.JNEstands forJump if Not Equal.


So, if the value in theEAXregister is not equal to 1, theCPUwill pass the execution to the address mentioned in theJNE
operand, in our case$LN2@main. Passing the control to this address results in theCPUexecutingprintf()with the
argumentWhat you entered? Huh?. But if everything is fine, the conditional jump is not be be taken, and another
printf()call is to be executed, with two arguments:'You entered %d...'and the value ofx.


Since in this case the secondprintf()has not to be executed, there is aJMPpreceding it (unconditional jump). It passes
the control to the point after the secondprintf()and just before theXOR EAX, EAXinstruction, which implements
return 0.


So, it could be said that comparing a value with another isusuallyimplemented byCMP/Jccinstruction pair, whereccis
condition code.CMPcompares two values and sets processor flags^6 .Jccchecks those flags and decides to either pass the
control to the specified address or not.


This could sound paradoxical, but theCMPinstruction is in factSUB(subtract). All arithmetic instructions set processor flags,
not justCMP. If we compare 1 and 1, 1 − 1 is 0 so theZFflag would be set (meaning that the last result was 0). In no
other circumstancesZFcan be set, except when the operands are equal.JNEchecks only theZFflag and jumps only if it
is not set.JNEis in fact a synonym forJNZ(Jump if Not Zero). Assembler translates bothJNEandJNZinstructions into the
same opcode. So, theCMPinstruction can be replaced with aSUBinstruction and almost everything will be fine, with the
difference thatSUBalters the value of the first operand.CMPisSUB without saving the result, but affecting flags.


7.3.2 MSVC: x86: IDA.


It is time to runIDAand try to do something in it. By the way, for beginners it is good idea to use/MDoption in MSVC,
which means that all these standard functions are not be linked with the executable file, but are to be imported from the
MSVCR*.DLLfile instead. Thus it will be easier to see which standard function are used and where.


While analysing code inIDA, it is very helpful to leave notes for oneself (and others). In instance, analysing this example,
we see thatJNZis to be triggered in case of an error. So it is possible to move the cursor to the label, press “n” and rename
it to “error”. Create another label—into “exit”. Here is my result:


.text:00401000 _main proc near
.text:00401000
.text:00401000 var_4 = dword ptr -4
.text:00401000 argc = dword ptr 8
.text:00401000 argv = dword ptr 0Ch
.text:00401000 envp = dword ptr 10h
.text:00401000
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 push ecx
.text:00401004 push offset Format ; "Enter X:\n"
.text:00401009 call ds:printf
.text:0040100F add esp, 4
.text:00401012 lea eax, [ebp+var_4]
.text:00401015 push eax
.text:00401016 push offset aD ; "%d"
.text:0040101B call ds:scanf
.text:00401021 add esp, 8
.text:00401024 cmp eax, 1
.text:00401027 jnz short error
.text:00401029 mov ecx, [ebp+var_4]
.text:0040102C push ecx
.text:0040102D push offset aYou ; "You entered %d...\n"
.text:00401032 call ds:printf
.text:00401038 add esp, 8
.text:0040103B jmp short exit
.text:0040103D
.text:0040103D error: ; CODE XREF: _main+27
.text:0040103D push offset aWhat ; "What you entered? Huh?\n"
.text:00401042 call ds:printf
.text:00401048 add esp, 4
.text:0040104B
.text:0040104B exit: ; CODE XREF: _main+3B
.text:0040104B xor eax, eax
.text:0040104D mov esp, ebp
.text:0040104F pop ebp


(^6) x86 flags, see also:wikipedia.

Free download pdf