downloadbrowsetomkol's BiT WalkeR ChAlLeNgE

Download bit_walker.zip, 49 kb (password: crackmes.de)
Browse contents of bit_walker.zip

Welcome to this small keygenme. Your task is to made my keygenme say it's registered by you. You can do whatever you want while reversing. Your final solution can't patch or bruteforce my code. Everything is fully reverseable. Should be interesting and unusual.

Crackme works only in windows xp.

Difficulty: 3 - Getting harder
Platform: Windows
Language: Assembler

Published: 19. Aug, 2013
Downloads: 244

Rating

Votes: 3
Crackme is good.

Rate this crackme:

Send a message to tomkol »

View profile of tomkol »

Solutions

Solution by tamaroth, published 03. sep, 2013; download (199 kb), password: crackmes.de or browse.

tamaroth has rated this crackme as awesome.

Submit your solution »

Discussion and comments

tamaroth
Moderator
16. Aug 2013
Hey, I think I have found out why your keygenme is not working under windows 7. It's all in your parsing of EAT of certain system API's. For instance:

API you want -> API you get
CloseHandle -> CloseHandle
CreateMutexA -> CreateMutexExA
CreateThread -> CreateThreadpoolCleanupGroup
FreeLibrary -> FreeResource
GetProcessHeap -> GetProcessIoCounters

As a result nothing's working and your code just crashes (thank you for SEH, at least no shitty windows).

Now, the reason for this is in ordinals. Again, an example (same order as functions above):

0054 -> 0054
009E -> 009D
00B9 -> 00B7
0167 -> 0164
024E -> 024A

It's because of this instruction, I believe:

004012CF . 43 INC EBX

Notice how the difference between your ordinal and the correct one increases by one with every API.
Below you will find the code that works both in w7 and xp (haven't tested with vista/8 but I reckon it should fare just fine).

typedef HANDLE (WINAPI *CrThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);

CrThread findCreateThread()
{
LPVOID lpFile = (LPVOID)GetModuleHandle("kernel32.dll");
IMAGE_DOS_HEADER *dosh = (IMAGE_DOS_HEADER *)lpFile;
IMAGE_NT_HEADERS *nth = (IMAGE_NT_HEADERS *)((PBYTE)lpFile + dosh->e_lfanew);
IMAGE_EXPORT_DIRECTORY *exp = (IMAGE_EXPORT_DIRECTORY *)((PBYTE)lpFile + nth->OptionalHeader.DataDirectory->VirtualAddress);

DWORD *pNames = (DWORD *)((PBYTE)lpFile + exp->AddressOfNames);
WORD *pOrds = (WORD *)((PBYTE)lpFile + exp->AddressOfNameOrdinals);
DWORD *pEAT = (DWORD *)((PBYTE)lpFile + exp->AddressOfFunctions);
BYTE *name;
WORD ordinal;
CrThread cr;

for (DWORD i = 0; i < exp->NumberOfNames; i++)
{
name = (PBYTE)lpFile + pNames[i];
if (strcmp((const char *)name, "GetProcessHeap") == 0)
{
ordinal = pOrds[i];
cr = (CrThread)((PBYTE)lpFile + pEAT[ordinal]);
break;
}
}
return cr;
}

Best regards,
tamaroth
tomkol
Author
17. Aug 2013
From my tests i've found out that win7 simply ignores entry point from PE header and starts in middle of the code. But theres always a VM. Maybe next time when i'll switch to win7 as main system.
tamaroth
Moderator
18. Aug 2013
When I tested on Win7 x64 it worked good until the import part. Maybe you had some old version of windows?

Anyhow, there's absolutely no reason why one would stick to xp still. It's ancient now. Follow new technologies and opportunities ;-)
tomkol
Author
19. Aug 2013
You're right. It was problem with my VM. Give me a day and i'll fix it. On older copy it starts but crashes. I'm working on making it run on win7.
andrewl.us
Moderator
19. Aug 2013
thanks tomkol and tamaroth for the win7 effort!
redoC
19. Aug 2013
timer always creates 5 new tooltip windows
tomkol
Author
20. Aug 2013
@tamaroth
i hope it now works correctly for you
@andrewl.us
thanks
@redoc
tooltips got sometimes lost, don't know why. thats why they recreated with timer. this shouldn't be a problem while reversing algo
tamaroth
Moderator
20. Aug 2013
Yep, it's working great now!
Time for some reversing ;-)
tomkol
Author
20. Aug 2013
Shouldn't be hard. It's only coded in different way. Good luck and I'm waiting for solution now.
redoC
20. Aug 2013
Checking code is somewhere in animation procedure?
redoC
20. Aug 2013
ehm ... WM_USER+1
tomkol
Author
21. Aug 2013
Your close redoC. It's a bit different than what you used to. And you can treat animation as a messagebox. It simply displays text and looks better than messagebox.
tamaroth
Moderator
21. Aug 2013
redoC - don't want to spoil everything (well ATM I'm working on the functions in the array) but you might want to check how to send a custom message to an application and try to figure out how to post name and serial there.
redoC
21. Aug 2013
WM_USER + wParam + lParam + Atom ....but that maze what follows ... i look at it sometime later.
tamaroth
Moderator
21. Aug 2013
It's really not that complicated once you figure out how the VM works, I'm still following what happens after the VM and should have the keygen by the end of the week, hopefully.
tomkol
Author
22. Aug 2013
VM is nothing complicated. It's really very simple. And what follows is also quite easy once you figure out what is going on.
tamaroth
Moderator
27. Aug 2013
One question: after all successful checks my name and serial shows up in a keygenme for a bit and then it's erased and 'Good Boy' message is nowhere to be seen. Is that on purpose or maybe I've missed something?

