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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 61208|回复: 120
收起左侧

[原创] Source Insight 4.0 破解过程

    [复制链接]
lakshmi 发表于 2018-3-19 18:25
本帖最后由 lakshmi 于 2018-3-20 08:33 编辑

0x1 写在前面
    由于最近准备向各位大牛们看齐,学习学习Linux源码,需要用到source insight ,因此就在网上找破解版的si,这个帖子已经给出了破解版 https://www.52pojie.cn/thread-580580-1-1.html
但是需要修改二进制文件,作为一个怀疑整个世界的渣,写了这么一篇帖子(不过最后本渣也还是修改了二进制文件),仅供学习交流!!!
    准备环境:
    Windows 7 32 bit
    百度上Source Insight 4.0 (Version 4.00.0086 built on 2017-04-27) (官网最新版是 4.00.0089),查看了一下破解过程相同
    IDA 7.0
    52破解专版OllDbg
    UltraEdit32

0x2 破解过程
    首先,查看PE文件,发现没有加壳,运行起来,提示需要输入注册码,如下图所示:
inputkey.png



点击下一步,然后随意输入注册码,点击确定,如下提示:
inputkey2.png
有提示,那就按套路出牌, 用IDA打开文件,C:\Program Files\Source Insight 4.0\sourceinsight4.exe,搜索字符串:
[C++] 纯文本查看 复制代码
int __cdecl register_function(int a1, int a2, int a3)
{
   。。。。。。。。。。。。。。。。
  if ( !check_register(&str_input, dword_1361930 + 0x608, dword_1361930 + 0x60C, dword_1361930 + 0x604, 1) )  {
    Error_SerialNumber(
      "The serial number you entered is not correct.\n\nPlease check the number and re-enter it.",
      v11,
      v12,
      *(int *)v13,
      v14,
      v15,
      v16,
      v17,
      v18);
    sub_1106A20(a1, 30);
    sub_1104660();
    if ( ++dword_13619CC >= sub_114D9A0(1) + 3 )
    {
      dword_13619CC = 0;
      sub_114C530();
      Sleep(0x1B58u);
      sub_114C580();
      return 0;
    }
    return 0;
  }
  dword_13619CC = 0;
  if ( *(_DWORD *)(dword_1361930 + 0x604) != HIBYTE(dword_13446B0) )
  {
    Error_SerialNumber(
      "The serial number you entered is for a different version of Source Insight.\n"
      "\n"
      "This version requires a version 4.x serial number.",
      v11,
      v12,
      *(int *)v13,
      v14,
      v15,
      v16,
      v17,
      v18);
    sub_1106A20(a1, 30);
    sub_1104660();
    return 0;
  }
  if ( *(_DWORD *)(dword_1361930 + 0x60C) == 3 )
  {
    Error_SerialNumber(
      "The serial number cannot be used with the 'release' version of Source Insight.",
      v11,
      v12,
      *(int *)v13,
      v14,
      v15,
      v16,
      v17,
      v18);
    sub_1104660();
    return 0;
  }
  if ( !sub_120AF10(&str_input) )
    return 0;
  if ( sub_120C670(dword_1361930 + 0x504) )
  {
    sub_11122A0("Upgrade License was validated: %s", dword_1361930 + 1284, v11, v12, *(int *)v13, v14, v15, v16, v17);
  }
  else
  {
    Error_SerialNumber(
      "Sorry, but we could not validate your previous license. Please make sure you have the correct serial number for ve"
      "rsion 3.x.\n"
      "\n"
      "If your old version of Source Insight is running, you can see the serial number by selecting Help > About Source I"
      "nsight. Otherwise, the serial number was typically provided in an email activation message when you purchased the old license.",
      v11,
      v12,
      *(int *)v13,
      v14,
      v15,
      v16,
      v17,
      v18);
    sub_1106A20(a1, 30);
    sub_1104660();
    sub_11121C0("Upgrade License could not be validated", v4, v5, v6, v7, v12, *(int *)v13, v14, v15);
  }
  return 0;
}

