飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 12767|回复: 21

[原创] 010 Editor v8.x 启动时网络验证绕过方案(多.维度击破)

  [复制链接]

该用户从未签到

发表于 2018-1-9 11:07:26 | 显示全部楼层 |阅读模式
111.png

早上打开之后提示网验失败并且已过期。动手分析下如何快速绕过:

有很多字符串可用,于是定位到如果[rcx+30] == 0 则认为是注册版(这里其实对破解上用处不大,只是作为一个定位后堆栈回溯的点)。


  1. 00007FF7F58938EC | FF 15 6E 50 BB 01  | call qword ptr ds:[<&QLoggingRule::~QLogging |
  2. 00007FF7F58938F2 | 8B 87 8C 01 00 00  | mov eax,dword ptr ds:[rdi+18C]               |
  3. 00007FF7F58938F8 | 3D DB 00 00 00     | cmp eax,DB                                   | 返回了 113
  4. 00007FF7F58938FD | 0F 85 F7 00 00 00  | jne 010editor.7FF7F58939FA                   | 不可以跳转
  5. 00007FF7F5893903 | 48 8B 0D 8E 92 9A  | mov rcx,qword ptr ds:[7FF7F723CB98]          |
  6. 00007FF7F589390A | 83 79 30 01        | cmp dword ptr ds:[rcx+30],1                  | 是否注册的标志位
  7. 00007FF7F589390E | 75 2D              | jne 010editor.7FF7F589393D                   |
  8. 00007FF7F5893910 | 48 8D 15 D9 25 EE  | lea rdx,qword ptr ds:[7FF7F6775EF0]          | 00007FF7F6775EF0:"Registered - Single User License"
  9. 00007FF7F5893917 | 48 8D 4D 30        | lea rcx,qword ptr ss:[rbp+30]                |
  10. 00007FF7F589391B | FF 15 E7 60 BB 01  | call qword ptr ds:[<&QString::QString>]      |
复制代码


通过堆栈回溯几层,来到这里,只要这里最后再跳即可进入程序界面:


  1. 00007FF7F5E0135B | 81 FB 77 01 00 00  | cmp ebx,177                                   |
  2. 00007FF7F5E01361 | 74 35              | je 010editor.7FF7F5E01398                     |
  3. 00007FF7F5E01363 | 83 FB 2F           | cmp ebx,2F                                    | 2F:'/'
  4. 00007FF7F5E01366 | 74 30              | je 010editor.7FF7F5E01398                     |
  5. 00007FF7F5E01368 | 81 FB ED 00 00 00  | cmp ebx,ED                                    |
  6. 00007FF7F5E0136E | 74 28              | je 010editor.7FF7F5E01398                     |
  7. 00007FF7F5E01370 | 81 FB 13 01 00 00  | cmp ebx,113                                   |
  8. 00007FF7F5E01376 | 74 20              | je 010editor.7FF7F5E01398                     |
  9. 00007FF7F5E01378 | 81 FB 0C 02 00 00  | cmp ebx,20C                                   |
  10. 00007FF7F5E0137E | 0F 85 DF 00 00 00  | jne 010editor.7FF7F5E01463                    | 要从这里跳走 即可绕过启动时的验证弹框
  11. 00007FF7F5E01384 | 48 8B 0D 0D B8 43  | mov rcx,qword ptr ds:[7FF7F723CB98]           |
  12. 00007FF7F5E0138B | E8 30 1E 3B FF     | call 010editor.7FF7F51B31C0                   |
  13. 00007FF7F5E01390 | 85 C0              | test eax,eax                                  |
  14. 00007FF7F5E01392 | 0F 84 C4 00 00 00  | je 010editor.7FF7F5E0145C                     |
复制代码


这样修改后程序就可以进入主界面,但是显示已经过期。

我们同时发现EBX的值为核心所在,搜索常量113,来到这里:


  1. 00007FF7F5CA61F0 | 48 89 5C 24 08     | mov qword ptr ss:[rsp+8],rbx                  | [rsp+8]:QArrayData::shared_null
  2. 00007FF7F5CA61F5 | 57                 | push rdi                                      |
  3. 00007FF7F5CA61F6 | 48 83 EC 20        | sub rsp,20                                    |
  4. 00007FF7F5CA61FA | 83 79 3C 00        | cmp dword ptr ds:[rcx+3C],0                   | IsRegister ... must zero   (通过验证 or 过期)
  5. 00007FF7F5CA61FE | 8B FA              | mov edi,edx                                   |
  6. 00007FF7F5CA6200 | 48 8B D9           | mov rbx,rcx                                   |
  7. 00007FF7F5CA6203 | 74 10              | je 010editor.7FF7F5CA6215                     | JMP
  8. 00007FF7F5CA6205 | B8 13 01 00 00     | mov eax,113                                   | remember 113
  9. 00007FF7F5CA620A | 48 8B 5C 24 30     | mov rbx,qword ptr ss:[rsp+30]                 |
  10. 00007FF7F5CA620F | 48 83 C4 20        | add rsp,20                                    |
  11. 00007FF7F5CA6213 | 5F                 | pop rdi                                       |
  12. 00007FF7F5CA6214 | C3                 | ret                                           |
  13. 00007FF7F5CA6215 | E8 2C DB 50 FF     | call 010editor.7FF7F51B3D46                   |
  14. 00007FF7F5CA621A | 83 F8 2D           | cmp eax,2D                                    | 2D:'-'
  15. 00007FF7F5CA621D | 0F 84 CB 00 00 00  | je 010editor.7FF7F5CA62EE                     |
  16. 00007FF7F5CA6223 | 83 F8 4E           | cmp eax,4E                                    | 4E:'N'
  17. 00007FF7F5CA6226 | 0F 84 90 00 00 00  | je 010editor.7FF7F5CA62BC                     |
复制代码


我们发现这里默认不跳直接赋值113了,于是将[rcx+3C]赋值为0(这里可能是判断是否已过期,过期将走网络验证),让其走后续流程。
(有兴趣的话大家可以自己定位下该数据是哪里赋值的,可能是网络验证的返回值,如果启动的时候把网络验证直接retn可能启动速度会更快一些)

010Editor.jpg

由于我本机保存了注册信息,所以修改后我们不仅绕过了启动验证,也可以在程序界面显示注册信息。

222.png

===============================================

方法2:

我们看一下网络发包:
http://www.sweetscape.com/cgibin ... d=0&chk=33086&typ=0

122.png

未通过网络验证的情况下返回 <ss>invalid</ss>  , 而随意输入的key返回值是"error":

000.png

我们在程序里搜索该字符串:

226.png

然后我们将字符串比较处修改,将字符串指向 invalid+2 的地址,

111.png

修改并保存(将 error 和 invalid 字符串 都修改为 invalid+2 的地址):

fix.png


至此,被封掉的KEY返回的错误值已被程序定义为通过了网络验证(将 error 修改为 invalid 字符串是不OK的 !)。


  1. 00007FF6EF597621 | 4C 8D 05 34 AC E2 00      | lea r8,qword ptr ds:[7FF6F03C225C]         | 00007FF6F03C225C:"error"
  2. 00007FF6EF597628 | 0F 1F 84 00 00 00 00 00   | nop dword ptr ds:[rax+rax]                 | 将上方的字符串地址修改为 invalid 地址
  3. 00007FF6EF597630 | 0F B6 04 0A               | movzx eax,byte ptr ds:[rdx+rcx]            |
  4. 00007FF6EF597634 | 48 FF C1                  | inc rcx                                    |
  5. 00007FF6EF597637 | 41 3A 44 08 FF            | cmp al,byte ptr ds:[r8+rcx-1]              |
  6. 00007FF6EF59763C | 75 0E                     | jne 010editor.7FF6EF59764C                 |
  7. 00007FF6EF59763E | 48 83 F9 06               | cmp rcx,6                                  |
  8. 00007FF6EF597642 | 75 EC                     | jne 010editor.7FF6EF597630                 |
  9. 00007FF6EF597644 | 8D 41 F4                  | lea eax,qword ptr ds:[rcx-C]               |
  10. 00007FF6EF597647 | E9 AC 00 00 00            | jmp 010editor.7FF6EF5976F8                 | 若为 error 则直接失败
  11. 00007FF6EF59764C | 33 C0                     | xor eax,eax                                |
  12. 00007FF6EF59764E | 48 8D 54 24 30            | lea rdx,qword ptr ss:[rsp+30]              |
  13. 00007FF6EF597653 | 4C 8D 05 06 38 F9 00      | lea r8,qword ptr ds:[7FF6F052AE60]         | 00007FF6F052AE60:"invalid"
  14. 00007FF6EF59765A | 66 0F 1F 44 00 00         | nop word ptr ds:[rax+rax]                  |
  15. 00007FF6EF597660 | 0F B6 0C 02               | movzx ecx,byte ptr ds:[rdx+rax]            |
  16. 00007FF6EF597664 | 48 FF C0                  | inc rax                                    |
  17. 00007FF6EF597667 | 41 3A 4C 00 FF            | cmp cl,byte ptr ds:[r8+rax-1]              | 比较字符串
  18. 00007FF6EF59766C | 75 19                     | jne 010editor.7FF6EF597687                 |
  19. 00007FF6EF59766E | 48 83 F8 08               | cmp rax,8                                  |
  20. 00007FF6EF597672 | 75 EC                     | jne 010editor.7FF6EF597660                 |
  21. 00007FF6EF597674 | C7 43 3C 01 00 00 00      | mov dword ptr ds:[rbx+3C],1                | 若为 invalid 则赋值为1 验证失败
  22. 00007FF6EF59767B | E8 3A 2A 51 FF            | call 010editor.7FF6EEAAA0BA                |
  23. 00007FF6EF597680 | BA 01 00 00 00            | mov edx,1                                  |
  24. 00007FF6EF597685 | EB 0E                     | jmp 010editor.7FF6EF597695                 |
  25. 00007FF6EF597687 | C7 43 3C 00 00 00 00      | mov dword ptr ds:[rbx+3C],0                | 跳向网络验证成功

复制代码


BTW: 或者将 invalid 字符串修改掉(修改任意字符即可)即可过网络验证。 感谢 不破不立 分享的改方案。

00007FF7F6C3AE50  00 00 00 00 00 00 00 00 73 73 00 00 00 00 00 00  ........ss......  
00007FF7F6C3AE60  69 6E 76 61 6C 69 64 00 00 00 00 00 3C 25 73 3E  invalid.....<%s>  
00007FF7F6C3AE70  00 00 00 00 3C 2F 25 73 3E 00 00 00 00 00 00 00  ....</%s>.......  


===============================================

补充(方法三):
上文提到了 cmp dword ptr ds:[rcx+3C],0 该值为是否走网络验证的一个关键值(可能是是否过期也可能是是否联网验证通过)。我们分析一下该数值的由来,第一次调用处堆栈回溯:


  1. 00007FF7F5E011F2 | E8 4B 25 0D 00                 | call <010editor.operator new>                      |
  2. 00007FF7F5E011F7 | 48 89 45 77                    | mov qword ptr ss:[rbp+77],rax                      |
  3. 00007FF7F5E011FB | 48 85 C0                       | test rax,rax                                       |
  4. 00007FF7F5E011FE | 74 0A                          | je 010editor.7FF7F5E0120A                          |
  5. 00007FF7F5E01200 | 48 8B C8                       | mov rcx,rax                                        | 申请对象
  6. 00007FF7F5E01203 | E8 68 6F 3B FF                 | call 010editor.7FF7F51B8170                        | 初始化对象
  7. 00007FF7F5E01208 | EB 03                          | jmp 010editor.7FF7F5E0120D                         |
  8. 00007FF7F5E0120A | 48 8B C7                       | mov rax,rdi                                        |
  9. 00007FF7F5E0120D | 48 89 05 84 B9 43 01           | mov qword ptr ds:[7FF7F723CB98],rax                |
  10. 00007FF7F5E01214 | 48 8B C8                       | mov rcx,rax                                        |
  11. 00007FF7F5E01217 | E8 3F 75 3B FF                 | call 010editor.7FF7F51B875B                        | 这里为对象的成员赋值
  12. 00007FF7F5E0121C | 48 8B 0D 75 B9 43 01           | mov rcx,qword ptr ds:[7FF7F723CB98]                |
复制代码


首先从注册表读取一个DWORD

time.png


  1. 00007FF7F5CA8A13 | 48 8D 15 DE 29 F9 00           | lea rdx,qword ptr ds:[7FF7F6C3B3F8]         | 00007FF7F6C3B3F8:"ThreadingModel"
  2. 00007FF7F5CA8A1A | 48 8D 4D B0                    | lea rcx,qword ptr ss:[rbp-50]               |
  3. 00007FF7F5CA8A1E | FF 15 E4 0F 7A 01              | call qword ptr ds:[<&QString::QString>]     |
  4. 00007FF7F5CA8A24 | 90                             | nop                                         |
  5. 00007FF7F5CA8A25 | 4D 8B C6                       | mov r8,r14                                  | r14:"{FA1395FC-83C3-0732-7D11-0134937462A0}"
  6. 00007FF7F5CA8A28 | 48 8D 55 C8                    | lea rdx,qword ptr ss:[rbp-38]               |
  7. 00007FF7F5CA8A2C | 48 8D 4D D0                    | lea rcx,qword ptr ss:[rbp-30]               | [rbp-30]:QArrayData::shared_null
  8. 00007FF7F5CA8A30 | E8 44 16 51 FF                 | call 010editor.7FF7F51BA079                 |
  9. 00007FF7F5CA8A35 | 90                             | nop                                         |
  10. 00007FF7F5CA8A36 | 4C 8D 05 D3 29 F9 00           | lea r8,qword ptr ds:[7FF7F6C3B410]          | 00007FF7F6C3B410:"\\InProcServer32A\"
  11. ... ...
  12. 00007FF7F5CA8AD2 | FF 15 98 02 7A 01              | call qword ptr ds:[<&QString::toUInt>]      |
  13. 00007FF7F5CA8AD8 | 89 07                          | mov dword ptr ds:[rdi],eax                  | 这里将 ThreadingModel 的 hex 值写入内存  (!**将这里修改为0即可!)
  14. 00007FF7F5CA8ADA | B3 01                          | mov bl,1                                    |
复制代码


112.png

然后对其运算(该函数的返回值决定是否走网络验证分支):

  1. 00007FF7F5CA4A70 | 81 F1 D4 9C 32 C7              | xor ecx,C7329CD4                            |
  2. 00007FF7F5CA4A76 | B8 33 43 90 34                 | mov eax,34904333                            |
  3. 00007FF7F5CA4A7B | 81 E9 FF B4 49 27              | sub ecx,2749B4FF                            |
  4. 00007FF7F5CA4A81 | 81 F1 C0 80 42 7C              | xor ecx,7C4280C0                            |
  5. 00007FF7F5CA4A87 | 44 8B C1                       | mov r8d,ecx                                 |
  6. 00007FF7F5CA4A8A | F7 E1                          | mul ecx                                     |
  7. 00007FF7F5CA4A8C | 44 2B C2                       | sub r8d,edx                                 |
  8. 00007FF7F5CA4A8F | 41 D1 E8                       | shr r8d,1                                   |
  9. 00007FF7F5CA4A92 | 44 03 C2                       | add r8d,edx                                 |
  10. 00007FF7F5CA4A95 | 41 C1 E8 0D                    | shr r8d,D                                   |
  11. 00007FF7F5CA4A99 | 41 69 C0 19 35 00 00           | imul eax,r8d,3519                           |
  12. 00007FF7F5CA4AA0 | 3B C8                          | cmp ecx,eax                                 |
  13. 00007FF7F5CA4AA2 | B8 00 00 00 00                 | mov eax,0                                   |
  14. 00007FF7F5CA4AA7 | 41 0F 44 C0                    | cmove eax,r8d                               |// ** 这里将 eax 清零即可绕开网络验证分支
  15. 00007FF7F5CA4AAB | C3                             | ret                                         |
复制代码


F5:

  1. __int64 __fastcall sub_140AF4A70(int a1)  // 注册表键值: 1690216811 = 0x64BEA96B
  2. {
  3.   unsigned int v1; // ecx
  4.   __int64 result; // rax

  5.   v1 = ((a1 ^ 0xC7329CD4) - 659141887) ^ 0x7C4280C0;
  6.   result = 0i64;
  7.   if ( v1 == 13593 * (v1 / 0x3519) )
  8.     result = v1 / 0x3519;
  9.   return result;
  10. }
复制代码



运算的结果保存到[rcx+3C]偏移中,若为0则不走网络验证。这个值是什么时候被修改的呢?随机网络验证还是过期的时候走了网络验证就不得而知了 。。。
将以下信息导入注入表(或自行修改)即可完成验证:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\SweetScape\010 Editor\CLASSES\CLSID\{FA1395FC-83C3-0732-7D11-0134937462A0}]

