On a rainy day, in a rare mood with nothing else to do, I set out to make a wallhack for that all time favourite online shooter, “Enemy Territory”.
My goals and design constraints were the following,
- embed in the main game.exe with affecting its size
- include some media files
- keep size to a minimum
The source is pretty much self explanatory. There are however a few nice tricks I used which bear some singling out:
1) Use of thunks
When you want to call a function, you need to know its address. Normally, this is done automatically in the final stage of making an executable object by the linker. A trick called a thunk is used to still be able to call functions if you don’t at runtime know their address.
A stub function is used to load the current address into a register,
thunky_thunk mov ebx, [esp] ret
and then the function you want to call is preceded by a thunk-call, like this,
thunk_EndFrame call thunky_thunk // ebx just got loaded with address pointing to this spot here! ret hook_EndFrame push ebp mov ebp, esp // and the normal function you want to call (hook_EndFrame) continues...
Finally, at the start of the program, you can call all the
2) Identify usable storage space
Using existing resources, and barring heap allocations, puts constraints on the memory accessible to the payload without interfering (too much) with the program. One easily accessible source is to identify fixed length static (.data) strings. These are often initialized as char arrays, and the space after the terminating zero is free for use.
3) hide literals
A modified shader is used to display the image. The string to reference this shader is easily recognized by anti-cheat software. So instead of writing “punkbuster”, i write it in the following way,
; sh_headtxt mov dword[sh_headtxt+0], 0x65646f6d mov dword[sh_headtxt+4], 0x702f736c mov dword[sh_headtxt+8], 0x6579616c mov dword[sh_headtxt+12], 0x682f7372 mov dword[sh_headtxt+16], 0x682f6475 mov dword[sh_headtxt+20], 0x2e646165 mov dword[sh_headtxt+24], 0x33646d
4) modify an in-game shader for chams
Often the game is filled with unused chams. Pick one, and change it as you see fit. In this case, I just needed to modify the last part (0.25..) with spaces so as not to change the string length,
; now the complete shader text is @ address eax, safe to use ; fixed offset for the replacement part ; change fixed color directive "rgbGen const ( 0.25 0.25 0.25 )" to "rgbGen entity" mov dword [eax+222], 0x69746e65 mov word [eax+226], 0x7974 push eax ; blank with spaces lea edi, [eax+228] mov eax, 32 mov ecx, 18 rep stosb pop eax add esp, 4 ret
5) logo compression/decompression
I created a 512×64 logo to display during the game. Normally, such a file is pretty big, compared to space in the .exe available to us. I used a compression scheme to only store non-black pixels and the single grayscale channel. Then I wrote the decompression function in C, and used gcc -c -Os option to generate the size-optimized code, and put this in the payload assembler file.
All in all, the image takes up a mere 4501 bytes.