Reverse Engineering for Beginners

(avery) #1

CHAPTER 47. STRINGS TRIMMING CHAPTER 47. STRINGS TRIMMING


; RAX = current string length
or rax, -1
label:
inc rax
cmp BYTE PTR [rcx+rax], 0
jne SHORT label
; RAX = string length


Try to write shorter if you want to initialize the counter at 0! OK, let’ try:


Listing 47.3: Our version ofstrlen()

; RCX = pointer to the input string
; RAX = current string length
xor rax, rax
label:
cmp byte ptr [rcx+rax], 0
jz exit
inc rax
jmp label
exit:
; RAX = string length


We failed. We need to use additional JMP instruction!


So what the MSVC 2013 compiler did is to move theINCinstruction to the place before the actual character loading. If the
first character is 0, that’s OK,RAXis 0 at this moment, so the resulting string length is 0.


The rest in this function seems easy to understand.


47.2 x64: Non-optimizing GCC 4.9.1.


str_trim:
push rbp
mov rbp, rsp
sub rsp, 32
mov QWORD PTR [rbp-24], rdi
; for() first part begins here
mov rax, QWORD PTR [rbp-24]
mov rdi, rax
call strlen
mov QWORD PTR [rbp-8], rax ; str_len
; for() first part ends here
jmp .L2
; for() body begins here
.L5:
cmp BYTE PTR [rbp-9], 13 ; c=='\r'?
je .L3
cmp BYTE PTR [rbp-9], 10 ; c=='\n'?
jne .L4
.L3:
mov rax, QWORD PTR [rbp-8] ; str_len
lea rdx, [rax-1] ; EDX=str_len-1
mov rax, QWORD PTR [rbp-24] ; s
add rax, rdx ; RAX=s+str_len-1
mov BYTE PTR [rax], 0 ; s[str_len-1]=0
; for() body ends here
; for() third part begins here
sub QWORD PTR [rbp-8], 1 ; str_len--
; for() third part ends here
.L2:
; for() second part begins here
cmp QWORD PTR [rbp-8], 0 ; str_len==0?
je .L4 ; exit then
; check second clause, and load "c"
mov rax, QWORD PTR [rbp-8] ; RAX=str_len
lea rdx, [rax-1] ; RDX=str_len-1
mov rax, QWORD PTR [rbp-24] ; RAX=s
add rax, rdx ; RAX=s+str_len-1

Free download pdf