Jump to content
Nytro

Keygenning ESET’s CONfidence 2012 Crackme

Recommended Posts

[h=2]Keygenning ESET’s CONfidence 2012 Crackme[/h]

[h=4]Intro[/h] Hi again. First, sorry for delaying this post so much, but i am currently so busy, that barly i am finding time for something more than neccessities. Anyways, i dont forget what i promiss, so here comes the post about keygenning the CONfidence 2012 Crackme…

In contrary to my previous post (focused on obtaining the key) now i will focus on analysis of the obfuscated algorithm used in generating MMX instructions. I assume, that you read my previous post, so if not – please refer to it.

If you don’t care about tutorial, just want to see the keygen – it’s here:

* requires: Microsoft Visual C++ 2008 Redistributable Package

[h=4]Tools used[/h]

  • ImmunityDbg (for it’s very useful & handy feature, which i will use a lot in deobfuscating – from context menu : Analysis -> During next analysis treat selection as -> Commands)

[h=4]Analysis

[/h] As we know, the MMX instructions are stored in a piece of memory starting at 403090. Generation of MMX instructions comes directly before the call to it, so it’s easy to spot. Before, the piece of memory from 403090 to 4044d0 is cleared (with RtlZeroMemory).

pic13.png?w=643&h=269

Pay attention at arguments, which are passed to the generating function (40118A). Content of EBX is pretty obvious – it is a pointer to the memory to be filled (304090). But in ESI there is 403000 and it means…

pic21.png?w=255&h=211

The piece of memory, where the hashes are stored. From 403000 to 40300f there is a copy of hash#1 (md5 of the given username). It is important information – this hash will be used in generating MMX instructions.

So, lets follow inside the generating function. Before the user-specific instructions will be genetated, first the MMX prolog is decrypted.

pic31.png?w=1000

Six dwords, stored at memory addresses from 417a8 are XOR-ed with 45534554. And the result is:

pic61.png?w=1000

Looks familiar? Yeah, it was easy, but now the real fun begins… icon_smile.gif?m=1129645325g

pic7.png?w=1000

Some initial values are set. ECX = 100h = 256… If you remember, there are 256 blocks of MMX instructions, so it may have something to deal with it…

Then it comes to processing of the hash#1. This part is slightly obfuscated, so i will explain it.

pic8.png?w=812&h=462

004010B6   $ 56             PUSH ESI
004010B7 . 52 PUSH EDX
004010B8 . 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+C] ; Unpacked.00403000
004010BC . 8B16 MOV EDX,DWORD PTR DS:[ESI] ; EDX = DS:[403000]
004010BE . 81E2 87000000 AND EDX,87
004010C4 . 0F9BC2 SETPO DL
[...]
004010EA . 33C0 XOR EAX,EAX
004010EC . D126 SHL DWORD PTR DS:[ESI],1
004010EE . D156 04 RCL DWORD PTR DS:[ESI+4],1
[...]
004010F6 > D156 08 RCL DWORD PTR DS:[ESI+8],1
004010F9 . D156 0C RCL DWORD PTR DS:[ESI+C],1
[...]
0040111A > 13C0 ADC EAX,EAX
0040111C . 33C2 XOR EAX,EDX
0040111E . 0906 OR DWORD PTR DS:[ESI],EAX
00401120 . 5A POP EDX
00401121 . 5E POP ESI
00401122 . C2 0400 RETN 4

As we see, the piece of memory containing hash#1 is modified after each execution of those instructions. Value of EAX is modified – it changes according to the content of memory at 403000 – that’s how the value of hash influences the process of generating MMX instructions. But obviously, we need to know details… The question is, how exectly every MMX instruction is generated and what is the connection between it and the hash/processed hash?

The previously described function is called twice. The result of first call is stored in EDX. (I will denote this function as get_cmd_base).

