Reverse Engineering for Beginners

(avery) #1

CHAPTER 3. HELLO, WORLD! CHAPTER 3. HELLO, WORLD!


.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
.section .note.GNU-stack,"",@progbits

The listing contains many macros (beginning with dot). These are not interesting for us at the moment.


For now, for the sake of simplification, we can ignore them (except the.stringmacro which encodes a null-terminated char-
acter sequence just like a C-string). Then we’ll see this^7 :


Listing 3.6: GCC 4.7.3

.LC0:
.string "hello, world\n"
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
ret


Some of the major differences between Intel and AT&T syntax are:



  • Source and destination operands are written in opposite order.


In Intel-syntax: <instruction> <destination operand> <source operand>.

In AT&T syntax: <instruction> <source operand> <destination operand>.

Here is an easy way to memorise the difference: when you deal with Intel-syntax, you can imagine that there is an
equality sign (=) between operands and when you deal with AT&T-syntax imagine there is a right arrow (→)^8.


  • AT&T: Before register names, a percent sign must be written (%) and before numbers a dollar sign ($). Parentheses
    are used instead of brackets.

  • AT&T: A suffix is added to instructions to define the operand size:

    • q — quad (64 bits)

    • l — long (32 bits)

    • w — word (16 bits)

    • b — byte (8 bits)




Let’s go back to the compiled result: it is identical to what we saw inIDA. With one subtle difference:0FFFFFFF0his
presented as$-16. It is the same thing: 16 in the decimal system is0x10in hexadecimaal.-0x10is equal to0xFFFFFFF0
(for a 32-bit data type).


One more thing: the return value is to be set to 0 by using the usualMOV, notXOR.MOVjust loads a value to a register. Its
name is a misnomer (data is not moved but rather copied). In other architectures, this instruction is named “LOAD” or “STORE”
or something similar.


3.2 x86-64


3.2.1 MSVC—x86-64


Let’s also try 64-bit MSVC:


Listing 3.7: MSVC 2012 x64

$SG2989 DB 'hello, world', 0AH, 00H


main PROC
sub rsp, 40
lea rcx, OFFSET FLAT:$SG2989
call printf


(^7) This GCC option can be used to eliminate “unnecessary” macros:-fno-asynchronous-unwind-tables
(^8) By the way, in some C standard functions (e.g., memcpy(), strcpy()) the arguments are listed in the same way as in Intel-syntax: first the pointer to the
destination memory block, and then the pointer to the source memory block.

Free download pdf