新手破解练习Crackme160之112 - CrackMe

  1. 脱壳
    这个程序也是有UPD壳, 用UPD Unpacker可以脱壳成功~ 运行后作者弹框提示不能修改原文件, 不能脱壳~, 文件名也不能改变_, 所以我们先将原文件备份一个, 下面就直接对原文件操作, 不改名, 并保证文件大小不变~ 直接用UE结合VB Decompiler来破解~
     

  2. 正常破解
    这个程序做法很新颖, 前面那些都没有遇到过的, 不让脱壳, 看代码无从下手~ OD载入程序后, 发现全是乱码形式的, 所以我们先用VB Decompiler先分析脱壳后的程序, 发现是P-Code模式的, 果然OD没办法玩了~
    Form_Load事件中看到调用了很多子程序

	Private Sub Form_Load() '404420
	  'Data Table: 4030F8
	  loc_4043FC: Proc_1_5_404640()	' 是否有NMSCMW50这个窗体程序在运行, 应该是什么破解工具吧, 我电脑中没有
	  loc_404401: Proc_1_8_404C24()	' 判断文件名是否为CrackMe.exe, 不区分大小写, 文件大小是否为0x3A00(14848字节)
	  loc_404406: Proc_1_6_404A48()	' 判断电脑系统目录下是否有w32dasm8.ini,  这个我电脑有, 第一个弹框是这个
	  loc_40440B: Proc_1_4_404580()	' 是否有RegmonClass这个程序正在运行, 应该也是破解工具吧, 我也没有
	  loc_404410: Proc_1_3_404810()	' 验证注册表中是否有IDA软件注册项, 我用的绿色版没这个项
	  loc_404415: Proc_1_8_404C24()	' 又一次验证文件名和大小
	  loc_40441A: Proc_1_2_405180()	' 生成一个机器码显示在界面上
	  loc_40441F: Exit Sub
	End Sub
我们直接运行原文件, 正常会被弹框提示错误~ 因为我们正在破解它, 对比弹框信息找到对方的方法, 把里面的if判断条件改为相反的即可,  前面的破文有过p-code模式下的破解方法, 即是将if条件改为 if not,  代码中的1C改为1D, 下面以我电脑为例举例操作一下:
第一个弹框是Proc_1_6_404A48(), 
	Private Sub Proc_1_6_404A48
	  'Data Table: 402C8C
	  loc_404979: Me(4) = CStr(Space(&HFF))
	  loc_4049A9: Me(8) = GetWindowsDirectory(Me(4), &HFF)
	  loc_4049CC: Me(4) = CStr(Left(Me(4), Me(8)))
	  loc_4049EB: Me(0) = Dir(CVar(Me(4) & "\w32dasm8.ini"), 6)
	  loc_4049FE: If (Me(0) <> vbNullString) Then		'条件在这里
	  loc_404A1A:   MsgBox("W32Dasm detected! Please uninstall this Cracking Program!", 0, var_CC, var_EC, var_10C)
	  loc_404A3A:   Me.Global.Unload MemVar_406008
	  loc_404A42:   End
	  loc_404A44: End If
	  loc_404A44: Exit Sub
	End Sub