00401125   $ 52             PUSH EDX
00401126 . 56 PUSH ESI
00401127 . 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+C] ; ESI = 403000
0040112B > 51 PUSH ECX ; bgn#1
[...]
0040114C . 59 POP ECX
0040114D . 56 PUSH ESI
0040114E . E8 63FFFFFF CALL Unpacked.004010B6 ; modify memory at 403000
00401153 . 8BD0 MOV EDX,EAX ; EAX = result of function at 4010B6
00401155 . 56 PUSH ESI
00401156 . E8 5BFFFFFF CALL Unpacked.004010B6 ; modify (again) memory at 403000
0040115B . 8D0450 LEA EAX,DWORD PTR DS:[EAX+EDX*2]
[...]
00401181 . 85C0 TEST EAX,EAX
00401183 >^74 A6 JE SHORT Unpacked.0040112B ; ;goto #bgn1
00401185 . 5E POP ESI
00401186 . 5A POP EDX
00401187 . C2 0400 RETN 4

Then, the first result is multiplied by 2 and added to second result in EAX.

DWORD get_cmd_base(BYTE *hashBuffer)
{
DWORD eax, edx;
do {
edx = process_hash(hashBuffer);
eax = process_hash(hashBuffer);
eax = eax + edx * 2;
} while (eax == 0);
return eax;
}

What are the possible valueas of EAX?

EAX = EAX + EDX * 2

where right side EAX and EDX are results from 403000 modifying function. So, EAX, EDX can take a value either 0 or 1. Means left side EAX (res) is:

| EAX | EDX | res |
-------------------
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 2 |
| 1 | 1 | 3 |
-------------------

If EAX == 0, then everything is repeated once again – (after some obfuscation) we go back to the same piece of code. If EAX != 0, then instruction is generated on its base.

Below is how the first instruction comes. The first instruction is MOVQ [MM6/MM7], [MM0/MM1]

0040120A   > 56             PUSH ESI
0040120B . E8 15FFFFFF CALL Unpacked.00401125
00401210 . D1E8 SHR EAX,1
00401212 . F7D8 NEG EAX
00401214 . 83E0 01 AND EAX,1
[...]
0040122B > 8BEB MOV EBP,EBX
[...]
0040124B > 81E5 00070000 AND EBP,700
00401251 . C1ED 05 SHR EBP,5
00401254 . 81CD C6000000 OR EBP,0C6
0040125A . 33E8 XOR EBP,EAX
[...]
0040147D $ 8BC5 MOV EAX,EBP
0040147F . C1E0 18 SHL EAX,18
[...]
004014A5 . 0D CC0F7F00 OR EAX,7F0FCC ; MOVQ MMx, MMy
004014AA . C1C8 08 ROR EAX,8
004014AD . 8907 MOV DWORD PTR DS:[EDI],EAX
004014AF . 83C7 03 ADD EDI,3
[...]
004014D0 > 8BC3 MOV EAX,EBX
004014D2 . C1E8 1F SHR EAX,1F
004014D5 . 33D8 XOR EBX,EAX
004014D7 . C3 RETN

b1.png?w=1000The first out of 6 instructions is generated…

And then, generating next instruction: MOVQ [MM7/MM6],[MM2/MM3/MM4/MM5].

The choise of first register depends on the perevious. if previuosly we had MOVQ MM6,[...] now there must be MOV MM7,[...]. The second choise is independent.

00401284   . 81CB 00000080  OR EBX,80000000
[...]
004012A8 > 8BC3 MOV EAX,EBX
004012AA . 83E0 07 AND EAX,7
004012AD . C1E0 03 SHL EAX,3
004012B0 . 81E5 C7000000 AND EBP,0C7
004012B6 . 0BE8 OR EBP,EAX
004012B8 . 83F5 01 XOR EBP,1
[...]
0040147D $ 8BC5 MOV EAX,EBP
0040147F . C1E0 18 SHL EAX,18
[...]
004014A5 . 0D CC0F7F00 OR EAX,7F0FCC ; MOVQ MMx, MMy
004014AA . C1C8 08 ROR EAX,8
004014AD . 8907 MOV DWORD PTR DS:[EDI],EAX
004014AF . 83C7 03 ADD EDI,3
[...]
004014D0 > 8BC3 MOV EAX,EBX
004014D2 . C1E8 1F SHR EAX,1F
004014D5 . 33D8 XOR EBX,EAX
004014D7 . C3 RETN

