-
-
010editor版本V13.0.1暴力破解过程
-
发表于:
2023-3-11 17:48
8203
-
首先声明,本文仅作软件安全研究使用,禁止做非法用途,否则后果自负。
序:
这个版本无法通过内存抓取用户名和验证码,我粗略的看了下,大概是用了线程保护,验证完成后线程结束,内存就清零了;但是幸运的话,也是可以看到的,只不过要看机遇,前提是内存清理不及时,这时也是可以搜到用户名调用地址的;但是内存下断会有困难。
IDA静态分析:
搜一下字符串‘EXPIRED’,如下:
主要分析函数sub_140211130,看下大体的执行流程:
通过分支语句,看出这个模块是通过状态码的对比来判断此刻软件版本属于什么状态的;状态码设置在寄存器EAX中:
先看第一次比较指令:
1 2 | cmp eax, 0DBh ;通过后文分析,DBh的状态码表示验证通过
jnz loc_1402114A1 ;不等,就是层层的比较,各种拦截
|
如果状态码是DBh,进入这里:
表示注册已经收到了,但是还未成功,因为进入这一步的前提是通过另外一个验证,即:
1 2 3 4 5 6 7 | mov rcx, cs:qword_140D64950
/ /
内存cs:qword_140D64950很关键,整个保护很多个地方引用了这个值,
该值 + 44h ,即rcx + 44h 如果等于 0 就‘退出了’,只有不为 0 才进入设置注册时间阶段;(这里并没进一步研究)
/ /
cmp dword ptr [rcx + 44h ], 0
jz loc_140212044
|
接下来程序进入日期验证阶段,即:
sub_14000AE20 就是时间验证函数,这个函数在多处调用到;先简单看下这个函数体:
1 2 3 4 5 6 7 8 9 10 11 12 | sub_14036F2B0 proc near
push rbx
sub rsp, 20h
mov rbx, rcx
call sub_140003EF4 / / 真正的时间对比函数
mov ecx, [rbx + 44h ]
sub ecx, eax / / 这里的对比会影响符号位
mov eax, ecx
add rsp, 20h
pop rbx
retn
sub_14036F2B0 endp
|
如果小于零,表示验证失败了,‘过期了’
1 | lea rdx, aExpired ; " (EXPIRED)"
|
如果大于零,就提示剩余天数:
接下来会根据验证状态,
设置程序的启动状态:
最后在000000014021219B处进行真正的程序启动
1 | .text: 000000014021219B call cs:?start@QBasicTimer@@QEAAXHPEAVQObject@@@Z ; QBasicTimer::start( int ,QObject * ) 程序启动入口
|
X64dbg动态调试:
通过分析,了解到关键看EAX中这个状态码是怎么来的:
该值来自[r14+19Ch],在该处下断,进行动态调试,以下是我改后的代码:
1 2 3 4 5 6 7 | 00007FF799E5EFB3 | 75 10 | jne 010editor . 7FF799E5EFC5
/ / 原先是je,改为jne
00007FF799E5EFB5 | B8 DB000000 | mov eax,DB
/ / 原值 113H ,DB表示注册通过了
00007FF799E5EFBA | 48 : 8B5C24 30 | mov rbx,qword ptr ss:[rsp + 30 ]
00007FF799E5EFBF | 48 : 83C4 20 | add rsp, 20
00007FF799E5EFC3 | 5F | pop rdi
|
然后就可以进入正常界面了:
后记:
其实这个软件动态下断并不难,但是未破解前的注册界面会把X64dbg的修改指令对话框挡住,而且注册界面是置顶的,这造成了一定的调试困难,其实这也是很常见的软件防逆向的小技巧。这里通过在注册界面启动前下断,然后直接改代码就解决了;需要多次调试,熟能生巧。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-3-11 17:55
被Valdik编辑
,原因: 补充