C++ Anti-Cracking “hide” your WinAPI-calls

September 18, 2007 by Asbra — Leave a comment

This is a re-post of a post from 2007 taken from my old blog ilsken.net

If you’re a software-programmer and/or reverse-engineer you should know that using Windows API-calls is a easy way to write code, and also in many cases a good point for reverse-engineers to trace to/from while removing potential protections ..

Let’s take a basic example, let’s use a standard WinAPI-call..

#include 

int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	MessageBox(0,”This is a nag-box to tell you to buy the software!”,”Info”,0);
	return 0;
}

Say we want to remove this messagebox, in a debugger such as OllyDBG this is simple..

hapic1.png

So we just NOP out the call or jump over it.. so it’s very easy for a new cracker.

Let’s try something different.. I will do this with a bit inline-ASM but it’s possible by making a typedef too if you’d rather do it in C++ only.

#include 

char *title = "Info";
char *text = "This is a nag-box to tell you to buy the software!";

int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	DWORD msgboxa = (DWORD)GetProcAddress(LoadLibrary("User32.dll"),"MessageBoxA");

	__asm
	{
		push NULL;
		push title;
		push text;
		push NULL;
		call msgboxa;
	}
	return 0;
}

What I do is get the address of the function MessageBoxA using GetProcAddress, and then in inline-ASM push the arguments and call the address..

In OllyDBG it will look like this:
hapic2.png

A bit more difficult to see.. the strings used for the messagebox are not visible in “All referenced text-strings” and in “Intermodular Calls” the call to MessageBoxA is not shown.. more stealthy?! 🙂

Now you might wonder what happens, I will explain it line-by-line..

00401004  |. 68 34514000    PUSH WinSteal.00405134                   ; /ProcNameOrOrdinal = "MessageBoxA"
00401009  |. 68 28514000    PUSH WinSteal.00405128                   ; |/FileName = "User32.dll"
0040100E  |. FF15 04504000  CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; |\LoadLibraryA
00401014  |. 50             PUSH EAX                                 ; |hModule
00401015  |. FF15 00504000  CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
0040101B  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX

This is the same thing as
DWORD msgboxa = (DWORD)GetProcAddress(LoadLibrary(”User32.dll”),”MessageBoxA”);
And is not difficult to see..

Now right after that comes

0040101E  |. 6A 00          PUSH 0
00401020  |. FF35 30704000  PUSH DWORD PTR DS:[407030]               ;  WinSteal.00405120
00401026  |. FF35 34704000  PUSH DWORD PTR DS:[407034]               ;  WinSteal.004050EC
0040102C  |. 6A 00          PUSH 0
0040102E  |. FF55 FC        CALL DWORD PTR SS:[EBP-4]

Because we eariler saw (on 0040101B) that the return from the call to GetProcAddress (EAX) is saved in (EBP-4) we see now that it’s called.. and since we previously saw that the function it got was MessageBoxA, so we know that this part (0040102E) calls MessageBoxA..
The arguments (WinSteal.00405120 and WinSteal.004050EC) are stored in the data so we can just look what those are ;P

Now it was easy to see that this place calls MessageBoxA since it’s so close to the GetProcAddress-call where it gets the address of MessageBoxA and stores it.. now imagine this was in a big application and there was a big bunch of code between the declaring (GetProcAddress) and the function-call.. it would be more difficult for the basic crackers! 🙂

I have seen some active applications using this technique, however, they have all done the same mistake, as in my example, declaring and calling next to eachother so it’s easy to see still!

Anyway.. hope this taught someone something <3 ~Mr. Novocain

Asbra

Posts Facebook

Blogging out of many years of experience with gamehacking, programming, reverse-engineering and general tomfoolery.

No Comments

Be the first to start the conversation.

Leave a Reply