b2.png?w=1000The second out of 6 instructions…

Third instruction:

As we know, 3-rd, 4-ty and 5-th instructions are various. Here we see from where this variety comes. The call to an instruction generating procedure is done to various places in memory, depeending on EAX.

004012DE   > 56             PUSH ESI                                 ;  Unpacked.00403000
004012DF . E8 41FEFFFF CALL Unpacked.00401125
[...]
00401307 . 8BEB MOV EBP,EBX
00401309 . 83E5 07 AND EBP,7
0040130C . 81CD F0000000 OR EBP,0F0
00401312 . FF1485 6D14400>CALL DWORD PTR DS:[EAX*4+40146D]
00401319 . E8 07000000 CALL Unpacked.00401325 ; //after #3

EAX = {1, 2, 3}

[EAX*4+40146D] = {401471, 401475, 401479}

dests.png?w=1000

EAX = 1 -> call 4015A6

EAX = 2 -> call 4016C3

EAX = 3 -> call 4014D8

dests31.png?w=1000

As we see, in each of these 3 cases, the function at 401125 is called. It leads, after some obfuscation, again to 40114D (described above, which result is “res”). Then, the “res” is used in further operations. After deobfuscation it is:

If EAX = 1

004015A6   $ 56             PUSH ESI                                 ;  Unpacked.00403000
004015A7 . E8 79FBFFFF CALL Unpacked.00401125
004015AC . 8AE0 MOV AH,AL
004015AE . 80E4 01 AND AH,1
004015B1 . C0E4 04 SHL AH,4
004015B4 . 80CC EF OR AH,0EF
[...]
004015DA . 8AD0 MOV DL,AL
004015DC . 80E2 02 AND DL,2
004015DF . D0E2 SHL DL,1
004015E1 . 80CA FB OR DL,0FB
[...]
00401602 > 22D4 AND DL,AH
[...]
00401618 > 8AF0 MOV DH,AL
0040161A . 80E6 01 AND DH,1
0040161D . F6DE NEG DH
[...]
00401642 . 56 PUSH ESI
00401643 . E8 DDFAFFFF CALL Unpacked.00401125
00401648 . 22F0 AND DH,AL
0040164A . 32D6 XOR DL,DH
[...]
0040166A > 8BC5 MOV EAX,EBP
0040166C . 0FB6D2 MOVZX EDX,DL
0040166F . 0FB6C0 MOVZX EAX,AL
00401672 . C1E0 10 SHL EAX,10
00401675 . C1E2 08 SHL EDX,8
[...]
00401691 > 33C2 XOR EAX,EDX
00401693 . 35 0F0000CC XOR EAX,CC00000F
00401698 . 8907 MOV DWORD PTR DS:[EDI],EAX
0040169A . 83C7 03 ADD EDI,3
[...]
004016BB > 8BC3 MOV EAX,EBX
004016BD . C1E8 1F SHR EAX,1F
004016C0 . 33D8 XOR EBX,EAX
004016C2 . C3 RETN

If (EAX = 2):

004016C3   $ 51             PUSH ECX
004016C4 . 56 PUSH ESI
004016C5 . E8 5BFAFFFF CALL Unpacked.00401125
004016CA . 8AC8 MOV CL,AL
[...]
004016D1 > 80E1 01 AND CL,1
004016D4 . B4 01 MOV AH,1
004016D6 . D2E4 SHL AH,CL
004016D8 . F6D4 NOT AH
004016DA . C0C4 04 ROL AH,4
[...]
00401700 24 02 AND AL,2
00401702 F6D0 NOT AL
00401704 D0C0 ROL AL,1
00401706 22E0 AND AH,AL
[...]
0040172B 8BCD MOV ECX,EBP
0040172D 25 00FF0000 AND EAX,0FF00
00401732 0FB6C9 MOVZX ECX,CL
00401735 C1E1 10 SHL ECX,10
00401738 0BC1 OR EAX,ECX
0040173A 35 0F0000CC XOR EAX,CC00000F
[...]
0040175D > 8907 MOV DWORD PTR DS:[EDI],EAX
0040175F . 83C7 03 ADD EDI,3
00401762 . 8BC3 MOV EAX,EBX
00401764 . C1E8 1F SHR EAX,1F
00401767 . 33D8 XOR EBX,EAX
00401769 . 59 POP ECX
0040176A . C3 RETN

