吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9217|回复: 13
收起左侧

[原创] [反汇编练习]160个Crackme之011-Andrénalin.4-详细分析

[复制链接]
pk8900 发表于 2017-6-22 00:57
本帖最后由 pk8900 于 2017-6-22 01:15 编辑

【程序说明】160个Crackme之011-Andrénalin.4,VB 5.0,无壳。
下载地址:】http://pan.baidu.com/share/link?shareid=541269&uk=4146939145


最近几天学C++学的头晕转向,于是继续进行160个Crackme系列,这个Andrénalin的系列Crackme还真是不好弄,前面几个研究完收获不小,尤其是自己仿写了些代码,反汇编研究,下面就这个Andrénalin.4,给大家详细介绍一下我的分析过程和心得。
Crackme界面如下 :

Image 001.png

一些数字键,*、#,<-(退格键),点任意数字键钮,上方文本框中显示字符,同时退格键亮起。右侧有"UNREGISTRIERT"字样,输入正确字符串后,会显示"REGISTRIERT"字样。搜索程序字符串资源,会发现有很多的字串及"REGISTRIERT"

Image 002.png

这说明程序采用的是Native Code编码方式,VB编写的应用程序有两种编译方式,一种是Native code方式,另一种是P-code方式,P-code方式程序是搜索不到字符串的。因为P-code方式程序的字节码是运行的时候由msvbvm50.dllmsvbvm60.dll解释执行,所以调试的时候往往会断在msvbvm50.dllmsvbvm60.dll的领空。这个程序爆破起来很容易,因为"REGISTRIERT"字样到处都是,修改之前的跳转,就能达到目的,而我要研究的是程序的算法,所以要进行跟踪,顺着"REGISTRIERT"上找,跟了半天,大致的明白了一点程序的验证流程,但一想到字符串搜索里那若干的REGISTRIERT"和长字符串,就有种不安的感觉,会不会掉到作者挖的坑里了。还是用VB Decompiler Pro反编译看看吧,随便说一下,VB程序反编译,对于分析破解VB程序非常重要,因为VB程序用OD分析,如果代码长,你跟踪变量都会跟丢了。
反编译程序果然发现很多信息:

Image 003.png

程序只有一个窗体,但有4个Timer控件,每个控件的周期为1毫秒,而所有的验证代码都在Timer事件中。每个事件中有15段代码,内容大至雷同。

Image 004.png

通过对其中一段代码进行分析:
  loc_00406CAD: For var_24 = 1 To Len(var_44) Step 1 循环读取字符输入字符
  loc_00406CBF:
   loc_00406CC1: If var_F8 = 0 Then GoTo loc_00406DF0 若当前为0跳到验证部分
  loc_00406CDB: var_50 = CStr(Left(var_44, 1))     ;取左第一个字母
  loc_00406D2D: var_304 = Asc(Mid$(CStr(var_44), CLng(var_24), 1))  取当前字母ASC值  
