http://www.execpc.com/~sbd - Webpage.
dllshow.zip - (132k).
Well this program could well be a useful tool of the trade, hence this tutorial. Lets get started and locate our registration option from Help/Register, you'll note 3 dialog boxes, (I'm using CrackZ, Zencrack and 0123456789 as my dummy values), so lets >bpx GetDlgItemTextA and allow the required 3 returns, you should be looking at this code.
:0040BAF3 LEA EAX,[ESP+10] <-- Registration Number entered.
:0040BAF7 PUSH EAX <-- Stack it.
:0040BAF8 CALL 00412FB0 <-- Check length and return it as ? EAX.
:0040BAFD ADD ESP,04 <-- Stack tidy.
:0040BB00 MOV EBP,EAX <-- Move Registration Number into EBP.
:0040BB02 PUSH 0041EA44 <-- "Gregory Braun".
:0040BB07 PUSH ESI <-- Entered user name.
:0040BB08 CALL [KERNEL32!lstrcmp] <-- Compare strings.
:0040BB0E TEST EAX,EAX <-- Check compare result.
:0040BB10 JNZ 0040BB36 <-- Jump_name_wasn't_Gregory_Braun.
:0040BB36 PUSH EBX <-- Push organisation.
:0040BB37 PUSH ESI <-- Push name.
:0040BB38 CALL 00411CF0 <-- Calculate good code.
:0040BB3D ADD ESP,08 <-- Stack tidy.
:0040BB40 CMP EAX,EBP <-- Compare good_code/code_entered.
:0040BB42 JZ 0040BB62 <-- Jump_good_code.
Well, this is a fairly easy to understand scheme, interestingly, there isn't actually any benefit if you use the name Gregory Braun, the program then checks the organization name against Software By Design before proceeding to the same calculation routine that all other codes will reach. The good code can obviously be snatched by typing ? eax, but you could also produce a key generator by examining 00411CF0.
The generation of the good code is well worth studying because it will introduce you to the concept of tables, in a HLL (high-level language) its fairly easy to create a function which computes a value, however in assembly language a function of this nature will be more efficient through the use of a lookup table than a loop, in this program, entry to the table is provided through the use of the string length. Examine the code snippet below.
:00412A70 MOVSX EBX, BYTE PTR [EAX+ECX+00422030] <-- Point to strlen in table.
:00412A78 MOVSX EBP, BYTE PTR [ESI+ECX] <-- First character of name.
:00412A7C LEA EDX,[ECX+01]
:00412A7F IMUL EBX,EBP <-- Multiply.
:00412A82 MOVSX ECX, BYTE PTR [ECX+00422068] <-- Hook into 2nd table.
:00412A89 IMUL EBX,ECX <-- Multiply.
:00412A8C IMUL EBX,EDX <-- Significant after first pass of loop.
:00412A8F ADD EDI,EBX <-- Store result in EDI.
:00412A91 MOV ECX,EDX <-- Counter.
:00412A93 CMP EAX,EDX <-- Check for end of string.
:00412A95 JG 00412A70 <-- Loop_until_end_of_string.
What the program actually has here are several lookup tables, the first 30 characters of the first are shown below.
s e r B & n z ¦ m f M 1 / 5 ( ! s d $ M q . { s ] + s F j t K p z .....
So what happens is this, the program hooks into this table using the string length taken from EAX, so for CrackZ, the table will grab 'n' i.e. the 6th character and load it into EBX at 00412A70. At 00412A78 the program fetches the 1st letter of the name, in my case C (43h), and multiplies it with the corresponding table value giving (43h * 6Eh = 1CCAh).
At 00412A82 we hook into the 2nd table, the first part of which looks like this.
¦ b ! p z * l f $ v i ^ A x p e ) r x 5 a i c & 9 / .....
So at 00412A82 we grab the 1st character of the 2nd table, i.e. ¦ (7Ch) and multiply that with 1CCAh to give DF1D8h. At 00412A8C we multiply this result by the character position, so on the first pass of the loop this is not significant because its multiplied by 1, however on subsequent passes this value will increase, then we store away the result in EDI. On the next pass of the loop, 00412A70 will fetch the next table value i.e. 'z'.
To add further problems, before this loop, note that ESI is actually initialised with the value DB95DB95h before being OR'ed with 378h to give DB95DBFDh, the 2 values calculated from the user name, organisation name and tables, in my case (113B598h - CrackZ) and (1393C14h - Zencrack) are then added to this to give the good code.
DLL Show v3.4
User Name: CrackZ
Organization: Zencrack
Registration: 3722628521
This scheme using tables is not actually particularly weak, in fact producing a key generator would be a fairly miserable process (especially for $20 of shareware), but the controlling check evidentally is the weak link, so the solution is almost certainly to patch the JZ to a JMP. Incidentally this information is written out to the registry.