只有当 check_register(&str_input, dword_1361930 + 0x608, dword_1361930 + 0x60C, dword_1361930 + 0x604, 1) 返回值非0时表示验证成功, 接着查看这个该函数:
[C++] 纯文本查看 复制代码
BOOL __cdecl check_register(char *sn, int a2, int a3, int a4, int one)
{
  BOOL result; // eax
  char v6; // al
  char v7; // al
  char v8; // al
  char v9; // al
  int v10; // [esp+4h] [ebp-18h]
  char v11; // [esp+8h] [ebp-14h]
  char v12; // [esp+17h] [ebp-5h]  _strupr(sn);
  if ( strlen(sn) != 0x13 || sn[4] != '-' || sn[9] != '-' || sn[0xE] != '-' || *sn != 'S' )// format: SXXX-XXX-XXXX-XXXX
    return 0;
  if ( one )
  {
    v6 = sn[6];
    if ( v6 != 'R' && v6 != 'G' && v6 != 'D' && v6 != 'F' )// SXXX-X(R|G|D|F)XX-XXXX-XXXX
      return 0;
  }
  v7 = sn[1];
  if ( v7 < '0' || v7 > '9' )                   // S(0-9)XX-X(R|G|D|F)XX-XXXX-XXXX
    return 0;
  *(_DWORD *)a4 = v7 - '0';
  v8 = sn[2];
  switch ( v8 )                                 // S(0-9)(T|B|S|U)X-X(R|G|D|F)XX-XXXX-XXXX
  {
    case 'T':
      *(_DWORD *)a3 = 1;
      break;
    case 'B':
      *(_DWORD *)a3 = 3;
      break;
    case 'S':
      *(_DWORD *)a3 = 0;
      break;
    case 'U':
      *(_DWORD *)a3 = 0;
      break;
    default:
      return 0;
  }
  v9 = sn[3];
  if ( v9 != 'G' )
  {
    if ( v9 == 'V' )
    {
      *(_DWORD *)a2 = 2;
      goto LABEL_28;
    }
    if ( v9 == 'R' )
    {
      *(_DWORD *)a2 = 0;
      goto LABEL_28;
    }
    return 0;
  }
  *(_DWORD *)a2 = 1;
LABEL_28:
  result = 0;
  if ( !split_key_compute_function(sn + 5, 4u, 0)// split_key_compute_function(XX, 4u, 0) == 0
    && !split_key_compute_function(sn + 10, 4u, 0)
    && !split_key_compute_function(sn + 0xF, 4u, 0) )
  {
    if ( !one
      || (strcpy(&v11, sn),
          v12 = 0,
          compute_last_four_byte(&v11, 0xFu, (int)byte_12F4A48, (int)&v10),
          *(_DWORD *)(sn + 0xF) == v10) )
    {
      result = 1;
    }
  }
  return result;
}


简单介绍上边的函数,首先是判断序列号的合法性,必须满足如下格式(其中X表示未知字符):
S(0-9)(T|B|S|U)X-X(R|G|D|F)XX-XXXX-XXXX
其中第二位,根据版本要求必须是4,第三位中T 表示 试用版,B表示Beta版,S表示Standard版,U未知。因此按照本软件的要求,序列号格式应该如下:
S4SX-X(R|G|D|F)XX-XXXX-XXXX
接着通过split_key_compute_function对序列号中按“-”分开的四位分别验证,其返回值必须是0,这个函数很好绕过,只要满足这4个字节中的第一个字节是字符即可满足(没什么作用),因此在最新版中已经将这块给省掉了。
接着是
[C++] 纯文本查看 复制代码
          compute_last_four_byte(&v11, 0xFu, (int)byte_12F4A48, (int)&v10),
          *(_DWORD *)(sn + 0xF) == v10) )