Anyhow, keygen is almost ready (just need to write some xgcd for unsigned int and it all be well)
tamaroth
Moderator
27. Aug 2013
It's hard to post correct values for you to check, as there's no easy way to input them as well as magic value changing now and then, however, here are some examples:

name: tomkol
magic: B910AB51-15171F0C-A8E1C64E
serial: 8F0627E8#EFA61684#93083B90

name: tamaroth
magic: 351FAA8D-D8E2C098-2FB4DF30
serial: 34C114D3#042E892F#03EEA86E

name: crackmes.de
magic: 737298DE-B5BF3C14-31B71E91
serial: F81E2B4F#FC1DCF71#14DEDF5C
tomkol
Author
28. Aug 2013
Thats the purpose. I hope you found a place where good boy message is shown. If not you missed something at the end of check procedure. Waiting for your solution.
tamaroth
Moderator
28. Aug 2013
Yeah, found it ... Silly me ;-) Writing a tut and finishing a kg (you know, non constant name, some sanity checks etc) as I write this.
tomkol
Author
28. Aug 2013
Can't wait to read it. And yes the serials you provided are correct. It's easy to test if you have source and can compile some test version that simply checks static data.
tamaroth
Moderator
30. Aug 2013
Solution submitted, hopefully it'll be accepted soon!
andrewl.us
Moderator
03. Sep 2013
despite finding that this "bosom of code" is cold and hard and uninviting, he bravely enters and exposes the bosom for all to see ... good job!
tomkol
Author
04. Sep 2013
Good work tamaroth. I see you love to complicate your life. Read pm from me and check what you missed. Especially check how easy it is to reverse mmx function.
tamaroth
Moderator
05. Sep 2013
Haha, I didn't even know about this! Well, at least I've learned something! :)
andrewl.us
Moderator
05. Sep 2013
share?
tomkol
Author
06. Sep 2013
It's all in tamaroth hands. If he wants he can post pass to archive and reveal all secrets.
tamaroth
Moderator
06. Sep 2013
When you look in my solution, you find that I have neg and add operation in the VM. This is the same as sub ... but for some reason it did not even occur to me when I was reversing. The other thing I did not know about was Gray code algorithm!

I won't post the pass to the archive though, maybe someone else wants to solve it still :)

You may leave your comment, thoughts and discuss this crackme with other reversers here.
Acting childish will not be tolerated.
HTML and such will be left as-is, so don't try.