Difference between revisions of "Example 3"

From SkullSecurity
Jump to navigation Jump to search
Line 2: Line 2:
[[Category: Assembly Examples]]
[[Category: Assembly Examples]]


<pre>                 push    ebp
This example is the implementation of strchr() found in Storm.dll, called SStrChr() (Storm_571).
 
Here is the prototype for this function:
char *__stdcall SStrChr(const char *str, int c);
 
And the summary of Linux's manpage for what strchr() does:
<pre>
    The strchr() function locates the first occurrence of c (converted to a
    char) in the string pointed to by s.  The terminating null character is
    considered part of the string; therefore if c is `\0', the functions
    locate the terminating `\0'.
</pre>
 
Below is the code, copied/pasted directly from IDA. The only thing different from IDA is that the addresses have been removed and the jump locations named. It would be a good exercise to use this opportunity to learn IDA a bit. Open "storm.dll" (any Blizzard game should have it) in IDA, go to the function list, and search for Storm_571.
<pre>
                push    ebp
                 mov    ebp, esp
                 mov    ebp, esp
                 mov    eax, [ebp+arg_0]
                 mov    eax, [ebp+arg_0]
Line 39: Line 54:
</pre>
</pre>


== Annotated Code ==
Please, try this yourself first!
Here, comments have been added explaining each line a little bit. These comments are added in an attempt to understand what the code's doing.
<pre>
    push    ebp                ; Preserve ebp.
    mov    ebp, esp          ; Set up the frame pointer.
    mov    eax, [ebp+arg_0]  ; Move the first argument (that IDA has helpfully named) into eax. Recall that the first .
                                ; argument is a pointer to the string.
    test    eax, eax          ; Check if the string is 0.
    jnz    short loc_1        ; Jump over the next section if eax is non-zero (presumably, a valid string).
    push    57h                ; dwErrCode = ERR_INVALID_PARAMETER.
    call    ds:SetLastError    ; This library function allows a program to set/retrieve the last error message.
    xor    eax, eax          ; Clear eax (for a return 0).
    pop    ebp                ; Restore ebp.
    retn    8                  ; Return, removing both parameters from the stack.
loc_1:
    mov    cl, [eax]          ; Recall that cl is a 1-byte value at the bottom of ecx. cl gets the character at [eax]
    test    cl, cl            ; Check if the character is '\0' (which indicates the end of the string).
    jz      short loc_3        ; If it's zero, then the character hasn't been found. Note that this differs from the
                                ; actual strchr() command, since it won't detect the terminator '\0' if c is '\0'.
    mov    dl, [ebp+arg_4]    ; Move the second parameter (names arg_4 by IDA, since it's 4-bytes into the parameter list
                                ; list) into dl, which is the right-most byte of edx. .
    jmp    short loc_2        ; Jump down to the next line (the compiler likely did something weird here, optimized
                                ; something out, perhaps).
; ---------------------------------------------------------------------------
loc_2:
    cmp    cl, dl            ; Compare cl (the current character) to dl (the character being searched for).
    jz      short loc_4        ; If they're equal, jump down, returning eax (the remaining sub-string).
    mov    cl, [eax+1]        ; Move the next character into cl.
    inc    eax                ; Point ecx at the next character.
    test    cl, cl            ; Check if the string terminator has been found.
    jnz    short loc_2        ; Go to the top of this loop as long as the end of the string hasn't been reached.
loc_3:
    xor    eax, eax          ; Returns 0, indicating that the character was not found
loc_4:
    pop    ebp                ; Restore ebp's previous value
    retn    8                  ; Return, removing 8 bytes (2 32-bit values) from the stack (the two parameters)
</pre>
== C Code ==




== Cleaned up C Code ==
== Reduced C Code ==
== Finished Code ==
== Questions ==
== Questions ==
== Questions ==
Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.
Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.

Revision as of 21:27, 13 March 2007

Assembly Language Tutorial
Please choose a tutorial page:

This example is the implementation of strchr() found in Storm.dll, called SStrChr() (Storm_571).

