Wednesday, January 7, 2015

Practical Reverse Engineering p. 35 #9

Question number 9 on page 35 of Practical Reverse Engineering is as follows:

Sample L. Explain what function sub_1000CEA0 does and then decompile it back to C.

Here is the disassembly of the function:

sub_1000CEA0:
    push    ebp
    mov     ebp, esp
    push    edi
    mov     edi, [ebp+8]
    xor     eax, eax
    or      ecx, 0FFFFFFFFh
    repne scasb
    add     ecx, 1
    neg     ecx
    sub     edi, 1
    mov     al, [ebp+0Ch]
    std
    repne scasb
    add     edi, 1
    cmp     [edi], al
    jz      short loc_1000CEC7
    xor     eax, eax
    jmp     short loc_1000CEC9 

loc_1000CEC7:                          
    mov     eax, edi

loc_1000CEC9:                       
    cld
    pop     edi
    leave
    retn

This function calculates the string length, then works backwards to return a pointer to the last instance of a character in the string.

char *sub_1000CEA0(char *str, char ch)
{
    /* mov edi, [ebp+8] */
    /* xor eax, eax
    /* or ecx, 0FFFFFFFFh */
    /* repne scasb */
    /* add ecx, 1 */
    /* neg ecx */
    size_t len = 1;
    while (*str)
    {
        ++str;
        ++len;
    }

    /* sub edi, 1 */
    /* mov al, [ebp+0Ch] */
    /* std */
    /* repne scasb */
    /* add edi, 1 */ 
    while (len)
    {
        /* cmp [edi], al */
        if (*str == ch)
            return str;
        --len;
        --str;
    }

    return 0;
}

This is an implementation of the strrchr() function, which is defined as follows:

char *strrchr(char *str, int character);

No comments :

Post a Comment