WARNING: Wiki content is an archive, no promise about quality!
Please choose a tutorial page:
- Fundamentals -- Information about C
- Tools
- Registers
- Simple Instructions
- Example 1 -- SC CDKey Initial Verification
- Example 2 -- SC CDKey Shuffle
- Example 2b -- SC CDKey Final Decode
- The Stack
- Functions
- Example 3 -- Storm.dll SStrChr
- Assembly Summary
- Machine Code
- Example 4 -- Smashing the Stack
- Cracking a Game
- Example 5 -- Cracking a game
- Example 6 -- Writing a keygen
- .dll Injection and Patching
- Memory Searching
- Example 7 -- Writing a cheat for Starcraft (1.05)
- Example 7 Step 1 -- Displaying Messages
- Example 7 Step 1b -- Above, w/ func ptrs
- Example 7 Final
- Example 8 -- Getting IX86.dll files
- 16-bit Assembly
- Example 9 -- Keygen for a 16-bit game
- Example 10 -- Writing a loader
The previous section about the stack has shown how to call a standard function with parameters. This section will go over some other "calling conventions" besides the standard.
A "calling convention" is the way in which a function is called. The standard convention, __cdecl, is what has been used up until now. Some other common ones are __stdcall, __fastcall, and __thiscall.
A less common declaration used when writing hacks is __declspec(naked).
__cdecl
__cdecl is the default calling convention on most C compilers. The properties are as follows:
- The caller places all the parameters on the stack
- The caller removes the parameters from the stack (often by adding the total size added to the stack pointer)
Throughout previous sections, __cdecl has been the calling convention used. However, here is an example to help illustrate it:
push param3
push param2
push param1 ; Parameters are pushed onto the stack
call func ; The function is called
add esp, 0Ch ; Parameters are removed from the stack
...
func:
...
ret
__stdcall
__stdcall is another common calling convention. The properties of __stdcall are:
- The caller places parameters on the stack
- The called function removes the parameters from the stack, often by using the return instruction with a parameter equal to the number of parameters, "ret xx"
Here's an example of a __stdcall function (note that if no parameters are passed, __stdcall is indistinguishable from __cdecl.
push param3
push param2
push param1 ; Parameters are pushed onto the stack
call func ; The function is called
...
func:
...
ret 0c; ; The function cleans up the stack
The most useful part about __stdcall is that it tells a reverse engineer how many parameters are passed to any given function. In cases where no examples of the function being called may be found (possibly because it's an exported .dll function), it is easier to check the return than to enumerate local variables (of course, IDA looks after that automatically if that's an option).
__fastcall
__fastcall is the final common calling convention seen. All implementations of __fastcall pass parameters in registers, although Microsoft and Borland, for example, use different registers. Here are the properties of Microsoft's __fastcall implementation:
- First two parameters are passed in ecx and edx, respectively
- Third parameter and on are passed on the stack, as usual
- Functions clean up their own stack, if necessary
Recognizing a __fastcall function is easy: look for ecx and edx being used without being initialized in a function.
A __fastcall with no parameters is identical to __cdecl and __stdcall with no parameters, and a __fastcall with a single parameter looks like __thiscall.
Here are some __fastcall examples:
mov ecx, 7
call func
...
func:
...
ret
mov ecx, 7
mov edx, 8
call func
...
func:
...
ret
mov ecx, 7
mov edx, 8
push param4
push param3
call func
...
func:
...
ret 8 ; Note that the function cleans up the stack.
__thiscall
Seen only in object-oriented programming, __thiscall is very similar to __stdcall, except that a pointer to the class whose member is being called is passed in ecx.
- ecx is assigned a pointer to the class whose member is being called
- The parameters are placed on the stack, the same as ''__stdcall'
- The function cleans itself up, the same as __stdcall
Here is an example of __thiscall:
push param3
push param2
push param1
mov ecx, this
call func
...
func:
...
ret 12
__declspec(naked)
__declspec(naked), a Visual Studio-specific convention, can't really be identified in assembly, since it's identical to __cdecl once it reaches assembly. However, the special property of this convention is that the compiler will generate no code in a function. This allows the program, in a __asm{} block, to write everything from preserving registers to allocating local variables and returning. This is useful when patching a jump in the middle of code, since it prevents the function from changing registers without the programmer's knowledge.
This C function:
void __declspec(naked) test()
{
}
Would translate to this in assembly:
Since no code is generated.
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.