申 请 I D:YuJia7777
个人邮箱:859904850@qq.com
原创技术文章:逆向工程——从分析到流程图至破解
-========================================================-
文章出处:CSDN
文章链接:https://blog.csdn.net/qq_40590152/article/details/84581877
网站登陆截图:
网站登陆截图
文章只供研究用 其他用途概不负责 有问题请私密软件名称: 天泽医院收费管理系统软件来源: 目标模块:登录 注册 重启验证 工具:OD(单分支执行)——IDA(详细分析)——PEiD(初步扫描)——Procmon(监控程序操作)前言:一个合格的逆向从事者或者研究者,在我看来不管程序安全机制完善度有多高,都应该拿出自己最高的技术标准去对待程序的操作行为是未知的,而你是探索这个黑盒的人,留个心眼总会给你带来安全感。 OD动态分析需要干什么: 打开:CreateProcess创建调试进程—接受调试事件 PS:因为资料缺陷以及本人比较懒,感兴趣的朋友可以私下分析
附加:注册窗口类—Createsorteddata创建进程表—填充进程表(详细请参考百度文章(https://wenku.baidu.com/view/0bd24c1d10a6f524ccbf8538.html)—OpenProcess打开目标进程—填充进程表—CreateWindow创建窗口—DebugActiveProcess调试器捆绑OD常用分析方法(附加):开发者稍微有点安全意识都会做防破解 壳——压缩壳这个感觉没啥好说的,使用PE变形技术对PE进行瘦身,嵌入代码到目标程序(修改程序OEP至嵌入的代码在接上程序本身代码),嵌入的代码作用为还原(针对使用的PE瘦身技术进行还原)壳——加密壳VMP:主要分为两个版本 3.0以上或3.0以下 3.0以下的反反调试/脱壳/技术已经成熟 。 (相对不安全)3.0以上的版本因为公开资料等等原因相对比较复杂。 (相对安全) PS:目前国内的几个团队自动化已经成功 ,公开资源已经有过反调试等脚本流露出来壳——压缩+加密(多层壳)外壳/里壳/壳中壳 (麻烦) PS:单层壳会脱 多层就不会了? 字符串加密 反调试 守护进程修改SSDT入口实现的HOOK技术 PS:SSDT分为两种 基于Win32k.sys的SSDT以及常规SSDT
PS:本文章的重点不再这里,所以就不详细解释了!!!
正文:
程序预览
​登陆
​软件功能
​注册
判断开发语言—加壳情况
​查壳
​节表
根据节表的信息判断为无壳 VB语言开发
首先附加程序——断下关机 格盘等API
​OD加载停留处
判断一下PEiD的识别是否准确
在IDE程序开发中一般会有重定位属性 所以根据Base Address+Offset获得程序入口地址
​程序入口
根据VB入口特征 以及OD反馈信息 确定PDiD识别准确 VB开发
定位登陆模块的方法
1:根据字符法+回溯法获得
2:根据按钮事件脚本获得
3:根据特征码( 816C24)获得
​按钮事件
开始定位模块地址
​判断账号
调试阶段——修改标志位,反向跳转
​跑飞处
跟踪到此,程序跑飞掉,恢复所有线程,继续跟踪。
​密码判断
​密码错误
修改标志位,反向跳转
​登陆成功
登陆模块破解完毕
定位注册模块的方法
1:根据字符法+回溯法获得
2:根据按钮事件脚本获得
3:API钩子
​判断注册名长度
VbaStrcmp 比较两个字符串
VbaFreeStr 释放出字符串所占的内存
VbaFreeObj 释放出VB一个对象
VbaVarDup 复制变量
4个函数的功能 从正向来说 你会干嘛?
判断串——释放内存——释放对象
这串信息会给我们分析提供很大的帮助 既然提示“注册名不允许为空” 肯定是判断了长度了 既然如此 我们肯定也能在这里得到注册名正确的长度,不过在这里我们先执行破解 摸清楚大概的程序走向!!!
​假码
​真码
​判断序列号
我们记住“48D070”这个地址 看是谁对这个地址进行了写入操作 在顺藤摸瓜就能找到算法Call了
​注册成功
一般来说到这里来说 程序的注册模块基本宣告破解完毕,但是真的如此么?开发者真的一点保护都没做?
在查壳阶段没看到加壳 分析的过程中也没碰到反调试/关键数据加密/这种时候就要留个心眼了,大家都是聪明人 别降低大家智商!!
伪注册
重新打开程序我们发现依然提示未注册 ,按照正向的思路
打开用户输入的序列号/注册码文件——调用算法模块——跟用户文件内容比较——根据结果做出相应反应
按照这种思路,我们之前的破解分析工作都白费了? 这是错误的思想 起码我们摸清楚了注册模块,这种伪注册也只是重新验证了一次而已,我们在把它干掉不就好了。逆向分析/破解的日常中 这是很正常的,文章开头提出的黑盒就是这个意思,你不知道它到底是个什么流程,你只能碰见一个问题,解决一个问题!!!
​伪注册
既然得出了正向思路,我们验证我们的思路
重启验证方法
API
监控软件
​监控操作
我们通过监控发现很多操作都是基于MDB数据库的,所以换一条路,通过API来实现
VB程序封装了一层 所以我们不通过Win32API,通过VB的API。 PS:吾爱OD/看雪/爱破解/是很成熟的OD
__vbastrcomp __vbastrcmp __vbavartsteq rtcMidCharVar rtcLeftCharVar __vbaStrCat ASC 这是比较常见的
​API断点
​Strcmp
断下来且没有弹出注册窗口。说明方法可行,继续跟踪!
​真码
再一次出现真码 我们细心分析后续操作
VbaStrMove
72A26C30 > 56 push esi ; 天泽医院.0048D07072A26C31 8BF1 mov esi,ecx ; 天泽医院.0048D07072A26C33 57 push edi72A26C34 8BFA mov edi,edx //Edi=真码(0069172C)72A26C36 8B06 mov eax,dword ptr ds:[esi]72A26C38 85C0 test eax,eax72A26C3A 74 07 je short msvbvm60.72A26C43 //ZF=172A26C3C 50 push eax72A26C3D FF15 F4199472 call dword ptr ds:[<&OLEAUT32.#6>] ; oleaut32.SysFreeString72A26C43 893E mov dword ptr ds:[esi],edi //DS:[48D070]=0069172C72A26C45 8BC7 mov eax,edi //Eax=真码(0069172C)72A26C47 5F pop edi72A26C48 5E pop esi ; 天泽医院.0048D070
真码被复制到了DS:[48D070]
0046F292 . 8B15 70D04800 mov edx,dword ptr ds:[0x48D070] //Edx=真码0046F298 . 8B45 D8 mov eax,dword ptr ss:[ebp-0x28]0046F29B . 8995 48FFFFFF mov dword ptr ss:[ebp-0xB8],edx //真码入栈 0046F2A1 . 8D55 AC lea edx,dword ptr ss:[ebp-0x54]0046F2A4 . C785 40FFFFFF>mov dword ptr ss:[ebp-0xC0],0x80080046F2AE . 8B08 mov ecx,dword ptr ds:[eax] ; msado15.1D70D3E80046F2B0 . 52 push edx0046F2B1 . 50 push eax0046F2B2 . FF51 54 call dword ptr ds:[ecx+0x54] ; msado15.1D70C3D2
真码入栈了 我们可以在细心一点跟踪
vbaVarTstEq
​重启验证—注册码判断
​重启验证—注册码判断
从表面来看 这似乎是判断真假码了,我们跟进去看下
72A497F6 > FF7424 08 push dword ptr ss:[esp+0x8] 72A497FA FF7424 08 push dword ptr ss:[esp+0x8]72A497FE 6A 00 push 0x072A49800 E8 51FEFFFF call msvbvm60.72A4965672A49805 8B0485 A4E69672 mov eax,dword ptr ds:[eax*4+0x7296E6A4]72A4980C C2 0800 retn 0x8
​Push真码地址(伪名称)
Push真码的地址进了栈,我们继续跟进Call
注意:因为观察栈结构中的数据 实际发现跟想法对不上 ,并且在后续分析中,这两个地址大量出现并且影响着最终注册结果,但是通过观察栈段和数据段,我们发现没有任何的联系。所以我们根据最理想的情况来做假想
call msvbvm60.72A49656
​取真假码地址
Eax=真码地址 Ecx=假码地址
​比较数据
继续跟踪不管它!
​真假码比较
这似乎才是真正的判断?
我们先看下函数
HRESULT VarBstrCmp( BSTR bstrLeft, BSTR bstrRight, LCID lcid, ULONG dwFlags );
bstrLeft 第一个串
bstrRight 第二个串
lcid 用于确定是使用UNICODE还是ANSI字符串的程序的语言环境标识符
dwFlags 以下是比较结果标志。 值 | 含义 |
NORM_IGNORECASE
00000001 | 忽略大小写。 |
NORM_IGNORENONSPACE
0x00000002 | 忽略非空格字符。 |
NORM_IGNORESYMBOLS
0x00000004 | 忽略符号。 |
NORM_IGNOREWIDTH
0x00000008 | 忽略字符串宽度。 |
NORM_IGNOREKANATYPE
0x00000040 | 忽略假名类型。 |
NORM_IGNOREKASHIDA
0x00040000 |
忽略阿拉伯语的kashida字符。 |
返回代码/值 | 描述 |
VARCMP_LT
0 | bstrLeft小于bstrRight。 |
VARCMP_EQ
1 | 参数相等。 |
VARCMP_GT
2 | bstrLeft大于bstrRight。 |
我们跟进去看下究竟是干嘛的
​真正的比较结果
Eax=2 根据MSDN的信息来看,第一个字符串大于第二个字符串。 即:真码大于假码
这么看来先前不明的两个地址 0018FA1C 018FA70是为这个函数准备的 即:vbaVarTstEq调用VarBstrCmp及后续的一系列操作需要这两个地址
现在我们继续跟踪 直到返回程序地址段
​注册码比较结果
Eax返回值为0 然后又释放掉了字符串变量 看来最终的结尾要来了
​注册结果
继续修改标志位 我们的注册是错误的 即:程序的执行结果,我们需要反着跟
​破解成功
程序后续还有些操作 但是主要判断已经破解掉 程序已经认为注册码是有效的 所以没继续跟下去。
到这里程序的 登陆模块——注册模块——重启验证模块等都已破解掉
注册机的开发将在另一篇博文
转载请注明出处.........感谢 |