VB Decompiler切换到HEX Editor面板中查看16进制代码对应的为: FB 3D 1C DC,  UE中搜索原文件这行代码在000015d0h这位置附近, 我们把1C改为1D保存, 重新执行程序便可跳过验证~,  如果还有别的弹框可以同理操作, 我电脑只有这个弹框, 运行后直接来到主界面了~
按钮事件中作者又把上面的验证来一遍~ 并多了一个验证loc_404469: Proc_1_7_404720(),  是否有winice.exe, 如果你有的话, 用上面同样的方式跳过验证~,  最后一个方法loc_40446E: Proc_1_1_404EAC() 才是真正的算法验证处, 输入不能为空, 不能小于8位, 再来到Proc_1_0_405730()这个方法继续验证, 
	Private Sub Proc_1_0_405730
	  'Data Table: 402C8C
	  Dim var_D0 As Integer
	  Dim var_E4 As Variant
	  Dim var_88 As TextBox
	  loc_4051E4: Set var_88 = MemVar_406008.Text4
	  loc_40520C: Me(68) = Replace(frmMain.Text4.Text, "-", vbNullString, 1, -1, 0)	' 将机器码中的减号都去掉
	  loc_40521C: Me(76) = CStr(0)
	  loc_405230: For var_90 = 1 To CInt(Len(Me(68))): Me(96) = var_90 'Integer	' 循环将机器码每一位加起来
	  loc_405257:   Me(72) = CStr(Mid(Me(68), CLng(Me(96)), 1))
	  loc_405279:   Me(76) = CStr((CDbl(Asc(Me(72))) + CDbl(Me(76))))
	  loc_405284: Next var_90 'Integer
	  loc_40528D: Me(80) = CStr(0)
	  loc_4052A6: Set var_88 = MemVar_406008.Text1
	  loc_4052BC: For var_D4 = 1 To CInt(Len(frmMain.Text1.Text)): Me(98) = var_D4 'Integer	' 循环将名称每一位加起来
	  loc_4052CE:   Set var_88 = MemVar_406008.Text1
	  loc_4052F6:   Me(84) = CStr(Mid(CVar(frmMain.Text1.Text), CLng(Me(98)), 1))
	  loc_40531D:   Me(80) = CStr((CDbl(Asc(Me(84))) + CDbl(Me(80))))
	  loc_405328: Next var_D4 'Integer
	  loc_405331: Me(88) = CStr(0)
	  loc_40534A: Set var_88 = MemVar_406008.Text2
	  loc_405360: For var_E8 = 1 To CInt(Len(frmMain.Text2.Text)): Me(100) = var_E8 'Integer	' 循环将公司每一位加起来
	  loc_405372:   Set var_88 = MemVar_406008.Text2
	  loc_40539A:   Me(92) = CStr(Mid(CVar(frmMain.Text2.Text), CLng(Me(100)), 1))
	  loc_4053C1:   Me(88) = CStr((CDbl(Asc(Me(92))) + CDbl(Me(88))))
	  loc_4053CC: Next var_E8 'Integer
	  loc_4053DD: Set var_88 = MemVar_406008.Text1
	  loc_405424: Me(104) = CStr(Mid(CVar(Replace(frmMain.Text1.Text, " ", vbNullString, 1, -1, 0)), 4, 2))	' 去空格
	  loc_405449: Set var_88 = MemVar_406008.Text2
	  loc_405490: Me(108) = CStr(Mid(CVar(Replace(frmMain.Text2.Text, " ", vbNullString, 1, -1, 0)), 5, 3))
	  loc_4054B5: Set var_88 = MemVar_406008.Text4
	  loc_4054FC: Me(112) = CStr(Mid(CVar(Replace(frmMain.Text4.Text, " ", vbNullString, 1, -1, 0)), 5, 3))
	  loc_405521: Set var_88 = MemVar_406008.Text3
	  loc_40552F: var_E4 = CVar(frmMain.Text3.Text) 'String
	  loc_40558C: var_D0 = Ucase(CVar("34" & Me(112) & "-" & Me(76) & StrReverse(Me(80)) & "-" & Me(108) & Me(88) & "-" & Me(104)))	' 组装新串
	  loc_4055B7: If CBool(var_E4 <> var_D0) Then	' 对比
	  loc_4055D3:   MsgBox("Incorrect Serial Number!", 0, var_D0, var_E4, var_11C)
	  loc_4055EF:   Set var_88 = MemVar_406008.Text1
	  loc_4055F5:   frmMain.Text1.Text = vbNullString
	  loc_405609:   Set var_88 = MemVar_406008.Text2
	  loc_40560F:   frmMain.Text2.Text = vbNullString
	  loc_405623:   Set var_88 = MemVar_406008.Text3
	  loc_405629:   frmMain.Text3.Text = vbNullString
	  loc_405631:   Exit Sub
	  loc_405632:   GoTo loc_40572F
	  loc_405635: End If
	  loc_405646: .Visible = 
	  loc_405659: Set var_88 = MemVar_406008.Text2
	  loc_40565F: frmMain.Text2.Visible = False
	  loc_405672: Set var_88 = MemVar_406008.Text3
	  loc_405678: frmMain.Text3.Visible = False
	  loc_40568B: Set var_88 = MemVar_406008.Text4
	  loc_405691: frmMain.Text4.Visible = False
	  loc_4056A4: Set var_88 = MemVar_406008.Label1
	  loc_4056AA: frmMain.Label1.Visible = False
	  loc_4056BD: Set var_88 = MemVar_406008.Label2
	  loc_4056C3: frmMain.Label2.Visible = False
	  loc_4056D6: Set var_88 = MemVar_406008.Label3
	  loc_4056DC: frmMain.Label3.Visible = False
	  loc_4056EF: Set var_88 = MemVar_406008.Label4
	  loc_4056F5: frmMain.Label4.Visible = False
	  loc_405708: Set var_88 = MemVar_406008.cmdCheck
	  loc_40570E: frmMain.cmdCheck.Visible = False
	  loc_405721: Set var_88 = MemVar_406008.Label5
	  loc_405727: frmMain.Label5.Visible = True
	  loc_40572F: ' Referenced from: 405632
	  loc_40572F: Exit Sub
	End Sub
