腾讯逆向分析训练题之高强度版???
本帖最后由 BeneficialWeb 于 2020-11-29 15:05 编辑# 简介
最近向某群里网友索要了他最近一两天正在做的一道腾讯面试题。
首先是一道经典的MFC程序。
首先图一表明这来自某训练题集。隐藏了标题后,直接成为了面试题。不知道题集有没有可能贡献出来给论坛的人玩玩。
拖入IDA:
作者: feifeicao
哈哈哈,不认识。
不管了,开始盘。
# 正文:
拖入不带反调试的od,直接F9,发现无法启动到界面。有反调试。
是否回收站呢,绝不可能!重新启动,从入口点慢慢看。
这里看到检测调试器标志位后,无论调试还是不存在调试,他都会重新设置值,并在函数中检测这个值,是否被一些反反调试插件给清0了。
所以他肯定读取了这个标志位,然后引用一下sub_403F00,发现了这个函数。
当然还发现其他检测函数
这里几处都打上补丁dump出来一个exe
```assembly
004010B9 | 90 | NOP |
004010BA | 90 | NOP |
004010BB | 90 | NOP |
```
```assembly
00401116 | 90 | NOP |
00401117 | 90 | NOP |
00401118 | 90 | NOP |
```
```assembly
004010E3 | B0 00 | mov al,0 |
```
```assembly
00401081 | B0 00 | mov al,0 |
```
重新调试打完补丁的进程,调试器启动他发现界面出来了,但还是不正常。
然后过了几秒,又退出来了。
估计对话框绘制里有检测,一般MFC的消息函数里都会先调用MFC提供的原来的函数**CDialog::OnPaint**,交叉引用这个函数。找到了函数**sub_401840**
这几个都是,直接函数尾部下断,哪个eax返回了1,盘哪个。打上补丁。
这几个函数我大致跟了一下。
有的检测这里syscall是否被接管,也就是第一个字节是否被inline hook为了**E9**
有的偷了点ntdll的代码过来跑,有**ZwQuerySection**,**ZwQuerySystemInformation**,**ZwQueryInformationProcess**,**ZwQueryObject**等,大部分调用后会判断一些NTSTATUS status的返回值是不是一些值。大部分都拿来检测反反调试插件的。应该是插件的返回值对应不上。我就没管了。
有的偷过来了之后,还把代码加了花花,不过很短,通过**mov eax,19**, 然后在ntdll.dll 搜索二进制 B8 19 00 00 00,还是可以知道调用的是哪个**Nt**函数。
走到最后,我又打了两个补丁。在我本机上,就可以创建调试了。因为其他检测函数在ret后eax都是0,就没管。
```assembly
004038B3 | 90 | nop |
004038B4 | 90 | nop |
004038B5 | 8B85 D4EFFFFF | mov eax,dword ptr ss: |
004038BB | 8378 0C 01 | cmp dword ptr ds:,1 |
004038BF | 90 | nop |
004038C0 | 90 | nop |
```
接下来是算法部分,在算法流程函数里,他故意制造了一些异常来导致函数流程不能被IDA F5. 这里贴一处。
这里会用到代码的机器码拿来加密用户名,所以导致我之前在明文比较的地方打补丁获取注册码失败,得到的注册码是错的。
```assembly
00401C1A | 81BD 44F7FFFF 60090 | cmp dword ptr ss:,960 |
00401C24 | 7D 1D | jge x32_dump_3.401C43 |
00401C26 | 8B85 44F7FFFF | mov eax,dword ptr ss: |
00401C2C | 8B8D 4CF7FFFF | mov ecx,dword ptr ss: |
00401C32 | 8B95 48F7FFFF | mov edx,dword ptr ss: |
00401C38 | 331481 | xor edx,dword ptr ds: | 401b99往后960都会重新拿来与加解密相关
00401C3B | 8995 48F7FFFF | mov dword ptr ss:,edx |
00401C41 | EB C8 | jmp x32_dump_3.401C0B |
00401C43 | C785 D8FBFFFF 00000 | mov dword ptr ss:,0 |
```
他的长度判断,也不用字符串长度,用缓冲区的固定位置的字符,和后一个字符是否是结尾**\0**来确定。
```assembly
00401E1B | 0FBE95 DFF7FFFF | movsx edx,byte ptr ss: | 用户名长度限制为8
00401E22 | 85D2 | test edx,edx |
00401E24 | 74 0B | je x32_dump_3.401E31 |
00401E26 | 0FBE85 E0F7FFFF | movsx eax,byte ptr ss: |
00401E2D | 85C0 | test eax,eax |
00401E2F | 74 05 | je x32_dump_3.401E36 |
00401E31 | E9 DD030000 | jmp x32_dump_3.402213 |
00401E36 | 0FBE8D F7FBFFFF | movsx ecx,byte ptr ss: | key长度限制为24
00401E3D | 85C9 | test ecx,ecx |
00401E3F | 74 0B | je x32_dump_3.401E4C |
00401E41 | 0FBE95 F8FBFFFF | movsx edx,byte ptr ss: |
```
开始加密UserName。
```assembly
00401E84 | 8995 3CF7FFFF | mov dword ptr ss:,edx |
00401E8A | 83BD 3CF7FFFF 08 | cmp dword ptr ss:,8 | 循环次数
00401E91 | 7D 7E | jge x32_dump_3.401F11 |
00401E93 | 8B85 3CF7FFFF | mov eax,dword ptr ss: |
00401E99 | 0FBE8C05 D8F7FFFF | movsx ecx,byte ptr ss:|
00401EA1 | 338D 3CF7FFFF | xor ecx,dword ptr ss: |
00401EA7 | 8B95 3CF7FFFF | mov edx,dword ptr ss: |
00401EAD | 888C15 D8F7FFFF | mov byte ptr ss:,cl |
00401EB4 | 8B85 3CF7FFFF | mov eax,dword ptr ss: |
00401EBA | 0FBE8C05 D8F7FFFF | movsx ecx,byte ptr ss:|
00401EC2 | 8B95 DCFBFFFF | mov edx,dword ptr ss: |
00401EC8 | 0395 3CF7FFFF | add edx,dword ptr ss: |
00401ECE | 0FBE02 | movsx eax,byte ptr ds: |
00401ED1 | 33C8 | xor ecx,eax |
00401ED3 | 8B95 3CF7FFFF | mov edx,dword ptr ss: |
00401ED9 | 888C15 D8F7FFFF | mov byte ptr ss:,cl |
00401EE0 | 8B85 3CF7FFFF | mov eax,dword ptr ss: |
00401EE6 | 0FBE8C05 D8F7FFFF | movsx ecx,byte ptr ss:|
00401EEE | 8B95 98F7FFFF | mov edx,dword ptr ss: |
00401EF4 | 0395 3CF7FFFF | add edx,dword ptr ss: |
00401EFA | 0FBE02 | movsx eax,byte ptr ds: |
00401EFD | 33C8 | xor ecx,eax |
00401EFF | 8B95 3CF7FFFF | mov edx,dword ptr ss: |
00401F05 | 888C15 D8F7FFFF | mov byte ptr ss:,cl |
00401F0C | E9 6AFFFFFF | jmp x32_dump_3.401E7B |
00401F11 | 8D85 D8F7FFFF | lea eax,dword ptr ss: |
00401F17 | 8985 58F7FFFF | mov dword ptr ss:,eax |
00401F1D | 8B8D 58F7FFFF | mov ecx,dword ptr ss: |
00401F23 | 8B11 | mov edx,dword ptr ds: |
00401F25 | 3395 48F7FFFF | xor edx,dword ptr ss: |
00401F2B | 8B85 58F7FFFF | mov eax,dword ptr ss: |
00401F31 | 8910 | mov dword ptr ds:,edx |
00401F33 | 8B8D 58F7FFFF | mov ecx,dword ptr ss: |
00401F39 | 8B51 04 | mov edx,dword ptr ds: |
00401F3C | 3395 48F7FFFF | xor edx,dword ptr ss: |
00401F42 | 8B85 58F7FFFF | mov eax,dword ptr ss: |
00401F48 | 8950 04 | mov dword ptr ds:,edx |
00401F4B | C685 5CF7FFFF 00 | mov byte ptr ss:,0 |
00401F52 | 33C9 | xor ecx,ecx |
00401F54 | 898D 5DF7FFFF | mov dword ptr ss:,ecx |
00401F5A | 898D 61F7FFFF | mov dword ptr ss:,ecx |
00401F60 | 898D 65F7FFFF | mov dword ptr ss:,ecx |
00401F66 | 898D 69F7FFFF | mov dword ptr ss:,ecx |
00401F6C | 898D 6DF7FFFF | mov dword ptr ss:,ecx |
00401F72 | 898D 71F7FFFF | mov dword ptr ss:,ecx |
00401F78 | 888D 75F7FFFF | mov byte ptr ss:,cl |
00401F7E | C785 38F7FFFF 00000 | mov dword ptr ss:,0 |
00401F88 | EB 0F | jmp x32_dump_3.401F99 |
00401F8A | 8B95 38F7FFFF | mov edx,dword ptr ss: |
00401F90 | 83C2 01 | add edx,1 |
00401F93 | 8995 38F7FFFF | mov dword ptr ss:,edx |
00401F99 | 83BD 38F7FFFF 08 | cmp dword ptr ss:,8 |
00401FA0 | 0F8D A4010000 | jge x32_dump_3.40214A |
00401FA6 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
00401FAC | 0FBE8405 D8F7FFFF | movsx eax,byte ptr ss:|
00401FB4 | 25 E0000000 | and eax,E0 |
00401FB9 | 99 | cdq |
00401FBA | 83E2 1F | and edx,1F |
00401FBD | 03C2 | add eax,edx |
00401FBF | C1F8 05 | sar eax,5 |
00401FC2 | 8885 37F7FFFF | mov byte ptr ss:,al |
00401FC8 | 8B8D 38F7FFFF | mov ecx,dword ptr ss: |
00401FCE | 0FBE840D D8F7FFFF | movsx eax,byte ptr ss:|
00401FD6 | 83E0 1C | and eax,1C |
00401FD9 | 99 | cdq |
00401FDA | 83E2 03 | and edx,3 |
00401FDD | 03C2 | add eax,edx |
00401FDF | C1F8 02 | sar eax,2 |
00401FE2 | 8885 35F7FFFF | mov byte ptr ss:,al |
00401FE8 | 8B95 38F7FFFF | mov edx,dword ptr ss: |
00401FEE | 0FBE8415 D8F7FFFF | movsx eax,byte ptr ss:|
00401FF6 | 83E0 03 | and eax,3 |
00401FF9 | 8885 36F7FFFF | mov byte ptr ss:,al |
00401FFF | 8B85 38F7FFFF | mov eax,dword ptr ss: |
00402005 | 99 | cdq |
00402006 | B9 03000000 | mov ecx,3 |
0040200B | F7F9 | idiv ecx |
0040200D | 83FA 02 | cmp edx,2 |
00402010 | 75 5A | jne x32_dump_3.40206C |
00402012 | 0FB695 36F7FFFF | movzx edx,byte ptr ss: |
00402019 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
0040201F | 6BC0 03 | imul eax,eax,3 |
00402022 | 8A8C15 9CF7FFFF | mov cl,byte ptr ss: |
00402029 | 888C05 5CF7FFFF | mov byte ptr ss:,cl |
00402030 | 0FB695 37F7FFFF | movzx edx,byte ptr ss: |
00402037 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
0040203D | 6BC0 03 | imul eax,eax,3 |
00402040 | 8A8C15 C4F7FFFF | mov cl,byte ptr ss: |
00402047 | 888C05 5DF7FFFF | mov byte ptr ss:,cl |
0040204E | 0FB695 35F7FFFF | movzx edx,byte ptr ss: |
00402055 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
0040205B | 6BC0 03 | imul eax,eax,3 |
0040205E | 8A8C15 8CF7FFFF | mov cl,byte ptr ss: |
00402065 | 888C05 5EF7FFFF | mov byte ptr ss:,cl |
0040206C | 8B85 38F7FFFF | mov eax,dword ptr ss: |
00402072 | 99 | cdq |
00402073 | B9 03000000 | mov ecx,3 |
00402078 | F7F9 | idiv ecx |
0040207A | 83FA 01 | cmp edx,1 |
0040207D | 75 5A | jne x32_dump_3.4020D9 |
0040207F | 0FB695 37F7FFFF | movzx edx,byte ptr ss: |
00402086 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
0040208C | 6BC0 03 | imul eax,eax,3 |
0040208F | 8A8C15 CCF7FFFF | mov cl,byte ptr ss: |
00402096 | 888C05 5CF7FFFF | mov byte ptr ss:,cl |
0040209D | 0FB695 35F7FFFF | movzx edx,byte ptr ss: |
004020A4 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
004020AA | 6BC0 03 | imul eax,eax,3 |
004020AD | 8A8C15 84F7FFFF | mov cl,byte ptr ss: |
004020B4 | 888C05 5DF7FFFF | mov byte ptr ss:,cl |
004020BB | 0FB695 36F7FFFF | movzx edx,byte ptr ss: |
004020C2 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
004020C8 | 6BC0 03 | imul eax,eax,3 |
004020CB | 8A8C15 9CF7FFFF | mov cl,byte ptr ss: |
004020D2 | 888C05 5EF7FFFF | mov byte ptr ss:,cl |
004020D9 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
004020DF | 99 | cdq |
004020E0 | B9 03000000 | mov ecx,3 |
004020E5 | F7F9 | idiv ecx |
004020E7 | 85D2 | test edx,edx |
004020E9 | 75 5A | jne x32_dump_3.402145 |
004020EB | 0FB695 35F7FFFF | movzx edx,byte ptr ss: |
004020F2 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
004020F8 | 6BC0 03 | imul eax,eax,3 |
004020FB | 8A8C15 CCF7FFFF | mov cl,byte ptr ss: |
00402102 | 888C05 5CF7FFFF | mov byte ptr ss:,cl |
00402109 | 0FB695 36F7FFFF | movzx edx,byte ptr ss: |
00402110 | 8B85 38F7FFFF | mov eax,dword ptr ss: |
00402116 | 6BC0 03 | imul eax,eax,3 |
00402119 | 8A8C15 84F7FFFF | mov cl,byte ptr ss: |
00402120 | 888C05 5DF7FFFF | mov byte ptr ss:,cl |
00402127 | 0FB695 37F7FFFF | movzx edx,byte ptr ss: |
0040212E | 8B85 38F7FFFF | mov eax,dword ptr ss: |
00402134 | 6BC0 03 | imul eax,eax,3 |
00402137 | 8A8C15 9CF7FFFF | mov cl,byte ptr ss: |
0040213E | 888C05 5EF7FFFF | mov byte ptr ss:,cl |
00402145 | E9 40FEFFFF | jmp x32_dump_3.401F8A |
0040214A | E8 111C0000 | call x32_dump_3.403D60 |
```
加密完成后,接着一段花指令,就来到了比较。
```assembly
004021E6 | 8DBD E0FBFFFF | lea edi,dword ptr ss: | 用户输入的注册码
004021EC | 8DB5 5CF7FFFF | lea esi,dword ptr ss: | 算出来的注册码
004021F2 | 33D2 | xor edx,edx |
004021F4 | F3:A7 | repe cmpsd | 明文比较
004021F6 | 75 14 | jne x32_dump_3.40220C |
004021F8 | 6A 00 | push 0 |
004021FA | 6A 00 | push 0 |
004021FC | 68 547D4200 | push x32_dump_3.427D54 |
00402201 | 8B8D 30F7FFFF | mov ecx,dword ptr ss: |
00402207 | E8 488B0000 | call x32_dump_3.40AD54 | 注册成功对话框
0040220C | C745 FC FEFFFFFF | mov dword ptr ss:,FFFFFFFE |
```
别看这里是明文比较,下图是我打没注意前面直接补丁出来直接用他的弹窗函数得出来的serial来是不对的。因为他使用了代码段的机器码进行加密用户名。代码被篡改的话,加密出来就是错的。
既然做了这个鬼把戏,我就想起来了**VEH** hook相关的知识,上CE VEH调试器
然后在004021F2 下断后,断下后试了一下,就获取到了真码。
如果有人想写出一个注册机,建议用CE VEH调试器,扣取正确的数据, 把算法逆完。本程序附件再后面。
至此,这个CrackMe结束。
再测试一个用户名
鸭子咯咯哒~ 发表于 2020-12-1 19:33
第一步拖入od后咋看的调试器标志位那个代码咋弄的
CDialog::DoModal,这是模态对话框的启动函数。先引用这个函数,然后看为什么启动不起来呀。 本帖最后由 钞sir 于 2020-11-29 16:02 编辑
第一步检测调试器标志位怎么找.... tx的都被你干了 这么强 感谢大佬分享{:1_921:} 学习一下,感谢分享 作者是我们风控组组长{:301_997:} 学习一下,谢谢分享 学习学习{:301_998:} 大佬太强了 不错不错,这种教程最有学习意义