新手破解练习Crackme160之048 - DueList.3
程序是通过18个checkbox来验证的, 也就是0和1, 应该就是一个确定的密钥二进制数
-
暴力破解, OD搜索成功关键字定位到0040116F, nop掉, 保存完成~
-
正常破解, 从成功分支向上找到入口点00401110, 下断点单步分析, 可以得知是循环取checkbox值, 如果有勾上的就乘以一个值, 具体用IDA分析看反编译代码:
if (ebp1->f12 == 0x111) {
if (ebp2->f16 == 1) {
esi3 = 0;
g40215e = 0;
g402162 = 0;
while (ecx4 = (int32_t)*(signed char*)(esi3 + (int32_t)"I^'&!%YS71H]aRM"), ecx4 != 77) {
g40215e = ecx4;
eax6 = IsDlgButtonChecked(ebp5->f8, ecx4);
++esi3;
if (eax6 == 0)
continue;
g402162 = g402162 + g40215e * *(signed char*)(esi3 + (int32_t)"I^'&!%YS71H]aRM") * esi3;
}
if (g402162 * 77 == 0xf35466)
goto addr_0x401171_8;
} else {
if (ebp7->f16 != 2) {
eax8 = 0;
goto addr_0x4010fa_11;
} else {
addr_0x4011c1_12:
ExitProcess(v9, v10, v11);
eax8 = 1;
goto addr_0x4010fa_11;
}
}
} else {
if (ebp12->f12 == 0x110) {
SetDlgItemTextA(ebp13->f8, 3);
eax8 = 1;
goto addr_0x4010fa_11;
} else {
if (ebp14->f12 == 16)
goto addr_0x4011c1_12;
eax8 = 0;
goto addr_0x4010fa_11;
}
}
其中字符串I^'&!%YS71H]aRM 对应的16进制值是: 16 49 5E 15 27 26 21 25 1D 59 53 37 31 48 5D 0C 61 52 4D, 最后一个0x4D=77,
程序左侧提示我们要用资源编辑器, 只看这一个提示完全看不懂什么意思, 但程序算法中checkbox取值时传入的是上面那些值, 那怎么知道当前取的是哪个checkbox的值呢, 反复对比上面的值 与资源编辑器中各checkbox的值, 发现只有一个ID值是匹配的, 现在需要确认的是哪个checkbox对应哪个ID值, 是否是按字符串中的顺序排列的, 经核对并不是按这个顺序排的, 所以我们还需要一个个把它们的关系对应好:
第一排: 97(61), 73(49), 94(5E), 22(16), 37(25), 38(26), 89(59), 33(21), 83(53),
第二排: 21(15), 55(37), 49(31), 72(48), 93(5D), 12(0C), 39(27), 82(52), 29(1D),
下面是注册机程序: keygen.c
#include <stdio.h>
#include "string.h"
int main() {
int n = 18;
char bstr[19] = {0}; //临时
char brlt[19] = {0}; //正确结果
char str[19] = {0x16, 0x49, 0x5E, 0x15, 0x27, 0x26, 0x21, 0x25, 0x1D, 0x59, 0x53, 0x37, 0x31, 0x48, 0x5D, 0x0C, 0x61, 0x52, 0x4D}; //计算串
char cid[19] = {97, 73, 94, 22, 37, 38, 33, 89, 83, 21, 55, 49, 72, 93, 12, 82, 39, 29, 0x4D}; //checkbox位置排列顺序
int rlt = 0;
int val = 0xF35466 / 0x4D;
for (int i = 0; i < (1 << n); i++) { //2^18全排列组合
rlt = 0;
for(int j=0; j < n; j++) { //初始化
bstr[j] = '0';
}
for (int j = 0; j < n; j++) { //对应位置1 ,并计算
if (i & (1 << j)){
bstr[j] = '1';
rlt += str[j] * str[j+1] * (j+1);
}
}
if(rlt == val){ //输出结果
for(int j = 0; j < n; j++){ //初始化
brlt[j] = 0;
}
for(int j = 0; j < n; j++){ //计算顺序转控件顺序
if(bstr[j] == '1'){
for(int k=0; k<n; k++){
if(str[j] == cid[k]){
brlt[k] = 1;
break;
}
}
}
}
printf("正确结果为:\n");
for(int j = 0; j < n; j++){
if(j == 9){
printf("\n");
}
printf(" %d", brlt[j]);
}
printf("\n\n"); //如果有多组,这里换两行好看些
}
}
printf("按任意键继续~");
getchar();
return 0;
}
运行结果只有一组正确答案:
正确结果为:
0 1 1 0 0 1 1 0 1
1 0 0 1 1 0 0 1 0
按任意键继续~
1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~