吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4533|回复: 38
收起左侧

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

  [复制链接]
冥界3大法王 发表于 2021-12-24 18:41
本帖最后由 冥界3大法王 于 2021-12-26 11:54 编辑

当某个软件过期来临时:我马上想到以下几句:
image.png
福兮祸所伏,祸兮福所倚。风萧萧兮易水寒,壮士一去兮不复返。(你要死了)
费话说完,步入主题:


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


一般情况下,我们有以下这么多种方法找到过期的关键点:
  • 利用日期类函数下断,Ctrl+F8,顺势向下运行,直至出现弹框提醒或相关窗口等出现
  • 利用注册表类函数。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 暂停法,利用堆栈窗口,栈帧调用地址列表
  • 利用右下角堆栈,临时性历史足迹
  • 利用【启动运行跟踪】
  • 利用Process Monitor/API Monitor/winapioverride抓取系统api函数名
  • 抓取网络数据包
  • 利用看到的可疑关键字+硬件断点或内存断点,断到其上层某个子程序或函数入口处
  • 直接拦截窗口事件
  • 随便找个其上层调用的API或dll中断当跳板继续向下跟

所以呢,我们就先用传统的
bp GetLocalTime,  用来获取当地的当前系统日期和时间的函数下个断点
能断到,但是呢,已经晚了。(就会出现贴子顶上的那张截图
接着是:
image.png
顺便点下功能比较
image.png
原来付费版这么多功能啊。
因为前面分析过程序主要靠regkey.xml来判断程序是否过期?
image.png
当然也跟其他的几个函数有关(如图所示)
image.png
显然那些是次要因素
如图所示,重点是粉色区域的那些关键字之一,我们任选一个字符串搜索,并F2下断
Ctrl+F2,Ctrl+F8顺势来到如图所示的地方
image.png

image.png
当执行到00007FF687E154E6时,程序就会弹框提醒,已经过期!
上面有4个jne,最后的那个如果改成JMP强制跳转,就永远不会过期!
或者让其在不过期时,左边就会出现实现的那条红线
image.png
image.png
test al, 0x2    //al与2做比较;要是al=2就是授权版(为啥我知道到呢,咱们接着向下看)
test al, 0x4    //al与4做比较;要是al=2就是Lite限定功能版
所以上边的那个call的返回值尤为重要:
也就是下面这句:00007FF687E15498     call <顶上那个多个可疑调用点>     全局重要判断点
所以呢,在00007FF687E15498这里我们要设个断点并F7进入分析下,究竟让哪里al=2才能返回全局注册标志?
[Asm] 纯文本查看 复制代码
00007FF687D84370      | 48:89 | mov qword ptr ss:[rsp+18],rbx          |
00007FF687D84375      | 55    | push rbp                               |
00007FF687D84376      | 56    | push rsi                               |
00007FF687D84377      | 57    | push rdi                               |
00007FF687D84378      | 48:8D | lea rbp,qword ptr ss:[rsp-FC0]         |
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:[7FF68810E020]    |
00007FF687D84394      | 48:33 | xor rax,rsp                            |
00007FF687D84397      | 48:89 | mov qword ptr ss:[rbp+FB0],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:[rsp+20],xmm0    |
00007FF687D843AD      | 33F6  | xor esi,esi                            |
00007FF687D843AF      | 48:89 | mov qword ptr ss:[rsp+30],rsi          |
00007FF687D843B4      | 48:8D | lea rdx,qword ptr ss:[rsp+20]          |
00007FF687D843B9      | E8 92 | call <sub_7FF687D84550> |
00007FF687D843BE      | 85C0  | test eax,eax                           |
00007FF687D843C0      | 0F88  | js 7FF687D844F2         |
00007FF687D843C6      | 48:89 | mov qword ptr ss:[rsp+50],rsi          |
00007FF687D843CB      | 48:89 | mov qword ptr ss:[rsp+58],rsi          |
00007FF687D843D0      | 48:89 | mov qword ptr ss:[rsp+50],rsi          |
00007FF687D843D5      | 48:C7 | mov qword ptr ss:[rsp+58],7            |
00007FF687D843DE      | 66:89 | mov word ptr ss:[rsp+40],si            |
00007FF687D843E3      | 44:8D | lea r8d,qword ptr ds:[rsi+13]          |
00007FF687D843E7      | 48:8D | lea rdx,qword ptr ds:[7FF687FD7A88]    | 00007FF687FD7A88:L"InstallationOptions"
00007FF687D843EE      | 48:8D | lea rcx,qword ptr ss:[rsp+40]          |
00007FF687D843F3      | E8 C8 | call 7FF687D741C0       |
00007FF687D843F8      | 90    | nop                                    |
00007FF687D843F9      | 48:8B | mov rcx,qword ptr ds:[rdi+58]          |
00007FF687D843FD      | 48:8B | mov rax,qword ptr ds:[rcx]             |
00007FF687D84400      | 48:8D | lea rdx,qword ptr ds:[rdi+8]           |
00007FF687D84404      | 45:33 | xor r9d,r9d                            |
00007FF687D84407      | 4C:8D | lea r8,qword ptr ss:[rsp+40]           |
00007FF687D8440C      | FF90  | call qword ptr ds:[rax+F0]             |
00007FF687D84412      | 48:89 | mov qword ptr ss:[rsp+38],rax          |
00007FF687D84417      | 48:8B | mov rdx,qword ptr ss:[rsp+58]          |
00007FF687D8441C      | 48:83 | cmp rdx,8                              |
00007FF687D84420      | 72 12 | jb 7FF687D84434         |
00007FF687D84422      | 48:8D | lea rdx,qword ptr ds:[rdx*2+2]         |
00007FF687D8442A      | 48:8B | mov rcx,qword ptr ss:[rsp+40]          |
00007FF687D8442F      | E8 0C | call 7FF687D74440       |
00007FF687D84434      | 48:89 | mov qword ptr ss:[rsp+50],rsi          |
00007FF687D84439      | 48:C7 | mov qword ptr ss:[rsp+58],7            |
00007FF687D84442      | 66:89 | mov word ptr ss:[rsp+40],si            |
00007FF687D84447      | 48:83 | cmp qword ptr ss:[rsp+38],0            |
00007FF687D8444D      | 0F84  | je 7FF687D844F2         |
00007FF687D84453      | 48:8D | lea rdi,qword ptr ds:[<&sub_7FF687D8D8 |
00007FF687D8445A      | 48:89 | mov qword ptr ss:[rsp+40],rdi          |
00007FF687D8445F      | 8B442 | mov eax,dword ptr ss:[rsp+28]          |
00007FF687D84463      | 48:8B | mov rdx,qword ptr ss:[rsp+20]          |
00007FF687D84468      | 2BC2  | sub eax,edx                            |
00007FF687D8446A      | 0F57C | xorps xmm0,xmm0                        |
00007FF687D8446D      | 0F114 | movups xmmword ptr ss:[rsp+48],xmm0    |
00007FF687D84472      | C6442 | mov byte ptr ss:[rsp+58],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:[rsp+48]          |
00007FF687D84489      | E8 1D | call <JMP.&memmove>                    |
00007FF687D8448E      | C6442 | mov byte ptr ss:[rsp+58],0             |
00007FF687D84493      | 48:8D | lea rcx,qword ptr ss:[rsp+60]          |
00007FF687D84498      | E8 73 | call <sub_7FF687DACE10> |
00007FF687D8449D      | 90    | nop                                    |
00007FF687D8449E      | 48:8D | lea rdx,qword ptr ss:[rsp+40]          |
00007FF687D844A3      | 48:8D | lea rcx,qword ptr ss:[rsp+60]          |
00007FF687D844A8      | E8 53 | call <sub_7FF687DAC200> |
00007FF687D844AD      | 48:8D | lea rdx,qword ptr ss:[rsp+38]          |
00007FF687D844B2      | 48:8D | lea rcx,qword ptr ss:[rsp+60]          |
00007FF687D844B7      | E8 54 | call <sub_7FF687DAD010> |
00007FF687D844BC      | 48:8B | mov rax,qword ptr ss:[rsp+38]          |
00007FF687D844C1      | 48:A9 | test rax,FFFFFFFFFFFF0000              |
00007FF687D844C7      | 75 19 | jne 7FF687D844E2        |
00007FF687D844C9      | 25 FF | and eax,3FF                            | 
00007FF687D844CE      | 8903  | mov dword ptr ds:[rbx],eax             |
00007FF687D844D0      | 48:8D | lea rcx,qword ptr ss:[rsp+60]          |
00007FF687D844D5      | E8 56 | call <sub_7FF687DACE30> | 与注册码有关
00007FF687D844DA      | 90    | nop                                    |
00007FF687D844DB      | 48:89 | mov qword ptr ss:[rsp+40],rdi          |
00007FF687D844E0      | EB 16 | jmp 7FF687D844F8        |
00007FF687D844E2      | 48:8D | lea rcx,qword ptr ss:[rsp+60]          |
00007FF687D844E7      | E8 44 | call <sub_7FF687DACE30> | 与注册码有关
00007FF687D844EC      | 90    | nop                                    |
00007FF687D844ED      | 48:89 | mov qword ptr ss:[rsp+40],rdi          |
00007FF687D844F2      | C703  | mov dword ptr ds:[rbx],200             |
00007FF687D844F8      | 48:8B | mov rcx,qword ptr ss:[rsp+20]          |
00007FF687D844FD      | 48:85 | test rcx,rcx                           |
00007FF687D84500      | 74 1B | je 7FF687D8451D         |
00007FF687D84502      | 48:8B | mov rdx,qword ptr ss:[rsp+30]          |
00007FF687D84507      | 48:2B | sub rdx,rcx                            |
00007FF687D8450A      | E8 31 | call 7FF687D74440       |
00007FF687D8450F      | 0F57C | xorps xmm0,xmm0                        |
00007FF687D84512      | 48:89 | mov qword ptr ss:[rsp+30],rsi          |
00007FF687D84517      | F3:0F | movdqu xmmword ptr ss:[rsp+20],xmm0    |
00007FF687D8451D      | 48:8B | mov rax,rbx                            |
00007FF687D84520      | 48:8B | mov rcx,qword ptr ss:[rbp+FB0]         |
00007FF687D84527      | 48:33 | xor rcx,rsp                            |
00007FF687D8452A      | E8 21 | call 7FF687E95E50       |
00007FF687D8452F      | 48:8B | mov rbx,qword ptr ss:[rsp+10F0]        |
00007FF687D84537      | 48:81 | add rsp,10C0                           |
00007FF687D8453E      | 5F    | pop rdi                                |
00007FF687D8453F      | 5E    | pop rsi                                |
00007FF687D84540      | 5D    | pop rbp                                |
00007FF687D84541      | C3    | ret                                    |

image.png
切换武器到AkeIPad
右击菜单【选择 =》筛选行】
image.png
筛选之后,我们就马上知道有13个call(子程序)的里边(修改)或是外面(临近处修改)
image.png
接下来,我们再接着标色筛选
找到相同的标色处理
image.png
所以呢? 我们仅凭重复出现的次数来猜:
00007FF687D8442F      | E8 0C | call 7FF687D74440  注册码验证后又回到这里
00007FF687D844D5      | E8 56 | call <sub_7FF687DACE30> 这两句是不是挨得很近?当然你不能仅这样看,你还得结合上下文
00007FF687D844E7      | E8 44 | call <sub_7FF687DACE30>  试想,是不是心肝宝贝,你才会去验证多次?倍受关怀?
00007FF687D8450A      | E8 31 | call 7FF687D74440   

call 7FF687D74440  和  call  7FF687DACE30 就非常可疑了!
为啥上面两个跟注册码有关呢?请看下面:
image.png
00007FF687D8442F      | E8 0C00FFFF                 | call 7FF687D74440         注册码验证后又回到这里
当点击关于时,又会断在上面这句!
所以呢?改修改哪一句呢?
image.png
粉色圈1 到 圈 20 ?  楼下的道友请作答~~
要是你的话,你会选择在哪一句上修改呢? 为什么?
不能直接告诉你,不能直接揭晓答案,还是让魔镜来告诉你吧。
接下来,请来接着往下看。
image.png

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

image.png

image.png
当然你也可以用命令完成: AddWatch 和 SetWatchdog,具体自己看帮助吧。
image.png
当你向下F8 单步时,程序就会自己中断下来,但是上次的信息就被覆盖掉了。
感觉 这个功能吧,是有些想法的,然而却并不实用:
  • 因为程序每次会被断下来
  • 上次的记录被覆盖掉
  • 不能保存多次记录
所以呢,知道就好,知道这是个鸡肋的功能,请无视吧。


接下来,让我们再换个方式玩玩:
image.png
这次我们玩玩【步过直到满足条件。。。】另一个也是同样道理,不再赘述。
image.png
打开界面后,是这个样子的。不知大家是否还记得OD中的那个shift+F4(条件断点设置)?
image.png
其实这个设置的界面中实现的功能要比OD的那个强大一万倍。
暂停条件: 就是程序中断下来的条件 或 表达式   ;0就是永远不中断,1则永远断下
比如我们可以填:  rip = 00007FF687E15490
image.png
确定之后,就停留在 00007FF687E15490这行了(跟我们在此行F2效果相等)
image.png
帮助中是这样写的,如果你非得写成  rip == 00007FF687E15490 能成功断下来才怪!
不知哪个天煞的给翻译的叫【日志文本】这名称起的很不直观和直白,所以正解该翻译为:【日志窗口中的记录下来的文本】
你看看,经过法王同学一个点睛之笔,又好理解,又亲切了很多,是不是?
虽然长点,但是呢,易于理解和消化啊。
比如呢,
我们想把RAX的数值记录下来
当前地址呢,也得记录下来。
所以呢?
先弹个框测试一下:
msg 当前地址:{RIP}▲RAX值为:{RAX} 【EIP或RIP用于得到32位程序或64位程序的当前行的VA地址】
看不明白的!搜索我以前做的x64dbg视频教程。或帮助中表达式与格式化章节。
image.png
没问题吧。
image.png
00007FF687E1549D再设个断点,其他断点全部禁用点!
然后Alt+L来到日志窗口中
image.png
就得到了那个子程序中所有修改RAX值的地址了。
然后再动动脑袋想一起? 对一个软件的注册标志而言,一般只有 :
-1 0  1 2 3 。。。。肯定不会超过10(1 般情况下,当然也有特殊的,这里只是相对而言,你不能说成绝对,否则就会犯错误!)

image.png
竟然有516行之多。
先观察一下数据:一般都是 1 和 0 结尾的,其他都是一大长串
我们用一下正则表达式: RAX值为:0$  和  RAX值为:1$ ;再用过滤掉重复的

上边的算法有误,故此黑底黑字屏蔽掉!没有删除线,凑合用吧。全当是一种构想好了。
这个东西列出的多与少?
  • 与到底是Ctrl+F8 或 Ctrl+F7
  • 前后分析选择的位置
  • 有效地址的判断方法都有关系

费话说的差不多了,该请出本贴中想要阐明的观点了

image.png
这就是用Delphi开发的的穷举爆破补丁批量生成器。其实呢,该工具的雏形可以追述到很多年前。只不过呢,第一个版本是用按键精灵来完成的。
那时候最初的假设是:WinRAR有穷举key生成器、安卓上也有幸运破解器。为啥逆向爆破时没有此类工具呢? 所以就试着开始写着玩了。
后来呢,我又换用AutoHotkey写了一个相对功能上比较全面的版本(但是输出的补丁数量可以直接写爆你的硬盘,,其稳定性也不好)后来呢。。
随着编程技术的提高,我又用Delphi写了最后一个版本。思路也变了,何必列出所有的可能,列出所有的地址,把最可疑的地址列表填入,岂不中奖概率直线提升?
image.png
在第一个界面中:
  • 主要为了处理EXE 和 DLL文件
  • 并设置了保存相关的配置到配置文件中
  • 保存补丁的编号(类似于WinRAR中的处理进度)
二和三界面仍然在资料制作
第四个界面主要按各中需求输出
image.png
其实呢? 我觉得上面都不算啥,最难搞的就是最后一个界面了。
  • 如何判断最终输出的那个【补丁_168.exe】达标了呢?若是一部分有效果,另一部分搞得程序崩溃了,到底算是爆破成功,还是不成功呢?
  • 当一个非法的PE文件被输出并被运行时,如何判断它现在运行正常,或不正常呢?也进到界面了,也弹出某种出错的警告了。
  • 各种未知的可能性的补丁都有可能被输出出来;所以那个AHK版的程序最终的完美版也没有搞出来。
所以综上所述:我放弃了原有的那种全自动化判断补丁到底哪个是有效的方法方案;而改用活人+有限数量补丁输出方式;还是活人验证更为靠谱一些。
未来计算机领域,或许会出现某种更完善的爆破体系。
最终,我们只需要把 00007FF7D56F4370至00007FF7D56F4541的地址列表填入我们自己的程序,就会自动化的输出补丁列表了。
image.png
我鼠标操作几下,瞬间就自动化输出了一堆可疑地址的补丁文件了。
20211226_115206.gif

免费评分

参与人数 15吾爱币 +16 热心值 +11 收起 理由
情受哥哥 + 1 + 1 用心讨论,共获提升!
18053317345 + 1 用心讨论,共获提升!
592618243 + 1 这头像真好看,
chenmintian + 1 + 1 热心回复!
Follow + 1 + 1 我很赞同!
zpzwz + 1 + 1 谢谢@Thanks!
13699513436 + 1 鼓励转贴优秀软件安全工具和文档!
jaffa + 1 谢谢@Thanks!
skymid + 1 + 1 用心讨论,共获提升!
chinawolf2000 + 1 + 1 热心回复!
Skitart + 1 + 1 我很赞同!
努力加载中 + 1 + 1 谢谢@Thanks!
SunsetShimmer + 1 + 1 用心讨论,共获提升!
笙若 + 1 + 1 谢谢@Thanks!
Nattevak + 2 + 1 我很赞同!

查看全部评分

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

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

万分感谢,以后多多支持你
 楼主| 冥界3大法王 发表于 2022-1-14 09:45
Hmily 发表于 2022-1-11 17:26
好复杂,真没看懂啥意思。。。

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

点评

那要是mov eax,2了?  详情 回复 发表于 2022-1-14 10:10
诗木 发表于 2021-12-24 19:13
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
法王又发功了
xuexiba 发表于 2021-12-24 20:15
深度好文啊,学习了。
orginly 发表于 2021-12-24 20:45
太强了啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-26 17:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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