学破解第120天,《160个CrackerMe之003》学习
## 学破解第120天,《160个CrackerMe之003》学习前言:
  从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。
  2017年12月16日,通过19元注册码注册论坛账号,开始做伸手党,潜水一年多,上来就是找软件。(拿论坛高大上的软件出去装X)
  2018年8月某一天,报名了华中科技大学网络教育本科(计算机科学与技术专业)2018级秋季。(开始提升学历)
  2019年6月17日,不愿再做小菜鸟一枚,开始零基础学习破解。(感谢小糊涂虫大哥在我刚开始学习脱壳时,录制视频解答我的问题)
  2020年7月7日,感谢H大对我的鼓励,拥有了第一篇获得优秀的文章。(接下来希望学习逆向,逆天改命)
  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:(https://www.52pojie.cn/thread-1208234-1-1.html)
立帖为证!--------记录学习的点点滴滴
### 0x1分析题目
  1.打开软件,发现有弹窗,显示数秒钟
  2.然后出现name/serial验证
  3.也就是说,我们需要解决以上两个地方才能算破解成功
### 0x2寻找爆破点
  1.看到弹窗,虽然是VB程序,还是想试试messageBOX行不行,显然又不行了,那么该从哪方面寻找突破口呢?
  2.实现想不到怎么去这个弹窗了,那就先去看看name/serial,输入52pojie和123456,有一个弹窗告诉我输入错误,我很想messageBOX回溯,但是无奈不行啊,只能下GetDlgItemTextA断点跟踪,发现也不行。
  3.算了算了,直接错误提示搜索字符串定位到了关键跳,爆破点
```
00408677 . /74 62 je short $ROI5LTX.004086DB
00408679 . |8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;msvbvm50.__vbaStrCat
0040867F . |68 C06F4000 push $ROI5LTX.00406FC0 ;You Get It
00408684 . |68 DC6F4000 push $ROI5LTX.00406FDC ; /\r\n
00408689 . |FFD6 call esi ; \__vbaStrCat
0040868B . |8BD0 mov edx,eax
0040868D . |8D4D E8 lea ecx,dword ptr ss:
00408690 . |FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
00408696 . |50 push eax
00408697 . |68 E86F4000 push $ROI5LTX.00406FE8 ;KeyGen It Now
```
### 0x3分析算法
  1.有了爆破点还是去段首004080F0 F2下断点,成功的断了下来,然后开始单步分析
```
004081F2 .50 push eax ; /52pojie
004081F3 .8B1A mov ebx,dword ptr ds: ; |计算长度
004081F5 .FF15 F8B04000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>] ; \__vbaLenBstr
004081FB .8BF8 mov edi,eax ;edi是52pojie的长度7
004081FD .8B4D E8 mov ecx,dword ptr ss: ;ecx是52pojie
00408200 .69FF 385B0100 imul edi,edi,0x15B38 ;7*15B38=97E88
00408206 .51 push ecx ; /取第name一个字符5
00408207 .0F80 B7050000 jo $ROI5LTX.004087C4 ; |
0040820D .FF15 0CB14000 call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBstr_516>]; \rtcAnsiValueBstr
00408213 .0FBFD0 movsx edx,ax ;0x35给edx
00408216 .03FA add edi,edx ;97E88+0x35=97EBD
00408218 .0F80 A6050000 jo $ROI5LTX.004087C4
0040821E .57 push edi ;转成十进制622269
0040821F .FF15 F4B04000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>] ;msvbvm50.__vbaStrI4
```
  2.上面的计算还是和前面两个CM一样的套路,继续单步,发现622269变成了622271,换数据输入,经过多次不同的值作比较,可以发现就是加了2。
```
00408333 .8BD0 mov edx,eax ;622271比之前多加了2
00408335 .8D4D E4 lea ecx,dword ptr ss:
```
  3.接下来开始单步跟,发现又将622271*3了。
```
004083F3 .8B19 mov ebx,dword ptr ds: ;622271
004083F5 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>] ;msvbvm50.__vbaR8Str
004083FB .DC0D 10104000 fmul qword ptr ds: ;622271*3=1866813
00408401 .83EC 08 sub esp,0x8
00408404 .DC25 18104000 fsub qword ptr ds: ;1866813-2=1866811
```
  4.继续单步走,总之就是注意那一串字符串的变化,然后发现值又变了
```
004084DC .52 push edx
004084DD .8B19 mov ebx,dword ptr ds: ;1866811
004084DF .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>] ;msvbvm50.__vbaR8Str
004084E5 .DC25 20104000 fsub qword ptr ds: ;1866811 - (-15)=1866826
```
  5.虽然找到了真码,可是算法在哪呢?根据一路走过来的流程,可以看到真码由AKA-拼接682770构成,那么682770从哪来的?为什么没有看到获取52pojie的地方呢?是不是还是不能用Windows API断点?算了,不要紧,反正已经定位到了关键比较函数了,在往上回溯就行了,去段首F2下断点,然后单步开始跟,看看有没有线索
```
004085C8 .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresultCheckObj>] ;msvbvm50.__vbaHresultCheckObj
004085CE >8B45 E8 mov eax,dword ptr ss: ;取出serial 123456
004085D1 .50 push eax
004085D2 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>] ;msvbvm50.__vbaR8Str
004085D8 .8B4D E4 mov ecx,dword ptr ss:
004085DB .DD9D 1CFFFFFF fstp qword ptr ss: ;123456赋值给0012F3FC
004085E1 .51 push ecx ;1866826
004085E2 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>] ;msvbvm50.__vbaR8Str
```
  6.这个CM说实话,我没有找到后面比较的地方,只看到test ah,0x40结果为0,然后清空esi,如果esi为0就跳向失败。
### 0x4注册机的编写
  1.算法部分:
name的长度*15B38+name的第一个字符,然后在加上2,接着乘以3,最后再-2,然后减去-15,得到真正的serial。
  2.代码实现:
```
package cpyutil.xiao.cai.niao.com;
import java.util.Scanner;
public class Register {
public static void main(String[] args) {
String name;
int code;
String serial;
System.out.println("请输入name(不小于4个字符):");
Scanner sc = new Scanner(System.in);// 初始化一个输入流
name = sc.nextLine();// 从控制台读取输入的字符串
if (name == null || name.length() < 4)// 如果输入的长度小于4退出程序
System.exit(0);
sc.close();// 关闭输入流
code = name.length() * 0x15B38;//将字符串的长度乘以0x15B38
code += name.charAt(0);//加上第一个字符
code += 2;//加2
code *= 3;//乘3
code -= 2;//减2
code -= -15;//减-15
// 将数值转换成字符串
serial = String.valueOf(code);
// 输出正确的serial
System.out.println("生成的serial:");
System.out.println(serial);
}
}
```
输出结果:
请输入name(不小于4个字符):
xiaocainiao
生成的serial:
2933683
  3.验证注册机的效果,输入xiaocainiao和2933683,提示注册成功。
### 0x5总结
  1.这个程序有点小bug,点×之后,窗口关闭了,任务管理器中程序却并没有退出。
  2.和前面的CM套路还是一样的,不过这个汇编代码大部分看不懂,出现了很多浮点数指令。
  3.通过多组数据的输入输出能够确定注册码的计算方法。
  4.不懂VB编程,用windows API对付起来还是有些困难啊,那个NAG弹窗搞不定,就这样吧。
  **PS:善于总结,善于发现,找到分析问题的思路和解决问题的办法。虽然我现在还是零基础的小菜鸟一枚,也许学习逆向逆天改命我会失败,但也有着成功的可能,只要还有希望,就决不放弃!** 吾爱吧52 发表于 2020-7-19 12:01
我也想学安卓逆向破解,不知道从哪里着手学习,请大佬告知。
直接b站搜索安卓逆向,有很多免费的系列视频
PS:我没学过安卓,我是在论坛自学的pc逆向,有零基础入门贴:handshake 欢迎分析讨论交流,吾爱破解论坛有你更精彩! 坐一楼 {:1_893:}佩服佩服佩服佩服 种一棵树,最好的时间是十年前,其次是现在 吾爱破解有你更精彩 我也想学安卓逆向破解,不知道从哪里着手学习,请大佬告知。 大佬用PE查出VMProtect v3.00的壳思路只能用补丁吗?脱壳有没有希望? 顶一下楼主!!!