Posted in Cracking,Debugging,Programming by Mr. Novocain on September 18, 2007 at 20:01

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

Get Learning PHP, MySQL, and JavaScript: A Step-By-Step Guide to Creating Dynamic Websites (Animal Guide) now!

_20050908_canapa_mariuana_droga_droghe.jpg
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

Incoming search terms for the article:

 

1 Comment for this post

 
September 25th, 2007 at 07:40

Very nice Mr. Novocain ;]
Easy to understand tutorial!

Keep up the good work

 

Leave a Reply