If (EAX =3)

004014D8   $ 56             PUSH ESI
004014D9 . E8 47FCFFFF CALL Unpacked.00401125
[...]
004014DE . D0E8 SHR AL,1
004014E0 . 8AD0 MOV DL,AL
004014E2 . C0E2 05 SHL DL,5
[...]
00401503 > 56 PUSH ESI ; Unpacked.00403000
00401504 . E8 1CFCFFFF CALL Unpacked.00401125
00401509 . 8AF0 MOV DH,AL
0040150B . 8BC5 MOV EAX,EBP
0040150D . C0E8 03 SHR AL,3
[...]
00401533 > 24 07 AND AL,7
00401535 . 0C F0 OR AL,0F0
00401537 . 32D0 XOR DL,AL
[...]
00401557 > 56 PUSH ESI ; Unpacked.00403000
00401558 . E8 C8FBFFFF CALL Unpacked.00401125
0040155D . 0C 70 OR AL,70
[...]
00401573 > C1E0 08 SHL EAX,8
00401576 . 0C 0F OR AL,0F
00401578 . C1E2 10 SHL EDX,10
0040157B . 33C2 XOR EAX,EDX
[...]
004015A0 . 8907 MOV DWORD PTR DS:[EDI],EAX
004015A2 . 83C7 04 ADD EDI,4
004015A5 . C3 RETN

As we see, when the EAX = 3 some 4-byte instruction is created (like PSLLD MM6,2). Other two cases creates 3-byte instructions (like PSUBW MM6,MM3).

Fourth instruction:

0040132D   > 56               PUSH ESI
0040132E . E8 F2FDFFFF CALL Unpacked.00401125
[...]
00401351 > 8BEB MOV EBP,EBX
00401353 . 83E5 07 AND EBP,7
00401356 . 81CD F8000000 OR EBP,0F8
0040135C . FF1485 6D14400> CALL DWORD PTR DS:[EAX*4+40146D]

- then if follows analogicaly like 3-rd.

Fifth

[...]
00401377 > 81E3 FFFFFF7F AND EBX,7FFFFFFF
0040137D . 56 PUSH ESI ; Unpacked.00403000
0040137E . E8 A2FDFFFF CALL Unpacked.00401125
00401383 . D1E8 SHR EAX,1
[...]
004013A8 . F7D8 NEG EAX
004013AA . 83E0 09 AND EAX,9
004013AD . BD F7000000 MOV EBP,0F7
004013B2 . 33E8 XOR EBP,EAX
[...]
004015A6 $ 56 PUSH ESI ; Unpacked.00403000
004015A7 . E8 79FBFFFF CALL Unpacked.00401125
004015AC . 8AE0 MOV AH,AL
004015AE . 80E4 01 AND AH,1
004015B1 . C0E4 04 SHL AH,4
004015B4 . 80CC EF OR AH,0EF
[...]
004015DA . 8AD0 MOV DL,AL
004015DC . 80E2 02 AND DL,2
004015DF . D0E2 SHL DL,1
004015E1 . 80CA FB OR DL,0FB
[...]
00401602 > 22D4 AND DL,AH
[...]
00401618 > 8AF0 MOV DH,AL
0040161A . 80E6 01 AND DH,1
0040161D . F6DE NEG DH
[...]
00401642 . 56 PUSH ESI ; Unpacked.00403000
00401643 . E8 DDFAFFFF CALL Unpacked.00401125
00401648 . 22F0 AND DH,AL
0040164A . 32D6 XOR DL,DH
[...]
0040166A > 8BC5 MOV EAX,EBP
0040166C . 0FB6D2 MOVZX EDX,DL
0040166F . 0FB6C0 MOVZX EAX,AL
00401672 . C1E0 10 SHL EAX,10
00401675 . C1E2 08 SHL EDX,8
[...]
00401691 > 33C2 XOR EAX,EDX
00401693 . 35 0F0000CC XOR EAX,CC00000F
00401698 . 8907 MOV DWORD PTR DS:[EDI],EAX
0040169A . 83C7 03 ADD EDI,3
[...]
004016BB > 8BC3 MOV EAX,EBX
004016BD . C1E8 1F SHR EAX,1F
004016C0 . 33D8 XOR EBX,EAX
004016C2 . C3 RETN