[HKEY_CURRENT_USER\Software\SweetScape\010 Editor\CLASSES\CLSID\{FA1395FC-83C3-0732-7D11-0134937462A0}\InProcServer32A]
"ThreadingModel"="1690216811"

===============================================

补充2(方法四):

我们跟踪一下网络验证过程:


  1. 00007FF6EF371CEF | FF 15 D3 75 9C 01         | call qword ptr ds:[<&QUrl::QUrl>]          | // 这里开始发送访问验证URL
  2. ...
  3. 00007FF6EF371DE5 | E8 BC 46 73 FF            | call 010editor.7FF6EEAA64A6                | // 这里获取本地时间 GetLocalTime 判定是否过期?
  4. ...
  5. 00007FF6EF371F04 | FF 15 D6 73 9C 01          | call qword ptr ds:[<&QIODevice::read>]     |// 这里获取网络验证返回值 参数在 rdx

  6. 1: rcx 0000021DBAEDD3E0
  7. 2: rdx 0000021DBAED7FD0         // buffer
  8. 3: r8 0000000000000013         // length
  9. 4: r9 000000000000001E
复制代码


0000021DBAEE0900  3C 73 73 3E 69 6E 76 61 6C 69 64 3C 2F 73 73 3E  <ss>invalid</ss>  
0000021DBAEE0910  20 0A 0A

