Книга: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
Назад: Recognizing Loops
Дальше: Analyzing switch Statements

, we discussed how the stack and the call instruction are used for function calls. Function calls can appear differently in assembly code, and calling conventions govern the way the function call occurs. These conventions include the order in which parameters are placed on the stack or in registers, and whether the caller or the function called (the callee) is responsible for cleaning up the stack when the function is complete.

The calling convention used depends on the compiler, among other factors. There are often subtle differences in how compilers implement these conventions, so it can be difficult to interface code that is compiled by different compilers. However, you need to follow certain conventions when using the Windows API, and these are uniformly implemented for compatibility (as discussed in ).

We will use the pseudocode in to describe each of the calling conventions.

when we introduced the stack and function calls. In cdecl, parameters are pushed onto the stack from right to left, the caller cleans up the stack when the function is complete, and the return value is stored in EAX. shows an example of what the disassembly would look like if the code in were compiled to use cdecl.

would not be needed if the stdcall convention were used, since the function called would be responsible for cleaning up the stack.

The test function in would be compiled differently under stdcall, because it must be concerned with cleaning up the stack. Its epilogue would need to take care of the cleanup.

stdcall is the standard calling convention for the Windows API. Any code calling these API functions will not need to clean up the stack, since that’s the responsibility of the DLLs that implement the code for the API function.

shows a C code example of a function call. The function adder adds two arguments and returns the result. The main function calls adder and prints the result using printf.

. As you can see, this code adds arg_0 to arg_4 and stores the result in EAX. (As discussed in , EAX stores the return value.)

00401730        push    ebp 00401731        mov     ebp, esp 00401733        mov     eax, [ebp+arg_0] 00401736        add     eax, [ebp+arg_4] 00401739        pop     ebp 0040173A        retn

displays different calling conventions used by two different compilers: Microsoft Visual Studio and GNU Compiler Collection (GCC). On the left, the parameters for adder and printf are pushed onto the stack before the call. On the right, the parameters are moved onto the stack before the call. You should be prepared for both types of calling conventions, because as an analyst, you won’t have control over the compiler. For example, one instruction on the left does not correspond to any instruction on the right. This instruction restores the stack pointer, which is not necessary on the right because the stack pointer is never altered.

sss
sss

© RuTLib.com 2015-2018