首页
论坛
课程
招聘
[原创]某型navicat软件时间限制破解
2020-10-22 18:23 2072

[原创]某型navicat软件时间限制破解

2020-10-22 18:23
2072

从同事手中得到某navicat程序,但是受限于时间限制不能一直使用,修改系统时间虽然是一种可行的方案,但是会影响到其他程序的正常运行,并不可取。



软件细节信息如下图所示:

过期消息如下图所示:


第一步



为实现破解时间授权的目的,我首先考虑到该软件可能会读取本地文件的日志记录,并通过某种算法,得到软件初始化的时间,并减去与当前时间差值,判断试用是否国企。基于这个基本判断,我将在文件读写函数下断点,并通过栈回溯定位相关算法,并实现算法的还原。



文件读写断点如下:




多次断点均未发现该程序读取了有用的日志信息,让人感到比较意外,继续f9运行,发现程序居然正常运行。



如下图所示:





此时基本可以确定:该软件使用了反调试措施,因此当我使用od调试的时候,软件不会读取日志信息并做校验,转而走向一条欺骗分支。由于我使用的是od携带有隐藏插件,因此其并非通过IsDebugPresent函数来判断。




第二步



此前我已经确定了该程序存在以欺骗为主的反调试手段,且并非通过IsDebugPresent函数来程序处于调试状态,因此我猜测其可能通过进程同步或者时差等方式来实现该功能。这种情况通过断点或者跟踪调试的工作量比较大,因此这里我不采用这种方式,转而使用代码通过CreateProcess函数以调试状态打开该程序验证之前的猜想,代码如下所示:





#include<Windows.h>
#include<iostream>
#include<stdio.h>
int main()
{
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
PROCESS_INFORMATION pi;
if (CreateProcess(TEXT("navicat.exe"),
NULL,
NULL,
NULL,
FALSE,
//0,
DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS,
NULL,
NULL,
&si,
&pi))
{
printf("success");
}
else
{
printf("failed");
}
printf("新进程的ID号:%d\n", pi.dwProcessId);
printf("新进程的主线程ID号:%d\n", pi.dwThreadId);
DEBUG_EVENT de;
while (WaitForDebugEvent(&de, INFINITE) != 0) {
if (pi.dwProcessId == de.dwProcessId) {
if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) { printf("createprocess\r\n"); Sleep(5000);}
if (de.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT) { printf("createthread\r\n"); Sleep(1000); }
if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)break;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
}
}
//WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
getchar();
return 0;
}


编译连接之后,测试的结果并没有验证我之前的猜想(这里我就不放图了)。




第三步



由于猜测的反调试手段不正确,所以工作回到起点,我将重新通过回溯找到时间验证函数的分支。基于Win32窗体函数进行分析,我首先在CreateWindow函数下断点,如下图所示:




这一步我成功找到了“试用”按钮,通过栈回溯,找到了创建窗口函数,其idb文件如下图所示:





第四步



在创建窗体之前,程序一定会对wndclass类做初始化,因此我继续倒推,找到了窗体初始化函数,如下图所示:



这一步我修改了一些控件属性,“试用”按钮被激活,正常双击该程序打开,此时单击该按钮,发现程序退出。此时我附加调试,并进行栈回溯,发现程序已经从主函数退出,并未走向正常的分支。如下图位置:





第五步



可以发现,修改按钮属性,双击运行,程序从主函数退出,因此我们判断在调试状态下,程序和正常情况下走向了主函数不同的分支。此时,我将程序拖拽入od,并在CreateWindow函数下断点,进行栈回溯,成功找到了主函数的调用地址,如下图所示:


在其调用地址下一条指令下断点如下图所示:


同时,双击第四步修改得到的程序,当其出现注册窗口时进行附加调试,和上图同样的地方断点,发现在地址010C5F12处,附加调试的程序走向了不同的分支,此处的伪代码如上图所示为判断(unsigned char)al>=2,因此只需要改为al>=0即可,patch修改,重新打包。双击运行程序,如下图所示可以正常运行。










总结:



程序使用的反调试手段:在调试器中不做时间授权期限检验,可以正常运行;在调试器外无法正常运行。

程序的破解思路:栈回溯修改按钮属性;附加调试查找程序退出分支;栈回溯找到注册窗口调用点;在注册窗口调用点后下断点,附加调试查找不同分支。

文件链接:链接: https://pan.baidu.com/s/1UrF7ScTpRjsGFGOSmd6kRg 提取码: vkp6 复制这段内容后打开百度网盘手机App,操作更方便哦






【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回