Sixth:

004013EB   > 8BC3           MOV EAX,EBX
004013ED . C1E8 05 SHR EAX,5
004013F0 . 83F0 08 XOR EAX,8
004013F3 . 83E0 38 AND EAX,38
004013F6 . C1ED 03 SHR EBP,3
[...]
0040141C 83E5 07 AND EBP,7
0040141F 0BE8 OR EBP,EAX
00401421 81CD C0000000 OR EBP,0C0
[...]
004015A6 $ 56 PUSH ESI ; Unpacked.00403000
004015A7 . E8 79FBFFFF CALL Unpacked.00401125
004015AC . 8AE0 MOV AH,AL
004015AE . 80E4 01 AND AH,1
004015B1 . C0E4 04 SHL AH,4
004015B4 . 80CC EF OR AH,0EF
[...]
004015DA . 8AD0 MOV DL,AL
004015DC . 80E2 02 AND DL,2
004015DF . D0E2 SHL DL,1
004015E1 . 80CA FB OR DL,0FB
[...]
00401602 > 22D4 AND DL,AH
[...]
00401618 > 8AF0 MOV DH,AL
0040161A . 80E6 01 AND DH,1
0040161D . F6DE NEG DH
[...]
00401642 . 56 PUSH ESI ; Unpacked.00403000
00401643 . E8 DDFAFFFF CALL Unpacked.00401125
00401648 . 22F0 AND DH,AL
0040164A . 32D6 XOR DL,DH
[...]
0040166A > 8BC5 MOV EAX,EBP
0040166C . 0FB6D2 MOVZX EDX,DL
0040166F . 0FB6C0 MOVZX EAX,AL
00401672 . C1E0 10 SHL EAX,10
00401675 . C1E2 08 SHL EDX,8
[...]
00401691 > 33C2 XOR EAX,EDX
00401693 . 35 0F0000CC XOR EAX,CC00000F
00401698 . 8907 MOV DWORD PTR DS:[EDI],EAX
0040169A . 83C7 03 ADD EDI,3
[...]
004016BB > 8BC3 MOV EAX,EBX
004016BD . C1E8 1F SHR EAX,1F
004016C0 . 33D8 XOR EBX,EAX
004016C2 . C3 RETN

After that…

00401454   . C0C3 04        ROL BL,4
00401457 . 81F3 00010000 XOR EBX,100 ; ECX = 100h
0040145D . 49 DEC ECX ; ECX = 0FFh
0040145E .^0F85 88FDFFFF JNZ Unpacked.004011EC

and navigation goes back to generation of first instruction. As we see, ECX is decremented - exactly 256 blocks of 6 instructions are generated.

The full MMX Generating code for any given login You can find in attached example: Generator.cpp

[h=4]Keygenning[/h] The MMX Generator was a missing piece of puzzle. Other pieces are described in my previous post. Now we must put them together and the keygen is ready!

But as we know, the generated MMX instructions must be reversed. There are two things to be done about it:

  1. Reversing the last (6-th instruction) in every block
  2. Reversing the order of blocks (first block must be the last and so on)

Ok, let’s do it one by one.

[h=5]Reversing the last (6-th instruction) in every block:[/h] The set of possible instructions occuring in the 6-th line is: {PADDB, PADDW, PADDQ, PSUBB,PSUBW, PSUBQ, XOR}. Three type of addition (add BYTE, add DWORD, add QWORD), analogical substractions and XOR. Reversing table will look like this:

