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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5924|回复: 102
上一主题 下一主题
收起左侧

[原创] 多种方法绕过某软件许可过期检测

    [复制链接]
跳转到指定楼层
楼主
Jx29 发表于 2024-9-15 13:16 回帖奖励
本帖最后由 Jx29 于 2024-9-15 14:57 编辑

起因


看到坛友求助的一个软件试用期不能重置的问题:

简单分析


软件下载下来发现是一个安装包,通过Total Uninstall监控软件安装,发现软件在安装过程中向注册表项写入一段数据,猜测是安装时间




使用InnoExtractor(www.52pojie.cn](https://www.52pojie.cn/thread-1718344-1-1.html)对安装包解包,在安装脚本install\_script.iss中发现有相关代码


导出注册表文件并往后修改系统时间使软件过期,软件弹出过期窗口,此时再将时间改回,软件也会弹出过期窗口。



将刚才导出的注册表文件重新导入,软件没有弹出过期窗口,看来它是通过注册表判断是否过期。到这里其实已经绕过许可过期检测了,只要更改系统时间就行了,但每次改时间也挺麻烦的,有没有一劳永逸的办法呢?

方法一:使用ida修改汇编代码,强制绕过许可检测



先将主程序SurrealCapture.exe丢到ida里,过期弹窗上有一个购买按钮,会打开某个网站,那么我们可以在ida搜索这个网站文本





每个都点进去,f5看看伪代码,发现第一个是正常窗口,第二个才是过期窗口

在这里按x看看交叉引用,找到是谁调用了这个函数



跳转到这,接下来就得分析伪代码了



int __thiscall sub_401350(const WCHAR *this)
{
  __int64 v2; // kr00_8
  DWORD (__stdcall *v3)(); // esi
  HANDLE v4; // eax
  char *v5; // edi
  __int16 v6; // ax
  char *v7; // edi
  __int16 v8; // ax
  HWND v9; // eax
  HANDLE v10; // ecx
  HANDLE v11; // eax
  BOOL Wow64Process; // [esp+10h] [ebp-3D8h] BYREF
  LPCWSTR lpParameters; // [esp+14h] [ebp-3D4h]
  __int64 v14; // [esp+18h] [ebp-3D0h] BYREF
  struct _NOTIFYICONDATAW Filename; // [esp+20h] [ebp-3C8h] BYREF

  lpParameters = this;
  if ( !sub_409180() )
  {
    sub_402810(
      &off_430C48,
      4,
      L"d:\\project\\surrealcapture\\surrealcapture\\surrealcapture\\360gamecapture.cpp",
      78,
      L"ASSERT");
    return 0;
  }
  v2 = qword_431D58;
  sub_40E084(&v14);
  if ( (v14 - v2) / 86400 >= 15 || v14 <= v2 )  // 计算当前时间与安装日期的时间差,如果超过15天或者当前时间早于安装时间,则提示试用期已过期
  {
    sub_408BC0(1u);
    sub_402810(
      &off_430C48,
      3,
      L"d:\\project\\surrealcapture\\surrealcapture\\surrealcapture\\360gamecapture.cpp",
      84,
      L"Surreal Capture trial period has expired.");
    goto LABEL_42;
  }
  if ( !sub_409180() )                          // 再次许可检查,如果 sub_409180() 再次返回 false,则显示一个错误消息
  {
    sub_402810(
      &off_430C48,
      4,
      L"d:\\project\\surrealcapture\\surrealcapture\\surrealcapture\\360gamecapture.cpp",
      101,
      L"ASSERT");
    MessageBoxW(
      0,
      L"The data for install date was corrupted. Please purchase Windows 10 Movies & TV Codec Pack.",
      L"Surreal Capture",
      0x10u);
    return 0;
  }
  if ( sub_409240() )                           // 如果 sub_409240() 返回 true,则表示试用期已过期
  {
    sub_402810(
      &off_430C48,
      3,
      L"d:\\project\\surrealcapture\\surrealcapture\\surrealcapture\\360gamecapture.cpp",
      108,
      L"Surreal Capture trial period has expired.");
...


通过伪代码,我们可以得知软件会进行3次许可检查,那么我们可以修改这三次判断,跳过许可检查。

右键同步到ida窗口



ctrl+alt+k修改汇编代码,nop掉跳转



这里我们需要让它能够往下运行,所以改成jmp




保存修改



打开看看,已经跳过过期检查了,这下不用修改系统时间也能打开了


方法二:Hook GetSystemTimeAsFileTime



深入分析sub_40E084,我们可以发现软件调用了GetSystemTimeAsFileTime计算时间戳

__int64 __cdecl sub_40E084(__int64 *a1)
{
  __int64 result; // rax
  struct _FILETIME SystemTimeAsFileTime; // [esp+0h] [ebp-8h] BYREF

  SystemTimeAsFileTime = 0i64;
  GetSystemTimeAsFileTime(&SystemTimeAsFileTime);// 调用GetSystemTimeAsFileTime
  if ( *(_QWORD *)&SystemTimeAsFileTime - 116444736000000000i64 >= 325368000000000000i64 )
    result = -1i64;
  else
    result = (*(_QWORD *)&SystemTimeAsFileTime - 116444736000000000i64) / 10000000;
  if ( a1 )
    *a1 = result;
  return result;
}


那么,我们可以尝试hook GetSystemTimeAsFileTime,让它返回特定的值

(这里使用了Detours 库)

#include <windows.h>
#include <detours.h>
#include <iostream>

static void (WINAPI* Real_GetSystemTimeAsFileTime)(LPFILETIME) = GetSystemTimeAsFileTime;

void WINAPI My_GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) {
    SYSTEMTIME st;
    // 2024年9月14日20:00:00
    st.wYear = 2024;
    st.wMonth = 9;
    st.wDay = 14;
    st.wHour = 20;
    st.wMinute = 0;
    st.wSecond = 0;
    st.wMilliseconds = 0;

    SystemTimeToFileTime(&st, lpSystemTimeAsFileTime);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

// 安装 Hook
extern "C" __declspec(dllexport) void hooknew() {
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    if (DetourAttach(&(PVOID&)Real_GetSystemTimeAsFileTime, My_GetSystemTimeAsFileTime) == NO_ERROR) {
        std::cout << "Hook attached successfully." << std::endl; 
    }
    else {
        std::cerr << "Failed to attach hook." << std::endl;
    }

    if (DetourTransactionCommit() == NO_ERROR) {
        std::cout << "Hook successfully installed.\n" << std::endl;
    }
    else {
        std::cerr << "Hook installation failed.\n" << std::endl;
    }
}

// 卸载 Hook
extern "C" __declspec(dllexport) void unhooknew() {
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    if (DetourDetach(&(PVOID&)Real_GetSystemTimeAsFileTime, My_GetSystemTimeAsFileTime) == NO_ERROR) {
        std::cout << "Hook detached successfully." << std::endl;
    }
    else {
        std::cerr << "Failed to detach hook." << std::endl;
    }
    DetourTransactionCommit();
}


编译为32位dll,使用studype+添加并保存




测试通过,这种方法可行


至此,本帖完结
感谢大家看到这里,再见!

免费评分

参与人数 40吾爱币 +34 热心值 +35 收起 理由
melooon + 1 + 1 我很赞同!
xielong + 1 + 1 我很赞同!
dapanglaile + 1 + 1 用心讨论,共获提升!
luckilygou + 1 谢谢@Thanks!
gezhonglunta + 1 + 1 我很赞同!
AnDawn + 1 + 1 热心回复!
GGbond141242 + 1 我很赞同!
slslsl + 1 + 1 我很赞同!
Icicle丶凌 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
mscsky + 1 + 1 我很赞同!
angelabebe + 1 + 1 我很赞同!
sdzcq + 1 + 1 谢谢@Thanks!
匿名网友哟 + 1 热心回复!
freesoft + 1 + 1 谢谢@Thanks!
jaffa + 1 谢谢@Thanks!
galaxys10 + 1 + 1 受益匪浅!!
mcbaiyun + 1 + 1 我很赞同!
Mooshed88 + 1 + 1 我很赞同!
midkr + 1 + 1 我很赞同!
st0rm + 1 + 1 热心回复!
1783780690 + 1 + 1 谢谢@Thanks!
Issacclark1 + 1 谢谢@Thanks!
yltz + 1 热心回复!
toot + 1 + 1 谢谢@Thanks!
repack9527 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Qiaoyuexuan + 1 + 1 谢谢@Thanks!
twl288 + 1 + 1 谢谢@Thanks!
78zhanghao87 + 1 我很赞同!
HillBoom + 1 + 1 用心讨论,共获提升!
lgc81034 + 1 谢谢@Thanks!
xiaonan22533 + 1 + 1 我很赞同!
真的小白 + 1 + 1 我很赞同!
二零一八小王子 + 1 热心回复!
BayMax2911 + 1 + 1 6666,学习了!!
andyle + 2 + 1 我很赞同!
han163426 + 1 我很赞同!
daoye9988 + 1 + 1 谢谢@Thanks!
丶峰宇 + 1 + 1 我很赞同!
F14990A + 1 我很赞同!
小朋友呢 + 2 + 1 我很赞同!

查看全部评分

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

推荐
tommys 发表于 2024-9-15 13:21
这三下五除二,就把时间搞定了,太厉害了
下次加上判断文件本身创建的时间和操作系统安装的时间,来验证
推荐
 楼主| Jx29 发表于 2024-9-16 10:39 |楼主
Creeperppp 发表于 2024-9-15 19:06
大佬,看了您的帖子以后收获颇丰,我也发了一个帖子求助,我的软件会在本地创建一个端口,然后连接端口获取 ...

没搞过C#程序,不过还是简单看了一下,通过卸载软件卸载程序后清理残留重新安装是不会检测到之前记录的时间,可以通过这种方法实现永远在试用期。
如果需要的话,我可以写一个软件来清理卸载残留。
关于重新启动会过期的问题,是开启了一个服务,然后检测注册表是否被修改,注册表文件实在是太多了,要研究起来很麻烦
3#
201613 发表于 2024-9-15 16:20
4#
理想的海洋 发表于 2024-9-15 16:34
感谢分享优质技术
5#
msxiaobei 发表于 2024-9-15 16:58
学习了!!真是学习资料很高的一篇帖子!!
6#
WK8888 发表于 2024-9-15 17:10
点个赞再说,虽然我也不会这些
7#
xxgame 发表于 2024-9-15 17:44
高手,敬佩
8#
daoye9988 发表于 2024-9-15 17:59
进来学习学习
9#
whz2009 发表于 2024-9-15 18:26
进来学习学习咱也试试
10#
WXJYXLWMH 发表于 2024-9-15 18:59
感谢分享宝贵经验 谢谢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

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

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

GMT+8, 2024-9-20 16:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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