loc_00406D72: var_8C = Hex$((var_30C + var_CC))    加上一个数后(经后来分析是一个基数,由输入的数左取固定位转10进制数值得来 变量: var_CC)转为十六进制字符串,
loc_00406D9C: var_34 = var_34 & Hex$((var_30C + var_CC))   累加字符串至变量
以上为大至分析结果,还看不出具体算法,于是用调试器跟踪,因为是时间事件,所以先取消所有断点,输好字符后,再至代码处下断,就会立即断下来。
X32dbg中分析流程:【注:反编译中的var_CC,就是调试器跟踪中的EBP-CC堆栈地址,可以锁定堆栈,把堆栈切换成+??或-??的EBP偏移,方便观察变量的值。

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
00406EDC | 85 C0                 | test eax,eax                               | 循环控制
00406EDE | 0F 84 29 01 00 00     | je 40700D                                  |
00406EE4 | 8D 4D BC              | lea ecx,dword ptr ss:[ebp-44]              | ebp-44是输入的字符串,字符串实际为ebp-3c
00406EE7 | 6A 02                 | push 2                                     | 2个
00406EE9 | 8D 55 8C              | lea edx,dword ptr ss:[ebp-74]              | ebp-74 结果返回地址,字符:ebp-6c
00406EEC | 51                    | push ecx                                   |
00406EED | 52                    | push edx                                   |
00406EEE | FF D3                 | call ebx                                   | msvbvm60.rtcLeftCharVar
00406EF0 | 8D 45 8C              | lea eax,dword ptr ss:[ebp-74]              | 返回的两个字符
00406EF3 | 8D 4D B0              | lea ecx,dword ptr ss:[ebp-50]              | 结果保存地址
00406EF6 | 50                    | push eax                                   |
00406EF7 | 51                    | push ecx                                   |
00406EF8 | FF D6                 | call esi                                   | var_50 = CStr(Left(var_44, 2))
00406EFA | 50                    | push eax                                   |
00406EFB | FF 15 D8 10 40 00     | call dword ptr ds:[<&rtcR8ValFromBstr>]    | 字符串转换成浮点数:st0
00406F01 | DD 9D 34 FF FF FF     | fstp qword ptr ss:[ebp-CC]                 | 数值传给变量ebp-cc *64位*
00406F07 | 8D 55 9C              | lea edx,dword ptr ss:[ebp-64]              |
00406F0A | 8D 45 DC              | lea eax,dword ptr ss:[ebp-24]              |
00406F0D | 52                    | push edx                                   |
00406F0E | 50                    | push eax                                   |
00406F0F | C7 45 A4 01 00 00 00  | mov dword ptr ss:[ebp-5C],1                |
00406F16 | C7 45 9C 02 00 00 00  | mov dword ptr ss:[ebp-64],2                |
00406F1D | FF 15 AC 10 40 00     | call dword ptr ds:[<&_vbaI4Var>]           |
00406F23 | 8D 4D BC              | lea ecx,dword ptr ss:[ebp-44]              |
00406F26 | 50                    | push eax                                   |
00406F27 | 8D 55 B8              | lea edx,dword ptr ss:[ebp-48]              |
00406F2A | 51                    | push ecx                                   |
00406F2B | 52                    | push edx                                   |
00406F2C | FF D6                 | call esi                                   |
00406F2E | 50                    | push eax                                   |
00406F2F | FF 15 4C 10 40 00     | call dword ptr ds:[<&rtcMidCharBstr>]      | 循环取字符从1开始
00406F35 | 8B D0                 | mov edx,eax                                |
00406F37 | 8D 4D B4              | lea ecx,dword ptr ss:[ebp-4C]              |
00406F3A | FF 15 BC 10 40 00     | call dword ptr ds:[<&_vbaStrMove>]         |
00406F40 | 50                    | push eax                                   |
00406F41 | FF 15 20 10 40 00     | call dword ptr ds:[<&rtcAnsiValueBstr>]    | ASCLL值
00406F47 | 0F BF C0              | movsx eax,ax                               | 存入变量ebp-310中
00406F4A | 89 85 F0 FC FF FF     | mov dword ptr ss:[ebp-310],eax             | var_310 = Asc(Mid$(CStr(var_44), CLng(var_24), 1))
00406F50 | 8D 8D 7C FF FF FF     | lea ecx,dword ptr ss:[ebp-84]              |
00406F56 | DB 85 F0 FC FF FF     | fild dword ptr ss:[ebp-310]                | 入栈 st0
00406F5C | 51                    | push ecx                                   |
00406F5D | C7 85 7C FF FF FF 05  | mov dword ptr ss:[ebp-84],5                |
00406F67 | DD 9D E8 FC FF FF     | fstp qword ptr ss:[ebp-318]                | 转化精度,给变量EBP-318
00406F6D | DD 85 E8 FC FF FF     | fld qword ptr ss:[ebp-318]                 |
00406F73 | DC 85 34 FF FF FF     | fadd qword ptr ss:[ebp-CC]                 | 加ebp-cc  前面转化来的数值
00406F79 | DD 5D 84              | fstp qword ptr ss:[ebp-7C]                 | 存入ebp-7c
00406F7C | DF E0                 | fnstsw ax                                  | 以下为较验运算,是否出错。
00406F7E | A8 0D                 | test al,D                                  |
00406F80 | 0F 85 D6 1D 00 00     | jne 408D5C                                 |
00406F86 | FF 15 94 10 40 00     | call dword ptr ds:[<&rtcHexBstrFromVar>]   | 十六进制转字符:给变量ebp-8c
00406F8C | 89 85 74 FF FF FF     | mov dword ptr ss:[ebp-8C],eax              | var_8C = Hex$((var_318 + var_CC))
00406F92 | 8D 55 CC              | lea edx,dword ptr ss:[ebp-34]              | 十六进制转的字符串
00406F95 | 8D 85 6C FF FF FF     | lea eax,dword ptr ss:[ebp-94]              |
00406F9B | 52                    | push edx                                   |
00406F9C | 8D 8D 5C FF FF FF     | lea ecx,dword ptr ss:[ebp-A4]              | 累加连接的字符串
00406FA2 | 50                    | push eax                                   |
00406FA3 | 51                    | push ecx                                   |
00406FA4 | C7 85 6C FF FF FF 08  | mov dword ptr ss:[ebp-94],8                |
00406FAE | FF 15 84 10 40 00     | call dword ptr ds:[<&_vbaVarCat>]          | 连接字符串
00406FB4 | 8B D0                 | mov edx,eax                                |
00406FB6 | 8D 4D CC              | lea ecx,dword ptr ss:[ebp-34]              |
00406FB9 | FF D7                 | call edi                                   |
00406FBB | 8D 55 B0              | lea edx,dword ptr ss:[ebp-50]              |
00406FBE | 8D 45 B4              | lea eax,dword ptr ss:[ebp-4C]              |
00406FC1 | 52                    | push edx                                   |
00406FC2 | 8D 4D B8              | lea ecx,dword ptr ss:[ebp-48]              |
00406FC5 | 50                    | push eax                                   |
00406FC6 | 51                    | push ecx                                   |
00406FC7 | 6A 03                 | push 3                                     |
00406FC9 | FF 15 9C 10 40 00     | call dword ptr ds:[<&_vbaFreeStrList>]     |
00406FCF | 8D 95 6C FF FF FF     | lea edx,dword ptr ss:[ebp-94]              |
00406FD5 | 8D 85 7C FF FF FF     | lea eax,dword ptr ss:[ebp-84]              |
00406FDB | 52                    | push edx                                   |
00406FDC | 8D 4D 8C              | lea ecx,dword ptr ss:[ebp-74]              |
00406FDF | 50                    | push eax                                   |
00406FE0 | 8D 55 9C              | lea edx,dword ptr ss:[ebp-64]              |
00406FE3 | 51                    | push ecx                                   |
00406FE4 | 52                    | push edx                                   |
00406FE5 | 6A 04                 | push 4                                     |
00406FE7 | FF 15 14 10 40 00     | call dword ptr ds:[<&_vbaFreeVarList>]     |
00406FED | 83 C4 24              | add esp,24                                 |
00406FF0 | 8D 85 E8 FE FF FF     | lea eax,dword ptr ss:[ebp-118]             |
00406FF6 | 50                    | push eax                                   |
00406FF7 | 8D 8D F8 FE FF FF     | lea ecx,dword ptr ss:[ebp-108]             |
00406FFD | 8D 55 DC              | lea edx,dword ptr ss:[ebp-24]              |
00407000 | 51                    | push ecx                                   |
00407001 | 52                    | push edx                                   |
00407002 | FF 15 C8 10 40 00     | call dword ptr ds:[<&_vbaVarForNext>]      |
00407008 | E9 CF FE FF FF        | jmp 406EDC                                 |
0040700D | 8D 45 CC              | lea eax,dword ptr ss:[ebp-34]              |
00407010 | 8D 8D 4C FF FF FF     | lea ecx,dword ptr ss:[ebp-B4]              |
00407016 | 50                    | push eax                                   |
00407017 | 51                    | push ecx                                   |
00407018 | C7 85 54 FF FF FF E8  | mov dword ptr ss:[ebp-AC],401EE8           | 401EE8:L"0817E747D7A7D7C7F82836D74747A7F7E7G7C7D826D817E7B7C"
00407022 | C7 85 4C FF FF FF 08  | mov dword ptr ss:[ebp-B4],8008             |
0040702C | FF 15 5C 10 40 00     | call dword ptr ds:[<&_vbaVarTstEq>]        | 比较字符串,进行验证


