Tuesday, December 30, 2014

Practical Reverse Engineering p.11 #1

Question number 1 on page 11 of Practical Reverse Engineering is as follows:

1. 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.

mov edi, [ebp+8]
mov edx, edi
xor eax, eax
or ecx, 0FFFFFFFFh
repne scasb
add ecx, 2
neg ecx
mov al, [ebp+0Ch]
mov edi, edx
rep stosb
mov eax, edx

The first part of the question asks to define the types at [EBP+8] and [EBP+C].

For [EBP+8], we see it is moved into the EDI register a few instructions before REPNE SCASB. That instruction is generally used in string operations, in which EDI is the "destination index" of the operation. It is safe to assume that [EBP+8] is a byte buffer; the char* type.

Looking at [EBP+C], we see that it is moved into the AL register. This is an obvious hint to us that the value is a single byte; the char type.

So just by deducing the types and seeing their context, we have a vague idea of what is going on. The first half of the code sets ECX to -1, EAX to the null byte, then repeats over the buffer until the null byte is found (decrementing ECX for each byte before the null byte). Two is then added to ECX, and the register is turned into a positive number.

In the end, the first part of the code is the length of the buffer before the null byte. It's an implementation of the strlen() function. The second part of the code uses REP STOSB, which copies the AL register to the EDI register ECX times. This is the memset() function.

Here is the function in C:

/* cdecl */ 
char *asm_func(char *buffer, char byte)
{
   memset(buffer, byte, strlen(buffer));
   return buffer;
}

1 comment :

  1. perfect articles but you should accept guest comment :)

    ReplyDelete