Here is the prototype for this function:

char *__stdcall SStrChr(const char *str, int c);

And the summary of Linux's manpage for what strchr() does:

     The strchr() function locates the first occurrence of c (converted to a
     char) in the string pointed to by s.  The terminating null character is
     considered part of the string; therefore if c is `\0', the functions
     locate the terminating `\0'.

Below is the code, copied/pasted directly from IDA. The only thing different from IDA is that the addresses have been removed and the jump locations named. It would be a good exercise to use this opportunity to learn IDA a bit. Open "storm.dll" (any Blizzard game should have it) in IDA, go to the function list, and search for Storm_571.

                 push    ebp
                 mov     ebp, esp
                 mov     eax, [ebp+arg_0]
                 test    eax, eax
                 jnz     short loc_1

                 push    57h             ; dwErrCode
                 call    ds:SetLastError
                 xor     eax, eax
                 pop     ebp
                 retn    8
 ; ---------------------------------------------------------------------------

 loc_1:
                 mov     cl, [eax]
                 test    cl, cl
                 jz      short loc_3
                 mov     dl, [ebp+arg_4]
                 jmp     short loc_2
 ; ---------------------------------------------------------------------------

 loc_2:
                 cmp     cl, dl
                 jz      short loc_4
                 mov     cl, [eax+1]
                 inc     eax
                 test    cl, cl
                 jnz     short loc_2

 loc_3:
                 xor     eax, eax

 loc_4:
                 pop     ebp
                 retn    8


Annotated Code

Please, try this yourself first!

Here, comments have been added explaining each line a little bit. These comments are added in an attempt to understand what the code's doing.

     push    ebp                ; Preserve ebp.
     mov     ebp, esp           ; Set up the frame pointer.
     mov     eax, [ebp+arg_0]   ; Move the first argument (that IDA has helpfully named) into eax. Recall that the first .
                                ; argument is a pointer to the string. 
     test    eax, eax           ; Check if the string is 0. 
     jnz     short loc_1        ; Jump over the next section if eax is non-zero (presumably, a valid string).

     push    57h                ; dwErrCode = ERR_INVALID_PARAMETER.
     call    ds:SetLastError    ; This library function allows a program to set/retrieve the last error message. 
     xor     eax, eax           ; Clear eax (for a return 0).
     pop     ebp                ; Restore ebp.
     retn    8                  ; Return, removing both parameters from the stack.

 loc_1:
     mov     cl, [eax]          ; Recall that cl is a 1-byte value at the bottom of ecx. cl gets the character at [eax]
     test    cl, cl             ; Check if the character is '\0' (which indicates the end of the string).
     jz      short loc_3        ; If it's zero, then the character hasn't been found. Note that this differs from the
                                ; actual strchr() command, since it won't detect the terminator '\0' if c is '\0'. 
     mov     dl, [ebp+arg_4]    ; Move the second parameter (names arg_4 by IDA, since it's 4-bytes into the parameter list
                                ; list) into dl, which is the right-most byte of edx. .
     jmp     short loc_2        ; Jump down to the next line (the compiler likely did something weird here, optimized 
                                ; something out, perhaps).
 ; ---------------------------------------------------------------------------

 loc_2:
     cmp     cl, dl             ; Compare cl (the current character) to dl (the character being searched for).
     jz      short loc_4        ; If they're equal, jump down, returning eax (the remaining sub-string).
     mov     cl, [eax+1]        ; Move the next character into cl.
     inc     eax                ; Point ecx at the next character.
     test    cl, cl             ; Check if the string terminator has been found.
     jnz     short loc_2        ; Go to the top of this loop as long as the end of the string hasn't been reached. 

 loc_3:
     xor     eax, eax           ; Returns 0, indicating that the character was not found

 loc_4:
     pop     ebp                ; Restore ebp's previous value
     retn    8                  ; Return, removing 8 bytes (2 32-bit values) from the stack (the two parameters)


C Code

Cleaned up C Code

Reduced C Code

Finished Code

Questions

Questions

Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.