起因
七月份的时候换了M芯片的MacBook,从Intel换到M一开始确实是用不惯,包括之前经常用的破解软件都得重新找M系列专版的,所以一开始就秉着能白嫖就不花钱的想法去白嫖朋友的;
但是总有白嫖不到的吧?八月份的时候需要用到数据库管理软件,去验证一些东西,找了半天没找到免费的破解版NxxxxxxPxxxxxx
,索性就直接在官网下载了最新版本来试用,因为这个软件有个好处就是虽然是试用版本但是是全功能试用,不会有阉割,下载安装后用了短短几分钟就完事儿了,是的白白浪费了14天试用。
就在月初当我又需要它的时候,它提示我过期了,总而言之就是让我花钱。
我当时属实是翻箱倒柜找尽了能找的资源站,当我以为找到能用的破解版时候往往是这样的
相同的购买解压密码页面,不同的价格(纯宾缝子),只能自己动手丰衣足食了,尝试更改本地时间到8月20左右,试试能不能重新试用
OK,看来思路正确,但是一些网页或者是站点又或者是网络资源会校验你本地时间和远程事件是否一致,不一致的话是没办法访问和使用的,所以短暂修改本地时间去一时半会的使用
NxxxxxxPxxxxxx
是没问题的,但就是来回修改时间太麻烦,所以有什么简单的办法呢?我第一时间想到了伪造时间给它!!!
正文
准备材料如下
1. `NxxxxxxPxxxxxx数据库管理软件`(应该是八月份左右的版本,新版也可以试试)
2. VSCode
3. MacBookPro For M3
我能想到的思路就是编写一个加载器,使其去加载目标程序,然后再目标程序初始化获取时间的时候,加载器给到它一个符合它试用范围的一个时间,使其正常试用;
除此之外还需要创建一个动态链接库文件,也就是dylib文件,类似于win中的dll,核心就在于loader
和libfaketime.dylib
这两个文件,一个用来伪造当前时间,一个用来加载NxxxxxxPxxxxxx软件
FakeTime.c
首先以时间戳的形式来创建虚假的时间,但是该时间是固定的
然后定义函数类型和相关函数指针
typedef time_t (*orig_time_t)(time_t *);
typedef int (*orig_gettimeofday_t)(struct timeval * __restrict, void * __restrict);
typedef int (*orig_clock_gettime_t)(clockid_t, struct timespec *);
然后整体来看就是无论当前时间是哪一年哪一月哪一天,我都给对应程序返回个8月21
完整代码如下
typedef time_t (*orig_time_t)(time_t *);
typedef int (*orig_gettimeofday_t)(struct timeval * __restrict, void * __restrict);
typedef int (*orig_clock_gettime_t)(clockid_t, struct timespec *);
time_t time(time_t *tloc) {
time_t fake_time = FAKE_TIMESTAMP;
if (tloc) {
*tloc = fake_time;
}
return fake_time;
}
int gettimeofday(struct timeval * __restrict tv, void * __restrict tz) {
if (tv) {
tv->tv_sec = FAKE_TIMESTAMP;
tv->tv_usec = 0;
}
return 0;
}
struct tm *localtime(const time_t *timep) {
static struct tm tm_storage;
time_t fake_time = FAKE_TIMESTAMP;
return localtime_r(&fake_time, &tm_storage);
}
struct tm *gmtime(const time_t *timep) {
static struct tm tm_storage;
time_t fake_time = FAKE_TIMESTAMP;
return gmtime_r(&fake_time, &tm_storage);
}
int clock_gettime(clockid_t clk_id, struct timespec *tp) {
if (tp) {
tp->tv_sec = FAKE_TIMESTAMP;
tp->tv_nsec = 0;
}
return 0;
}
__attribute__((constructor))
static void init(void) {
printf("Fake time library loaded. Setting date to 2024-08-21n");
}
然后编译为libfaketime.dylib
文件,接下来编写加载器loader
loader思路是设置环境变量,然后把我们的假时间库(libfaketime.dylib)注入到目标程序,然后通过loader加载目标程序去调用假时间库,试图达到效果
loader.c代码如下
extern char **environ;
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <program path>n", argv[0]);
return 1;
}
pid_t pid;
char *program_path = argv[1];
char *new_argv[] = {program_path, NULL};
char *dyld_env = "DYLD_INSERT_LIBRARIES=./libfaketime.dylib";
char *new_env[] = {dyld_env, NULL};
printf("Starting program: %sn", program_path);
printf("Using fake time: 2024-08-21 12:00:00n");
int status = posix_spawn(&pid, program_path, NULL, NULL, new_argv, new_env);
if (status != 0) {
printf("Error launching program: %sn", strerror(status));
return 1;
}
printf("Program started with PID: %dn", pid);
waitpid(pid, &status, 0);
return 0;
}
通过编译我们从loader.c
和fake_time.c
得到了loader
加载器程序和libfaketime.dylib
文件
尝试运行测试
1 |
|
跟我预期还是有点出入的,根据设置日期到到期日期(21-26貌似只有五天),貌似重新开始使用完整的14天?
不过问题应该不大,点击试用
试用是正常,但是不确定这样会不会丢失数据,以为我八月份的数据是丢失了,但是貌似从加载器加载后的以后数据应该不会丢失(纯猜测)
但是以后每次运行都要通过手动使用加载去去加载都挺麻烦的,试试看能不能打包为一体,使其每次点击图标就能自动使用加载器去加载程序
我们可以创建一个AppleScript
应用程序,根据实际路径创建
cd /Volumes/Files/Fake
# 创建 AppleScript
cat > NXXXLauncher.scpt << "EOF"
do shell script "cd /Volumes/Files/Fake && sudo ./loader "/Applications/NXXX PXXX.app/Contents/MacOS/NXXX PXXX"" with administrator privileges
EOF
# 将 AppleScript 编译为应用程序
osacompile -o NXXXLauncher.app NXXXLauncher.scpt
# 删除源文件(可选)
rm NXXXLauncher.scpt
双击启动,但启动后会要求输入密码,输入即可
开始试用正版
正常劫持流程如下
整体工作流程如下
最后讲两句,如果你是windows用户,理论上可以在网络上随意搜索并下载破解版使用(有没有后门就不得而知了),但是如果想自己逆向破解可以参考52大佬的一篇文章:
https://www.52pojie.cn/thread-1987041-1-1.html
但是尝试写完本文发现好像网上有无限试用脚本,对比完别人的方法就感觉我这个操作貌似是有点麻烦,例如:
https://www.52pojie.cn/thread-1669993-1-1.html
抵制盗版软件 人人有责
原文始发于微信公众号(白帽100安全攻防实验室):分享一个简单且粗暴的白嫖某数据库管理软件的思路
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论