新手破解练习Crackme160之39 - damn
-
暴力破解, 不会脱壳, 放弃 (后记: aspack uppacker在window10下无法使用, 在XP下试一下发现是正常的, 脱壳成功了, 既然已经脱壳成功了, 那就继续暴破工作吧, 前面正常破解中可知00402313处的值是显示图标的关键, 所以我们在数据区定位到00402313, 在值00上右键, 在内存硬件写入下个断点, F9运行, 断点处停下0040201C处看到mov dword ptr ds:[0x402313],edx, F8运行返回到调用点, 在上一个方法处0040119D下个断点, 重新运行程序, F7进入方法, 004013BA处有个关键跳, 将004013B4中的值随便改一个让其不跳, je处nop掉也可以, 然后将004013BE改为mov edx, 0x2, 这个值就是要赋值给00402313的, 所以我们直接改为02, 就是unlocked图片序号, 到此, 图标暴破完成, 保存测试~. 我们继续努力, 还有注册按键还是灰的, 还是直接延用正常破解中的信息, 004012F4这个方法是来验证算法是否通过, 通过则按钮亮起, 那我们直接让其任意条件下通过即可,004012F4处修改为retn 0x1,保存完事~, 随意输入name 和 key 注册按钮亮起, 到此暴破全搞定~ , 由于想着logo有三张, 怎么也得想办法瞧瞧真容是吧, 点击logo按钮会有弹框, 且跟踪发现点一下00402313的值会减1一下, 竟然值已经变了, 说明作者应该也是想着让我们去改变图标的吧, 于是我们跟踪到弹框完的代码处004012DC, 发现几行都是pop操作, 恢复寄存器的值, 再到004011A2处看显示图标的程序, 一开始就对这几个寄存器赋值, 所以恢复就变得无意义了, 直接将004012DC改为jmp 004011A2, 改完发现后面004012E0的retn 0x10没了, 也不知道会不会影响先不管了, 保存测试一下, 竟然完全正常, 可能是因为图标显示完成的方法后面也有个retn 0x10吧, 这个不太明白, 反正程序正常运行了, 图标也会变了, 就这样吧, 这个是后传了_, 多出一个破解~)
-
正常破解, 因为不会脱壳, 所以无法通过反编译得到事件入口, 直接OD加载F9运行, ctrl+g输入401000定位到源程序区域, 如果反汇编区域看到是一干堆db ?? 的那就右键->分析->从模块中删除分析, 那就可以看到正常的汇编代码了, 搜索失败成功等关键字, 定位相关位置后, 向上看是没有看到算法代码块的, 也没看到相关的调用模块, 这招没用了, 然后我们用获取输入框数据的方法打断点, 插件->api断点设置工具->常用断点设置->getWindowTextA勾上确定, 在输入框定输入数据, 我们发现一点击用户名框, 程序就停下来了,,说明有个聚焦监听事件, 我们在数据区看到返回到damn.00401139 来自 damn.004013FF, 说明是由程序004013FF这个方法调用了, 调用完数据框数据, 得到一个结果eax写入到内存[0x402389], 看这个eax就是数据长度, 说明程序是在另一处要验证长度什么, 国为这边的程序就几行, 没有算法的东东, 所以, 我们查找这个内存在哪里使用, 右键->查找->所有常量, 出来两个结果 , 一个是写入, 一个是读取, 我们来到读取处004012F4, 前面的断点没什么用了先取消掉, 不然一聚焦程序就停, 很麻烦的, 在004012F4处下新断点, 输入用户名, 准备输入key时, 一点框, 程序又停下来了, 说明新断点是key框的监听事件, 看程序是有算法里面的, 说明这里需要验证输入的key与name是否匹配, 接下来就是研究算法吧
ebx = 0x44414D4E 先定义一个常量,
然后进入循环, 取每一位的用户名加起来 edx += username[i]; ebx ror 1, ebx ror i;
循环完, ebx or 0x10101010; 到这里用户名的处理就完成了,
下面是取key的值 判断是否8位, 有循环与对比, 应该是与用户名算出来的结果比较吧, 先放着, 我们先输入一组用户名看具体算出来的结果是什么, 输入abcde得到ebx=54389971(8位), 有戏, 直接输入看是不是就是key, 输完Register按钮亮起来了, 我们猜对了, key那部分的代码就不分析了,
注册机代码放上:
#include <stdio.h>
#include "string.h"
int ror(unsigned int num, unsigned char i){ //这个简单方便, 右移几位, 把顶掉的几位补到前面
return (num >> i) | (num << (sizeof(int) * 8 - i));
}
int ror1(unsigned int num , unsigned char i ) { //这个是汇编
__asm__ (
"ROR %%cl, %%eax\n\t" //at&t模式参数是反过来 ror 1, 10, intel模式是 ror 10, 1
:"=a"(num)
: "a"(num), "c"(i) //eax, ecx
);
return num;
}
int ror2(unsigned int num, unsigned char i){ //这个自己实现的循环右移
if(i==0) return num;
int size = sizeof(int) * 8; //32位系统 = 4字节 * 8位
int a[size], b[size];
int j=0,t=0;
for(j=0; j<size; j++) {
a[j] = 0; //倒序
b[j] = 0; //正序
}
j = 0;
while((num != 0) && (j<=size)){
t = num % 2;
a[j++] = t==0 ? 0 : 1;
num = num / 2;
}
for(;j>=0;j--){ //正序
b[size-j-1] = a[j];
}
for(j=0;j<i;j++){
a[j] = b[size-i+j]; //缓存需要移动的最后i位
}
for(j=size-1;j>=i;j--){ //剩下的全右移
b[j] = b[j-i];
}
for(j=0;j<i;j++){ //把缓存的存回前面i位
b[j] = a[j];
}
num = 0;
for(j=0;j<size;j++){
num *= 2;
num += b[j];
}
return num;
}
int main(){
while(true){
unsigned int ebx = 0x44414D4E;
int edx = 0;
char user[20] = {0};
printf("请输入用户名: ");
scanf("%s", user);
int len = strlen(user);
for(int i=0; i<len; i++){
edx += user[i];
ebx = ror(ebx, 1);
ebx = ror(ebx, i);
ebx ^= edx;
}
ebx |= 0x10101010; //or
printf("系列号为: %X\n", ebx);
}
return 0;
}
- 解锁logo, 注册破解完了, 发现下面的图标不会变, 随意点了一下发现是个按钮, 会提示信息(搜索框有看到对应的信息), 那就搜索中定位关键字004012BA, 方法入口004012A9是从内存中取数, 说明是有别的地方存这个数的, 找找, 右键->查找->所有变量, 输入402313, 找到5条记录, 没有写入的地方, 到这边就晕了, 作者应该不会通过手动修改这个内存值来看不同的图片吧, 内存处下个硬件断点, 启动时强制修改这个值再放行~ 就可以看到其它图片了, 0:locked, 1:cracked, 2:unlocked, 我觉得做成这样比较完美, 1.按钮亮起时, 图片变1, 点击注册时图片变2
1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号