PADDB -> PSUBB PADDW -> PSUBW PADDD -> PSUBD PSUBB -> PADDB PSUBW -> PADDW PSUBD -> PADDD XOR -> XOR But we can operate on opcodes only. The representation of following instruction is:

PADDB = 0xfc PADDW = 0xfd PADDQ = 0xfe PSUBB = 0xf8 PSUBW = 0xf9 PSUBQ = 0xfa XOR = 0xef So, when the 6-th instruction is generated, we must substitute one opcode by another – representing reversed operation. Take a look at the code generating 6-th instruction in Generator.cpp:

rev1.png?w=1000

thus, instruction in EDX should be reversed before the XORing wih EAX (line 332). It can be done easyli:

if (EDX == 0xef) -> don’t do anything (it’s XOR)

else if (EDX < 0xfc) -> EDX += 4

else -> EDX -= 4

I hope everything is clear icon_smile.gif?m=1129645325g

[h=5]Reversing the order of blocks[/h] We must fill the buffer of blocks from the back to front. Here the only problem is, we don’t know the exact length in bytes of a single block, because instructions{3, 4} can be either of 3 or of 4 bytes. That’s why we have to reserve memory for the maximal case and fill the gaps with NOPs (0×90).

Then, adding RET at the end of the buffer, and we can call the generated code as a function, from within assembler code. Mind that the keygen must be compiled with DEP (Data Execution Prevention) switched off (eventualy you can set this page of memory executable by VirtualProtect).

It’s time to look at the Keygen.cpp!

