Reverse Engineering for Beginners

(avery) #1

CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS


str w1, [sp] ; store 9th argument in the stack
mov w1, 1
mov w2, 2
mov w3, 3
mov w4, 4
mov w5, 5
mov w6, 6
mov w7, 7
bl printf
sub sp, x29, #16
; restore FP and LR
ldp x29, x30, [sp,16]
add sp, sp, 32
ret


The first 8 arguments are passed in X- or W-registers: [ARM13c]. A string pointer requires a 64-bit register, so it’s passed in
X0. All other values have aint32-bit type, so they are stored in the 32-bit part of the registers (W-). The 9th argument (8)
is passed via the stack. Indeed: it’s not possible to pass large number of arguments through registers, because the number
of registers is limited.


Optimizing GCC (Linaro) 4.9 generates the same code.


6.3 MIPS


6.3.1 3 arguments.


Optimizing GCC 4.4.5


The main difference with the “Hello, world!” example is that in this caseprintf()is called instead ofputs()and 3 more
arguments are passed through the registers $5...$7 (or $A0...$A2).


That is why these registers are prefixed with A-, which implies they are used for function arguments passing.


Listing 6.12: Optimizing GCC 4.4.5 (assembly output)

$LC0:
.ascii "a=%d; b=%d; c=%d\000"
main:
; function prologue:
lui $28,%hi(gnu_local_gp)
addiu $sp,$sp,-32
addiu $28,$28,%lo(
gnu_local_gp)
sw $31,28($sp)
; load address of printf():
lw $25,%call16(printf)($28)
; load address of the text string and set 1st argument of printf():
lui $4,%hi($LC0)
addiu $4,$4,%lo($LC0)
; set 2nd argument of printf():
li $5,1 # 0x1
; set 3rd argument of printf():
li $6,2 # 0x2
; call printf():
jalr $25
; set 4th argument of printf() (branch delay slot):
li $7,3 # 0x3


; function epilogue:
lw $31,28($sp)
; set return value to 0:
move $2,$0
; return
j $31
addiu $sp,$sp,32 ; branch delay slot


Listing 6.13: Optimizing GCC 4.4.5 (IDA)

.text:00000000 main:

Free download pdf