compute_last_four_byte函数的作用是利用替换查表的方法,将sn中的前15个字节计算出一个四字节的数,这个四字节的数就是sn的最后4字节,具体代码如下:
[C++] 纯文本查看 复制代码
BYTE char_table[26] = { 'K', 'V', '9', '6', 'G', 'M', 'J', 'Y', 'H', '7', 'Q', 'F', '5', 'T', 'C', 'W', '4', 'U', '3', 'X', 'Z', 'P', 'R', 'S', 'D', 'N'};
BYTE byte_table[256] = {
    0x23, 0xDD, 0x78, 0xB5, 0x33, 0x6F, 0xD4, 0xF9, 0xA6, 0xE8, 0xCC, 0x7C, 0x9F, 0xB3, 0x22, 0xDA,
0x32, 0xDF, 0x71, 0xB7, 0x61, 0x3D, 0x6B, 0x57, 0xD7, 0xA1, 0x34, 0x38, 0xF2, 0xE1, 0xF3, 0xB8,
0x1A, 0x80, 0xF5, 0xFE, 0x91, 0x01, 0x3C, 0x73, 0x93, 0x48, 0xA0, 0xE0, 0x94, 0xAA, 0x39, 0x8F,
0x58, 0xE2, 0x31, 0x0B, 0xBB, 0xCE, 0x4C, 0xD2, 0x56, 0xC2, 0x5E, 0x27, 0xB6, 0xFB, 0x65, 0xAE,
0x55, 0x60, 0xBD, 0x10, 0x86, 0xF7, 0xC1, 0x88, 0x12, 0xED, 0x67, 0xC4, 0x74, 0x30, 0x1B, 0xBC,
0x9A, 0xB0, 0xEF, 0x36, 0xC5, 0x72, 0x5B, 0x7E, 0x54, 0x2C, 0x0F, 0xF6, 0xA9, 0x85, 0x2A, 0xB1,
0x37, 0xF1, 0x2F, 0x4E, 0xE7, 0x6A, 0x75, 0xA8, 0x26, 0xEB, 0x3F, 0x6C, 0x69, 0x20, 0x87, 0x62,
0x8D, 0x68, 0xA5, 0xFA, 0x3A, 0x04, 0x21, 0x1F, 0xAC, 0x05, 0xA4, 0x76, 0x11, 0x70, 0x9E, 0x46,
0x24, 0x5D, 0xC6, 0xE4, 0x95, 0x82, 0x1C, 0xBA, 0x59, 0x09, 0xD9, 0x44, 0x98, 0x92, 0x07, 0xAF,
0xA7, 0x41, 0x96, 0x90, 0xB4, 0x42, 0x63, 0x99, 0xD0, 0x4D, 0x97, 0xBE, 0x40, 0xCF, 0x84, 0xE5,
0x1D, 0x5A, 0x0C, 0x7F, 0xC7, 0xEA, 0xEE, 0xEC, 0x00, 0xD5, 0x49, 0x2D, 0x51, 0xAD, 0xB9, 0x89,
0x77, 0x52, 0x3E, 0x8C, 0xE6, 0xFF, 0x15, 0xDE, 0x6D, 0x14, 0xA2, 0xCD, 0xA3, 0xD6, 0x17, 0x81,
0xC8, 0x45, 0x4B, 0x35, 0x0A, 0x0D, 0xFC, 0x9D, 0x16, 0x3B, 0xD3, 0x7D, 0xD1, 0xF4, 0xFD, 0xCA,
0x25, 0x06, 0x6E, 0xF8, 0x5F, 0xBF, 0x8A, 0x7B, 0x50, 0xD8, 0x79, 0x9C, 0xAB, 0x43, 0x53, 0xCB,
0x8E, 0x4F, 0xE3, 0xC9, 0x8B, 0xDC, 0x5C, 0xC0, 0x1E, 0x9B, 0x18, 0x02, 0x47, 0x03, 0x2B, 0x0E,
0x66, 0x4A, 0xB2, 0xF0, 0xE9, 0x19, 0x29, 0x7A, 0xC3, 0x08, 0x83, 0xDB, 0x64, 0x13, 0x2E, 0x28 };

int  compute_last_four_byte(BYTE *keystr,DWORD key_length, int table, int retvalue)
{
unsigned int value_index; // esi
BYTE v5; // cl
unsigned int iIndex; // eax
int result; // eax
value_index = 0;
do
{
  v5 = *(BYTE *)((BYTE)(value_index + *keystr) + table);
  for (iIndex = 1; iIndex< key_length; ++iIndex)
   v5 = *(BYTE *)((v5 ^ (char)keystr[iIndex]) + table);
  result = retvalue;
  *(BYTE *)(++value_index + retvalue - 1) = char_table[v5 % 26];
} while (value_index < 4);
return result;
}


