冥界3大法王 发表于 2021-12-24 18:41

魔镜魔镜告诉我,返回值在哪里修改?让程序自动化“坦白交待”!

本帖最后由 冥界3大法王 于 2021-12-26 11:54 编辑

当某个软件过期来临时:我马上想到以下几句:

福兮祸所伏,祸兮福所倚。风萧萧兮易水寒,壮士一去兮不复返。(你要死了)
费话说完,步入主题:

https://static.52pojie.cn/static/image/hrline/2.gif
工具:

[*]屠龙宝刀:x64dbg
[*]文本编辑器:AkeIPad
[*]编程工具:Delphi 11
[*]法王的脑袋+经验+智慧+幻想

https://static.52pojie.cn/static/image/hrline/2.gif
一般情况下,我们有以下这么多种方法找到过期的关键点:

[*]利用日期类函数下断,Ctrl+F8,顺势向下运行,直至出现弹框提醒或相关窗口等出现
[*]利用注册表类函数。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
[*]暂停法,利用堆栈窗口,栈帧调用地址列表
[*]利用右下角堆栈,临时性历史足迹
[*]利用【启动运行跟踪】
[*]利用Process Monitor/API Monitor/winapioverride抓取系统api函数名
[*]抓取网络数据包
[*]利用看到的可疑关键字+硬件断点或内存断点,断到其上层某个子程序或函数入口处
[*]直接拦截窗口事件
[*]随便找个其上层调用的API或dll中断当跳板继续向下跟
https://static.52pojie.cn/static/image/hrline/2.gif
所以呢,我们就先用传统的
bp GetLocalTime,用来获取当地的当前系统日期和时间的函数下个断点
能断到,但是呢,已经晚了。(就会出现贴子顶上的那张截图
接着是:

顺便点下功能比较

原来付费版这么多功能啊。
因为前面分析过程序主要靠regkey.xml来判断程序是否过期?

当然也跟其他的几个函数有关(如图所示)

显然那些是次要因素
如图所示,重点是粉色区域的那些关键字之一,我们任选一个字符串搜索,并F2下断
Ctrl+F2,Ctrl+F8顺势来到如图所示的地方



当执行到00007FF687E154E6时,程序就会弹框提醒,已经过期!
上面有4个jne,最后的那个如果改成JMP强制跳转,就永远不会过期!
或者让其在不过期时,左边就会出现实现的那条红线


test al, 0x2    //al与2做比较;要是al=2就是授权版(为啥我知道到呢,咱们接着向下看)
test al, 0x4    //al与4做比较;要是al=2就是Lite限定功能版
所以上边的那个call的返回值尤为重要:
也就是下面这句:00007FF687E15498   call <顶上那个多个可疑调用点>   全局重要判断点
所以呢,在00007FF687E15498这里我们要设个断点并F7进入分析下,究竟让哪里al=2才能返回全局注册标志?
00007FF687D84370      | 48:89 | mov qword ptr ss:,rbx          |
00007FF687D84375      | 55    | push rbp                               |
00007FF687D84376      | 56    | push rsi                               |
00007FF687D84377      | 57    | push rdi                               |
00007FF687D84378      | 48:8D | lea rbp,qword ptr ss:         |
00007FF687D84380      | B8 C0 | mov eax,10C0                           |
00007FF687D84385      | E8 F6 | call <sub_7FF687E9C980> |
00007FF687D8438A      | 48:2B | sub rsp,rax                            |
00007FF687D8438D      | 48:8B | mov rax,qword ptr ds:    |
00007FF687D84394      | 48:33 | xor rax,rsp                            |
00007FF687D84397      | 48:89 | mov qword ptr ss:,rax         |
00007FF687D8439E      | 48:8B | mov rbx,rdx                            |
00007FF687D843A1      | 48:8B | mov rdi,rcx                            |
00007FF687D843A4      | 0F57C | xorps xmm0,xmm0                        |
00007FF687D843A7      | F3:0F | movdqu xmmword ptr ss:,xmm0    |
00007FF687D843AD      | 33F6| xor esi,esi                            |
00007FF687D843AF      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D843B4      | 48:8D | lea rdx,qword ptr ss:          |
00007FF687D843B9      | E8 92 | call <sub_7FF687D84550> |
00007FF687D843BE      | 85C0| test eax,eax                           |
00007FF687D843C0      | 0F88| js 7FF687D844F2         |
00007FF687D843C6      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D843CB      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D843D0      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D843D5      | 48:C7 | mov qword ptr ss:,7            |
00007FF687D843DE      | 66:89 | mov word ptr ss:,si            |
00007FF687D843E3      | 44:8D | lea r8d,qword ptr ds:          |
00007FF687D843E7      | 48:8D | lea rdx,qword ptr ds:    | 00007FF687FD7A88:L"InstallationOptions"
00007FF687D843EE      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D843F3      | E8 C8 | call 7FF687D741C0       |
00007FF687D843F8      | 90    | nop                                    |
00007FF687D843F9      | 48:8B | mov rcx,qword ptr ds:          |
00007FF687D843FD      | 48:8B | mov rax,qword ptr ds:             |
00007FF687D84400      | 48:8D | lea rdx,qword ptr ds:         |
00007FF687D84404      | 45:33 | xor r9d,r9d                            |
00007FF687D84407      | 4C:8D | lea r8,qword ptr ss:         |
00007FF687D8440C      | FF90| call qword ptr ds:             |
00007FF687D84412      | 48:89 | mov qword ptr ss:,rax          |
00007FF687D84417      | 48:8B | mov rdx,qword ptr ss:          |
00007FF687D8441C      | 48:83 | cmp rdx,8                              |
00007FF687D84420      | 72 12 | jb 7FF687D84434         |
00007FF687D84422      | 48:8D | lea rdx,qword ptr ds:         |
00007FF687D8442A      | 48:8B | mov rcx,qword ptr ss:          |
00007FF687D8442F      | E8 0C | call 7FF687D74440       |
00007FF687D84434      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D84439      | 48:C7 | mov qword ptr ss:,7            |
00007FF687D84442      | 66:89 | mov word ptr ss:,si            |
00007FF687D84447      | 48:83 | cmp qword ptr ss:,0            |
00007FF687D8444D      | 0F84| je 7FF687D844F2         |
00007FF687D84453      | 48:8D | lea rdi,qword ptr ds:[<&sub_7FF687D8D8 |
00007FF687D8445A      | 48:89 | mov qword ptr ss:,rdi          |
00007FF687D8445F      | 8B442 | mov eax,dword ptr ss:          |
00007FF687D84463      | 48:8B | mov rdx,qword ptr ss:          |
00007FF687D84468      | 2BC2| sub eax,edx                            |
00007FF687D8446A      | 0F57C | xorps xmm0,xmm0                        |
00007FF687D8446D      | 0F114 | movups xmmword ptr ss:,xmm0    |
00007FF687D84472      | C6442 | mov byte ptr ss:,1             |
00007FF687D84477      | B9 10 | mov ecx,10                           |
00007FF687D8447C      | 3BC1| cmp eax,ecx                            |
00007FF687D8447E      | 0F4FC | cmovg eax,ecx                        |
00007FF687D84481      | 4C:63 | movsxd r8,eax                        |
00007FF687D84484      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D84489      | E8 1D | call <JMP.&memmove>                  |
00007FF687D8448E      | C6442 | mov byte ptr ss:,0             |
00007FF687D84493      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D84498      | E8 73 | call <sub_7FF687DACE10> |
00007FF687D8449D      | 90    | nop                                    |
00007FF687D8449E      | 48:8D | lea rdx,qword ptr ss:          |
00007FF687D844A3      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D844A8      | E8 53 | call <sub_7FF687DAC200> |
00007FF687D844AD      | 48:8D | lea rdx,qword ptr ss:          |
00007FF687D844B2      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D844B7      | E8 54 | call <sub_7FF687DAD010> |
00007FF687D844BC      | 48:8B | mov rax,qword ptr ss:          |
00007FF687D844C1      | 48:A9 | test rax,FFFFFFFFFFFF0000            |
00007FF687D844C7      | 75 19 | jne 7FF687D844E2      |
00007FF687D844C9      | 25 FF | and eax,3FF                            |
00007FF687D844CE      | 8903| mov dword ptr ds:,eax             |
00007FF687D844D0      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D844D5      | E8 56 | call <sub_7FF687DACE30> | 与注册码有关
00007FF687D844DA      | 90    | nop                                    |
00007FF687D844DB      | 48:89 | mov qword ptr ss:,rdi          |
00007FF687D844E0      | EB 16 | jmp 7FF687D844F8      |
00007FF687D844E2      | 48:8D | lea rcx,qword ptr ss:          |
00007FF687D844E7      | E8 44 | call <sub_7FF687DACE30> | 与注册码有关
00007FF687D844EC      | 90    | nop                                    |
00007FF687D844ED      | 48:89 | mov qword ptr ss:,rdi          |
00007FF687D844F2      | C703| mov dword ptr ds:,200             |
00007FF687D844F8      | 48:8B | mov rcx,qword ptr ss:          |
00007FF687D844FD      | 48:85 | test rcx,rcx                           |
00007FF687D84500      | 74 1B | je 7FF687D8451D         |
00007FF687D84502      | 48:8B | mov rdx,qword ptr ss:          |
00007FF687D84507      | 48:2B | sub rdx,rcx                            |
00007FF687D8450A      | E8 31 | call 7FF687D74440       |
00007FF687D8450F      | 0F57C | xorps xmm0,xmm0                        |
00007FF687D84512      | 48:89 | mov qword ptr ss:,rsi          |
00007FF687D84517      | F3:0F | movdqu xmmword ptr ss:,xmm0    |
00007FF687D8451D      | 48:8B | mov rax,rbx                            |
00007FF687D84520      | 48:8B | mov rcx,qword ptr ss:         |
00007FF687D84527      | 48:33 | xor rcx,rsp                            |
00007FF687D8452A      | E8 21 | call 7FF687E95E50       |
00007FF687D8452F      | 48:8B | mov rbx,qword ptr ss:      |
00007FF687D84537      | 48:81 | add rsp,10C0                           |
00007FF687D8453E      | 5F    | pop rdi                              |
00007FF687D8453F      | 5E    | pop rsi                              |
00007FF687D84540      | 5D    | pop rbp                              |
00007FF687D84541      | C3    | ret                                    |

切换武器到AkeIPad
右击菜单【选择 =》筛选行】

筛选之后,我们就马上知道有13个call(子程序)的里边(修改)或是外面(临近处修改)

接下来,我们再接着标色筛选
找到相同的标色处理

所以呢? 我们仅凭重复出现的次数来猜:
00007FF687D8442F      | E8 0C | call 7FF687D74440注册码验证后又回到这里00007FF687D844D5      | E8 56 | call <sub_7FF687DACE30> 这两句是不是挨得很近?当然你不能仅这样看,你还得结合上下文
00007FF687D844E7      | E8 44 | call <sub_7FF687DACE30>试想,是不是心肝宝贝,你才会去验证多次?倍受关怀?00007FF687D8450A      | E8 31 | call 7FF687D74440   
call 7FF687D74440和call7FF687DACE30 就非常可疑了!
为啥上面两个跟注册码有关呢?请看下面:

00007FF687D8442F      | E8 0C00FFFF               | call 7FF687D74440         注册码验证后又回到这里
当点击关于时,又会断在上面这句!
所以呢?改修改哪一句呢?

粉色圈1 到 圈 20 ?楼下的道友请作答~~ {:301_986:}
要是你的话,你会选择在哪一句上修改呢? 为什么?
不能直接告诉你,不能直接揭晓答案,还是让魔镜来告诉你吧。
接下来,请来接着往下看。



所以呢 call 0x00007FF687D84370 这个里边所有RAX的值如果能够被统统记录下来(AL是它的最低位)
自动告诉我们哪里。。。哪里变化了。。。是不是问题就解决了呢?{:301_986:}
00007FF687E15498   call <顶上那个多个可疑调用点>      | 全局重要判断点【所以,我们可以尝试在这里使用看门狗功能】





当然你也可以用命令完成: AddWatch 和 SetWatchdog,具体自己看帮助吧。

当你向下F8 单步时,程序就会自己中断下来,但是上次的信息就被覆盖掉了。
感觉 这个功能吧,是有些想法的,然而却并不实用:

[*]因为程序每次会被断下来
[*]上次的记录被覆盖掉
[*]不能保存多次记录
所以呢,知道就好,知道这是个鸡肋的功能,请无视吧。

https://static.52pojie.cn/static/image/hrline/2.gif
接下来,让我们再换个方式玩玩:

这次我们玩玩【步过直到满足条件。。。】另一个也是同样道理,不再赘述。

打开界面后,是这个样子的。不知大家是否还记得OD中的那个shift+F4(条件断点设置)?

其实这个设置的界面中实现的功能要比OD的那个强大一万倍。
暂停条件: 就是程序中断下来的条件 或 表达式   ;0就是永远不中断,1则永远断下
比如我们可以填:rip = 00007FF687E15490

确定之后,就停留在 00007FF687E15490这行了(跟我们在此行F2效果相等)

帮助中是这样写的,如果你非得写成rip == 00007FF687E15490 能成功断下来才怪!
不知哪个天煞的给翻译的叫【日志文本】这名称起的很不直观和直白,所以正解该翻译为:【日志窗口中的记录下来的文本】{:301_993:}
你看看,经过法王同学一个点睛之笔,又好理解,又亲切了很多,是不是? {:301_997:}
虽然长点,但是呢,易于理解和消化啊。
比如呢,
我们想把RAX的数值记录下来
当前地址呢,也得记录下来。
所以呢?
先弹个框测试一下:
msg 当前地址:{RIP}▲RAX值为:{RAX} 【EIP或RIP用于得到32位程序或64位程序的当前行的VA地址】
看不明白的!搜索我以前做的x64dbg视频教程。或帮助中表达式与格式化章节。

没问题吧。

00007FF687E1549D再设个断点,其他断点全部禁用点!
然后Alt+L来到日志窗口中

就得到了那个子程序中所有修改RAX值的地址了。
然后再动动脑袋想一起? 对一个软件的注册标志而言,一般只有 :
-1 01 2 3 。。。。肯定不会超过10(1 般情况下,当然也有特殊的,这里只是相对而言,你不能说成绝对,否则就会犯错误!)

竟然有516行之多。
先观察一下数据:一般都是 1 和 0 结尾的,其他都是一大长串
我们用一下正则表达式: RAX值为:0$和RAX值为:1$ ;再用过滤掉重复的
上边的算法有误,故此黑底黑字屏蔽掉!没有删除线,凑合用吧。全当是一种构想好了。
这个东西列出的多与少?

[*]与到底是Ctrl+F8 或 Ctrl+F7
[*]前后分析选择的位置
[*]有效地址的判断方法都有关系
https://static.52pojie.cn/static/image/hrline/2.gif
费话说的差不多了,该请出本贴中想要阐明的观点了:

这就是用Delphi开发的的穷举爆破补丁批量生成器。其实呢,该工具的雏形可以追述到很多年前。只不过呢,第一个版本是用按键精灵来完成的。
那时候最初的假设是:WinRAR有穷举key生成器、安卓上也有幸运破解器。为啥逆向爆破时没有此类工具呢? 所以就试着开始写着玩了。
后来呢,我又换用AutoHotkey写了一个相对功能上比较全面的版本(但是输出的补丁数量可以直接写爆你的硬盘,,其稳定性也不好)后来呢。。
随着编程技术的提高,我又用Delphi写了最后一个版本。思路也变了,何必列出所有的可能,列出所有的地址,把最可疑的地址列表填入,岂不中奖概率直线提升?

在第一个界面中:

[*]主要为了处理EXE 和 DLL文件
[*]并设置了保存相关的配置到配置文件中
[*]保存补丁的编号(类似于WinRAR中的处理进度)
二和三界面仍然在资料制作
第四个界面主要按各中需求输出

其实呢? 我觉得上面都不算啥,最难搞的就是最后一个界面了。

[*]如何判断最终输出的那个【补丁_168.exe】达标了呢?若是一部分有效果,另一部分搞得程序崩溃了,到底算是爆破成功,还是不成功呢?
[*]当一个非法的PE文件被输出并被运行时,如何判断它现在运行正常,或不正常呢?也进到界面了,也弹出某种出错的警告了。
[*]各种未知的可能性的补丁都有可能被输出出来;所以那个AHK版的程序最终的完美版也没有搞出来。
所以综上所述:我放弃了原有的那种全自动化判断补丁到底哪个是有效的方法方案;而改用活人+有限数量补丁输出方式;还是活人验证更为靠谱一些。
未来计算机领域,或许会出现某种更完善的爆破体系。
最终,我们只需要把 00007FF7D56F4370至00007FF7D56F4541的地址列表填入我们自己的程序,就会自动化的输出补丁列表了。

我鼠标操作几下,瞬间就自动化输出了一堆可疑地址的补丁文件了。{:301_999:}

不苦小和尚 发表于 2021-12-24 20:04

冥界3大法王 发表于 2021-12-24 19:59
@不苦小和尚
https://wwi.lanzouy.com/iqtQtxxwita

万分感谢,以后多多支持你{:301_978:}

冥界3大法王 发表于 2022-1-14 09:45

Hmily 发表于 2022-1-11 17:26
好复杂,真没看懂啥意思。。。

@Hmily
其实要表达的意思很简单:
1.得知大事件点上al=2时,则会是注册版
2.上面那个call F7进入之后,搞不清具体在哪句上修改成mov al, 2
3.故此编程输出若干个补丁,以实测哪条上会得到预期值
在没人工找到最佳修改点的方法下,想到的解决策略。

诗木 发表于 2021-12-24 19:13

{:301_998:}大法王的前排

hanlaoshi 发表于 2021-12-24 19:28

这软件也太棒了,看门狗yyds

不苦小和尚 发表于 2021-12-24 19:40

看上法王你那个AkeIPad编辑器了,能不能私发我一份啊

咬字分开念 发表于 2021-12-24 19:51

用od不可以吗

冥界3大法王 发表于 2021-12-24 19:59

不苦小和尚 发表于 2021-12-24 19:40
看上法王你那个AkeIPad编辑器了,能不能私发我一份啊

@不苦小和尚
https://wwi.lanzouy.com/iqtQtxxwita

正己 发表于 2021-12-24 20:06

法王又发功了{:301_1000:}

xuexiba 发表于 2021-12-24 20:15

深度好文啊,学习了。

orginly 发表于 2021-12-24 20:45

太强了啊
页: [1] 2 3 4
查看完整版本: 魔镜魔镜告诉我,返回值在哪里修改?让程序自动化“坦白交待”!