破解 QCAD for Mac

查看 101|回复 9
作者:QiuChenly   
破解 QCAD for Mac
因为今天要修改一个图,不能有其他公司的名字,光改PDF没用,所以只能从dxf文件下手。搜来搜去又不想装Autodesk CAD,太麻烦了,所以随便找了个QCAD破一下,好像这软件还挺好用。
1. 分析
没激活前是这样的


16983236052493.jpg (514.18 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

充斥着Trial等字样,右下角还有一个审判按钮。
其次,使用大约30-40分钟左右,会有退出弹窗


16983233226012.jpg (518.49 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

并显示我试用到期。
并且最重要的是,导出图纸到pdf有一很大的水印,如果没有水印我可能就不会破解他了。
我打算以“This is a trial version of”为切入点,暴力搜索所有文件试试。


16983242327040.jpg (66.7 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

就让审判来得更猛烈些吧!
2. 审判
常规搜索我们是搜索不到的。所以我们需要用一些特别的手段来暴力搜索所有二进制里的文件。
因为我们知道,英文字符串大部分就是原文在二进制中,所以我们暴力搜索一定能搜索到相关的内容。
find /Applications/QCAD.app/Contents -type f -exec sh -c 'strings "$1" | grep "This is a trial version of" && echo "$1"' sh {} \;


16983273366657.jpg (250.68 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

差不多也就搜索到这了。
我们发现第一个文件和第二个文件都存在这个字符串,那么我们就着重搞这两个文件。
首先打开第一个:


16983274665225.jpg (729.26 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

因为只有几百K,分析速度很快,我们一搜,还真有。
那这下不得不跳过去看下了:


16983275016996.jpg (297.52 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

糟糕糟糕OMG,魔法怎么施灵辣!
却说这大魔导师落叶不愧是强者,事情发展出乎意料却也不急,冷笑着说道:“尔等不过区区Qt多语言,待我略施小技,必取你首级!”
那QCAD本就是小作坊出产,哪里见过这等阵仗?当下心中狂跳,嘴上却是硬道:“兀那乱臣贼子!休要在此胡言乱语妖言惑众,我等在此会你一二,看你还有什么手段?”
那大魔导师落叶出道以来哪里受到如此挫折?闻得QCAD猖狂挑衅,当下却是道心不稳,怒从心中起,恶言道:“区区蝼蚁也敢在本魔导师面前螳臂当车?死来!”
当下落叶长啸一声,法杖高举,大喝道:“天圆地方乾坤倒转,禁术·Hopper disassembler,启动!”
说时迟那时快,原本万里无云的蓝天诡异的传出一声巨响,那QCAD当即被一个邪异蓝色光罩团团围住,进出不得。QCAD惊怒交加,一时不察竟受制于人,怒不可遏:“贼子敢尔!”
那大魔导师落叶也不说话,匆忙的结印,操作着究极禁术HP疯狂攻击:


16983283509738.jpg (660.11 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

此时令所有人震惊的一幕出现了,那究极禁术竟然对QCAD毫发无伤!
QCAD原本还略有慌乱,此时发现自己没有受到任何伤害,眼珠一转便哈哈大笑:“黄毛小儿,想害我?再去修炼几年!”
”可恶!“落叶面如金纸,噗的吐出一口黑血,原来这禁术无法施展太久,否则会反噬施术者。一时之间,竟然僵持不下。
远处,迦南世家伯爵迦南二世皱眉道:”此子成长速度太快,区区魔导师境界的魔力就已经能越级施展禁术,之前还得罪了他,如此看来只好斩草除根了!告诉QCAD大师,如果能当场斩杀魔子落叶,我们迦南世家将不遗余力的帮助他成为璃月大陆的风神代言人!“ 说到最后,竟然已经是咬牙切齿。
两名骑士对视一眼,不敢怠慢,当即领命去设法通知QCAD大师。
那QCAD见这所谓的大魔导师兼魔子对自己毫发无伤,更是轻视三分,又收到迦南二世伯爵送来的密信,当即冷笑一声:”黄口小儿,你的死期到了!“
当即吟唱法术,欲要突破牢笼。
此时落叶本就被反噬遭到重创,哪里敢让QCAD突破?拼了命维护牢笼,一时之间却也想不到别的办法。
此时,落叶突然想到这里:


16983291033863.jpg (87.72 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

这可不就是苦苦寻觅么线索?查不到又如何?还不是漏出了破绽?
当即狂喜,迅速xref过去一看:
果然发现这arg0+0x28偏移处的地址值若为0,则跳转到7a73,也就是trial模式。


16983291717642.jpg (343.34 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

那么就让他不跳转吧!
落叶默默想着,迅速回到IDA:


16983292935703.jpg (1.32 MB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

找到checkLicense函数,进去发现若v4 = QVariant::toInt((QVariant )&v8, 0LL);的值大于9,则走一串神秘的js脚本,并传递了this的指针地址,盲猜返回上级函数会让if ( ((_BYTE *)this + 40) )判断成立,因为默认v4得到的值是NULL,也就是0,所以这将是我们的突破口!
v4 = QVariant::toInt((QVariant *)&v8, 0LL);
  QVariant::~QVariant((QVariant *)&v8);
  QVariant::~QVariant((QVariant *)&v9);
  *((_BYTE *)this + 40) = 0;
  if ( v4 > 3 )
  {
    if ( v4 > 9 )
      QTimer::singleShot(
        (QTimer *)"(_0x3c3852,_0x10a608){var _0x36519d=a0_0x3651();return a0_0x4121=function(_0x4121b1,_0x35735a){_0x4121"
                  "b1=_0x4121b1-0xd3;var _0x3e8b74=_0x36519d[_0x4121b1];return _0x3e8b74;}...............省略",
        (int)this,
        (const QObject *)"1uninitSlot()",
        v5);
于是想办法将这v4 = QVariant::toInt((QVariant *)&v8, 0LL);改成v4 = 10:


16983296622206.jpg (195.93 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

光标放在这一行,切换到HexView:


16983296862611.jpg (56.54 KB, 下载次数: 0)
下载附件
2023-10-26 23:23 上传

自动定位到对应的十六进制地址,右键点击菜单Edit...修改为:


16983297397675.jpg (99.93 KB, 下载次数: 2)
下载附件
2023-10-26 23:23 上传

最后Apply即可。
返回反汇编即可看到


16983297694135.jpg (132.36 KB, 下载次数: 1)
下载附件
2023-10-26 23:23 上传

被修改成了赋值0xa,加一个NOP,nop是为了对齐指令。否则ida分析会出现断层。
最后保存到文件,重启app看效果。


16983299893705.jpg (405.99 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

却说那落叶狂喜道:“找到你了!”操作法器ida狠狠的向QCAD攻去!
QCAD惨叫一声,怒吼:“你敢伤我!我今日必将你碎尸万段!”


16983301189358.jpg (355.97 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

没想到此时又生事端,那签名没有通过,落叶情急之下确实连这等基础操作也忘了,连忙补上:


16983301908011.jpg (67.59 KB, 下载次数: 2)
下载附件
2023-10-26 23:24 上传

重新打开QCAD:


16983302268754.jpg (83.77 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

还是这样,但至少能打开了。
刚才修改的是一个插件,所以我们看下关于:


16983304372535.jpg (165.16 KB, 下载次数: 1)
下载附件
2023-10-26 23:24 上传

可以看到还是试用版本,落叶满脸自信最终被打脸,这让要脸的魔子如何忍受?当即两眼发红,恶声道:“老贼,受死!”
当即也不恋战,看到这里:


16983305385490.jpg (210.28 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

大大的Trial赫然在目。
这次,我看你怎么躲!落叶默默冷笑。


16983305992071.jpg (102.84 KB, 下载次数: 1)
下载附件
2023-10-26 23:24 上传

重新暴力搜索,发现仍然在这个文件内,当即冷笑道:“老贼,我已找到你的弱点,你乖乖引颈就戮吧!”
说完顾不得QCAD的狂骂,回到IDA迅速搜索:


16983307494311.jpg (174.38 KB, 下载次数: 1)
下载附件
2023-10-26 23:24 上传

果然搜索到了!
进一步看:


16983308818348.jpg (185.32 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

LABEL94来自LABLE89,89来自LABEL_79...一路溯源到:LABEL_56。
LABEL_56:
  if ( !(unsigned __int8)RPluginBase::isTrial((RPluginBase *)a2) )
  {
    v50 = (volatile signed __int32 *)QString::fromAscii_helper((QString *)"NameOverride", dword_C, v25);
    QVariant::QVariant((QVariant *)&v49, "QCAD Professional");
    QMap::insert(v2, &v50, &v49);
    goto LABEL_107;
  }
  v50 = (volatile signed __int32 *)QString::fromAscii_helper((QString *)"TrialExpiredReason", &dword_10[2], v25);
  QVariant::QVariant((QVariant *)&v49, (const QString *)(a2 + 48));
  QMap::insert(v2, &v50, &v49);
  QVariant::~QVariant((QVariant *)&v49);
  v27 = v50;
  if ( *v50 != -1 )
  {
    if ( *v50 )
    {
      if ( _InterlockedDecrement(v50) )
        goto LABEL_62;
      v27 = v50;
    }
    QArrayData::deallocate(v27, 2LL, 8LL);
  }
LABEL_62:
  v50 = (volatile signed __int32 *)QString::fromAscii_helper((QString *)"TrialExpired", dword_C, v26);
  QVariant::QVariant((QVariant *)&v49, a2[41]);
  QMap::insert(v2, &v50, &v49);
  QVariant::~QVariant((QVariant *)&v49);
  v29 = v50;
  if ( *v50 == -1 )
    goto LABEL_67;
。。。省略
LABEL_74:
  v34 = v47;
  if ( *v47 == -1 )
    goto LABEL_79;
  if ( *v47 )
  {
    if ( _InterlockedDecrement(v47) )
      goto LABEL_79;
    v34 = v47;
  }
  QArrayData::deallocate(v34, 2LL, 8LL);
LABEL_79:
  v35 = v45;
  if ( *v45 == -1 )
    goto LABEL_84;
  if ( *v45 )
  {
    if ( _InterlockedDecrement(v45) )
      goto LABEL_84;
    v35 = v45;
  }
  QArrayData::deallocate(v35, 2LL, 8LL);
LABEL_84:
  v36 = v46;
  if ( *v46 == -1 )
    goto LABEL_89;
  if ( *v46 )
  {
    if ( _InterlockedDecrement(v46) )
      goto LABEL_89;
    v36 = v46;
  }
  QArrayData::deallocate(v36, 2LL, 8LL);
LABEL_89:
终于找到!
if ( !(unsigned __int8)RPluginBase::isTrial((RPluginBase *)a2) )
  {
    v50 = (volatile signed __int32 *)QString::fromAscii_helper((QString *)"NameOverride", dword_C, v25);
    QVariant::QVariant((QVariant *)&v49, "QCAD Professional");
    QMap::insert(v2, &v50, &v49);
    goto LABEL_107;
  }
如果RPluginBase::isTrial返回0就是专业版,否则就是试用版。
此番终于找到重点,落叶狂笑道:“老狗,你死期已至也!”
那QCAD被人发现要害,终于变了脸色,口气也软了三分:“放过老儿,我可以保你无恙走出这里!”
落叶闻言冷笑道:“三年...你知道这三年我怎么过的吗?走出?我就是来复仇的!”
大魔导师的气势此时终于完全散发出来,强大的威压让璃月大陆上的智慧生灵纷纷跪下祈祷,不知又是哪位法神震怒。
当下落叶也不啰嗦,进入isTrial函数,将下面的语句强制返回0:
bool __fastcall RPluginBase::isTrial(RPluginBase *this)
{
  return *((_BYTE *)this + 40) == 0;
}


16983314609989.jpg (106.37 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

将这个函数头开始直接覆盖为6a 00 58 c3,保存修改到文件,重新运行试试:


16983315510926.jpg (205.27 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

神奇的一幕出现了,虽然还有激活弹窗,但是这里已经成功授权!


16983315832529.jpg (165.56 KB, 下载次数: 1)
下载附件
2023-10-26 23:24 上传

包括这里也变成了授权状态,和上面的试用版本截然不同!
于是,落叶记住了两个函数:checkLicense 和 isTrial,让其他的文件中的这两个函数也统统消失吧!
对照


16983316875164.jpg (39.14 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

有激活字样的文件名,一一修改这里不再赘述。


16983325262561.jpg (148.16 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

总共需要修改这9个文件,同样的checkLicense 强制
mov     ebx, 0Ah
nop
isTrial变成6a 00 58 c3.
却说那奄奄一息的QCAD看着缓缓走来的魔子落叶,惊恐道:“不...!不能杀我!我背后的迦南世家不会放过你的!”
落叶毫无反应,淡漠的看着挣扎的QCAD冷冷道:“三年前,曾经你们迦南家族从我手里抢走的,我要亲手一步步夺回来!”
目光如电,看向迦南二世隐匿的方向,迦南二世心头一惊,连忙低喝道:“发现我们了,快走!此子绝不是区区魔导师实力!暂且避其锋芒!”
临走前仇恨的看着魔子落叶:“早晚要除掉你这个孽障!”,一咬牙,化为一阵青烟遁走。
落叶看着求饶的QCAD,一脚踏下,只听得喀喳一声,世间一片寂静,再无声响。
重新打开QCAD看下:


16983326261295.jpg (783.12 KB, 下载次数: 0)
下载附件
2023-10-26 23:24 上传

成了激活所有功能,导出pdf也没有水印,弹窗也没有了,非常完美。
3. 结束
这篇教程不涉及到LLDB/补丁注入破解,尽管我是lldb+注入hook一路调试过来的,本篇教程仅用于给X1a0He同学以及其他同学用于入门逆向学习用,所以讲的非常精炼,省略了很多繁杂的步骤。
最后留了一个30分钟强制关闭的漏洞,请各位同学根据上面的思路自己处理掉吧!
4. LLDB 解决破解不完全依然提示弹框
我们lldb /Applications/QCAD.app/Contents/MacOS/QCAD启动后
可以看到:
23:46:18: Debug:    loading plugins...
23:46:19: Debug:    RDwgPlugin::init: trial
23:46:19: Debug:    RProScriptsPlugin::init: trial
23:46:20: Debug:    RTracePlugin::init: trial
23:46:20: Debug:    loading static plugins...
Warning:  Populating font family aliases took 632 ms. Replace uses of missing font family "Sans" with one that exists to avoid this cost.
Warning:  Cannot read file ':/scripts/Pro/Block/CreateLibraryItem/CreateLibraryItem-inverse.svg', because: Expected '?', '!', or '[a-zA-Z]', but got '
16983352372312.jpg (392.58 KB, 下载次数: 0)
下载附件
2023-10-26 23:59 上传

这三个依然是trial阶段,所以我们要patch掉:
RDwgPlugin::init: trial
RProScriptsPlugin::init: trial
RTracePlugin::init: trial


16983354154562.jpg (222.61 KB, 下载次数: 0)
下载附件
2023-10-26 23:59 上传

可以看到结果是这样子,所以我们ida打开这个文件直接搜:


16983354801911.jpg (223.86 KB, 下载次数: 0)
下载附件
2023-10-26 23:59 上传

可以看到这里存在字符串


16983356494770.jpg (113.71 KB, 下载次数: 2)
下载附件
2023-10-26 23:59 上传

仔细一看,这里checkLicense里面的修改根本没起作用,那么我们只好暴力点,直接全部强制条转:
我们将其jz跳转改为nop即可:


16983357647038.jpg (450.22 KB, 下载次数: 1)
下载附件
2023-10-26 23:59 上传

改后:


16983358029671.jpg (258.24 KB, 下载次数: 1)
下载附件
2023-10-26 23:59 上传

把指令所在位置强制改为9090,即可nop。


16983358273253.jpg (174.95 KB, 下载次数: 0)
下载附件
2023-10-26 23:59 上传

保存到文件,启动:


16983358701809.jpg (233.41 KB, 下载次数: 0)
下载附件
2023-10-26 23:59 上传

成功解决第一个,那么第二个第三个我就不多说了,大家去试试吧!
注入库补丁开源地址:
https://github.com/QiuChenlyOpenSource
注入补丁参考项目:
https://github.com/QiuChenlyOpenSource/InjectLib

下载次数, 下载附件

刘俊海   

天呐 这正是我们需要的帖子
魔术使nqy   

Mac居然也有破解软件,可以安装吗?
abcxyzmn   

只看到,大神们在打架!
曾经接触过这个qcad,win的,英文,似乎苹果的才有中文。不及格,放弃。
w011025   

怎么没人回帖,前来顶帖
封神之剑   

我是来拿成品的
YZ_TX   

感谢感谢
fengliuyang   

就是感觉挺厉害
tek2y   

牛逼,膜拜大佬
shixin   

看君一个贴,犹如神魔局,虽然看不懂破解,看看小说
您需要登录后才可以回帖 登录 | 立即注册

返回顶部