既然后四字节可以算出来,那么此处的破解思路就是,按照格式S4SX-X(R|G|D|F)XX-XXXX-XXXX要求,固定前如下字节 S4SV-UFWT-ZPRX-,那么通过穷举X(此处为了缩小范围,直接遍历char_table中的字符即可),来计算出最后四个字节,在选出满足要求的序列号即可,代码如下:
[C++] 纯文本查看 复制代码
int _tmain(int argc, _TCHAR* argv[])
{
int res;
CHAR serial_number[0x1f] = { 'S', '4', 'S', 'V', '-', 'U', 'F', 'W', 'T', '-', 'Z', 'P', 'R', 0x0, '-', 0x0, 0x0, 0x0, 0x0, 0x0 };

for (DWORD dwIndex = 0; dwIndex < 26; dwIndex++)
{
  serial_number[13] = char_table[dwIndex];
  compute_last_four_byte((BYTE *)serial_number, 0xf, (int)byte_table, (int)&res);
  memcpy(serial_number + 0xf, (BYTE *)&res, 4);
  if (serial_number[0xf] >= 0x41)
   printf("%s\n", serial_number);
}
}

结果如下:
test.png


任选一组,调试发现成功绕过,但是此处还是没有完全破解成功,因为,source insight 需要一个license文件,文件保存在C:\programdata\source insigth\4.0\si4.lic中,格式如下(根据试用版获取到):
[XML] 纯文本查看 复制代码
<!--
Source Insight 4.x License File
DO NOT EDIT THIS FILE.  Doing so will render it unusable.
This license was created for:

  lakshmi
  52pojie
  [url=mailto:XXX@XX.com]XXX@XX.com[/url]

-->
<SourceInsightLicense>
<Header
  Value="1"
/>
<LicenseProperties
  LicensedUser="lakshmi"
  ActId="9980973922"
  HWID="XXXXXXXXX"
  Serial="S4SV-UFWT-ZPR6-F336"
  Organization="52pojie"
  Email="XXX@XX.com"
  Type="Standard"
  Version="4"
  MinorVersion="0"
  Date="2018-03-12 00:00:00"
  Expiration="2028-09-12 00:00:00"
/>
<Signature
  Value="az2bGw1ks1ftqXzf/tVrq071RbJqclxWljohEAcOwvx3pimSMZa/isSdpIRM5vXsTt/ZVeD62r8SlzvNlt/5C6XzPTMKvik+fzOakeM8zQNSCmJ/W1MQ9WgXZyiQpp3VnZgkrO3Ut/YHRWCe4zPJjcPJZ7tXf62Lvxx5MO29uEqHCvc8ZHUGg0wafuYooRoeUWzLneTisGDnfAy3UTaH3oxdqwlMFbDa10sVEEbW2WTzZFxL826r4lAGmH9MUCiu/3R/tpvrYlyWRv+29kQoqGlkwQUV4B1iL6Dyp5bC17JSYpChsjdm9JkoEg6HRsA3WtdQBRecA65Jyhr8XbMPFg=="
/>
</SourceInsightLicense>