我们将其修改为其他值,即可绕过网络验证:

0000021DBAEE0900  3C 73 73 3E 73 75 63 63 65 73 73 3C 2F 73 73 3E  <ss>success</ss>
0000021DBAEE0910  20 0A 0A

qint64 QIODevice::read(char *data, qint64 maxSize)
官方文档:http://doc.qt.io/qt-5/qiodevice.html#read

所以我们也可以直接 HOOK  qt5core.dll 中的 QIODevice::read 函数,当 maxSize == 0x13 时 && 返回字符串为 “<ss>invalid</ss> ”或“<ss>error</ss>   ”
则修改返回值为“<ss>success</ss>”,即可通过网络验证!

评分

参与人数 12威望 +112 飘云币 +140 收起 理由
NoNameX2016 + 8 + 8 赞一个!
smallhorse + 8 + 8 咱小白菜要的就是这样的分析!学习了!
pentium450 + 20 + 20 太厉害了!
dryzh + 4 校长威武霸气
linuxchao + 20 + 20 很给力!
666888tzq + 4 赞一个!
liutongbao + 4 + 4 PYG有你更精彩!
不破不立 + 20 + 20 感谢发布原创作品!
Rooking + 40 分分钟干掉了
zeknight + 3 PYG有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-1-10 10:07
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2018-1-9 11:14:47 | 显示全部楼层
    校长V5,分分钟搞定
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-4-1 09:59
  • 签到天数: 76 天

    [LV.6]常住居民II

    发表于 2018-1-9 12:26:03 | 显示全部楼层
    本帖最后由 theend 于 2018-1-9 12:27 编辑

    感谢校长分享,学习了!
    自己测试了一下,触发验证并不是JE都不跳,默认跳过的次数多
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-19 21:36
  • 签到天数: 245 天

    [LV.8]以坛为家I

    发表于 2018-1-9 13:23:19 | 显示全部楼层
    谢谢分享,学习了。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2022-9-4 21:29
  • 签到天数: 1756 天

    [LV.Master]伴坛终老

    发表于 2018-1-9 13:58:33 | 显示全部楼层
    大神就是大神!V5
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    7 天前
  • 签到天数: 1523 天

    [LV.Master]伴坛终老

    发表于 2018-1-9 18:15:23 | 显示全部楼层
    多年未见这么详细的文章了!赞
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-9-18 06:39
  • 签到天数: 1930 天

    [LV.Master]伴坛终老

    发表于 2018-1-9 18:55:33 来自手机 | 显示全部楼层
    666,大佬威武,受教育了
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 20:40
  • 签到天数: 1790 天

    [LV.Master]伴坛终老

    发表于 2018-1-9 20:29:57 | 显示全部楼层
    校长亲自操刀果然是精华学习了
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 09:32
  • 签到天数: 2178 天

    [LV.Master]伴坛终老

    发表于 2018-1-9 21:02:07 | 显示全部楼层
    收藏,学习,校长今天兴致高,一气呵成,相当于三个学习教程
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2018-1-9 21:07
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-1-9 21:09:04 | 显示全部楼层
    谢谢楼主,分享.
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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