通过OD的跟踪分析,已明子软件的算法,具体算法为:从左取用户输入的字符串N位(1-8位),转为十进制数值。用的就是VB中的Val函数,转字符转 10进度数字,*、#则中断,如:VAL(“789”)--- 789 ;VAL(“078*#89”)---- 78  这个值是基数,加上第一个字符的ASC值,两值之和,转为16进制字符,依此类推:第2个字符ASC 加78,转十六进制字符追加后面,直到输入的全部字符,就会得到一个长的十六进制字符串,这里没弄明白的是最前面的字符“0”,在vbaVarCat调用中没发现读取,但在生成后最前加了一个“0”字符,面只有第一次才加。
知道了算法,接下来就是研究做个注册机,分析了一下程序里的字符串,只有这一组:
2 (左取字符为2个)0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C
全是由十六进制字符,于是用刚学一半的C++试着编了一个算法:

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <sstream>
 
using namespace std;
 
string kb="0123456789*#";
int kb_dec[]={48,49,50,51,52,53,54,55,56,57,42,35};
int kb_hex[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
string hexlist="0123456789ABCDEF";
int key_num=2;
string key="0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C";
 
int hexstr_to_dec(const string s) //转16进制两位字符到十进制数
        {
        int a,b;
        a=hexlist.find(s[0]);
        b=hexlist.find(s[1]);
        return a*16+b;
        }
void main()  
        {
        int key_value;
        int base_value;
        string psword;
        char p;
        string key_str=key.substr(1,2);  //取Key的二、三位
        key_value=hexstr_to_dec(key_str);
         
        for(int x=1;x<=9;x++)                //确定公共值base_value                
        {
                for(int y=0;y<=9;y++)
                    {
                        if (y+x*10+kb_dec[x]==key_value)
                        {
                        base_value=x*10+y;
                        break;
                        }
                        }
        }
        cout<<"公共值:"<<base_value<<endl;
        for(int x=1;x<key.length();x+=2)          /*计算 注册码 部分*/
                {
                key_str=key.substr(x,2);
                key_value=hexstr_to_dec(key_str);
                p=(char)(key_value-base_value);
                psword=psword+p;
                }
        cout<<"password:"<<psword<<endl;
        system("pause");

Image 6.png
至此分析完成,我还用C++写了一个更长的程序,不用穷举的方法计算取1-8位时验证计算,因为刚学的原因,程序最终还是不完善,程序乱的没法贴上来。
【想法】:VB Decompiler分析得不错,可惜没写过OD或X64DBG的插件,等有时间找点资料学一学,把VB Decompiler分析内容加到调试器里,分析起来就方便多了。

免费评分

参与人数 6威望 +1 吾爱币 +12 热心值 +6 收起 理由
海天一色001 + 1 + 1 我很赞同!
Sound + 1 + 8 + 1 已经处理,感谢您对吾爱破解论坛的支持!
孤独之悔 + 1 + 1 已答复!
WYWZ + 1 + 1 热心回复!
Glimmer + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
木子木泗 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

luziye233 发表于 2018-4-14 00:23
哦还有还有,我自己在分析算法的时候只能分析出来大致的情况,所以和你的算法感觉有一点小差别。我目前还只进了一个register,发现我们的汇编代码有一些小差别,主要是我这个每个字符加的基数就只是字符串的第一个字符(额怎么说呢,数字版的这个数据吧)。有点郁闷,不知道是我分析错了,还是被软件作者坑了。。。
 楼主| pk8900 发表于 2018-4-14 08:10
luziye233 发表于 2018-4-14 00:23
哦还有还有,我自己在分析算法的时候只能分析出来大致的情况,所以和你的算法感觉有一点小差别。我目 ...

不要郁闷,VB的程序就是不好弄,因为VB程序数据结构在内存中的特殊性,所以调试起来很不好弄,在VB Decompiler Pro中找到关键位置,然后OD跟踪,会省些时间。
jun57663796 发表于 2017-6-22 01:38
ryan515 发表于 2017-6-22 06:29
虽然看不懂,但很厉害滴赶脚、
拉风的蚂蚁 发表于 2017-6-22 09:21
感觉很厉害的样子,留个爪慢慢看
lyxi841213 发表于 2017-6-22 09:37 来自手机
呵呵看不懂
孤独之悔 发表于 2017-6-22 16:11

感谢 大佬
HONGYC 发表于 2017-6-23 10:40
初学 能达到这种程度已经很不错了 我学的时候傻傻分不清,加油!
世间自在王佛 发表于 2017-6-23 19:15
不明觉厉
jingcard 发表于 2018-2-2 20:05
学习一下。。。。。。。。。
luziye233 发表于 2018-4-14 00:04
请问od或者其他反编译器有没有什么能很好的查看地址的方法,用of的时候老是每一步去数据窗口跟随去看有点小昏还浪费时间
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-29 20:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表