分析完代码, 算法就明朗了~ 下面开始写注册机~ keygen.c
	#include <stdio.h>
	#include <string.h>

	void myreplace(char *str, char *oldstr, char *newstr){
		int len = strlen(str);
		int i=0,j=0;
		for(i=0; i<len; i++){
			if(str[i] != oldstr[0]) continue;
			if(newstr != "") str[i] = newstr[0];
			else {
				for(j=i; j<len-1; j++) str[j] = str[j+1];
				str[j] = '\0';
				len--;
			}
		}
		return;
	}

	int main() {
		char name[21] = {0};	//用户名 
		char comp[21] = {0};	//公司名 
		char sysc[21] = {0};	//机器码 
		char code[61] = {0};	//系列号 
		int lenn,lenc,lens;
		int namev=0, compv=0, syscv=0;
		int in=0;
		char a;
		unsigned int eax = 0xFFFFFF00;
		printf("请输入用户名(8位以上): ");
		in = 0; while((a=getchar()) != '\n') name[in++] = a;
		printf("请输入公司名(8位以上): ");
		in = 0; while((a=getchar()) != '\n') comp[in++] = a;
		printf("请输入机器码: ");
		in = 0; while((a=getchar()) != '\n') sysc[in++] = a;
		lenn = strlen(name);
		lenc = strlen(comp);
		lens = strlen(sysc);
		int ci = 0;
		//34
		code[ci++] = '3';
		code[ci++] = '4';
		//Me(112)
		for(int i=0; i<lens; i++){
			if(sysc[i] == '-') continue;
			syscv += sysc[i];
		}
		lenc = strlen(sysc);
		myreplace(sysc, (char*)" ", (char*)"");
		code[ci++] = sysc[4];
		code[ci++] = sysc[5];
		code[ci++] = sysc[6];
		//Me(76) 
		code[ci++] = '-';
		char syscStr[20];
		sprintf(syscStr, "%d", syscv); //转字符串 
		lens = strlen(syscStr);
		for(int i=0; i<lens; i++){
			code[ci++] = (char)syscStr[i];
		}
		//StrReverse(Me(80))
		for(int i=0; i<lenn; i++){
			namev += name[i];
		}
		char nameStr[20];
		sprintf(nameStr, "%d", namev);
		lens = strlen(nameStr);
		for(int i=lens-1; i>=0; i--){ //这个是倒序 
			code[ci++] = (char)nameStr[i];
		}
		//Me(108)
		code[ci++] = '-';
		for(int i=0; i<lenc; i++){
			compv += comp[i];
		}
		myreplace(comp, (char*)" ", (char*)"");
		code[ci++] = comp[4];
		code[ci++] = comp[5];
		code[ci++] = comp[6];
		//Me(88)
		char compStr[20];
		sprintf(compStr, "%d", compv);
		lenc = strlen(compStr);
		for(int i=0; i<lenc; i++){
			code[ci++] = (char)compStr[i];
		}
		//Me(104)
		code[ci++] = '-';
		myreplace(name, (char*)" ", (char*)"");
		code[ci++] = name[3] < 96 ? name[3] : (name[3] - 32); //转大写 
		code[ci++] = name[4] < 96 ? name[4] : (name[4] - 32); //转大写 
		printf("注册码为: %s\n", code);
		
		getchar();getchar();
		return 0;
	}
输入验证后出现了个异常, 提示路径/文件访问错误~ ,  说明新加的那个验证需要访问文件~ 经核对是我电脑C盘锁了, 没有读写权限~ 放到虚拟机验证成功~

上面注册机运行示例:

请输入用户名(8位以上): abcabcabc
请输入公司名(8位以上): 123123123
请输入机器码: F54-E071B513-052
注册码为: 34E07-766288-231450-AB

请输入用户名(8位以上): abc abc abc
请输入公司名(8位以上): 123 123 123
请输入机器码: F54-E071B513-052
注册码为: 34E07-766649-231514-AB

用VB写更简单些, 大部分可以直接复制VB Decompiler中的代码: keygen.vbs
	name = inputbox("请输入用户名")
	company = inputbox("请输入公司名")
	unique = inputbox("请输入机器码")
	 
	s1 = Replace(unique, "-", vbNullString, 1, -1, vbBinaryCompare)
	 
	ss1 = 0
	For i = 1 To Len(s1)
	  ss1 = ss1 + Asc(Mid(s1, i, 1))
	Next
	 
	ss2 = 0
	For i = 1 To Len(name)
	  ss2 = ss2 + Asc(Mid(name, i, 1))
	Next
	 
	ss3 = 0
	For i = 1 To Len(company)
	  ss3 = ss3 + Asc(Mid(company, i, 1))
	Next
	 
	s3 = Replace(name, " ", vbNullString, 1, -1, vbBinaryCompare)
	s4 = Mid(s3, 4, 2)
	 
	s5 = Replace(company, " ", vbNullString, 1, -1, vbBinaryCompare)
	s6 = Mid(s5, 5, 3)
	 
	s7 = Replace(unique, " ", vbNullString, 1, -1, vbBinaryCompare)
	s8 = Mid(s7, 5, 3)
	 
	getSerial = UCase("34" & s8 & "-" & CStr(ss1) & StrReverse(ss2) & "-" & s6 & ss3 & "-" & s4)
	
	msgbox "机器码: "&unique&chr(13)&chr(10)&"用户名: "&name&chr(13)&chr(10)&"公司名: "&company&chr(13)&chr(10)&"序列号: "&getSerial,0,"注册机"

 
 
 
这是160个软件part1
这是160个软件part2

1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载

新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~

下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~
OD界面布局

posted @ 2024-07-16 16:33  hankerstudio  阅读(4)  评论(0)    收藏  举报