飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 6463|回复: 11

[原创] Internet Download Manager 算法分析

[复制链接]
  • TA的每日心情
    无聊
    2016-10-10 10:27
  • 签到天数: 26 天

    [LV.4]偶尔看看III

    发表于 2015-8-4 13:44:45 | 显示全部楼层 |阅读模式
    【文章标题】Internet Download Manager 算法分析
    【文章作者】BinGzL
    【软件版本】Internet Download Manager v6.23 Build17
    【保护方式】序列号
    【作者声明】刚刚结束在科锐的学习生活,感谢钱老师以及科锐其他老师的教导。即将入职某公司,入职前分析些东西找找感觉。
    【分析过程】
    本文不阐述定位算法的过程,通过调试定位如下函数(看官可略过,看下面的分析):
    刚进入函数就看到了获取注册信息的部分与初始化一张Key表
    获取名字
    1. .text:004FFB31                 lea     eax, [ebp+szName]
    2. .text:004FFB3A                 push    32h             ; cchMax
    3. .text:004FFB3E                 push    eax             ; lpString
    4. .text:004FFB3F                 push    4B0h            ; nIDDlgItem
    5. .text:004FFC4A                 call    GetRegUserInfo
    复制代码

    获取姓氏
    1. .text:004FFC78                 lea     edx, [ebp+szSurName]
    2. .text:004FFC7E                 push    32h             ; cchMax
    3. .text:004FFC80                 push    edx             ; lpString
    4. .text:004FFC81                 push    413h            ; nIDDlgItem
    5. .text:004FFC88                 call    GetRegUserInfo
    复制代码

    获取EMail
    1. .text:004FFC9F                 lea     ecx, [ebp+szEmail]
    2. .text:004FFCA5                 push    32h             ; cchMax
    3. .text:004FFCA7                 push    ecx             ; lpString
    4. .text:004FFCA8                 push    4A5h            ; nIDDlgItem
    5. .text:004FFCAF                 call    GetRegUserInfo
    复制代码

    获取序列号
    1. .text:004FFCC7                 lea     eax, [ebp+szSerialNum]
    2. .text:004FFCCD                 push    32h             ; cchMax
    3. .text:004FFCCF                 push    eax             ; lpString
    4. .text:004FFCD0                 push    4AAh            ; nIDDlgItem
    5. .text:004FFCD7                 call    GetRegUserInfo
    复制代码

    1. .text:005E30A4 ; int __stdcall GetRegUserInfo(int nIDDlgItem, LPSTR lpString, int cchMax)
    2. .text:005E30A4 GetRegUserInfo  proc near               ; CODE XREF: IsRegister+13Ap
    3. .text:005E30A4                                         ; IsRegister+178p ...
    4. .text:005E30A4
    5. .text:005E30A4 nIDDlgItem      = dword ptr  8
    6. .text:005E30A4 lpString        = dword ptr  0Ch
    7. .text:005E30A4 cchMax          = dword ptr  10h
    8. .text:005E30A4
    9. .text:005E30A4                 push    ebp
    10. .text:005E30A5                 mov     ebp, esp
    11. .text:005E30A7                 mov     eax, [ecx+34h]
    12. .text:005E30AA                 test    eax, eax
    13. .text:005E30AC                 jnz     short loc_5E30C2
    14. .text:005E30AE                 push    [ebp+cchMax]    ; cchMax
    15. .text:005E30B1                 push    [ebp+lpString]  ; lpString
    16. .text:005E30B4                 push    [ebp+nIDDlgItem] ; nIDDlgItem
    17. .text:005E30B7                 push    dword ptr [ecx+1Ch] ; hDlg
    18. .text:005E30BA                 call    ds:GetDlgItemTextA
    19. .text:005E30C0                 jmp     short loc_5E30D2
    20. .text:005E30C2 ; ---------------------------------------------------------------------------
    21. .text:005E30C2
    22. .text:005E30C2 loc_5E30C2:                             ; CODE XREF: GetRegUserInfo+8j
    23. .text:005E30C2                 push    [ebp+cchMax]
    24. .text:005E30C5                 mov     edx, [eax]
    25. .text:005E30C7                 mov     ecx, eax
    26. .text:005E30C9                 push    [ebp+lpString]
    27. .text:005E30CC                 push    [ebp+nIDDlgItem]
    28. .text:005E30CF                 call    dword ptr [edx+78h]
    29. .text:005E30D2
    30. .text:005E30D2 loc_5E30D2:                             ; CODE XREF: GetRegUserInfo+1Cj
    31. .text:005E30D2                 pop     ebp
    32. .text:005E30D3                 retn    0Ch
    33. .text:005E30D3 GetRegUserInfo  endp
    复制代码


    Key表内容为:
    1. char g_KeyTable[] =
    2. {
    3.         0x32, 0x59, 0x4f, 0x50, 0x42, 0x33,
    4.         0x41, 0x51, 0x43, 0x56, 0x55, 0x58,
    5.         0x4d, 0x4e, 0x52, 0x53,        0x39, 0x37,
    6.         0x57, 0x45, 0x30, 0x49, 0x5a, 0x44,
    7.         0x34, 0x4b, 0x4c, 0x46, 0x47, 0x48,
    8.         0x4a, 0x38, 0x31, 0x36, 0x35, 0x54
    9. };
    复制代码


    检查序列号是否为空
    1. .text:004FFCF1                 mov     dl, ' '         ; 0x20 == ' '
    2. .text:004FFCF3                 cmp     [ebp+szSerialNum], dl
    3. .text:004FFCF9                 jnz     short loc_4FFD57 ;
    复制代码


    序列号转换与检查
    1. .text:004FFDAD                 lea     edx, [ebp+szSerialNum]
    2. .text:004FFDB3                 push    edx             ; char *
    3. .text:004FFDB4                 call    __strupr        ; 序列号转换大写
    4. .text:004FFDB9                 lea     edi, [ebp+szSerialNum]
    5. .text:004FFDBF                 or      ecx, 0FFFFFFFFh
    6. .text:004FFDC2                 xor     eax, eax
    7. .text:004FFDC4                 add     esp, 4
    8. .text:004FFDC7                 repne scasb
    9. .text:004FFDC9                 not     ecx
    10. .text:004FFDCB                 dec     ecx
    11. .text:004FFDCC                 cmp     ecx, 23         ; 比较序列号是否为23位
    12. .text:004FFDCF                 jnz     short loc_4FFD69
    13. .text:004FFDD1                 mov     cl, [ebp+szSerialNum+5]
    14. .text:004FFDD4                 mov     byte ptr [ebp+var_14+3], al ; bSerialNumLog == FALSE
    15. .text:004FFDD7                 mov     al, 2Dh
    16. .text:004FFDD9                 cmp     cl, al          ; 比较序列号第6位是否为'-'(0x2d)
    17. .text:004FFDDB                 jnz     short loc_4FFDE7 ; bSerialNumLog == TRUE
    18. .text:004FFDDD                 cmp     [ebp+szSerialNum+0Bh], al ; 比较序列号第12位是否为'-'(0x2d)
    19. .text:004FFDE0                 jnz     short loc_4FFDE7 ; bSerialNumLog == TRUE
    20. .text:004FFDE2                 cmp     [ebp+szSerialNum+11h], al ; 比较序列号第18位是否为'-'(0x2d)
    21. .text:004FFDE5                 jz      short loc_4FFDEB
    复制代码

    由此可以确定系列号的格式为XXXXX-XXXXX-XXXXX-XXXXX,接下来又把4段系列号分别拷贝出来
    1. .text:004FFDEB                 lea     eax, [ebp+szSerialNum]
    2. .text:004FFDF1                 push    5               ; size_t
    3. .text:004FFDF3                 lea     ecx, [ebp+szSerialNum_0_4]
    4. .text:004FFDF6                 push    eax             ; char *
    5. .text:004FFDF7                 push    ecx             ; char *
    6. .text:004FFDF8                 call    _strncpy        ; 获取0-4位的序列号
    7. .text:004FFDFD                 lea     edx, [ebp+szSerialNum+6]
    8. .text:004FFE00                 push    5               ; size_t
    9. .text:004FFE02                 lea     eax, [ebp+szSerialNum_6_10]
    10. .text:004FFE05                 push    edx             ; char *
    11. .text:004FFE06                 push    eax             ; char *
    12. .text:004FFE07                 call    _strncpy        ; 获取6-10位序列号
    13. .text:004FFE0C                 lea     ecx, [ebp+szSerialNum+0Ch]
    14. .text:004FFE0F                 push    5               ; size_t
    15. .text:004FFE11                 lea     edx, [ebp+szSerialNum_12_16]
    16. .text:004FFE14                 push    ecx             ; char *
    17. .text:004FFE15                 push    edx             ; char *
    18. .text:004FFE16                 call    _strncpy        ; 获取12-16位序列号
    19. .text:004FFE1B                 lea     eax, [ebp+szSerialNum+12h]
    20. .text:004FFE1E                 push    5               ; size_t
    21. .text:004FFE20                 lea     ecx, [ebp+szSerialNum_18_22]
    22. .text:004FFE23                 push    eax             ; char *
    23. .text:004FFE24                 push    ecx             ; char *
    24. .text:004FFE25                 call    _strncpy        ; 获取18-22位序列号
    25. .text:004FFE2A                 xor     edi, edi
    26. .text:004FFE2C                 add     esp, 30h
    27. .text:004FFE2F                 mov     [ebp+szSerialNum_0_4+5], 0 ; 为拷贝出来的每段加'\0'
    28. .text:004FFE33                 mov     [ebp+szSerialNum_6_10+5], 0
    29. .text:004FFE37                 mov     [ebp+szSerialNum_12_16+5], 0
    30. .text:004FFE3B                 mov     [ebp+szSerialNum_18_22+5], 0 ;
    复制代码


    算法的准备工作就算完成了,接下来出现了四段一样的算法,如下
    1. .text:004FFE3F                 mov     [ebp+dwResult0_4], edi
    2. .text:004FFE42                 xor     esi, esi
    3. .text:004FFE44
    4. .text:004FFE44 loc_4FFE44:                             ; CODE XREF: IsRegister+362j
    5. .text:004FFE44                 cmp     esi, 5
    6. .text:004FFE47                 jge     short loc_4FFE7B ; nData = 0
    7. .text:004FFE49                 mov     dl, [ebp+esi+szSerialNum_0_4]
    8. .text:004FFE4D                 or      ecx, 0FFFFFFFFh
    9. .text:004FFE50                 xor     eax, eax
    10. .text:004FFE52
    11. .text:004FFE52 loc_4FFE52:                             ; CODE XREF: IsRegister+365j
    12. .text:004FFE52                 cmp     eax, 36         ; KeyTable Len
    13. .text:004FFE55                 jge     short loc_4FFE61 ;
    14. .text:004FFE55                                         ; ;
    15. .text:004FFE57                 cmp     g_szKeyTable[eax], dl
    16. .text:004FFE5D                 jnz     short loc_4FFE74
    17. .text:004FFE5F                 mov     ecx, eax        ; nIndex = j
    18. .text:004FFE61
    19. .text:004FFE61 loc_4FFE61:                             ; CODE XREF: IsRegister+345j
    20. .text:004FFE61                 cmp     ecx, 0FFFFFFFFh
    21. .text:004FFE64                 jz      short loc_4FFE77
    22. .text:004FFE66                 lea     edx, [edi+edi*8]
    23. .text:004FFE69                 add     ecx, edi
    24. .text:004FFE6B                 inc     esi
    25. .text:004FFE6C                 lea     edi, [ecx+edx*4] ; nData = nIndex + dwResult0_4 + (dwResult0_4 * 9) * 4;
    26. .text:004FFE6F                 mov     [ebp+dwResult0_4], edi ; dwResult = nData
    27. .text:004FFE72                 jmp     short loc_4FFE44
    28. .text:004FFE74 ; ---------------------------------------------------------------------------
    29. .text:004FFE74
    30. .text:004FFE74 loc_4FFE74:                             ; CODE XREF: IsRegister+34Dj
    31. .text:004FFE74                 inc     eax
    32. .text:004FFE75                 jmp     short loc_4FFE52 ; KeyTable Len
    33. .text:004FFE77 ; ---------------------------------------------------------------------------
    34. .text:004FFE77
    35. .text:004FFE77 loc_4FFE77:                             ; CODE XREF: IsRegister+354j
    36. .text:004FFE77                 mov     byte ptr [ebp+var_14+3], 1
    复制代码

    分析过后得出如下代码:
    1. int CIDMKeyGenDlg::GetCalcResult(char *pData)
    2. {
    3.         int i = 0, j = 0;
    4.         int nIndex = 0;
    5.         int nData = 0;

    6.         while (i < 5)
    7.         {
    8.                 for (j = 0; j < 36; j++)
    9.                 {
    10.                         if (g_KeyTable[j] == pData[i])
    11.                         {
    12.                                 nIndex = j;
    13.                                 nData = nIndex + nData + (nData * 9) * 4;
    14.                                 i++;
    15.                                 break;
    16.                         }
    17.                 }
    18.         }
    19.         return nData;
    20. }
    复制代码


    接下来在得到4段序列号计算出的值后,分别有对四个值做了校验
    1. 第一段
    2. .text:004FFF42                 mov     ecx, [ebp+dwResult0_4]
    3. .text:004FFF45                 mov     esi, 43
    4. .text:004FFF4A                 mov     eax, ecx
    5. .text:004FFF4C                 cdq
    6. .text:004FFF4D                 idiv    esi
    7. .text:004FFF4F                 test    edx, edx
    8. .text:004FFF51                 jnz     short loc_4FFF57
    9. 第二段
    10. .text:004FFF5B                 mov     ecx, dword ptr [ebp+dwResult6_10]
    11. .text:004FFF5E                 mov     esi, 23
    12. .text:004FFF63                 mov     eax, ecx
    13. .text:004FFF65                 cdq
    14. .text:004FFF66                 idiv    esi
    15. .text:004FFF68                 test    edx, edx
    16. .text:004FFF6A                 jnz     short loc_4FFF70
    17. 第三段
    18. .text:004FFF74                 mov     eax, ebx
    19. .text:004FFF76                 mov     ecx, 17
    20. .text:004FFF7B                 cdq
    21. .text:004FFF7C                 idiv    ecx
    22. .text:004FFF7E                 test    edx, edx
    23. .text:004FFF80                 jnz     short loc_4FFF86
    24. 第四段
    25. .text:004FFF8A                 mov     eax, edi
    26. .text:004FFF8C                 mov     ecx, 53
    27. .text:004FFF91                 cdq
    28. .text:004FFF92                 idiv    ecx
    29. .text:004FFF94                 test    edx, edx
    30. .text:004FFF96                 jnz     short loc_4FFFA3
    复制代码


    剩下的就是保存注册信息的代码了,由此可以了解软件注册的验证流程为4段计算的值都可以整除一个值才可以注册。本以为到此结束....第二天用的时候打开弹出了让我心碎的提示
    error.png
    再次分析启动验证,发现是有网络验证,看来是不能够愉快的KeyGen了,这KeyGen自然也就是然并卵了。通杀补丁可以去飘云阁找飘哥的那份补丁。

    评分

    参与人数 3威望 +12 飘云币 +44 收起 理由
    0xcb + 8 + 8 加油
    飞天 + 4 + 4 赞一个!
    GeekCat + 32 PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情

    2021-7-20 14:52
  • 签到天数: 78 天

    [LV.6]常住居民II

    发表于 2015-8-4 15:55:10 | 显示全部楼层
    该软件我已经在吾爱上面破解发布了 6.23.17.2

    点评

    其实这个软件并没有你想象的复杂,有兴趣可以看看我的优雅补丁,支持最新版的更新,只需要修改主程序的几处而已!  详情 回复 发表于 2015-8-5 07:57
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-6-16 14:07
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2015-8-4 16:22:29 | 显示全部楼层
    不错了!
    我那个没更新了,只适合6.1x

    点评

    你的补丁支持我这个版本  详情 回复 发表于 2015-8-5 09:51
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 20:48
  • 签到天数: 1976 天

    [LV.Master]伴坛终老

    发表于 2015-8-4 22:24:22 | 显示全部楼层
    崇拜算法高手
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 20:48
  • 签到天数: 1976 天

    [LV.Master]伴坛终老

    发表于 2015-8-4 22:24:46 | 显示全部楼层
    本帖最后由 wkxq 于 2015-8-4 22:26 编辑

    因网速问题,不好意思点重复了,请管理员删除此回复
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-1 23:51
  • 签到天数: 559 天

    [LV.9]以坛为家II

    发表于 2015-8-5 07:55:23 | 显示全部楼层
    现在的idm似乎是正确的sn会网络验证,然并卵。还是用爆破吧!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-1 23:51
  • 签到天数: 559 天

    [LV.9]以坛为家II

    发表于 2015-8-5 07:57:37 | 显示全部楼层
    昔邪 发表于 2015-8-4 15:55
    该软件我已经在吾爱上面破解发布了 6.23.17.2

    其实这个软件并没有你想象的复杂,有兴趣可以看看我的优雅补丁,支持最新版的更新,只需要修改主程序的几处而已!
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2016-1-13 12:25
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2015-8-5 08:50:02 | 显示全部楼层
    一直用老漂的补丁,不用天天更新就下载而以
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2016-10-10 10:27
  • 签到天数: 26 天

    [LV.4]偶尔看看III

     楼主| 发表于 2015-8-5 09:51:33 | 显示全部楼层
    飘云 发表于 2015-8-4 16:22
    不错了!
    我那个没更新了,只适合6.1x

    你的补丁支持我这个版本
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 149 天

    [LV.7]常住居民III

    发表于 2015-8-8 19:25:16 | 显示全部楼层
    技术上来讲,不觉得这个然并卵,挺好的分析思路
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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