Practical Reverse Engineering Exercises – Ch1-Ex1 – Write-Up

Posted by

–

Intro

This is the first post of what should be a blog series following my progress with the “Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation”, Bruce Dang, Alexandre Gazet, Elias Bachaalany, Sebastien Josse, ISBN: 978-1-118-78731-1.

The book includes number of exercises and the authors encourage the people to blog their solutions. That is exactly what I intent to do.
The solutions source code and write-ups PDF versions could be found also at the github repository at https://github.com/malchugan/PRE-Exercises.

Chapter1-Exercise1 – Task

“This function uses a combination SCAS and STOS to do its work. First, explain what is the type of the [EBP+8] and [EBP+C] in line 1 and 8, respectively. Next, explain what this snippet does.

01: 8B 7D 08         mov   edi, [ebp+8]
02: 8B D7            mov   edx, edi
03: 33 C0            xor   eax, eax
04: 83 C9 FF         or    ecx, 0FFFFFFFFh
05: F2 AE            repne scasb
06: 83 C1 02         add   ecx, 2
07: F7 D9            neg   ecx
08: 8A 45 0C         mov   al, [ebp+0Ch]
09: 8B FA            mov   edi, edx
10: F3 AA            rep stosb
11: 8B C2            mov   eax, edx”

Excerpt from: “Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation”,
Bruce Dang, Alexandre Gazet, Elias Bachaalany, Sebastien Josse, ISBN: 978-1-118-78731-1

My Short answer

EBP+8 is of type pointer to a char (first element of null terminated string)
EBP+C is of type char (1 byte)
The snippet is a body of a function responsible for replacing every character from a given string with another predefined character.
Functionality

My Interpretation


Using some initial previous knowledge about how the function calls in assembly work I assumed that the snippet is most probably part of a function body. Those suspicions were fed by the use of EBP register, particularly [EBP+8] and [EBP+0Ch]. Usually those are pointers to the function arguments. The following is a standard representation of the stack layout after a function call.
StackLayout

Detailed Intel x86 function calls explanation could be found on http://unixwiz.net/techtips/win32-callconv-asm.html

Snippet walkthrough

Line of codeExplanation
01: 8B 7D 08 mov edi, [ebp+8]Load the first function argument to EDI (pointer to our string abcdefgh)
02: 8B D7 mov edx, ediStore the current EDI value (pointer to our string abcdefgh) into EDX for purpose clarified later
03: 33 C0 xor eax, eaxEAX =0
04: 83 C9 FF or ecx, 0FFFFFFFFhSet ECX to maximum representable value (-1 when viewed as signed value).
05: F2 AE repne scasbTraverse through every string character (the one pointed by EDI) till Null terminator is reached. That comes as a combination of SCASB instruction which compares EDI and AL values. REPNE re- peats SCASB until EDI and AL(0) match or until ECX becomes 0.

This operation increments EDI and decrements ECX automatically.

repne-scasb

06: 83 C1 02 add ecx, 2 Those 2 lines could be explained as follows:
Before executing the instruction at line 06 the initial string has been traversed including the Null terminator.
Assuming that the string is N characters long (In the case of abcdefgh N=8) then the ECX has been decreased N +1 times (be- cause of the Null terminator) and taking in account the fact that its initial value was -1 then at that point
ECX = -N -2
So what exactly is going on in line 06 and 07?
add ecx, 2 ;increase the ECX value with 2 i.e. ECX=-N
neg ecx ; ECX=-(-N)=N

That means that after executing line 06 and 07, ECX register contains the length of the initial string (in our case 8).

07: F7 D9 neg ecx
08: 8A 45 0C mov al, [ebp+0Ch]Load the second function argument into AL (Our character *). Since AL register is used we can safely assume that the size of the argu- ment is 1 byte.
09: 8B FA mov edi, edxLoad what is stored in EDX to EDI. Looking back at line02 we see that EDX stores pointer to the first function argument (our initial string abcdefgh)
10: F3 AA rep stosbSTOSB reads AL value (*) and stores it at the address pointed by EDI (first character of our abcdefgh string). REP will execute STOSB until ECX value becomes 0. After each execution EDI is increment- ed and ECX is decremented automatically. Before executing this instruction ECX=N which means that the operation will be repeat- ed N times (in our case 8 times)
res-stosb
11: 8B C2 mov eax, edx”EDX points to the first character of the modified string. Usually the result of a function is stored in EAX register. That line of code sup- ports the initial theory that the snipped is part of a function body.

Proof of concept

I decided to write an assembly program and run it through IDA Debugger to check if my interpretation is holding up which it did.
Note: This is a Linux assembly file using AT&T syntax. To assemble and link the code bellow execute the following form the command line:
$as -gstabs -o ex1_att.o ex1_att.s
$ld -o ex1_att ex1_att.o

As a result you should have ex1_att executable which you could examine with GDB, IDA or any other debugger of your choice.

Here is the listing of the program ex1_att.s:

.data
     myString:
        .asciz "abcdefgh"
.text
        .globl _start
        .type TestFunc, @function
TestFunc:
        # function prologue
        push %ebp              # preserve the old EBP value
        movl %esp, %ebp  
        # function body - same as the code from the book but in AT&T syntax
        movl 8(%ebp), %edi     # load the first function parameter in EDI - pointer to myStirng
        movl %edi, %edx        # store the initial EDI value in EDX
        xor %eax, %eax         # EAX = 0
        or $0xffffffff, %ecx   # set ECX to the maximum representable value
        repne scasb            # compare EDI content byte by byte with AL (NULL) or ECX becomes 0 :)
        add $2, %ecx           # at the end of repne scasb ECX has value (-strlen -2). With this sum ECX = -strlen
        neg %ecx               # ECX = strlen
        movb 12(%ebp), %al     # load second function argument
        movl %edx, %edi        # load the initial EDI value (firts argument) back to EDI
        rep stosb              # store strlen number of bytes in EDI al with the al value (character)
        movl %edx, %eax        # store EDX value in EAX
        # function epilogue 
        movl %ebp, %esp       # restore the old ESP value
        pop %ebp              # restore the old EBP value
        ret
_start:
       # push the function arguments into the stack
       push $0x2A             # ASCII '*'
       push $myString         # pointer to myString
       # call the function
       call TestFunc
       # exit gracefully (call software interrupt 1 - exit)
       movl $1, %eax
       movl $0, %ex
       int $0x80

One response

  1. Somik Avatar
    Somik

Leave a Reply

Your email address will not be published. Required fields are marked *

ePsiLoN's Information Security Blog
Privacy Overview

This website uses cookies for security purposes only. We do not track you or see your data.