菜鸟逆袭 Crackme第三弹 附带注册机

有个哲人说:凡人总是迷失在call的海洋中。

=============================================

用PEid查壳:Borland Delphi 6.0 - 7.0 用Delphi写的,无壳。
用w32asm 查看竟然“Could not get file handle”
看雪大神说:先用peid查查是不是有壳,如果没壳还这错误,试试其他反汇编工具,如IDA等 
不纠结了。OD架起。
Ctrl+N捉不到关键API。
用超级字符串,发现奇怪字样。
0048C718  |.  E8 D77EFAFF   CALL 壹只老虎.004345F4              ; 下断 
0048C71D  |.  8D45 F4       LEA EAX,DWORD PTR SS:[EBP-C]   
0048C720  |.  BA 80C84800   MOV EDX,壹只老虎.0048C880           ;  i am Bin Laden
0048C725  |.  E8 CA77F7FF   CALL 壹只老虎.00403EF4
0048C72A  |.  8D45 F0       LEA EAX,DWORD PTR SS:[EBP-10]
0048C72D  |.  BA 98C84800   MOV EDX,壹只老虎.0048C898           ;  i am yi zhi lao hu
0048C732  |.  E8 BD77F7FF   CALL 壹只老虎.00403EF4
0048C737  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]        ; [EBP-4]为用户名xihuan
0048C73A  |.  E8 DD79F7FF   CALL 壹只老虎.0040411C              ; 检查字符串长度为 6
0048C73F  |.  83F8 0A       CMP EAX,0A                          ; 如果长度比 0xA 小,则挂
0048C742  |.  0F8C FC000000 JL 壹只老虎.0048C844
0048C748  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0048C74B  |.  E8 CC79F7FF   CALL 壹只老虎.0040411C
0048C750  |.  83F8 10       CMP EAX,10                          ;这里namelen <= 0x10   
0048C753  |.  0F8F EB000000 JG 壹只老虎.0048C844
0048C759  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0048C75C  |.  E8 BB79F7FF   CALL 壹只老虎.0040411C              ; 返回serialLen  
0048C761  |.  83F8 11       CMP EAX,11                          ; serialLen >= 0x11
0048C764  |.  0F8C DA000000 JL 壹只老虎.0048C844
0048C76A  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0048C76D  |.  E8 AA79F7FF   CALL 壹只老虎.0040411C
0048C772  |.  83F8 16       CMP EAX,16                          ; serialLen <= 0x16
0048C775  |.  0F8F C9000000 JG 壹只老虎.0048C844
0048C77B  |.  8D45 FC       LEA EAX,DWORD PTR SS:[EBP-4]
0048C77E  |.  8B55 F4       MOV EDX,DWORD PTR SS:[EBP-C]        ;  壹只老虎.0048C880
0048C781  |.  E8 9E79F7FF   CALL 壹只老虎.00404124
0048C786  |.  BB 64000000   MOV EBX,64
0048C78B  |.  8D45 88       LEA EAX,DWORD PTR SS:[EBP-78]