//---------------------------------------------------------------------------
// the code published under Creative Commons (CC-BY-NC) license
// author: hasherezade (http://hshrzd.wordpress.com)
// the keygenerator for ESET CrackMe, CONfidence2012 (http://2012.confidence.org.pl)
// remarks: compile with DEP disabled
//---------------------------------------------------------------------------
#include <windows.h>
#include <iostream>
using namespace std;
BYTE hsh[16];
BYTE hashes[4][16];
BYTE output[16];
/*
maxBlock =
6 instructions total:
instruction[1,2,5,6] -> 3 bytes
instruction[3,4] -> 3 or 4 bytes -> max 4 bytes
+ 1 byte -> NOP at the end of 6-th instruction (padding)
*/
const DWORD maxBlock = 4 * 3 + 2 * 4 + 1;
const DWORD bufMax = maxBlock * 256;
BYTE buffer[bufMax];
DWORD bufIndex = bufMax - maxBlock;
DWORD blockStart = bufMax;
//----------------------------------------
typedef struct {
ULONG i[2];
ULONG buf[4];
unsigned char in[64];
unsigned char digest[16];
} MD5_CTX;
typedef void (WINAPI *t_MD5Init)(
MD5_CTX *context
);
t_MD5Init MD5Init;
typedef void (WINAPI *t_MD5Update)(
MD5_CTX *context,
const unsigned char *input,
unsigned int inlen
);
t_MD5Update MD5Update;
typedef void (WINAPI *t_MD5Final)
(
MD5_CTX *context
);
t_MD5Final MD5Final;
char revrs(int a)
{
a += 0x41;
if (a >= 'A' && a <= 'Z')
return a;
a += 6;
return a;
}
void decode_chunks()
{
int V = 0x29, i = 0;
WORD* out = (WORD*)output;
while (i < 8) {
WORD chunk = out[i];
i++;
//printf("\n%4X",chunk);
int x,y,z;
int a;
z = chunk % V;
a = chunk / V;
y = a % V;
x = a / V;
printf("%c%c%c", revrs(x), revrs(y), revrs(z));
}
}
//----------------------------------------
void call_generated()
{
memset(output,0,16);
void* generated = (void*)buffer;
_asm {
EMMS
MOVQ MM0,QWORD PTR hashes[0]
MOVQ MM1,QWORD PTR hashes[8]
MOVQ MM2,QWORD PTR hashes[0x10]
MOVQ MM3,QWORD PTR hashes[0x18]
MOVQ MM4,QWORD PTR hashes[0x20]
MOVQ MM5,QWORD PTR hashes[0x28]
call generated
MOVQ QWORD PTR output[0], MM0
MOVQ QWORD PTR output[8], MM1
};
}
void genetrateReversed()
{
memset(buffer, 0x90, bufMax);
__asm {
push ebp
mov EBX, 0x42
mov ECX, 0x100
jmp start
process_hsh:
PUSH ESI
PUSH EDX
MOV EDX, dword ptr hsh[0]
AND EDX,0x87
SETPO DL
XOR EAX,EAX
SHL dword ptr hsh[0],1
RCL DWORD PTR hsh[4],1
RCL DWORD PTR hsh[8],1
RCL DWORD PTR hsh[0xC],1
ADC EAX,EAX
XOR EAX,EDX
OR DWORD PTR hsh[0],EAX
POP EDX
POP ESI
RET
get_cmd_base:
PUSH EDX
PUSH ESI
bgn1:
call process_hsh
MOV EDX,EAX
call process_hsh
LEA EAX,DWORD PTR DS:[EAX+EDX*2]
TEST EAX,EAX
JE bgn1
POP ESI
POP EDX
RET
Instruction1:
call get_cmd_base
SHR EAX,1
NEG EAX
AND EAX,1
MOV EBP,EBX
AND EBP,0x700
SHR EBP,5
OR EBP,0xC6
XOR EBP,EAX
MOV EAX,EBP
SHL EAX,0x18
OR EAX,0x7F0FCC
ROR EAX,8
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
RET
Instruction2:
OR EBX,0x80000000
MOV EAX,EBX
AND EAX,7
SHL EAX,3
AND EBP,0xC7
OR EBP,EAX
XOR EBP,1
MOV EAX,EBP
SHL EAX,0x18
OR EAX,0x7F0FCC
ROR EAX,8
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
RET
case1:
call get_cmd_base
MOV AH,AL
AND AH,1
SHL AH,4
OR AH,0xEF
MOV DL,AL
AND DL,2
SHL DL,1
OR DL,0xFB
AND DL,AH
MOV DH,AL
AND DH,1
NEG DH
call get_cmd_base
AND DH,AL
XOR DL,DH
MOV EAX,EBP
MOVZX EDX,DL
MOVZX EAX,AL
SHL EAX,0x10
SHL EDX,8
XOR EAX,EDX
XOR EAX,0xCC00000F
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
RET
case2:
PUSH ECX
call get_cmd_base
MOV CL,AL
AND CL,1
MOV AH,1
SHL AH,CL
NOT AH
ROL AH,4
AND AL,2
NOT AL
ROL AL,1
AND AH,AL
MOV ECX,EBP
AND EAX,0xFF00
MOVZX ECX,CL
SHL ECX,0x10
OR EAX,ECX
XOR EAX,0xCC00000F
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
POP ECX
RET
case3:
call get_cmd_base
SHR AL,1
MOV DL,AL
SHL DL,5
call get_cmd_base
MOV DH,AL
MOV EAX,EBP
SHR AL,3
AND AL,7
OR AL,0xF0
XOR DL,AL
call get_cmd_base
OR AL,0x70
SHL EAX,8
OR AL,0x0F
SHL EDX,0x10
XOR EAX,EDX
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,4
RET
Instruction3:
call get_cmd_base
MOV EBP,EBX
AND EBP,7
OR EBP,0x0F0
the_switch:
cmp eax, 1
jne c2
jmp case1
c2:
cmp eax, 2
jne c3
jmp case2
c3:
cmp eax, 3
jne c4
jmp case3
c4:
RET
Instruction4:
call get_cmd_base
MOV EBP,EBX
AND EBP,7
OR EBP,0x0F8
jmp the_switch
RET
Instruction5:
AND EBX,0x7FFFFFFF
call get_cmd_base
SHR EAX,1
NEG EAX
AND EAX,9
MOV EBP,0xF7
XOR EBP,EAX
call get_cmd_base
MOV AH,AL
AND AH,1
SHL AH,4
OR AH,0xEF
MOV DL,AL
AND DL,2
SHL DL,1
OR DL,0xFB
AND DL,AH
MOV DH,AL
AND DH,1
NEG DH
call get_cmd_base
AND DH,AL
XOR DL,DH
MOV EAX,EBP
MOVZX EDX,DL
MOVZX EAX,AL
SHL EAX,0x10
SHL EDX,8
XOR EAX,EDX
XOR EAX,0xCC00000F
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
RET
Instruction6:
MOV EAX,EBX
SHR EAX,5
XOR EAX,8
AND EAX,0x38
SHR EBP,3
AND EBP,7
OR EBP,EAX
OR EBP,0xC0
call get_cmd_base
MOV AH,AL
AND AH,1
SHL AH,4
OR AH,0xEF
MOV DL,AL
AND DL,2
SHL DL,1
OR DL,0xFB
AND DL,AH
MOV DH,AL
AND DH,1
NEG DH
call get_cmd_base
AND DH,AL
XOR DL,DH
MOV EAX,EBP
MOVZX EDX,DL
MOVZX EAX,AL
SHL EAX,0x10
call reverseInstruction6
SHL EDX,8
XOR EAX,EDX
XOR EAX,0x9000000F ;// i want NOP at the end of the last instruction (instead of INT 3: XOR EAX,0xCC00000F)
MOV EDI, bufIndex
MOV DWORD PTR buffer[EDI], EAX
ADD bufIndex,3
MOV EAX,EBX
SHR EAX,0x1F
XOR EBX,EAX
RET
reverseInstruction6:
;/*
; 0xfc -> 0xf8 (PADDB -> PSUBB)
; 0xfd -> 0xf9 (PADDW -> PSUBW)
; 0xfe -> 0xfa (PADDD -> PSUBD)
;
; 0xf8 -> 0xfc (PSUBB -> PADDB)
; 0xf9 -> 0xfd (PSUBW -> PADDW)
; 0xfa -> 0xfe (PSUBD -> PADDD)
;
; 0xef -> 0xef (reversed XOR is XOR)
;*/
cmp EDX, 0xef
je revEnd
cmp EDX, 0xfc
jb r1
SUB EDX,4
jmp revEnd
r1:
ADD EDX,4
revEnd:
RET
start:
push ebx
mov ebx,blockStart
sub ebx, maxBlock
mov blockStart, ebx
mov bufIndex, ebx
pop ebx
call Instruction1
call Instruction2
call Instruction3
call Instruction4
call Instruction5
call Instruction6
ROL BL,4
XOR EBX,0x100
DEC ECX
JNZ start
pop ebp
};
BYTE ret = 0xc3;
buffer[bufMax-1] = ret;
}
int main(){
//load
int i;
HMODULE hCryptdll = LoadLibraryA("Cryptdll.dll");
if (hCryptdll==NULL) return (-1);
MD5Init = (t_MD5Init)GetProcAddress(hCryptdll, "MD5Init");
MD5Update = (t_MD5Update)GetProcAddress(hCryptdll, "MD5Update");
MD5Final = (t_MD5Final)GetProcAddress(hCryptdll, "MD5Final");
//Get input
const int MAX = 33;
char input[MAX];
printf("Name:\n");
scanf("%[ A-Za-z]s", input); //including space
int len = strlen(input);
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,(const unsigned char *)input, len);
MD5Final(&md5);
memcpy(hsh, md5.digest, 16);
//other hashes
memcpy(hashes[0], md5.digest, 16);
char backup[16];
memcpy(backup, md5.digest, 16);
int x;
for (x = 1; x < 3; x++) {
MD5Init(&md5);
MD5Update(&md5,(const unsigned char *)backup, 16);
MD5Final(&md5);
memcpy(hashes[x], md5.digest, 16);
memcpy(backup, md5.digest, 16);
}
//---
genetrateReversed();
call_generated();
printf("\nRegistration key:\n");
decode_chunks();
printf("\n\n---\n");
system("pause");
return 0;
}

Sursa: Keygenning ESET’s CONfidence 2012 Crackme | hasherezade's 1001 nights

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...