source insight 会根据自带公钥,对license文件中的 除了Signature中的数据进行签名,并与变换后的Signature值进行比较,具体怎么变换没有去跟踪,反正臣妾都破不了签名,最后还是手贱地选择了修改二进制文件
[C++] 纯文本查看 复制代码
int __cdecl sub_50B440(BYTE *pbData, DWORD dwDataLen, BYTE *pbSignature, DWORD dwSigLen)
{
  BOOL v5; // esi
  HCRYPTHASH phHash; // [esp+0h] [ebp-818h]
  HCRYPTPROV phProv; // [esp+4h] [ebp-814h]
  struct _CERT_PUBLIC_KEY_INFO *pvStructInfo; // [esp+8h] [ebp-810h]
  HCRYPTKEY phKey; // [esp+Ch] [ebp-80Ch]
  DWORD pcbBinary; // [esp+10h] [ebp-808h]
  DWORD pcbStructInfo; // [esp+14h] [ebp-804h]
  BYTE pbBinary; // [esp+18h] [ebp-800h]
  phHash = 0;
  phKey = 0;
  pcbBinary = 2048;
  phProv = 0;
  if ( !CryptStringToBinaryA(pszString, 0, 0, &pbBinary, &pcbBinary, 0, 0)
    || !CryptDecodeObjectEx(1u, (LPCSTR)8, &pbBinary, pcbBinary, 0x8000u, 0, &pvStructInfo, &pcbStructInfo) )
  {
    return 472;
  }
  if ( !CryptAcquireContextW(&phProv, 0, 0, 1u, 0xF0000000) )
    return 473;
  if ( !CryptImportPublicKeyInfo(phProv, 1u, pvStructInfo, &phKey) )
    return 474;
  LocalFree(pvStructInfo);
  if ( !CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) )
    return 474;
  if ( !CryptHashData(phHash, pbData, dwDataLen, 0) )
    return 475;
  v5 = CryptVerifySignatureW(phHash, pbSignature, dwSigLen, phKey, 0, 0);
  CryptDestroyHash(phHash);
  CryptReleaseContext(phProv, 0);
  return v5 != 0 ? 0xC8 : 0x1CE;
}

让函数最终直接返回0xC8即可
最终效果如下:
active.png

免费评分

参与人数 35威望 +2 吾爱币 +43 热心值 +32 收起 理由
coralzyzy + 1 + 1 热心回复!
nomoretime + 1 + 1 谢谢@Thanks!
yeeboys + 1 我很赞同!
rollin7 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
godczj + 1 + 1 谢谢@Thanks!
kid0dada + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
diaojianxiao + 1 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
noth + 1 + 1 我很赞同!
式姐美如画 + 1 + 1 我很赞同!
at2all + 1 + 1 热心回复!
smarxx + 1 用心讨论,共获提升!
liphily + 2 + 1 我很赞同!
liutongwei + 1 + 1 谢谢@Thanks!
MistHill + 2 + 1 鼓励!
peter_king + 1 谢谢@Thanks!
Probious + 1 谢谢@Thanks!
k9982874 + 1 + 1 我很赞同!
cz12312388 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
gfjykldd + 1 + 1 用心讨论,共获提升!
a5606495 + 1 + 1 谢谢@Thanks!
fengyuner + 1 + 1 谢谢@Thanks!
kendling + 1 + 1 用心讨论,共获提升!
caowei1 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qzr + 1 + 1 用心讨论,共获提升!
某些人 + 1 + 1 谢谢@Thanks!
龙性 + 1 我很赞同!
Tim-52Pojie + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
qaz003 + 1 哈哈,好可爱的文章风格。。谢谢分享
朱小强007 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Xyzkst + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
XMickey + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hmily + 2 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
西凉小破破 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
大喵 + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

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

stxxb 发表于 2018-3-19 21:17
楼主厉害啊
MistHill 发表于 2018-3-22 12:11
lakshmi 发表于 2018-3-20 08:31
嗯,不过@MistHill 大神的那个key,被新版的4.0.86-4.0.89给强制过滤掉了
这几个版本直接内嵌了n多key, ...

嗯,最初只需要替换公钥就可以了。

后来它加入了:更新信息黑名单检查、程序硬编码黑名单检查、定时在线检查。

代码只需要改动4个字节就可以过掉这些检查。
swjtu_ray 发表于 2018-3-19 18:27
起点陌离 发表于 2018-3-19 18:34
一直很想学习这个,看起来确实很难呀!
gusha915 发表于 2018-3-19 18:48
感谢分享,,,
大喵 发表于 2018-3-19 18:55
可以可以
lggjlpph 发表于 2018-3-19 19:06
牛逼牛逼嘻嘻
ping170 发表于 2018-3-19 19:26
大佬辛苦了,感谢分享
Atomi 发表于 2018-3-19 19:27
感谢分享            
elpsycongroo001 发表于 2018-3-19 21:00
感谢分享,大佬辛苦了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

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

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

GMT+8, 2024-4-20 07:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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