调整namelen[0xA,0x10],serialLen[0x11,0x16],
我们重新开始后,F9,我们输入xihuanshagua (12) woaininiaiwomaoyjg(18)
发现关键代码:
0048C781   |.  E8 9E79F7FF   CALL 壹只老虎.00404124             ;  strcpt -> string1
0048C786   |.  BB 64000000   MOV EBX,64                         ;  100
0048C78B   |.  8D45 88       LEA EAX,DWORD PTR SS:[EBP-78]
0048C78E   |>  C600 2E       /MOV BYTE PTR DS:[EAX],2E          ;  初始化,100次2E
0048C791   |.  40            |INC EAX
0048C792   |.  4B            |DEC EBX
0048C793   |.^ 75 F9         \JNZ SHORT 壹只老虎.0048C78E
0048C795   |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0048C798   |.  E8 7F79F7FF   CALL 壹只老虎.0040411C             ;  strlen
0048C79D   |.  8BF8          MOV EDI,EAX
0048C79F   |.  85FF          TEST EDI,EDI
0048C7A1   |. /7E 47         JLE SHORT 壹只老虎.0048C7EA
0048C7A3   |. |BB 01000000   MOV EBX,1                          ;  这里开始一波循环运算
0048C7A8   |> |8B45 F0       /MOV EAX,DWORD PTR SS:[EBP-10]     ;  壹只老虎.0048C898
0048C7AB   |. |E8 6C79F7FF   |CALL 壹只老虎.0040411C            ;  strlen
0048C7B0   |. |8BF0          |MOV ESI,EAX
0048C7B2   |. |85F6          |TEST ESI,ESI
0048C7B4   |. |7E 30         |JLE SHORT 壹只老虎.0048C7E6
0048C7B6   |. |B9 01000000   |MOV ECX,1                         ;  EBX = i  ECX =j
0048C7BB   |> |8B45 FC       |/MOV EAX,DWORD PTR SS:[EBP-4]     ;  string1
0048C7BE   |. |0FB64418 FF   ||MOVZX EAX,BYTE PTR DS:[EAX+EBX-1];  string1[i]
0048C7C3   |. |8B55 F8       ||MOV EDX,DWORD PTR SS:[EBP-8]     ;  SN
0048C7C6   |. |0FB6540A FF   ||MOVZX EDX,BYTE PTR DS:[EDX+ECX-1];  SN[j]
0048C7CB   |. |F7EA          ||IMUL EDX                         ;  string1[i] * SN[j]
0048C7CD   |. |51            ||PUSH ECX
0048C7CE   |. |B9 1A000000   ||MOV ECX,1A                       ;  ECX = 1A
0048C7D3   |. |33D2          ||XOR EDX,EDX
0048C7D5   |. |F7F1          ||DIV ECX                          ;  string1[i]*SN[j] / 1A
0048C7D7   |. |59            ||POP ECX                          ;  0012FDDC
0048C7D8   |. |83C2 41       ||ADD EDX,41                       ;  string1[i]*SN[j] mod 1A +41
0048C7DB   |. |8D0419        ||LEA EAX,DWORD PTR DS:[ECX+EBX]   ;  EAX = i + j
0048C7DE   |. |885405 87     ||MOV BYTE PTR SS:[EBP+EAX-79],DL  ;  结果DL存放起来
0048C7E2   |. |41            ||INC ECX
0048C7E3   |. |4E            ||DEC ESI
0048C7E4   |.^|75 D5         |\JNZ SHORT 壹只老虎.0048C7BB
0048C7E6   |> |43            |INC EBX
0048C7E7   |. |4F            |DEC EDI
0048C7E8   |.^|75 BE         \JNZ SHORT 壹只老虎.0048C7A8
0048C7EA   |> \8D45 EC       LEA EAX,DWORD PTR SS:[EBP-14]
0048C7ED   |.  E8 6A76F7FF   CALL 壹只老虎.00403E5C              ;  ?
0048C7F2   |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0048C7F5   |.  E8 2279F7FF   CALL 壹只老虎.0040411C              ;  strlen
0048C7FA   |.  8BF8          MOV EDI,EAX
0048C7FC   |.  85FF          TEST EDI,EDI
0048C7FE   |.  7E 1F         JLE SHORT 壹只老虎.0048C81F         ;  第二波运算
0048C800   |.  8D5D 8E       LEA EBX,DWORD PTR SS:[EBP-72]       ;  string2的第六位开始算
0048C803   |>  8D45 84       /LEA EAX,DWORD PTR SS:[EBP-7C]
0048C806   |.  8A13          |MOV DL,BYTE PTR DS:[EBX]           ;  string2[i]
0048C808   |.  E8 3778F7FF   |CALL 壹只老虎.00404044
0048C80D   |.  8B55 84       |MOV EDX,DWORD PTR SS:[EBP-7C]
0048C810   |.  8D45 EC       |LEA EAX,DWORD PTR SS:[EBP-14]
0048C813   |.  8B4D EC       |MOV ECX,DWORD PTR SS:[EBP-14]
0048C816   |.  E8 4D79F7FF   |CALL 壹只老虎.00404168
0048C81B   |.  43            |INC EBX
0048C81C   |.  4F            |DEC EDI
0048C81D   |.^ 75 E4         \JNZ SHORT 壹只老虎.0048C803        ;  长度为 SNlen
0048C81F   |>  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]       ;  以上的运算讲的是倒序存储
0048C822   |.  8B55 F8       MOV EDX,DWORD PTR SS:[EBP-8]        ;  尽量别跟进call,会晕,看结果容易些
0048C825   |.  E8 3E7AF7FF   CALL 壹只老虎.00404268              ;  strcmp
0048C82A   |.  75 18         JNZ SHORT 壹只老虎.0048C844
0048C82C   |.  6A 40         PUSH 40
0048C82E   |.  B9 ACC84800   MOV ECX,壹只老虎.0048C8AC           ;  恭喜你
0048C833   |.  BA B4C84800   MOV EDX,壹只老虎.0048C8B4           ;  注册成功!请联系我!QQ:609841314
0048C838   |.  A1 D0EB4800   MOV EAX,DWORD PTR DS:[48EBD0]
0048C83D   |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
0048C83F   |.  E8 F478FCFF   CALL 壹只老虎.00454138


