飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 7308|回复: 10

[原创] 对有关pc qq8.7提示版本太低进行分析

[复制链接]
  • TA的每日心情
    擦汗
    2016-4-19 21:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2019-12-2 21:41:35 | 显示全部楼层 |阅读模式
    本帖最后由 wai1216 于 2019-12-3 09:58 编辑

    好久不见,上来冒个泡

    前几天在windows上登qq,被提示如下文字
    因当前版本存在安全风险,将无法继续使用................

    无奈,逆向之.

    逆向前,先思考了下.
    这样突然出现不能登录,从逻辑上来讲应该是服务器返回过来判断的.因此发包的时候会去效验了版本之类的东西.
    但是呢,我又不太想通过走网络层面去patch,虽然有可能patch就不是以下地方了。

    1. 进行修改
    一番搜索后,发现有一款叫ntrqq的小插件,可以搞定这个限制.
    下载了最新版,载入后dump了下来,看了看作者是如何实现的.
    [Asm] 纯文本查看 复制代码
    {
      if ( v31 == 1 )
        v31 = 0x1636;
      __fuckqqloginlimit_pubno = v31;
      v34 = sub_68F73290(v31, L"PreloginLogic.dll");
      v35 = GetProcAddress(dword_68F3B7C4, "?GetPubNo@Version@@YAKXZ");
      if ( v34 )
      {
        if ( !v35 )
        {
          v36 = v7(L"AFBase.dll");
          v35 = GetProcAddress(v36, "?GetPubNo@Version@@YAKXZ");
          if ( !v35 )
          {
            v37 = v7(L"AppUtil.dll");
            v35 = GetProcAddress(v37, "?GetPubNo@Version@@YAKXZ");
            if ( !v35 )
            {
              v38 = v7(L"PreloginLogic.dll");
              v35 = GetProcAddress(v38, "?GetPubNo@Version@@YAKXZ");
            }
          }
        }
        result = sub_68EF2A30(v35, "KernelUtil.dll", v7, sub_68EE3500, v34);
      }
      else
      {
        v39 = v35;
        if ( v35
          || (v40 = v7(L"AFBase.dll"), (v39 = GetProcAddress(v40, "?GetPubNo@Version@@YAKXZ")) != 0)
          || (v41 = v7(L"AppUtil.dll"), (v39 = GetProcAddress(v41, "?GetPubNo@Version@@YAKXZ")) != 0)
          || (v42 = v7(L"PreloginLogic.dll"), result = GetProcAddress(v42, "?GetPubNo@Version@@YAKXZ"), (v39 = result) != 0) )
        {
          LOBYTE(Buffer) = -23;
          result = (sub_68EE3500 - v39 - 5);
          *(&Buffer + 1) = sub_68EE3500 - v39 - 5;
          if ( v39 != -1 )
          {
            flOldProtect = 0;
            VirtualProtect(v39, 5u, 0x40u, &flOldProtect);
            WriteProcessMemory(0xFFFFFFFF, v39, &Buffer, 5u, 0);
            result = VirtualProtect(v39, 5u, flOldProtect, 0);
          }
        }
      }
      return result;
    }
    
    其中 v31 = GetPrivateProfileIntW("Login", "FuckQQLoginLimit", 0, "NtrQQ.ini");
    


    作者把有调用GetPubNo这个函数的几个dll进行了patch,以至于返回NtrQQ.ini中设定好的数值,如果为1,则为0x1636
    当然还在其它地方进行了修改,这个稍后再谈

    现在有了大概方向就好办了,首先看了看这个函数的代码
    [Asm] 纯文本查看 复制代码
    kernelutil.dll <?GetPubNo@Version@@YAKXZ>
    int Version::GetPubNo()
    {
      return dword_5331CCCC;
    }
    


    只是一个全局变量,在下面函数进行的初始化
    [Asm] 纯文本查看 复制代码
    kernelutil.dll<?Init@Version@@YAHXZ>  // hummerengine.dll 中调用
    int __thiscall Version::Init(void *ecx0)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      v23 = L"vi.dat";
      v22 = ecx0;
      Target = 0;
      NumberOfBytesRead = 0;
      CTXStringW::CTXStringW((CTXStringW *)&v22, &Default);
      v1 = Util::Sys::GetProgramBinDir(&v27);
      operator+(&v24, v1);
      CTXStringW::~CTXStringW((CTXStringW *)&v27);
      v23 = 0;
      v22 = 0;
      v2 = (const WCHAR *)CTXStringW::operator wchar_t const *(&v24);
      v3 = CreateFileW(v2, 0x80000000, 1u, 0, 3u, (DWORD)v22, (HANDLE)v23);
      if ( v3 != (HANDLE)-1 )
      {
        FileSizeHigh = 0;
        v4 = GetFileSize(v3, &FileSizeHigh);
        v5 = v4;
        if ( !FileSizeHigh && v4 < 0x5000 )
        {
          Target = unknown_libname_95(v4);
          ReadFile(v3, (LPVOID)Target, v5, &NumberOfBytesRead, 0);
        }
        CloseHandle(v3);
      }
      v32 = 15;
      v31 = 0;
      LOBYTE(v30) = 0;
      sub_532970AA(&v30, NumberOfBytesRead);
      sub_53270CB5(&Target);
      if ( v31 < 0x10 )
        goto LABEL_20;
      v6 = v30;
      if ( v32 < 0x10 )
        v6 = &v30;
      memcpy(&byte_5331CCB4, v6, 0xCu);
      v7 = *((_WORD *)v6 + 6);
      v8 = v31 - 14;
      v9 = (int)v6 + 14;
      v29 = v7;
      if ( v31 - 14 < v7 + 2 )
        goto LABEL_20;
      CTXStringW::CTXStringW(&FileSizeHigh, v9, v7 >> 1);
      v10 = (_WORD *)(v29 + v9);
      v11 = *v10;
      v12 = v8 - v29 - 2;
      v13 = (int)(v10 + 1);
      v29 = v11;
      if ( v12 < v11 )
      {
        CTXStringW::~CTXStringW((CTXStringW *)&FileSizeHigh);
    LABEL_20:
        v20 = 0;
        goto LABEL_18;
      }
      CTXStringW::CTXStringW(&v27, v13, v11 >> 1);
      v14 = CTXStringW::operator wchar_t const *(&v27);
      CTXStringW::operator=(&unk_5331CCC0, v14);
      v15 = CTXStringW::operator wchar_t const *(&FileSizeHigh);
      CTXStringW::operator=(&unk_5331CCC4, v15);
      v16 = v29 + v13;
      v17 = v12 - v29;
      dword_5331CCC8 = 65793;
      dword_5331CCCC = 25600;
      if ( (unsigned __int8)byte_5331CCB5 + 100 * (unsigned __int8)byte_5331CCB4 >= 2574 && v17 >= 8 )
      {
        memcpy(&dword_5331CCC8, (const void *)v16, 4u);
        memcpy(&dword_5331CCCC, (const void *)(v16 + 4), 4u);
        v16 += 8;
        v17 -= 8;
      }
      if ( v17 >= 2 )
      {
        v18 = *(_WORD *)v16;
        if ( v17 - 2 >= v18 )
        {
          CTXStringW::CTXStringW(&v29, v16 + 2, v18 >> 1);
          v19 = CTXStringW::operator wchar_t const *(&v29);
          CTXStringW::operator=(&unk_5331CCD0, v19);
          CTXStringW::~CTXStringW((CTXStringW *)&v29);
        }
      }
      CTXStringW::~CTXStringW((CTXStringW *)&v27);
      CTXStringW::~CTXStringW((CTXStringW *)&FileSizeHigh);
      v20 = 1;
    LABEL_18:
      std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(&v30, 1, 0);
      CTXStringW::~CTXStringW((CTXStringW *)&v24);
      return v20;
    }
    


    注意到有个call sub_532970AA,该函数首先通过CTXCommPack::GetWord得到dat文件的开头两字节判断是否为0,之后调用GetByte判断是否2了
    也就是说dat头部要满足00 00 02,之后通过GetModuleFileNameW得到qq.exe计算md5,再将其md5循环20次得到的hash作为解密vi.dat的密钥(变形tea),伪代码如下
    [Asm] 纯文本查看 复制代码
    signed int __cdecl sub_53296DB9(char a1, unsigned __int8 *a2)
    {
      MD5_Init((struct MD5state_st *)&v14);
      for ( i = ReadFile(hFile, &Buffer, 0x1000u, &NumberOfBytesRead, 0);
            i && NumberOfBytesRead;
            i = ReadFile(hFile, &Buffer, 0x1000u, &NumberOfBytesRead, 0) )
      {
        MD5_Update((struct MD5state_st *)&v14, (const unsigned __int8 *)&Buffer, NumberOfBytesRead);
      }
      CloseHandle(hFile);
      if ( a1 != 3 )
        goto LABEL_12;
      v7 = GetModuleHandleW(0);
      if ( v7 )
      {
        MD5_Update(
          (struct MD5state_st *)&v14,
          (const unsigned __int8 *)v7 + *(_DWORD *)((char *)v7 + *((_DWORD *)v7 + 15) + 44),
          *(_DWORD *)((char *)v7 + *((_DWORD *)v7 + 15) + 28));
    LABEL_12:
        MD5_Final(a2, (struct MD5state_st *)&v14);
        v8 = 20;
        do
        {
          MD5_Init((struct MD5state_st *)&v13);
          MD5_Update((struct MD5state_st *)&v13, a2, 0x10u);
          MD5_Final(a2, (struct MD5state_st *)&v13);
          --v8;
        }
        while ( v8 );
        v3 = 1;
      }
    }
    


    之后通过GetBuf和GetWord获取到加密数据的大小,而此时文件的偏移刚好是加密后数据的起始位置
    那么有关vi.dat的结构就可以抽象成如下
    [Asm] 纯文本查看 复制代码
    struct s_buf{
    short flag;
    byte  type;
    short offset;
    byte unknown_like_padding[offset];
    short define_tea_encrypt_size;
    byte define_tea_encrypt_data[encrypt_size];
    };
    

    接着通过oi_symmetry_decrypt2进行解密
    [Asm] 纯文本查看 复制代码
    .text:532971D1                 lea     ecx, [ebp+var_40]
    .text:532971D4                 push    ecx
    .text:532971D5                 push    eax
    .text:532971D6                 mov     [ebp+var_48], eax
    .text:532971D9                 lea     eax, [ebp+var_14]
    .text:532971DC                 push    eax
    .text:532971DD                 movzx   eax, [ebp+var_34]
    .text:532971E1                 push    eax
    .text:532971E2                 push    [ebp+var_44]
    .text:532971E5                 call    ds:?oi_symmetry_decrypt2@@YAHPBEH0PAEPAH@Z ; oi_symmetry_decrypt2(uchar const *,int,uchar const *,uchar *,int *)
    .text:532971EB                 add     esp, 18h
    


    以我所使用的版本得到如下数据
    [Asm] 纯文本查看 复制代码
    00526280  37 03 00 00 C9 4A 00 00 08 00 00 00 46 00 24 00  7...éJ......F.$.  
    00526290  50 00 52 00 4F 00 44 00 4E 00 41 00 4D 00 45 00  P.R.O.D.N.A.M.E.  
    005262A0  24 00 20 00 50 00 72 00 65 00 76 00 69 00 65 00  $. .P.r.e.v.i.e.  
    005262B0  77 00 34 00 28 00 38 00 2E 00 37 00 2E 00 31 00  w.4.(.8...7...1.  
    005262C0  39 00 31 00 34 00 35 00 2E 00 32 00 30 00 31 00  9.1.4.5...2.0.1.  
    005262D0  29 00 00 00 1C 00 38 00 2E 00 37 00 2E 00 31 00  ).....8...7...1.  
    005262E0  39 00 31 00 34 00 35 00 2E 00 32 00 30 00 31 00  9.1.4.5...2.0.1.  
    005262F0  00 00 01 01 01 00 24 68 00 00 70 01 48 00 75 00  ......$h..p.H.u.  
    00526300  6D 00 6D 00 65 00 72 00 45 00 6E 00 67 00 69 00  m.m.e.r.E.n.g.i.  
    00526310  6E 00 65 00 2E 00 64 00 6C 00 6C 00 3A 00 46 00  n.e...d.l.l.:.F.  
    00526320  30 00 41 00 32 00 46 00 45 00 36 00 41 00 42 00  0.A.2.F.E.6.A.B.  
    00526330  41 00 46 00 32 00 42 00 35 00 43 00 34 00 32 00  A.F.2.B.5.C.4.2.  
    00526340  43 00 36 00 34 00 39 00 36 00 43 00 32 00 45 00  C.6.4.9.6.C.2.E.  
    00526350  36 00 39 00 35 00 43 00 30 00 42 00 43 00 7C 00  6.9.5.C.0.B.C.|.  
    00526360  4C 00 6F 00 6E 00 67 00 43 00 6E 00 6E 00 2E 00  L.o.n.g.C.n.n...  
    00526370  64 00 6C 00 6C 00 3A 00 35 00 33 00 35 00 42 00  d.l.l.:.5.3.5.B.  
    00526380  42 00 33 00 39 00 43 00 39 00 45 00 42 00 35 00  B.3.9.C.9.E.B.5.  
    00526390  31 00 30 00 42 00 42 00 36 00 46 00 46 00 32 00  1.0.B.B.6.F.F.2.  
    005263A0  35 00 32 00 33 00 44 00 31 00 30 00 30 00 35 00  5.2.3.D.1.0.0.5.  
    005263B0  31 00 39 00 45 00 37 00 7C 00 4B 00 65 00 72 00  1.9.E.7.|.K.e.r.  
    005263C0  6E 00 65 00 6C 00 55 00 74 00 69 00 6C 00 2E 00  n.e.l.U.t.i.l...  
    005263D0  64 00 6C 00 6C 00 3A 00 39 00 31 00 34 00 33 00  d.l.l.:.9.1.4.3.  
    005263E0  39 00 43 00 33 00 36 00 33 00 36 00 32 00 36 00  9.C.3.6.3.6.2.6.  
    005263F0  41 00 37 00 32 00 30 00 42 00 46 00 42 00 33 00  A.7.2.0.B.F.B.3.  
    00526400  33 00 32 00 45 00 42 00 34 00 45 00 32 00 32 00  3.2.E.B.4.E.2.2.  
    00526410  31 00 31 00 36 00 37 00 7C 00 54 00 53 00 49 00  1.1.6.7.|.T.S.I.  
    00526420  50 00 2E 00 44 00 41 00 54 00 3A 00 31 00 39 00  P...D.A.T.:.1.9.  
    00526430  37 00 34 00 33 00 38 00 31 00 30 00 43 00 30 00  7.4.3.8.1.0.C.0.  
    00526440  36 00 43 00 42 00 39 00 31 00 44 00 32 00 37 00  6.C.B.9.1.D.2.7.  
    00526450  33 00 35 00 45 00 34 00 44 00 33 00 34 00 46 00  3.5.E.4.D.3.4.F.  
    00526460  44 00 42 00 34 00 38 00 31 00 37 00 00 00 00 00  D.B.4.8.1.7.....
    


    给出分析的结构
    [Asm] 纯文本查看 复制代码
    struct s_data{
    typedef struct s_ver{
    byte majorver:1;
    byte minorver:1;
    short padding:2;
    }t_ver;
    dword buildver;
    dword unknown;
    byte  vername[];
    dword clienttype;
    dowrd pubno;
    short dll_information_size; 
    byte  dll_information[dll_information_size];
    };
    


    到这里就可以构造出想要的pubno号,然后调用oi_symmetry_encrypt2加密数据替换掉vi.dat.

    然后打开qq却发现提示了两个初始化错误0x0d以及0x30,继续进行分析,注意到仅替换了pubno.
    int Version::GetPubNo()处下断,发现是在HummerEngine.dll中进行的check,伪代码如下: //ntrqq的作者好像对此函数也进行了path
    [Asm] 纯文本查看 复制代码
    signed int sub_528CAE70()
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      if ( sub_528D2997()
        && ((CTXStringW::CTXStringW(&v10, L"platform"),
             operator+(&v9, &v10, L"res:"),
             CTXStringW::~CTXStringW(&v10),
             v1 = sub_528CAD0A(&v9),
             CTXStringW::~CTXStringW(&v9),
             CTXStringW::CTXStringW(&v9, L"platform"),
             operator+(&v10, &v9, L"xtml:"),
             CTXStringW::~CTXStringW(&v9),
             v8 = sub_528CAD0A(&v10),
             CTXStringW::~CTXStringW(&v10),
             CTXStringW::CTXStringW(&v9, L"platform"),
             operator+(&v10, &v9, L"data:"),
             CTXStringW::~CTXStringW(&v9),
             v2 = sub_528CAD0A(&v10),
             CTXStringW::~CTXStringW(&v10),
             v3 = CTXStringW::CTXStringW(&v9, L"platformtheme:"),
             v4 = sub_528CAD0A(v3),
             CTXStringW::~CTXStringW(&v9),
             v5 = Version::GetPubNo(),
             v1 != v5)
         || v8 != v5
         || v2 != v5
         || v4 != v5) )
      {
            .....
      }
    }
    

    sub_528D2997() 点进去看了看,大概是为创建另一进程起的部分参数
    对赋值函数进行分析,伪代码如下
    [Asm] 纯文本查看 复制代码
    int __stdcall sub_528CAD0A(int a1)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      qmemcpy(&v12, L"pubversion.dat", 0x1Eu);
      v1 = CTXStringW::operator wchar_t const *(a1);
      FS::CombineQNC(&v9, v1, &v12);
      v11 = 0;
      v2 = CTXStringW::operator wchar_t const *(&v9);
      FS::CreateFileW(v2, 0, &v11);
      ...
      CTXStringA::CTXStringA(&v6, v7, v8);
      v3 = CTXStringA::GetBuffer(&v6);
      v4 = StrToIntA(v3);
      CTXStringA::~CTXStringA(&v6);
      ...
    }
    

    动态跟了跟,原来读取的安装目录下Resource.8.7.19145的四个.rdb
    搜索了下网上对rdb解析的工具,发现解析不了.
    无奈之下只有分析下结构对值进行修改.给出逆向后的结构
    [Asm] 纯文本查看 复制代码
    struct s_rdb{
    byte feature[0x10];
    dword count;
    dword res_struct_offset;
    dword padding;
    dword res_data_offset;
    };
    
    struct s_res{
    wchar name[];
    dword offset;
    dowrd unknown;
    dword size;
    };
    


    用资源下的data.rdb来举例子
    [Asm] 纯文本查看 复制代码
    00000000  35 33 31 45 39 38 32 30  34 46 38 35 34 32 46 30  531E98204F8542F0
    00000010  18 09 00 00 24 00 00 00  00 00 00 00 CC 3D 02 00  ....$........=..
    00000020  00 00 00 00 62 00 74 00  6E 00 72 00 65 00 70 00  ....b.t.n.r.e.p.
    00000030  6F 00 72 00 74 00 5C 00  67 00 75 00 69 00 64 00  o.r.t.\.g.u.i.d.
    00000040  32 00 74 00 74 00 2E 00  64 00 61 00 74 00 00 00  2.t.t...d.a.t...
    00000050  00 00 00 00 00 00 00 00  85 F1 01 00 00 00 00 00  ................
    00000060  70 00 75 00 62 00 76 00  65 00 72 00 73 00 69 00  p.u.b.v.e.r.s.i.
    00000070  6F 00 6E 00 2E 00 64 00  61 00 74 00 00 00 85 F1  o.n...d.a.t.....
    00000080  01 00 00 00 00 00 05 00  00 00 00 00 00 00 61 00  ..............a.
    


    pubversion.data数据的位置应该是 0x23dcc + 0x1f185 + 0x24
    [Asm] 纯文本查看 复制代码
    00042F6B  B9 DD DD F0 C2 82 18 00  08 01 32 36 36 36 30 7B  ..........26660{
    

    为什么需要再加0x24,见如下代码
    [Asm] 纯文本查看 复制代码
    705BD10D | 76 09                    | jbe common.705BD118                                 |
    705BD10F | 8B42 10                  | mov eax,dword ptr ds:[edx+10]                       |
    705BD112 | 2B45 0C                  | sub eax,dword ptr ss:[ebp+C]                        |
    705BD115 | 8945 14                  | mov dword ptr ss:[ebp+14],eax                       |
    705BD118 | 8B41 28                  | mov eax,dword ptr ds:[ecx+28]                       |
    705BD11B | 0342 08                  | add eax,dword ptr ds:[edx+8]                        |
    705BD11E | 8B71 2C                  | mov esi,dword ptr ds:[ecx+2C]                       |
    705BD121 | 1372 0C                  | adc esi,dword ptr ds:[edx+C]                        |
    705BD124 | 0345 0C                  | add eax,dword ptr ss:[ebp+C]                        |
    705BD127 | 1375 10                  | adc esi,dword ptr ss:[ebp+10]                       |
    705BD12A | 83C0 24                  | add eax,24                                          |
    705BD12D | 13F7                     | adc esi,edi                                         |
    705BD12F | 8975 10                  | mov dword ptr ss:[ebp+10],esi                       |
    705BD132 | 897D FC                  | mov dword ptr ss:[ebp-4],edi                        |
    

    也正是因为这个原因,导致解析失败么
    得到数值,之后在进行转换.
    [Asm] 纯文本查看 复制代码
    v4 = StrToIntA(v3);
    


    对四个rdb进行size和data的修改.
    至此打开没问题,也可以进行登录了.


    2.问题来了
    登录后却提示,qq损坏.
    发现不点提示框时,不会结束掉qq.
    还有收到消息,但是不能打开好友和群的聊天框.
    无奈又只有挂上调试器,进行分析.

    先对打不开聊天框进行分析
    先逆了半天,以为对修改的文件进行了校验或者触发了暗桩,转念一想发现不应该,回想起来有些惯性思维了.
    随意找了个能断下来的地方,跟踪发现弹窗是由于版本变化了,加载时对Plugin目录下的插件版本进行check导致.
    [Asm] 纯文本查看 复制代码
    ChatFrameApp.dll:
    signed int __cdecl sub_51529DC6(const wchar_t *a1, _DWORD **a2, int a3)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      v80 = &v77;
      sub_51526E09(v3);
      CTXStringW::CTXStringW(&v81, L"com.tencent.advertisement", v78);
      v77 = (int *)&v81;
      v4 = *((_DWORD *)v79 + 1);
      v82 = (char *)v79 + 4;
      v5 = 1;
      v6 = sub_51527264(v79, v4, &v81);
      sub_51526E59(1);
      *(_DWORD *)v82 = v6;
      **(_DWORD **)(v6 + 4) = v6;
      CTXStringW::~CTXStringW((CTXStringW *)&v81);
      CTXStringW::CTXStringW(&v81, L"com.tencent.audiovideo", v78);
      ...
    }
    
    signed int __cdecl sub_51529CFF(_DWORD **a1, _DWORD **a2, int a3)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      v9 = &v7;
      sub_51526E09(v3);
      for ( i = *(char **)v8; i != v8; i = *(char **)i )
      {
        sub_51527FC9(&v11, **a1, *a1, i + 8);
        if ( v11 == *a1 )
        {
          sub_51527FC9(&v10, **a2, *a2, i + 8);
          if ( v10 == *a2 )
          {
            v9 = (int **)CTXStringW::operator wchar_t const *(i + 8);
            v7 = (int *)&v9;
            sub_51511243(L"file", 120, L"func", 2, L"plc", (const char *)L"%s", &v9);
            sub_515280C1(*(_DWORD *)a3, i + 8);
          }
        }
      }
      v5 = 0;
      if ( !*(_DWORD *)(a3 + 4) )
        v5 = 1;
      sub_51528BF0(&v8);
      operator delete(v8);
      return v5;
    }
    

      
    patch了下,能打开聊天框,进行聊天了,由于时间挂太久,还T我下线了.
    依法炮制干掉了AppMisc.dll对于插件的加载.
    再次打开qq,进行登录.
    恩,能进行聊天就行,作为基本功能满足即可.

    事后发现由于插件没加载,不能传文件.
    打开Com.Tencent.FileTransfer,将目录里Bundle.rdb文件中pubversion.dat有关数据进行修改.
    再再次打开qq,进行登录.测试了下功能发现可行.
    patch.png


    舒服了.
    还好只是用来聊天交流.

    3.反思
    方式不是太好,理想方式,应该只在发包的时候对pubno和ver相关进行修改,可能hook的地方多一些.
    然后在根据ntrqq中,再对一些校验的地方在进行patch.
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2021-7-20 11:28
  • 签到天数: 42 天

    [LV.5]常住居民I

    发表于 2019-12-2 22:05:10 | 显示全部楼层
    厉害了,楼主!PYG15周年生日快乐!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    1 小时前
  • 签到天数: 1095 天

    [LV.10]以坛为家III

    发表于 2019-12-3 09:57:17 | 显示全部楼层
    感觉新版的qq除了有广告其他的也还行
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2023-7-21 17:53
  • 签到天数: 30 天

    [LV.5]常住居民I

    发表于 2019-12-3 14:10:46 | 显示全部楼层
    这么好的技术贴,为啥没人回复呢?
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-10-8 10:37
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2019-12-3 15:42:13 | 显示全部楼层
    学习了楼主,讲解认真
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 20:55
  • 签到天数: 1302 天

    [LV.10]以坛为家III

    发表于 2019-12-3 20:45:07 | 显示全部楼层
    直接用国际版。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:47
  • 签到天数: 34 天

    [LV.5]常住居民I

    发表于 2019-12-3 20:55:00 | 显示全部楼层
    厉害了楼主,讲解认真
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-2-28 11:05
  • 签到天数: 82 天

    [LV.6]常住居民II

    发表于 2019-12-25 02:24:59 | 显示全部楼层
    太强了。坐沙发学习一
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2020-12-16 17:04
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2020-5-7 02:36:47 | 显示全部楼层
    QQ里面暗桩挺多的,破解登录这块我是直接IATHook把PreloginLogic.dll的导入表的GetPubNo给Hook了,我发现小于25600的版本都可以登录。
    但是最近QQ服务器似乎检测pubno了,低于25600的版本都是旧版,都被禁止登录了。
    我不知道是我的处理手法有问题还是说服务器那边一刀切了,不知道楼主用改vi.dat这个方法最近有没有被封号之类的?因为改vi.dat的话要改的地方挺多的,不过理论上应该比我直接勾函数要完美吧。

    点评

    服务器对其他地方做了check 有问题就冻结掉了 具体在哪 你可以看看发的包还包括那些地方 // 因为发的包长度肯定是不变的 所以要校验的话 就那么一些数据 哪些有关就显而易见了不过不建议搞成插件发出去 了解就好  详情 回复 发表于 2020-6-18 18:03
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-4-19 21:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

     楼主| 发表于 2020-6-18 18:03:26 | 显示全部楼层
    Lance.Moe 发表于 2020-5-7 02:36
    QQ里面暗桩挺多的,破解登录这块我是直接IATHook把PreloginLogic.dll的导入表的GetPubNo给Hook了,我发现小 ...

    服务器对其他地方做了check 有问题就冻结掉了 具体在哪 你可以看看发的包还包括那些地方 // 因为发的包长度肯定是不变的 所以要校验的话 就那么一些数据 哪些有关就显而易见了不过不建议搞成插件发出去 了解就好
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

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