Eternal's Bliss VB CrackMe 10

 

Tools: WKTVBDebugger

Target: Here

A fast tutorial with some tricks to learn how to patch P-Code when you don't have NOP instructions XDD.

Hi All! This is my first tute, to start with we're gonna make a fast crack of the target file to see how powerful the debugger is.

1.- Load the crackme with the Loader and execute, no code will be shown, don't worry that's normal because the crackme has no initialization code. Press the check button, nothing happens so the crackme is intelligent because it does not alert the user about about a bad combination.

2.- But we're more clever , press Ctrl+P, this hotkey activates the debugger (you will heard a beep), now press the "Check" button. The debugger popups.

3.- Now you can see this code

 

 

004043DC: 28 LitVarI2 0063F360h 0h , 0
004043E1: FC Lead1/FStVar
004043E5: 04 FLdRfVar 0063F35Ah
004043E8: 21 FLdPrThis 005104C0h
004043E9: 0F VCallAd Form1.Check1
004043EC: 19 FStAdFunc
004043EF: 08 FLdPr
004043F2: 0D VCallHresult
004043F7: 6B FLdI2
004043FA: E7 CI4UI1
004043FB: F5 LitI4: -> 1h 1
00404400: C7 EqI4
00404401: 1A FFree1Ad
00404404: 1C BranchF 00404410 »
00404407: 28 LitVarI2 1h , 1
0040440C: FC Lead1/FStVar
00404410: 04 FLdRfVar 0063F35Ah
00404413: 21 FLdPrThis 005104C0h
00404414: 0F VCallAd Form1.Check2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

As you can see the program is dealing with the Check boxes, as you can see in lines 4043E9 and 404414. Let's try first a fast crack (yes I'm lazy cracker).
Out beloved new brand debugger provides a cool function called BranchX Refs, this cool feature provides us with a list of all the branches done by the current procedure, the one specified at the top part of the disassembly screen Proc: 4043DCh-4048Eh, this belongs to the procedure start address and ending address. So we're gonna check the branches for this procedure.

4.- Click on Analize BranchX Refs.You will see a list containing the following:

00404404h : BranchF 00404410h
0040442Fh : BranchF 00404442h
00404461h : BranchF 00404474h
00404493h : BranchF 004044A6h
004044C5h : BranchF 004044D8h
004044F7h : BranchF 0040440Ah
00404529h : BranchF 0040443Ch
0040455Bh : BranchF 0040446Eh
0040458Dh : BranchF 004044A0h
004045BFh : BranchF 004044D2h
004045F1h : BranchF 00404404h
00404623h : BranchF 00404436h
00404655h : BranchF 00404468h
00404687h : BranchF 0040449Ah
004046B9h : BranchF 004044CCh
004046EBh : BranchF 00404401h
00404720h : BranchF 00404436h
00404755h : BranchF 0040446Bh
0040478Ah : BranchF 004044A0h
004047BFh : BranchF 004044D5h
004047F4h : BranchF 0040440Ah
00404829h : BranchF 0040443Fh
0040485Eh : BranchF 00404474h
00404893h : BranchF 004044A9h
004048B7h : BranchF 004043E3h

The first number belong to the address were the opcode gets executed, and the next part is the Branch itself and it's jump address, the jumps are sorted so we can see that we have a lot of branches here. Curiously the distante between this jumps are 35h or 32h bytes, so we could be pretty sure that the code executed between each jump is quite similar. Lets try to put a BPX on the last one, wait, why the last one?, Good question, the answer is easy, we're going to see it the last branch is the one that decides the whole thing, i mean the bad guy good guy check. To do this right click above the last branch (a context menu appears) select BreakPoint On/Off to set a bpx on this jump. Close the dialog box and press Go! (F5).

5- The bpx takes effect we're here now:

00404889: E7 CI4UI1
0040488A: F5 LitI4: -> 1h 1
0040488F: C7 EqI4
00404890: 1A FFree1Ad
00404893: 1C BranchF 004048A9 »
00404896: 04 FLdRfVar 0063F370h
00404899: FE Lead3/LitVarI4
004048A1: 94 AddVar
004048A5: FC Lead1/FStVar
004048A9: 04 FLdRfVar 0063F370h
004048AC: FE Lead3/LitVarI4
004048B4: 5D HardType
004048B5: 33 EqVarBool
004048B7: 1C BranchF 004048E3 (Jump ») <- We're HERE
004048BA: 27 LitVar_Missing 0063F2E8h
004048BD: 27 LitVar_Missing 0063F308h
004048C0: 27 LitVar_Missing 0063F328h
004048C3: F5 LitI4: -> 0h 0
004048C8: 3A LitVarStr 'You have solved it...'

 

 

 

 

 

 

 

Pretty cool as you can see, we're on line 4048B7, and the debugger says that the Branch is going to be taken. Check the next lines of code, the app is doing something with a nice message at 004048C8 you can see 'You have solved it...', does is look as a god guy/bad guy check? Clearly it is ;) ok so you've three options

A) Invert the jump, that's not very clever because if you get with the correct combination the Branch will be taken.

B) Delete the BranchF at 4048B7. To make the proggy continue the flow without jumping. This is not possible because P-Code does not have a NOP instruction.

C) The last option is the most complicated one but os the right one. Let me first explain how the BranchX instruction works. It takes de value from the top of the stack (ESP) and test if the dword there is TRUE (in VB TRUE = -1 = FFFFFFFh).

According to this:

BranchF will jump if the stack value is 0h
BranchT will jump if the stack values is FFFFFFFh=-1

The opcode for BranchF is 1Ch and for BranchT is 1Dh, but we don't need this now we need to change the stack value in a manner that BranchF always get -1. How we can do this?
Let's see what we have before the jump:

004048B5: 33 EqVarBool

This opcode test the equality of two boolean vars and pushes -1 or 0 to the stack according to the comparision result. This opcode belongs to the second set of opcodes (Lead0).

Well maybe we can find and instruction that pushes and inmediate value to the stack, but to do this we need to use only 2 bytes because that's the size of EqVarBool opcode. Checking the opcode list we can see and instruction with the same size that says:

F4h LitI2_Byte

For those of you that are not very used to P-Code mnemonics prefix Lit means "Literal" and is used to load and save literal values to the stack. The format of this opcode is like this:

F4 XXh

Where XXh is and inmediate value to push to the stack, and wich value we need ? You're right -1 of FFh if you prefer :) so we're gonna patch the EqVarBool. In fact this opcode pushes a DWORD not a BYTE Value so it's all we need for our porpouses.

6- Open the Memory Dumper and enter the address for the EqVarBool (4048B5). You'll see the opcodes in memory, the first ones are FBh 33h (EqVarBool) so let's patch it. Double click on the fist memory line (the one with the FBh 33h) now change this two bytes by F4h FFh (LitI2_Byte -1).

7- Remove the BPX by double clicking on the BranchF line, and press F5, now enter any check box combination and press Check. Surprise! You've cracked it :).