看到第一波运算的时候,就发现注册机不好写,因为序列号也参加运算了。
条件:SN.运算后 == SN.运算前
这个不仅仅注册机不好写,连正确的SN都不好获得。

注册机思路:

我猜到原作者的思想:
1. strcat(name,Laden);
2. 两层循环,i外j内,name[i] * SN[j] % 0x1A +0x41 的值赋值给 Result1[i+j]
3. 从Result1的第六位开始,截取len(SN)位,赋值为Result2 
4. 逆序,使Result2为真正的SN

关键在第2点上:
Result1[i+j],这将导致:
赋值顺序:i=0  0,1,2,3,4,5...
          i=1  1,2,3,4,5,6...
          i=2  2,3,4,5,6,7...
前面的除了每一轮的首位不会被覆盖掉,其它都会被覆盖掉,而每一轮的首位就是我们Result1[i]
所以:name[i]  -> Result1[i] 通过(name[i] * SN[0] % 0x1A +0x41 )
明显:我们只要先求出SN[0]即可。

Ps:在求的过程中,发现18的SN的首位得不到,转为求17位的SN,成功。

// getSerial.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "string.h"
#include "stdlib.h"

int main(int argc, char* argv[])
{
	int i,j;
	char name[100];
	char laden[] = "i am Bin Laden";
	char *SN =(char*)malloc(sizeof(char) * 100); 

	while(true)
	{
		printf("Please enter name[10,16],finished with '#':");
		scanf("%s",name);
		if(0 == strcmp(name,"#") ) break;
		
		strcat(name,laden);
		//这里我假设SN的长度为17..注意SN不唯一
	    //实验证明,如果取18则找不到SN[0]
		int cnt = 0 ;
		int lastCharIndex = 21;
		int startCharIndex = 5;
		for(j = 'A'; j <= 'Z' ;j++)
		{
			if(j == (((name[lastCharIndex] * j) % 0x1A) + 0x41) )
			{
				SN[cnt++] = j;
			}
		}
		for(i = lastCharIndex-1; i >= startCharIndex ; i--)
		{
			SN[cnt++] = name[i] * SN[0] % 0x1A +0x41;
		}
		SN[cnt]='\0';
		printf("Serial number is %s\n",SN);

	}
	return 0;
}


你可能感兴趣的:(菜鸟逆袭 Crackme第三弹 附带注册机)