首页
社区
课程
招聘
[原创] CTF2017 第七题不问少年 CrackMe 详细破解分析过程
2017-6-14 14:07 10417

[原创] CTF2017 第七题不问少年 CrackMe 详细破解分析过程

2017-6-14 14:07
10417

序言:


本题采用TLS、SMC等反调试、反分析手段,算法为索引一个64字节“环”匹中密文再进行加密和隐藏比较,
并利用注册码进行SMC解码,想爆破都不容易!本题算法和防护手段都算上乘之作,无奈碰到了大神而饮恨。
本文是在提交答案之后重新写的,假设输入答案:BwnsAtPediy2017KX9Ok,节省笔墨纸砚,努力把文章写好。


一、查壳,试运行,分析TLS反调试


//首先查壳,Microsoft Linker(14.0)[EXE32],OD加载直接运行,OEP停不下来,噶么鬼?
//检查PE格式发现TLS

//勾选SOD插件“Break On Tls”,重新加载,跟踪40C120 TLS函数,看看都做了什么小动作
//加载停在了40C120

0040C120    55                     PUSH EBP
0040C121    8BEC                   MOV EBP,ESP
0040C123    83EC 10                SUB ESP,0x10
0040C126    A1 84044000            MOV EAX,DWORD PTR DS:[0x400484]
0040C12B    33C5                   XOR EAX,EBP
0040C12D    8945 FC                MOV DWORD PTR SS:[EBP-0x4],EAX
0040C130    837D 0C 01             CMP DWORD PTR SS:[EBP+0xC],0x1
0040C134    53                     PUSH EBX
0040C135    56                     PUSH ESI
0040C136    57                     PUSH EDI
0040C137    75 48                  JNZ X7-不问少.0040C181
0040C139    8365 F0 00             AND DWORD PTR SS:[EBP-0x10],0x0
0040C13D    60                     PUSHAD
0040C13E    64:A1 18000000         MOV EAX,DWORD PTR FS:[0x18]
0040C144    64:A1 18000000         MOV EAX,DWORD PTR FS:[0x18]
0040C14A    8B40 30                MOV EAX,DWORD PTR DS:[EAX+0x30]
0040C14D    8B40 08                MOV EAX,DWORD PTR DS:[EAX+0x8]
0040C150    8B58 3C                MOV EBX,DWORD PTR DS:[EAX+0x3C]
0040C153    03D8                   ADD EBX,EAX                                                         ; 取得PE头地址
0040C155    8B5B 28                MOV EBX,DWORD PTR DS:[EBX+0x28]
0040C158    03D8                   ADD EBX,EAX                                                         ; 取得OEP
0040C15A    895D F0                MOV DWORD PTR SS:[EBP-0x10],EBX
0040C15D    61                     POPAD
0040C15E    8D45 F4                LEA EAX,DWORD PTR SS:[EBP-0xC]
0040C161    C745 F4 EB7458CC       MOV DWORD PTR SS:[EBP-0xC],0xCC5874EB
0040C168    66:C745 F8 E875        MOV WORD PTR SS:[EBP-0x8],0x75E8
0040C16E    6A 06                  PUSH 0x6                                                            ; 密钥长度 0x6 字节
0040C170    50                     PUSH EAX                                                            ; 异或密钥 EB 74 58 CC E8 75
0040C171    68 C8000000            PUSH 0xC8                                                           ; 解密 0xC8 字节
0040C176    FF75 F0                PUSH DWORD PTR SS:[EBP-0x10]                                        ; OEP 起始地址
0040C179    E8 584C0000            CALL 7-不问少.00410DD6                                                 ; 利用6字节密钥循环解密并清除OEP开始0xC8字节
0040C17E    83C4 10                ADD ESP,0x10
0040C181    8B4D FC                MOV ECX,DWORD PTR SS:[EBP-0x4]
0040C184    5F                     POP EDI
0040C185    5E                     POP ESI
0040C186    33CD                   XOR ECX,EBP
0040C188    5B                     POP EBX
0040C189    E8 CD7D0000            CALL 7-不问少.00413F5B
0040C18E    8BE5                   MOV ESP,EBP
0040C190    5D                     POP EBP
0040C191    C2 0C00                RETN 0x

//使用6字节密钥“EB 74 58 CC E8 75”分别异或OEP入口0xC8字节代码,还原并清除了OD自动设置的OEP断点,所以载入就跑飞了
//接下来对代码段设置内存访问断点,几次运行后就能断到OEP

00414422 >  E8 16050000            CALL 7-不问少.0041493D
00414427  ^ E9 5CFEFFFF            JMP 7-不问少.00414288


二、分析主体流程

//断点 bp GetDlgItemTextA,输入注册码,单击“开始验证”

0012FAE0   00410502  /CALL 到 GetDlgItemTextA 来自 7-不问少.004104FC
0012FAE4   000E02A0  |hWnd = 000E02A0 ('CrackMe By 不问年少',class='#32770')
0012FAE8   000003E8  |ControlID = 3E8 (1000.)
0012FAEC   0012FB20  |Buffer = 0012FB20
0012FAF0   00000064  \Count = 64 (100.)

//断下来之后,返回主程序

004104F1    6A 64           PUSH 0x64
004104F3    50              PUSH EAX
004104F4    68 E8030000     PUSH 0x3E8
004104F9    FF76 04         PUSH DWORD PTR DS:[ESI+0x4]
004104FC    FF15 283E4500   CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; user32.GetDlgItemTextA

00410520    C745 E8 5045444>MOV DWORD PTR SS:[EBP-0x18],0x49444550
00410527    53              PUSH EBX
00410528    BF 301B4100     MOV EDI,7-不问少.00411B30
0041052D    C645 EC 59      MOV BYTE PTR SS:[EBP-0x14],0x59          ; PEDIY
00410531    57              PUSH EDI
00410532    E8 9F080000     CALL 7-不问少.00410DD6

//用“PEDIY”作为密钥,解密426字节,对应“CALL 00411B30”所需要的主算法程序

00410DD6  /$  55            PUSH EBP
00410DD7  |.  8BEC          MOV EBP,ESP
00410DD9  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+0x8]
00410DDC  |.  56            PUSH ESI
00410DDD  |.  33F6          XOR ESI,ESI
00410DDF  |.  3975 0C       CMP DWORD PTR SS:[EBP+0xC],ESI
00410DE2  |.  7E 17         JLE X7-不问少.00410DFB
00410DE4  |.  57            PUSH EDI
00410DE5  |.  8B7D 10       MOV EDI,DWORD PTR SS:[EBP+0x10]
00410DE8  |>  8BC6          /MOV EAX,ESI
00410DEA  |.  99            |CDQ
00410DEB  |.  F77D 14       |IDIV DWORD PTR SS:[EBP+0x14]
00410DEE  |.  8A043A        |MOV AL,BYTE PTR DS:[EDX+EDI]
00410DF1  |.  3001          |XOR BYTE PTR DS:[ECX],AL
00410DF3  |.  41            |INC ECX
00410DF4  |.  46            |INC ESI
00410DF5  |.  3B75 0C       |CMP ESI,DWORD PTR SS:[EBP+0xC]
00410DF8  |.^ 7C EE         \JL X7-不问少.00410DE8
00410DFA  |.  5F            POP EDI
00410DFB  |>  5E            POP ESI
00410DFC  |.  5D            POP EBP
00410DFD  \.  C3            RETN

//处理前

00411B30  3A 6D FC 6C 5F 15 45 AC 2E 7D 50 45 CF B8 6A 8B  :m黮_E?}PE细j
00411B40  CC 19 B5 DA BC 5D C9 0C 51 D9 20 A0 C2 95 00 AD  ?第糫?Q?犅?
00411B50  F7 A8 A6 AF 83 01 B5 58 D8 18 B8 C2 97 B8 3F 45  鳕Ο?礨?嘎椄?E
00411B60  49 59 D4 85 4B CD 02 51 45 44 C4 17 74 C8 01 41  IY詤K?QED?t?A
00411B70  62 98 31 4D 23 A6 03 15 AC F2 B6 AF BA CF 0C 41  b?M#?动合.A
00411B80  DD 08 B4 18 09 DD 08 9C C0 1C 80 CD 19 B9 D0 0D  ??.?溊€?剐.
00411B90  9D CD 14 85 D9 18 A4 A1 EC 51 45 44 8F 1C AC 47  澩呝ぁ霶ED?珿
00411BA0  C9 04 51 DB 18 58 CA A2 40 CE 01 51 56 13 08 4C  ?Q?X盛@?QVL
00411BB0  4A 98 D3 BE 54 C4 14 58 CE BC 46 1A 1D 4D 77 9B  J樣綯?X渭FMw
00411BC0  78 05 A9 6F B0 62 98 4A 03 34 B5 D5 BA 30 45 D9  x﹐癰楯4嫡?E
00411BD0  61 89 05 0B 62 87 30 B3 C2 04 4C 76 8D C0 14 B8  a?b?陈Lv嵗
00411BE0  7C 09 99 56 DE F4 44 49 59 DB 38 9C 7A 99 10 CC  |.橵摁DIY?渮?
00411BF0  39 A5 72 97 82 01 AD 5C 50 45 44 C0 1C 9C BA 31  9梻璡PED?満1
00411C00  AD DA AB 55 C9 0C 51 5F 06 01 41 5A 91 15 BB 3F  玌?Q_AZ??
00411C10  5D AF 73 AC 7D AA AF BA CF 81 DA 94 55 7F 07 5D  ]痵瑌合佢擴]
00411C20  24 25 CE 88 73 56 CD 43 3C 5C 63 9E 07 A2 5A 5F  $%螆sV虲<\c?_
00411C30  FB 9C CA 24 B8 45 CC 56 25 6E CE 01 85 5A 97 CC  麥?窫蘓%n?匷椞
00411C40  01 9D 6A AF 04 7F 07 5D 25 47 CF 47 56 EE 86 03  漥?]%G螱V顔
00411C50  D0 AE 2D A1 2E 4C 03 53 87 7F B1 2C B7 CE 39 A5  挟-?LS??肺9
00411C60  D3 91 6F 42 C1 5E 25 40 77 92 1A BB 46 4B F7 81  討oB羄%@w?籉K鱽
00411C70  D3 28 90 48 D1 4F 30 8E 46 E7 5F CE 42 C3 5D 51  ?怘袿0嶧鏮蜝胅Q
00411C80  CD 43 C2 14 B8 04 03 C0 14 B8 CC 39 A5 62 1D 95  虲???柑9
00411C90  39 41 D2 0D 59 AD 2D A6 AF BA C9 0C A9 00 BA 31  9A?Y?Ο荷.??
00411CA0  95 A6 25 9D AC 85 AB AF BA C7 8D 55 DD 00 9C C4  暒%潿叓菎U?溎
00411CB0  17 5C 15 AC 7D A3 AF BA 77 92 D1 0D B9 C9 04 81  \瑌/簑捬.股
00411CC0  B8 8C 46 49 59 D3 08 B8 B6 D4 1D 4D 17 23 58 B8  笇FIY?付?M#X
00411CD0  4A AA B6 A6 B8 D6 66 49 59 92                    JΩ謋IY?.j.

//处理后

00411B30  6A 28 B8 25 06 45 00 E8 67 24 00 00 8B F1 33 DB  j(?E.鑗$..嬹3
00411B40  89 5D FC 83 EC 18 8D 45 08 89 65 E4 8B CC 50 E8  塢鼉?岴塭鋴蘌
00411B50  B3 E1 FF FF C6 45 FC 01 88 5D FC 8B CE E8 7A 01  翅艵?圿鼖舞z
00411B60  00 00 84 C0 0F 84 5B 01 00 00 8D 4E 24 8D 45 08  ..劺刐..峃$岴
00411B70  3B C8 74 09 6A FF 53 50 E8 BB EF FF FF 8B 45 18  ;萾.jSP杌?婨
00411B80  8D 4D F0 51 50 8D 4D D8 89 45 D0 88 5D F0 89 5D  峂餛P峂貕E袌]饓]
00411B90  D8 89 5D DC 89 5D E0 E8 B5 01 00 00 C6 45 FC 02  貕]軌]噼?..艵?
00411BA0  8D 4D 08 8B 5D 1C 83 FB 10 8B 45 18 0F 43 4D 08  峂媇凔婨CM
00411BB0  03 C1 83 FB 10 8D 4D 08 8B F8 0F 43 4D 08 33 D2  羶?峂孁CM3
00411BC0  21 55 EC 2B F9 3B C8 0F 47 7D EC 85 FF 74 0C 80  !U???G}靺t.€
00411BD0  31 CC 41 42 3B D7 75 F7 8B 5D 1C 33 C9 89 4D E8  1藺B;譽鲖]3蓧M
00411BE0  39 4D D0 0F 8E B1 00 00 00 8B 7D D8 33 C0 40 89  9M?幈...媫?繞
00411BF0  7D EC 2B C7 C7 45 E4 05 00 00 00 89 45 CC FF 75  }?乔E?...塃?u
00411C00  E4 83 FB 10 8D 45 08 0F 43 45 08 03 C1 50 FF 76  鋬?岴CE罰v
00411C10  04 FF 36 E8 34 F3 FF FF 8B C8 83 C4 10 3B 4E 04  6??嬋兡;N
00411C20  74 60 8A C1 2A 06 88 07 75 05 33 DB 43 EB 03 0F  t`娏*?u3跜?
00411C30  BE D8 83 7D E8 00 88 1F 7C 3E 8B 45 CC 03 C7 89  矩儅??|>婨?菈
00411C40  45 D4 33 FF 41 3B 4E 04 75 02 8B 0E 0F BE C3 47  E?A;Nu?久G
00411C50  99 F7 7D E4 6A 05 5A 03 C2 3B F8 75 E7 8B 7D EC  欦}鋔Z?鴘鐙}
00411C60  8A C1 2A 06 88 07 75 05 33 DB 43 EB 03 0F BE D8  娏*?u3跜?矩
00411C70  83 6D D4 01 88 1F 75 CA 0F BE 0F 8B 06 8A 04 01  僲??u????
00411C80  88 07 8B 4D E8 41 47 89 4D E8 89 7D EC 3B 4D D0  ?婱鐰G塎鑹}?M
00411C90  7D 08 8B 5D 1C E9 64 FF FF FF 8D 45 F0 50 FF 75  }媇閐岴餚u
00411CA0  DC FF 75 D8 E8 CC F2 FF FF 83 C4 0C 8D 45 D8 8D  ?u罔舔兡.岴貚
00411CB0  4E 0C 50 E8 34 FA FF FF 33 DB 88 5D FC 8D 4D D8  N.P??3蹐]鼚M
00411CC0  E8 C9 02 00 00 83 4D FC FF 8D 4D 08 53 6A 01 E8  枭..僊?峂Sj
00411CD0  0F EE FF FF E8 93 22 00 00 C2                    ?钃"..?.j
//IDA -- 处理426字节

char __cdecl sub_410DD6(int a1, signed int a2, int a3, signed int a4)
{
  int v4; // ecx@1
  signed int i; // esi@1
  char result; // al@2

  v4 = a1;
  for ( i = 0; i < a2; ++i )
  {
    result = *(_BYTE *)(i % a4 + a3);
    *(_BYTE *)v4++ ^= result;
  }
  return result;
}

int __thiscall sub_40FD07(int this, int a2)
{
  int v2; // esi@1

  v2 = this;
  *(_DWORD *)(this + 20) = 15;
  *(_DWORD *)(this + 16) = 0;
  *(_BYTE *)this = 0;
  sub_410B38(a2, 0, -1);
  return v2;
}

//继续跟踪主程序

00410518    6A 05           PUSH 0x5
0041051A    50              PUSH EAX
0041051B    BB AA010000     MOV EBX,0x1AA
00410520    C745 E8 5045444>MOV DWORD PTR SS:[EBP-0x18],0x49444550
00410527    53              PUSH EBX
00410528    BF 301B4100     MOV EDI,7-不问少.00411B30
0041052D    C645 EC 59      MOV BYTE PTR SS:[EBP-0x14],0x59          ; PEDIY
00410531    57              PUSH EDI
00410532    E8 9F080000     CALL 7-不问少.00410DD6                      ; 用“PEDIY”作为密钥,解密426字节
00410537    51              PUSH ECX
00410538    51              PUSH ECX
00410539    8D85 68FFFFFF   LEA EAX,DWORD PTR SS:[EBP-0x98]
0041053F    89A5 64FFFFFF   MOV DWORD PTR SS:[EBP-0x9C],ESP
00410545    8BCC            MOV ECX,ESP
00410547    50              PUSH EAX
00410548    E8 BAF7FFFF     CALL 7-不问少.0040FD07                      ; 字符串拷贝
0041054D    C645 FC 01      MOV BYTE PTR SS:[EBP-0x4],0x1
00410551    C645 FC 00      MOV BYTE PTR SS:[EBP-0x4],0x0
00410555    8D4E 40         LEA ECX,DWORD PTR DS:[ESI+0x40]
00410558    E8 D3150000     CALL 7-不问少.00411B30                      ; Function2
0041055D    6A 05           PUSH 0x5
0041055F    8D45 E8         LEA EAX,DWORD PTR SS:[EBP-0x18]
00410562    50              PUSH EAX
00410563    53              PUSH EBX
00410564    57              PUSH EDI
00410565    E8 6C080000     CALL 7-不问少.00410DD6
0041056A    83C4 10         ADD ESP,0x10
0041056D    8D4E 40         LEA ECX,DWORD PTR DS:[ESI+0x40]
00410570    E8 B0120000     CALL 7-不问少.00411825                      ; check


三、分析算法程序

//断点410558,断下后单步跟进 CALL 00411B30

00411BBA  |.  0F434D 08     CMOVNB ECX,DWORD PTR SS:[EBP+0x8]                           ;  取input
00411BBE  |.  33D2          XOR EDX,EDX
00411BC0  |.  2155 EC       AND DWORD PTR SS:[EBP-0x14],EDX
00411BC3  |.  2BF9          SUB EDI,ECX                                                 ;  位数
00411BC5  |.  3BC8          CMP ECX,EAX
00411BC7  |.  0F477D EC     CMOVA EDI,DWORD PTR SS:[EBP-0x14]                           ;  位数结束
00411BCB  |.  85FF          TEST EDI,EDI
00411BCD  |.  74 0C         JE X7-不问少.00411BDB
00411BCF  |>  8031 CC       /XOR BYTE PTR DS:[ECX],0xCC                                 ;  将用户输入input[]每一位与0xCC异或
00411BD2  |.  41            |INC ECX
00411BD3  |.  42            |INC EDX
00411BD4  |.  3BD7          |CMP EDX,EDI
00411BD6  |.^ 75 F7         \JNZ X7-不问少.00411BCF
00411BD8  |.  8B5D 1C       MOV EBX,DWORD PTR SS:[EBP+0x1C]

//Array1:(用户输入与0xCC异或后)

0068F9B0  8E BB A2 BF 8D B8 9C A9 A8 A5 B5 FE FC FD FB 87  幓⒖嵏湬ē叠麌
0068F9C0  94 F5 83 A7  

00411BF4  |.  C745 E4 05000>MOV DWORD PTR SS:[EBP-0x1C],0x5                             ;  5
00411BFB  |.  8945 CC       MOV DWORD PTR SS:[EBP-0x34],EAX
00411BFE  |>  FF75 E4       /PUSH DWORD PTR SS:[EBP-0x1C]                               ;  5
00411C01  |.  83FB 10       |CMP EBX,0x10
00411C04  |.  8D45 08       |LEA EAX,DWORD PTR SS:[EBP+0x8]
00411C07  |.  0F4345 08     |CMOVNB EAX,DWORD PTR SS:[EBP+0x8]
00411C0B  |.  03C1          |ADD EAX,ECX
00411C0D  |.  50            |PUSH EAX                                                   ;  xor_input
00411C0E  |.  FF76 04       |PUSH DWORD PTR DS:[ESI+0x4]
00411C11  |.  FF36          |PUSH DWORD PTR DS:[ESI]                                    ;  注意 [esi]

Array2:(64字节)

00684C90  89 BC 95 FC FB BA ED 9A BB AE FE 99 A2 98 B9 F9  壖朁須划郭
00684CA0  9F 84 9C FD 83 AD B6 A9 A5 F5 8C A7 9E 96 8A F4  焺滮儹订ヵ導灃婔
00684CB0  85 BE A8 8F 86 AF 88 9D 87 BF FF A1 8B 81 A0 AB  吘◤啹垵嚳仩?
00684CC0  8E BD B5 AA 82 94 A4 8D A3 F8 B4 FA 9B A6 B8 80  幗氮倲x代洣竴
00411BFE  |> /FF75 E4       /PUSH DWORD PTR SS:[EBP-0x1C]
00411C01  |. |83FB 10       |CMP EBX,0x10
00411C04  |. |8D45 08       |LEA EAX,DWORD PTR SS:[EBP+0x8]
00411C07  |. |0F4345 08     |CMOVNB EAX,DWORD PTR SS:[EBP+0x8]
00411C0B  |. |03C1          |ADD EAX,ECX
00411C0D  |. |50            |PUSH EAX
00411C0E  |. |FF76 04       |PUSH DWORD PTR DS:[ESI+0x4]
00411C11  |. |FF36          |PUSH DWORD PTR DS:[ESI]
00411C13  |. |E8 34F3FFFF   |CALL 7-不问少.00410F4C                     ;  Array1 逐位搜索在 Array2 中的位置
00411C18  |. |8BC8          |MOV ECX,EAX
00411C1A  |. |83C4 10       |ADD ESP,0x10
00411C1D  |. |3B4E 04       |CMP ECX,DWORD PTR DS:[ESI+0x4]          ;  不超出数组下限
00411C20  |. |74 60         |JE X7-不问少.00411C82
00411C22  |. |8AC1          |MOV AL,CL
00411C24  |. |2A06          |SUB AL,BYTE PTR DS:[ESI]                ;  Array2 下标,如果索引超出下标就回头,类似一个环
00411C26  |. |8807          |MOV BYTE PTR DS:[EDI],AL
00411C28  |. |75 05         |JNZ X7-不问少.00411C2F
00411C2A  |. |33DB          |XOR EBX,EBX
00411C2C  |. |43            |INC EBX
00411C2D  |. |EB 03         |JMP X7-不问少.00411C32
00411C2F  |> |0FBED8        |MOVSX EBX,AL
00411C32  |> |837D E8 00    |CMP DWORD PTR SS:[EBP-0x18],0x0         ;  计数器
00411C36  |. |881F          |MOV BYTE PTR DS:[EDI],BL
00411C38  |. |7C 3E         |JL X7-不问少.00411C78
00411C3A  |. |8B45 CC       |MOV EAX,DWORD PTR SS:[EBP-0x34]
00411C3D  |. |03C7          |ADD EAX,EDI
00411C3F  |. |8945 D4       |MOV DWORD PTR SS:[EBP-0x2C],EAX         ;  小循环次数
00411C42  |> |33FF          |/XOR EDI,EDI
00411C44  |> |41            ||/INC ECX
00411C45  |. |3B4E 04       |||CMP ECX,DWORD PTR DS:[ESI+0x4]
00411C48  |. |75 02         |||JNZ X7-不问少.00411C4C
00411C4A  |. |8B0E          |||MOV ECX,DWORD PTR DS:[ESI]
00411C4C  |> |0FBEC3        |||MOVSX EAX,BL                          ;  最近一次匹中Array2的下标
00411C4F  |. |47            |||INC EDI
00411C50  |. |99            |||CDQ
00411C51  |. |F77D E4       |||IDIV DWORD PTR SS:[EBP-0x1C]
00411C54  |. |6A 05         |||PUSH 0x5
00411C56  |. |5A            |||POP EDX
00411C57  |. |03C2          |||ADD EAX,EDX
00411C59  |. |3BF8          |||CMP EDI,EAX
00411C5B  |.^|75 E7         ||\JNZ X7-不问少.00411C44                   ;  小间隔定位
00411C5D  |. |8B7D EC       ||MOV EDI,DWORD PTR SS:[EBP-0x14]
00411C60  |. |8AC1          ||MOV AL,CL
00411C62  |. |2A06          ||SUB AL,BYTE PTR DS:[ESI]               ;  Array2 下标 (小间隔)
00411C64  |. |8807          ||MOV BYTE PTR DS:[EDI],AL               ;  就是个索引算法,详细见附件Python
00411C66  |. |75 05         ||JNZ X7-不问少.00411C6D
00411C68  |. |33DB          ||XOR EBX,EBX
00411C6A  |. |43            ||INC EBX
00411C6B  |. |EB 03         ||JMP X7-不问少.00411C70
00411C6D  |> |0FBED8        ||MOVSX EBX,AL
00411C70  |> |836D D4 01    ||SUB DWORD PTR SS:[EBP-0x2C],0x1        ;  小间隔循环次数
00411C74  |. |881F          ||MOV BYTE PTR DS:[EDI],BL
00411C76  |.^|75 CA         |\JNZ X7-不问少.00411C42
00411C78  |> |0FBE0F        |MOVSX ECX,BYTE PTR DS:[EDI]
00411C7B  |. |8B06          |MOV EAX,DWORD PTR DS:[ESI]
00411C7D  |. |8A0401        |MOV AL,BYTE PTR DS:[ECX+EAX]
00411C80  |. |8807          |MOV BYTE PTR DS:[EDI],AL
00411C82  |> |8B4D E8       |MOV ECX,DWORD PTR SS:[EBP-0x18]
00411C85  |. |41            |INC ECX
00411C86  |. |47            |INC EDI
00411C87  |. |894D E8       |MOV DWORD PTR SS:[EBP-0x18],ECX
00411C8A  |. |897D EC       |MOV DWORD PTR SS:[EBP-0x14],EDI
00411C8D  |. |3B4D D0       |CMP ECX,DWORD PTR SS:[EBP-0x30]         ;  位数
00411C90  |. |7D 08         |JGE X7-不问少.00411C9A
00411C92  |. |8B5D 1C       |MOV EBX,DWORD PTR SS:[EBP+0x1C]
00411C95  |.^\E9 64FFFFFF   \JMP 7-不问少.00411BFE

//在Array2环中索引查询结果
//Array3:

001D29B8  B8 AD AF 9C 9D BB 85 BF F9 BB BE 99 B8 A1 9C 99  腑瘻澔吙緳浮湙
001D29C8  8C 85 9A A4                                      寘殼B.

//对Array3再次异或、移位、与等加密,结果还是更新到Array3中

00411C9D  |.  50            PUSH EAX
00411C9E  |.  FF75 DC       PUSH DWORD PTR SS:[EBP-0x24]
00411CA1  |.  FF75 D8       PUSH DWORD PTR SS:[EBP-0x28]
00411CA4  |.  E8 CCF2FFFF   CALL 7-不问少.00410F75                      ;  Array3 异或 移位 与 等,结果还是存到 Array3

char __cdecl sub_410F75(unsigned int arrary3, unsigned int a2)
{
  unsigned int arrary3_; // edx@1
  char result; // al@1
  int len; // esi@1
  int i; // edi@1

  arrary3_ = arrary3;
  result = 0;
  len = a2 - arrary3;
  i = 0;
  if ( arrary3 > a2 )
    len = 0;
  if ( len )
  {
    do
    {
      result = 8 * (*(_BYTE *)arrary3_ ^ 0xCC) | ((char)(*(_BYTE *)arrary3_ ^ 0xCC) >> 5);
      *(_BYTE *)arrary3_++ = result;
      ++i;
    }
    while ( i != len );
  }
  return result;
}

//加密后的Array3

001D29B8  A3 0B 1B 82 8A BB 4A 9B A9 BB 93 AA A3 6B 82 AA  ?倞籎洨粨k偑
001D29C8  02 4A B2 43                                      J睠B


四、分析验证程序

//返回主程序

0041055D  |.  6A 05         PUSH 0x5
0041055F  |.  8D45 E8       LEA EAX,DWORD PTR SS:[EBP-0x18]
00410562  |.  50            PUSH EAX
00410563  |.  53            PUSH EBX
00410564  |.  57            PUSH EDI
00410565  |.  E8 6C080000   CALL 7-不问少.00410DD6                                ;  用“PEDIY”作密钥,处理426字节

char __cdecl sub_410DD6(int Array3, signed int len_426, int miyao, signed int div_5)
{
  int Array3_; // ecx@1
  signed int i; // esi@1
  char result; // al@2

  Array3_ = Array3;
  for ( i = 0; i < len_426; ++i )
  {
    result = *(_BYTE *)(i % div_5 + miyao);
    *(_BYTE *)Array3_++ ^= result;
  }
  return result;
}

0012FA8C   00411B30  入口地址
0012FA90   000001AA
0012FA94   0012FB30
0012FA98   00000005

//加密“CALL 00411B30”对应主算法流程的426字节,主算法程序加密掉,理念不错,用完弃之!

00411B30  3A 6D FC 6C 5F 15 45 AC 2E 7D 50 45 CF B8 6A 8B  :m黮_E?}PE细j?
00411B40  CC 19 B5 DA BC 5D C9 0C 51 D9 20 A0 C2 95 00 AD  ?第糫?Q?犅??
00411B50  F7 A8 A6 AF 83 01 B5 58 D8 18 B8 C2 97 B8 3F 45  鳕Ο?礨?嘎椄?E
00411B60  49 59 D4 85 4B CD 02 51 45 44 C4 17 74 C8 01 41  IY詤K?QED?t?A
00411B70  62 98 31 4D 23 A6 03 15 AC F2 B6 AF BA CF 0C 41  b?M#?动合.A
00411B80  DD 08 B4 18 09 DD 08 9C C0 1C 80 CD 19 B9 D0 0D  ??.?溊€?剐.
00411B90  9D CD 14 85 D9 18 A4 A1 EC 51 45 44 8F 1C AC 47  澩呝ぁ霶ED?珿
00411BA0  C9 04 51 DB 18 58 CA A2 40 CE 01 51 56 13 08 4C  ?Q?X盛@?QVL
00411BB0  4A 98 D3 BE 54 C4 14 58 CE BC 46 1A 1D 4D 77 9B  J樣綯?X渭FMw?
00411BC0  78 05 A9 6F B0 62 98 4A 03 34 B5 D5 BA 30 45 D9  x﹐癰楯4嫡?E?
00411BD0  61 89 05 0B 62 87 30 B3 C2 04 4C 76 8D C0 14 B8  a?b?陈Lv嵗?
00411BE0  7C 09 99 56 DE F4 44 49 59 DB 38 9C 7A 99 10 CC  |.橵摁DIY?渮??
00411BF0  39 A5 72 97 82 01 AD 5C 50 45 44 C0 1C 9C BA 31  9梻璡PED?満1
00411C00  AD DA AB 55 C9 0C 51 5F 06 01 41 5A 91 15 BB 3F  玌?Q_AZ??
00411C10  5D AF 73 AC 7D AA AF BA CF 81 DA 94 55 7F 07 5D  ]痵瑌合佢擴]
00411C20  24 25 CE 88 73 56 CD 43 3C 5C 63 9E 07 A2 5A 5F  $%螆sV虲<\c?_
00411C30  FB 9C CA 24 B8 45 CC 56 25 6E CE 01 85 5A 97 CC  麥?窫蘓%n?匷椞
00411C40  01 9D 6A AF 04 7F 07 5D 25 47 CF 47 56 EE 86 03  漥?]%G螱V顔
00411C50  D0 AE 2D A1 2E 4C 03 53 87 7F B1 2C B7 CE 39 A5  挟-?LS??肺9?
00411C60  D3 91 6F 42 C1 5E 25 40 77 92 1A BB 46 4B F7 81  討oB羄%@w?籉K鱽
00411C70  D3 28 90 48 D1 4F 30 8E 46 E7 5F CE 42 C3 5D 51  ?怘袿0嶧鏮蜝胅Q
00411C80  CD 43 C2 14 B8 04 03 C0 14 B8 CC 39 A5 62 1D 95  虲???柑9?
00411C90  39 41 D2 0D 59 AD 2D A6 AF BA C9 0C A9 00 BA 31  9A?Y?Ο荷.??
00411CA0  95 A6 25 9D AC 85 AB AF BA C7 8D 55 DD 00 9C C4  暒%潿叓菎U?溎
00411CB0  17 5C 15 AC 7D A3 AF BA 77 92 D1 0D B9 C9 04 81  \瑌/簑捬.股?
00411CC0  B8 8C 46 49 59 D3 08 B8 B6 D4 1D 4D 17 23 58 B8  笇FIY?付?M#X?
00411CD0  4A AA B6 A6 B8 D6 66 49 59 92                    JΩ謋IY?.j.

//CHECK,跟进 CALL 00411825

0041056D  |.  8D4E 40       LEA ECX,DWORD PTR DS:[ESI+0x40]
00410570  |.  E8 B0120000   CALL 7-不问少.00411825                                ;  check

//检验Array3是否满足,如果不满足就不进行后续SMC解码

00411825   $  6A 18         PUSH 0x18
00411827   .  B8 4A054500   MOV EAX,7-不问少.0045054A
0041182C   .  E8 DD270000   CALL 7-不问少.0041400E
00411831   .  894D E4       MOV DWORD PTR SS:[EBP-0x1C],ECX
00411834   .  E8 3C010000   CALL 7-不问少.00411975                      ;  检验Array3是否满足,如果不满足就不进行后续SMC解码
00411839   .  84C0          TEST AL,AL
0041183B   .  0F84 D8000000 JE 7-不问少.00411919

//再跟进 CALL 00411975

004119D2  |.  6A 28         PUSH 0x28
004119D4  |.  E8 A2040000   CALL 7-不问少.00411E7B
004119D9  |.  85FF          TEST EDI,EDI                                       ;  40位
004119DB  |.  7E 54         JLE X7-不问少.00411A31

004119E7  |. |0F4345 D8     |CMOVNB EAX,DWORD PTR SS:[EBP-0x28]                ;  Array3 转为 字符串 Array4
004119EB  |. |03C3          |ADD EAX,EBX
004119ED  |. |50            |PUSH EAX
004119EE  |. |FF75 B0       |PUSH DWORD PTR SS:[EBP-0x50]
004119F1  |. |FF75 AC       |PUSH DWORD PTR SS:[EBP-0x54]
004119F4  |. |E8 53F5FFFF   |CALL 7-不问少.00410F4C                               ;  按十六进制转数值
004119F9  |. |2A45 AC       |SUB AL,BYTE PTR SS:[EBP-0x54]
004119FC >|. |83C4 10       |ADD ESP,0x10
004119FF  |. |0FBEC8        |MOVSX ECX,AL
00411A02  |. |8BC1          |MOV EAX,ECX
00411A04  |. |99            |CDQ
00411A05  |. |83E2 03       |AND EDX,0x3
00411A08  |. |03C2          |ADD EAX,EDX
00411A0A  |. |C1F8 02       |SAR EAX,0x2                                       ;  保存商
00411A0D  |. |8845 C4       |MOV BYTE PTR SS:[EBP-0x3C],AL                     ;  *(_BYTE *)(a1 - 0x3C) = (char)(v8 - *(_BYTE *)(a1 - 0x54)) / 4;
00411A10  |. |81E1 03000080 |AND ECX,0x80000003                                ;  0,1,2
00411A16  |. |79 05         |JNS X7-不问少.00411A1D
00411A18  |. |49            |DEC ECX
00411A19  |. |83C9 FC       |OR ECX,0xFFFFFFFC
00411A1C  |. |41            |INC ECX
00411A1D  |> |8D45 C4       |LEA EAX,DWORD PTR SS:[EBP-0x3C]                   ;  保存余数
00411A20  |. |884D C5       |MOV BYTE PTR SS:[EBP-0x3B],CL                     ;  *(_BYTE *)(a1 - 0x3B) = (char)(v8 - *(_BYTE *)(a1 - 0x54)) % 4;
00411A23 >|. |50            |PUSH EAX
00411A24  |. |8D4D B8       |LEA ECX,DWORD PTR SS:[EBP-0x48]
00411A27  |. |E8 06070000   |CALL 7-不问少.00412132                               ;  转存校验值,打乱地址
00411A2C  |. |43            |INC EBX
00411A2D  |. |3BDF          |CMP EBX,EDI
00411A2F  |.^\7C AC         \JL X7-不问少.004119DD

004119DD  |> /837D EC 10    /CMP DWORD PTR SS:[EBP-0x14],0x10
004119E1  |. |8D45 D8       |LEA EAX,DWORD PTR SS:[EBP-0x28]
004119E4  |. |FF75 C4       |PUSH DWORD PTR SS:[EBP-0x3C]
004119E7  |. |0F4345 D8     |CMOVNB EAX,DWORD PTR SS:[EBP-0x28]                ;  Array3 转为 字符串

//Array3 未转换之前:

001D29B8  A3 0B 1B 82 8A BB 4A 9B A9 BB 93 AA A3 6B 82 AA  ?倞籎洨粨k偑
001D29C8  02 4A B2 43                                      J睠B

//索引表,字符串、十六进制转换:

0012FA20  30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46  0123456789ABCDEF

//Array3转为字符串Array4 "A30B1B828ABB4A9BA9BB93AAA36B82AA024AB243"
//确定输入位数20位,这里才能达到80(0x50),异或后为0才能触发跳转

00411A31    8B4E 1C         MOV ECX,DWORD PTR DS:[ESI+0x1C]
00411A34    8B45 BC         MOV EAX,DWORD PTR SS:[EBP-0x44]
00411A37    2B4E 18         SUB ECX,DWORD PTR DS:[ESI+0x18]                    ; 0x50 0x50
00411A3A    2B45 B8         SUB EAX,DWORD PTR SS:[EBP-0x48]                    ; 0x24 0x50
00411A3D    33C8            XOR ECX,EAX                                        ; 0x74 0x0
00411A3F    F7C1 FEFFFFFF   TEST ECX,0xFFFFFFFE
00411A45    74 04           JE X7-不问少.00411A4B
//IDA

int __usercall sub_411975@<eax>(int a1@<ebp>)
{
  int v1; // ecx@1
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // edi@1
  int v5; // ST0C_4@1
  int v6; // eax@2
  int v7; // ST0C_4@2
  char v8; // al@4
  signed int v9; // ecx@4

  sub_413FD7(72);
  v2 = v1;
  sub_41191F(a1 - 40);
  v3 = 0;
  *(_DWORD *)(a1 - 4) = 0;
  v4 = *(_DWORD *)(a1 - 24);
  *(_BYTE *)(a1 - 60) = 0;
  v5 = *(_DWORD *)(a1 - 60);
  *(_OWORD *)(a1 - 56) = xmmword_403D50;
  *(_DWORD *)(a1 - 84) = 0;
  *(_DWORD *)(a1 - 80) = 0;
  *(_DWORD *)(a1 - 76) = 0;
  sub_410E2D(a1 - 56, a1 - 40, v5);
  *(_BYTE *)(a1 - 4) = 1;
  *(_DWORD *)(a1 - 72) = 0;
  *(_DWORD *)(a1 - 68) = 0;
  *(_DWORD *)(a1 - 64) = 0;
  *(_BYTE *)(a1 - 4) = 2;
  sub_411E7B(40);
  if ( v4 > 0 )
  {
    do
    {
      v6 = a1 - 40;
      v7 = *(_DWORD *)(a1 - 60);
      if ( *(_DWORD *)(a1 - 20) >= 0x10u )
        v6 = *(_DWORD *)(a1 - 40);
      v8 = sub_410F4C(*(_DWORD *)(a1 - 84), *(_DWORD *)(a1 - 80), v3 + v6);
      v9 = (char)(v8 - *(_BYTE *)(a1 - 84));
      *(_BYTE *)(a1 - 60) = (char)(v8 - *(_BYTE *)(a1 - 84)) / 4;
      *(_BYTE *)(a1 - 59) = v9 % 4;
      sub_412132(a1 - 60);
      ++v3;
    }
    while ( v3 < v4 );
  }
  if ( !(((*(_DWORD *)(a1 - 68) - *(_DWORD *)(a1 - 72)) ^ (*(_DWORD *)(v2 + 28) - *(_DWORD *)(v2 + 24))) & 0xFFFFFFFE) )
    sub_41612A(*(_DWORD *)(v2 + 24), *(_DWORD *)(a1 - 72), 2 * ((*(_DWORD *)(v2 + 28) - *(_DWORD *)(v2 + 24)) >> 1));
  *(_BYTE *)(a1 - 4) = 1;
  sub_411FB4(a1 - 72);
  *(_BYTE *)(a1 - 4) = 0;
  sub_411F8E(a1 - 84);
  *(_DWORD *)(a1 - 4) = -1;
  sub_410AE3(1, 0);
  return sub_413F81();
}

//目的是为了将Array4每个字母作为十六进制数进行除以4,取商和余数变形,阻止破解者轻易理解算法,藏得好辛苦,作者辛苦了!
//下记录断点,查看40组变形结果

Breakpoints
地址       模块       激活                       反汇编                                注释
004119FC   7-不问少      Log "十六进制"                   ADD ESP,0x10
00411A23   7-不问少      Log "转换为校验值"                  PUSH EAX

Log data
地址       消息
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 03
00411A23   COND: 转换为校验值 = 00000300
004119FC   COND: 十六进制 = 00
00411A23   COND: 转换为校验值 = 00000000
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 01
00411A23   COND: 转换为校验值 = 00000100
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 08
00411A23   COND: 转换为校验值 = 00000002
004119FC   COND: 十六进制 = 02
00411A23   COND: 转换为校验值 = 00000200
004119FC   COND: 十六进制 = 08
00411A23   COND: 转换为校验值 = 00000002
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 04
00411A23   COND: 转换为校验值 = 00000001
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 09
00411A23   COND: 转换为校验值 = 00000102
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 09
00411A23   COND: 转换为校验值 = 00000102
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 09
00411A23   COND: 转换为校验值 = 00000102
004119FC   COND: 十六进制 = 03
00411A23   COND: 转换为校验值 = 00000300
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 03
00411A23   COND: 转换为校验值 = 00000300
004119FC   COND: 十六进制 = 06
00411A23   COND: 转换为校验值 = 00000201
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 08
00411A23   COND: 转换为校验值 = 00000002
004119FC   COND: 十六进制 = 02
00411A23   COND: 转换为校验值 = 00000200
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 00
00411A23   COND: 转换为校验值 = 00000000
004119FC   COND: 十六进制 = 02
00411A23   COND: 转换为校验值 = 00000200
004119FC   COND: 十六进制 = 04
00411A23   COND: 转换为校验值 = 00000001
004119FC   COND: 十六进制 = 0A
00411A23   COND: 转换为校验值 = 00000202
004119FC   COND: 十六进制 = 0B
00411A23   COND: 转换为校验值 = 00000302
004119FC   COND: 十六进制 = 02
00411A23   COND: 转换为校验值 = 00000200
004119FC   COND: 十六进制 = 04
00411A23   COND: 转换为校验值 = 00000001
004119FC   COND: 十六进制 = 03
00411A23   COND: 转换为校验值 = 00000300

//找到要比较的表,必须相同

00416164  |.  8B75 08       MOV ESI,DWORD PTR SS:[EBP+0x8]                     ;  Default case of switch 00416134

//正确值

0029C788    0202   0300   0000   0302   0100   0302   0002   0200
0029C798    0002   0202   0302   0302   0001   0202   0102   0302
0029C7A8    0202   0102   0302   0302   0102   0300   0202   0202
0029C7B8    0202   0300   0201   0302   0002   0200   0202   0202
0029C7C8    0000   0200   0001   0202   0302   0200   0001   0300

//Array4校验值

002A4F00    0202   0300   0000   0302   0100   0302   0002   0200
002A4F10    0002   0202   0302   0302   0001   0202   0102   0302
002A4F20    0202   0102   0302   0302   0102   0300   0202   0202
002A4F30    0202   0300   0201   0302   0002   0200   0202   0202
002A4F40    0000   0200   0001   0202   0302   0200   0001   0300
00416171  |> /8B06          /MOV EAX,DWORD PTR DS:[ESI]
00416173  |. |3B02          |CMP EAX,DWORD PTR DS:[EDX]                        ;  比较第1、2位;17、18位;
00416175  |. |0F84 80000000 |JE 7-不问少.004161FB                                 ;  必须跳

00416205  |.  8B46 04       |MOV EAX,DWORD PTR DS:[ESI+0x4]
00416208  |.  3B42 04       |CMP EAX,DWORD PTR DS:[EDX+0x4]                    ;  比较第3、4位;19、20位;
0041620B  |.  74 7F         |JE X7-不问少.0041628C                                ;  必须跳

00416296  |.  8B46 08       |MOV EAX,DWORD PTR DS:[ESI+0x8]
00416299  |.  3B42 08       |CMP EAX,DWORD PTR DS:[EDX+0x8]                    ;  比较第5、6位;21、22位;
0041629C  |.  74 7F         |JE X7-不问少.0041631D                                ;  必须跳

00416327  |.  8B46 0C       |MOV EAX,DWORD PTR DS:[ESI+0xC]
0041632A  |.  3B42 0C       |CMP EAX,DWORD PTR DS:[EDX+0xC]                    ;  比较第7、8位;23、24位;
0041632D  |.  74 7F         |JE X7-不问少.004163AE                                ;  必须跳

004163B8  |.  8B46 10       |MOV EAX,DWORD PTR DS:[ESI+0x10]
004163BB  |.  3B42 10       |CMP EAX,DWORD PTR DS:[EDX+0x10]                   ;  比较第9、10位;25、26位;
004163BE  |.  0F84 80000000 |JE 7-不问少.00416444                                 ;  必须跳

0041644E  |.  8B46 14       |MOV EAX,DWORD PTR DS:[ESI+0x14]
00416451  |.  3B42 14       |CMP EAX,DWORD PTR DS:[EDX+0x14]                   ;  比较第11、12位;27、28位;
00416454  |.  74 7F         |JE X7-不问少.004164D5                                ;  必须跳

004164DF  |.  8B46 18       |MOV EAX,DWORD PTR DS:[ESI+0x18]
004164E2  |.  3B42 18       |CMP EAX,DWORD PTR DS:[EDX+0x18]                   ;  比较第13、14位;29、30位;
004164E5  |.  74 7F         |JE X7-不问少.00416566                                ;  必须跳

00416570  |.  8B46 1C       |MOV EAX,DWORD PTR DS:[ESI+0x1C]
00416573  |.  3B42 1C       |CMP EAX,DWORD PTR DS:[EDX+0x1C]                   ;  比较第15、16位;31、32位;
00416576  |.  74 7F         |JE X7-不问少.004165F7                                ;  必须跳

004167EB  |> \8B46 F0       MOV EAX,DWORD PTR DS:[ESI-0x10]                    ;  Case 10 of switch 00416616
004167EE  |.  3B42 F0       CMP EAX,DWORD PTR DS:[EDX-0x10]                    ;  比较第33、34位;
004167F1  |.  0F84 81000000 JE 7-不问少.00416878                                  ;  必须跳

00416882  |> \8B46 F4       MOV EAX,DWORD PTR DS:[ESI-0xC]                     ;  Case C of switch 00416616
00416885  |.  3B42 F4       CMP EAX,DWORD PTR DS:[EDX-0xC]                     ;  比较第35、36位;
00416888  |.  0F84 82000000 JE 7-不问少.00416910                                  ;  必须跳

0041691A  |> \8B46 F8       MOV EAX,DWORD PTR DS:[ESI-0x8]                     ;  Case 8 of switch 00416616
0041691D  |.  3B42 F8       CMP EAX,DWORD PTR DS:[EDX-0x8]                     ;  比较第37、38位;
00416920  |.  0F84 81000000 JE 7-不问少.004169A7                                  ;  必须跳

004169B1  |> \8B46 FC       MOV EAX,DWORD PTR DS:[ESI-0x4]                     ;  Case 4 of switch 00416616
004169B4  |.  3B42 FC       CMP EAX,DWORD PTR DS:[EDX-0x4]                     ;  比较第39、40位;
004169B7  |.  74 75         JE X7-不问少.00416A2E                                 ;  必须跳

//算法破解思路:
//根据40位校验值按“4的倍数+余数”,求出40个字符Array4,然后转Array3,再进行20位字符串,逐位穷举,限定合法字符


五、分析关键CHECK的SMC解码程序(隐含注册码筛选要求)


//返回到上级程序,分析后续SMC过程
//申请内存4096字节,用于SMC,这种方法可取,防止爆破和静态分析

00411841   .  6A 40                 PUSH 0x40                                          ; /Protect = PAGE_EXECUTE_READWRITE
00411843   .  BB 00100000           MOV EBX,0x1000                                     ; |
00411848   .  53                    PUSH EBX                                           ; |AllocationType => MEM_COMMIT
00411849   .  53                    PUSH EBX                                           ; |Size => 1000 (4096.)
0041184A   .  33F6                  XOR ESI,ESI                                        ; |
0041184C   .  56                    PUSH ESI                                           ; |Address => NULL
0041184D   .  FF15 583C4500         CALL DWORD PTR DS:[<&KERNEL32.VirtualAlloc>]       ; \VirtualAlloc

//待解码数据拷贝

00411858   .  68 94000000           PUSH 0x94
0041185D   .  68 9C1A4100           PUSH 7-不问少.00411A9C
00411862   .  53                    PUSH EBX
00411863   .  57                    PUSH EDI
00411864   .  E8 84090000           CALL 7-不问少.004121ED                                ;  从411A9C拷贝0x94字节到新申请的内存中
00411869   .  83C4 10               ADD ESP,0x10

//源:

00411A9C  17 FC 82 19 BE 1C B8 60 21 69 1D 93 30 31 37 4B  鼈?竊!i?17K
00411AAC  08 BA A3 4F E3 F3 6A 33 41 47 95 EC 21 99 29 BF  海O泱j3AG曥!?
00411ABC  75 C5 53 E8 58 39 4F 6B C1 12 B6 73 CC 31 88 35  u臩鑈9Ok?秙??
00411ACC  E9 24 A5 F5 75 ED 75 1C 16 6A 1E E6 07 9A A9 36  ?ヵu韚j?毄6
00411ADC  A1 61 62 47 5B 39 F4 77 D0 F6 72 AF 3A 0A 6E 56  bG[9魒婿r?.nV
00411AEC  12 FA 2B A3 86 31 B8 42 12 1D 03 62 F6 74 DB 09  ?1窧b鰐?
00411AFC  B0 2B B9 94 BD F4 AA 67 CC 31 B0 0F 24 01 64 0F  ?箶紧猤??$d
00411B0C  70 31 67 21 58 C6 5A 9B 7F 32 6E F8 0C 80 34 EC  p1g!X芞?2n?€4
00411B1C  69 69 79 32 30 68 BC 06 A8 0A 82 83 6D 53 6E 73  iiy20h??們mSns
00411B2C  CA 91 0D A6                                      蕬.?m

//目的:

00EC0000  17 FC 82 19 BE 1C B8 60 21 69 1D 93 30 31 37 4B  鼈?竊!i?17K
00EC0010  08 BA A3 4F E3 F3 6A 33 41 47 95 EC 21 99 29 BF  海O泱j3AG曥!?
00EC0020  75 C5 53 E8 58 39 4F 6B C1 12 B6 73 CC 31 88 35  u臩鑈9Ok?秙??
00EC0030  E9 24 A5 F5 75 ED 75 1C 16 6A 1E E6 07 9A A9 36  ?ヵu韚j?毄6
00EC0040  A1 61 62 47 5B 39 F4 77 D0 F6 72 AF 3A 0A 6E 56  bG[9魒婿r?.nV
00EC0050  12 FA 2B A3 86 31 B8 42 12 1D 03 62 F6 74 DB 09  ?1窧b鰐?
00EC0060  B0 2B B9 94 BD F4 AA 67 CC 31 B0 0F 24 01 64 0F  ?箶紧猤??$d
00EC0070  70 31 67 21 58 C6 5A 9B 7F 32 6E F8 0C 80 34 EC  p1g!X芞?2n?€4
00EC0080  69 69 79 32 30 68 BC 06 A8 0A 82 83 6D 53 6E 73  iiy20h??們mSns
00EC0090  CA 91 0D A6                                      蕬.?.

//SMC解码,异或

0041187A   > /81FE 94000000         CMP ESI,0x94                                       ;  0x94 循环条件 (148)
00411880   . |7D 27                 JGE X7-不问少.004118A9
00411882   . |8BC6                  MOV EAX,ESI
00411884   . |33D2                  XOR EDX,EDX
00411886   . |F771 34               DIV DWORD PTR DS:[ECX+0x34]                        ;  % 0x14
00411889   . |46                    INC ESI                                            ;  +1
0041188A   . |8975 E0               MOV DWORD PTR SS:[EBP-0x20],ESI                    ;  计数器
0041188D   . |8D41 24               LEA EAX,DWORD PTR DS:[ECX+0x24]
00411890   . |8378 14 10            CMP DWORD PTR DS:[EAX+0x14],0x10
00411894   . |72 02                 JB X7-不问少.00411898
00411896   . |8B00                  MOV EAX,DWORD PTR DS:[EAX]                         ;  取input
00411898   > |8A0410                MOV AL,BYTE PTR DS:[EAX+EDX]                       ;  逐位取input
0041189B   . |8B55 EC               MOV EDX,DWORD PTR SS:[EBP-0x14]
0041189E   . |3002                  XOR BYTE PTR DS:[EDX],AL                           ;  异或
004118A0   . |42                    INC EDX                                            ;  +1
004118A1   . |8955 EC               MOV DWORD PTR SS:[EBP-0x14],EDX
004118A4   . |8955 DC               MOV DWORD PTR SS:[EBP-0x24],EDX
004118A7   .^\EB D1                 JMP X7-不问少.0041187A
004118A9   >  8B41 34               MOV EAX,DWORD PTR DS:[ECX+0x34]

004118B8   .  8B09                  MOV ECX,DWORD PTR DS:[ECX]               ;  input
004118BA   >  8BC6                  MOV EAX,ESI
004118BC   .  33D2                  XOR EDX,EDX
004118BE   .  F775 E4               DIV DWORD PTR SS:[EBP-0x1C]              ;  0x94 % 0x14 = 0x8
004118C1   .  8A040A                MOV AL,BYTE PTR DS:[EDX+ECX]             ;  取input第8位
004118C4   .  8B4D EC               MOV ECX,DWORD PTR SS:[EBP-0x14]
004118C7   .  3001                  XOR BYTE PTR DS:[ECX],AL                 ;  用input第8位解密
004118C9   .  8D4F 60               LEA ECX,DWORD PTR DS:[EDI+0x60]
004118CC   .  BA 9C1A4100           MOV EDX,7-不问少.00411A9C
004118D1   .  8BC2                  MOV EAX,EDX
004118D3   .  2BC1                  SUB EAX,ECX
004118D5   .  83C0 60               ADD EAX,0x60
004118D8   .  0141 01               ADD DWORD PTR DS:[ECX+0x1],EAX
004118DB   .  8D8F 8B000000         LEA ECX,DWORD PTR DS:[EDI+0x8B]
004118E1   .  8B41 01               MOV EAX,DWORD PTR DS:[ECX+0x1]
004118E4   .  2BC1                  SUB EAX,ECX
004118E6   .  81C2 8B000000         ADD EDX,0x8B
004118EC   .  03C2                  ADD EAX,EDX
004118EE   .  8941 01               MOV DWORD PTR DS:[ECX+0x1],EAX           ;  解密


六、算法破解

//1、根据40位校验值按“4的倍数+余数”,求出40个字符Array4,然后转Array3,再进行20位字符串,逐位穷举,限定合法字符

//Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Ctf.pediy.com ctf2017 crackme 7 keygen
# python 3.6.0 32bit
# written by 爱琴海
# 2017/06/14 

def Main():    
    #跟破文对应,穷举20位合规字符注册码
    Array2 = [0x89,0xBC,0x95,0xFC,0xFB,0xBA,0xED,0x9A,0xBB,0xAE,0xFE,0x99,0xA2,0x98,0xB9,0xF9,0x9F,0x84,0x9C,0xFD,
    0x83,0xAD,0xB6,0xA9,0xA5,0xF5,0x8C,0xA7,0x9E,0x96,0x8A,0xF4,0x85,0xBE,0xA8,0x8F,0x86,0xAF,0x88,0x9D,0x87,0xBF,
    0xFF,0xA1,0x8B,0x81,0xA0,0xAB,0x8E,0xBD,0xB5,0xAA,0x82,0x94,0xA4,0x8D,0xA3,0xF8,0xB4,0xFA,0x9B,0xA6,0xB8,0x80]
    Array3 = [0xA3,0x0B,0x1B,0x82,0x8A,0xBB,0x4A,0x9B,0xA9,0xBB,0x93,0xAA,0xA3,0x6B,0x82,0xAA,0x02,0x4A,0xB2,0x43]
    for n in range (0x0,len(Array3)):
    #穷举20位输入
        for sn in range(0x30,0x7B):
        #字符串范围缩小一些,还可以继续缩小,速度够快,想想没必要了,如果显示结果非字母数字则忽略即可
            sn1 = sn ^ 0xCC
            if sn1 in Array2:
                Start1 = Array2.index(sn1)
                Element_new = Search(Array2,Start1,n)
                if Array3[n] == (((Element_new ^ 0xCC) << 0x3) | ((Element_new ^ 0xCC) >> 0x5)) & 0xFF:
                    print ('第 %d 位' % (n+1),chr(sn))
    return

def Search(Array,Start,Count):
    #Start、Count下标均从0开始,跟上层调用保持一致
    #Count为0-19,也就是数组下标
    #Start为上层匹配Array2的下标
    for i in range(0,Count+1):
        n = Start // 5 + 5
        Start = (Start + n) % len(Array)
    return Array[Start]

if __name__ == '__main__':    
    #调用算法程序
    Main()

//穷举合法字符注册码如下:第1、3、11、19位只有唯一解,而其他位都存在好几个解,为了进一步筛选注册码,需要分析SMC解码

第 1 位 B
第 2 位 j
第 2 位 w
第 3 位 n
第 4 位 d
第 4 位 s
第 5 位 A
第 5 位 Y
第 5 位 l
第 6 位 b
第 6 位 t
第 7 位 P
第 7 位 i
第 8 位 H
第 8 位 e
第 9 位 c
第 9 位 d
第 9 位 s
第 10 位 P
第 10 位 i
第 11 位 y
第 12 位 2
第 12 位 5
第 13 位 0
第 13 位 g
第 13 位 o
第 14 位 1
第 14 位 a
第 15 位 4
第 15 位 7
第 15 位 B
第 16 位 K
第 16 位 r
第 17 位 G
第 17 位 J
第 17 位 X
第 18 位 9
第 18 位 D
第 18 位 I
第 19 位 O
第 20 位 F
第 20 位 k

//2、根据SMC解码,结合对反汇编代码的认知进行推理,在待选注册码范围中人工筛选出最终答案:(作者你也太狠了吧,呵呵)

第1字节:(唯一)
  第 1 位 B --> “55” --> PUSH EBP

第2字节:
  第 2 位 j --> “96” --> XCHG EAX,ESI 不符合
  第 2 位 w --> “8B” --> 8BEC MOV EBP,ESP 符合
  推出第2位:“w”,选出前3位注册码为“Bwn”

第3字节:(唯一)
  第 3 位 n --> “EC”

第4字节:
  第 4 位 d --> “7D” --> JGE 不符合
  第 4 位 s --> “6A” --> PUSH 符合
  推出第4位:“s”,选出前4位注册码为“Bwns”

第5字节:
  第 5 位 A --> “FF” --> -1 符合
  第 5 位 Y --> “E7” --> -19 不符合
  第 5 位 l --> “D2” --> -2E 不符合
  推出第5位:“A”,选出前5位注册码为“BwnsA”

第6字节:
  第 6 位 b --> “7E” --> JLE 不符合
  第 6 位 t --> “68” --> PUSH 符合
  推出第6位:“t”,选出前6位注册码为“BwnsAt”

第7字节:
  第 7 位 P --> “E8” --> 不确定
  第 7 位 i --> “D1” --> 不确定

第8字节:
  第 8 位 H --> “28” --> 不确定
  第 8 位 e --> “05” --> 不确定

第9字节:
  第 9 位 c --> “42” --> 不符合
  第 9 位 d --> “45” --> 符合
  第 9 位 s --> “52” --> 不符合
  推出第9位:“d”,选出前9位注册码为“BwnsAt??d”

第10字节:
  第 10 位 P --> “39” --> 不符合
  第 10 位 i --> “00” --> 符合
  推出第10位:“i”,选出前10位注册码为“BwnsAt??di”

第11字节:(唯一)
  第 11 位 y --> “64”
  选出前11位注册码为“BwnsAt??diy”

第12字节:
  第 12 位 2 --> “A1” --> 符合
  第 12 位 5 --> “A6” --> 不符合
  推出第12位:“2”,选出前12位注册码为“BwnsAt??diy2”

第13字节:
  第 13 位 0 --> “00” --> 不确定
  第 13 位 g --> “57” --> 不确定
  第 13 位 o --> “5F” --> 不确定

第14字节:
  第 14 位 1 --> “00” --> 不确定
  第 14 位 a --> “50” --> 不确定

第15字节:
  第 15 位 4 --> “03” --> 不符合
  第 15 位 7 --> “00” --> 符合
  第 15 位 B --> “75” --> 不符合
  推出第15位:“7”,选出前12位注册码为“BwnsAt??diy2??7”

第16字节:
  第 16 位 K --> “00” --> 符合
  第 16 位 r --> “39” --> 不符合
  结合第13、14、15的条件,应该是 MOV EAX,DWORD PTR FS:[0]
  推出第13位:“0”,第14位:“1”,第16位:“K”,选出前16位注册码为“BwnsAt??diy2017K”

第17字节:
  第 17 位 G --> “4F” --> 关于EDI 不符合
  第 17 位 J --> “42” --> 关于EDX 不符合
  第 17 位 X --> “50” --> PUSH EAX 符合
  推出第17位:“X”,选出前17位注册码为“BwnsAt??diy2017KX”

第18字节:
  第 18 位 9 --> “83” --> 符合
  第 18 位 D --> “FE” --> 不符合
  第 18 位 I --> “F3” --> 不符合
  推出第18位:“9”,选出前18位注册码为“BwnsAt??diy2017KX9”

第19字节:(唯一)
  第 19 位 O --> “83”
  选出前19位注册码为“BwnsAt??diy2017KX9O”

第20字节:
  第 20 位 F --> “09” --> 不符合
  第 20 位 k --> “24” --> 符合
  选出20注册码位“BwnsAt??diy2017KX9Ok”

//对不确定的第7、8位手工验证,最多4次:

第1组、BwnsAtPHdiy2017KX9Ok
第2组、BwnsAtPediy2017KX9Ok
第3组、BwnsAtiHdiy2017KX9Ok
第4组、BwnsAtiediy2017KX9Ok

//当输入第2组:BwnsAtPediy2017KX9Ok 弹出信息成功提示“Well Done!:)”
//当输入第4组:BwnsAtiediy2017KX9Ok 弹出空白信息提示,确定后退出程序
//因此最终答案为:BwnsAtPediy2017KX9Ok


七、提示成功程序分析(SMC)

//SMC代码最终解密结果:

00EC0000  55 8B EC 6A FF 68 E8 05 45 00 64 A1 00 00 00 00  U嬱jh?E.d?...
00EC0010  50 83 EC 24 A1 84 04 40 00 33 C5 89 45 F0 50 8D  P冹$@.3艍E餚
00EC0020  45 F4 64 A3 00 00 00 00 83 65 D8 00 8D 45 D8 50  E鬱?...僥?岴豍
00EC0030  8D 4D DC C7 45 DC 42 57 4E 53 51 8D 45 ED C7 45  峂芮E蹷WNSQ岴砬E
00EC0040  E0 15 32 22 3F 50 8D 45 E0 C7 45 E4 62 33 21 3D  ?2"?P岴嗲E鋌3!=
00EC0050  50 8D 45 D0 C7 45 E8 27 76 74 7A 50 C6 45 EC 42  P岴星E?vtzP艵霣
00EC0060  E8 AE 10 55 FF 83 C4 14 8D 45 E0 6A 40 68 1D 3D  璁U兡岴鄇@h=
00EC0070  40 00 50 6A 00 FF 15 F0 3D 45 00 8B 4D F4 64 89  @.Pj.?E.婱鬱
00EC0080  0D 00 00 00 00 59 8B 4D F0 33 CD E8 CB 3E 55 FF  .....Y婱?丸?U
00EC0090  8B E5 5D C3 64                                   嬪]胐..

//调用SMC执行,跟进

004118F1   .  FF55 E8               CALL DWORD PTR SS:[EBP-0x18]

//SMC最终反汇编

00EC0000    55                      PUSH EBP
00EC0001    8BEC                    MOV EBP,ESP
00EC0003    6A FF                   PUSH -0x1
00EC0005    68 E8054500             PUSH 0x4505E8
00EC000A    64:A1 00000000          MOV EAX,DWORD PTR FS:[0]
00EC0010    50                      PUSH EAX
00EC0011    83EC 24                 SUB ESP,0x24
00EC0014    A1 84044000             MOV EAX,DWORD PTR DS:[0x400484]
00EC0019    33C5                    XOR EAX,EBP
00EC001B    8945 F0                 MOV DWORD PTR SS:[EBP-0x10],EAX
00EC001E    50                      PUSH EAX
00EC001F    8D45 F4                 LEA EAX,DWORD PTR SS:[EBP-0xC]
00EC0022    64:A3 00000000          MOV DWORD PTR FS:[0],EAX
00EC0028    8365 D8 00              AND DWORD PTR SS:[EBP-0x28],0x0
00EC002C    8D45 D8                 LEA EAX,DWORD PTR SS:[EBP-0x28]
00EC002F    50                      PUSH EAX
00EC0030    8D4D DC                 LEA ECX,DWORD PTR SS:[EBP-0x24]
00EC0033    C745 DC 42574E53        MOV DWORD PTR SS:[EBP-0x24],0x534E5742
00EC003A    51                      PUSH ECX
00EC003B    8D45 ED                 LEA EAX,DWORD PTR SS:[EBP-0x13]
00EC003E    C745 E0 1532223F        MOV DWORD PTR SS:[EBP-0x20],0x3F223215
00EC0045    50                      PUSH EAX
00EC0046    8D45 E0                 LEA EAX,DWORD PTR SS:[EBP-0x20]
00EC0049    C745 E4 6233213D        MOV DWORD PTR SS:[EBP-0x1C],0x3D213362
00EC0050    50                      PUSH EAX
00EC0051    8D45 D0                 LEA EAX,DWORD PTR SS:[EBP-0x30]
00EC0054    C745 E8 2776747A        MOV DWORD PTR SS:[EBP-0x18],0x7A747627
00EC005B    50                      PUSH EAX
00EC005C    C645 EC 42              MOV BYTE PTR SS:[EBP-0x14],0x42
00EC0060    E8 AE1055FF             CALL 7-不问少.00411113                      ; 解密提示信息
00EC0065    83C4 14                 ADD ESP,0x14
00EC0068    8D45 E0                 LEA EAX,DWORD PTR SS:[EBP-0x20]
00EC006B    6A 40                   PUSH 0x40
00EC006D    68 1D3D4000             PUSH 0x403D1D
00EC0072    50                      PUSH EAX                                 ; 传字符串"Well done!:)"
00EC0073    6A 00                   PUSH 0x0
00EC0075    FF15 F03D4500           CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; user32.MessageBoxA
00EC007B    8B4D F4                 MOV ECX,DWORD PTR SS:[EBP-0xC]
00EC007E    64:890D 00000000        MOV DWORD PTR FS:[0],ECX
00EC0085    59                      POP ECX
00EC0086    8B4D F0                 MOV ECX,DWORD PTR SS:[EBP-0x10]
00EC0089    33CD                    XOR ECX,EBP
00EC008B    E8 CB3E55FF             CALL 7-不问少.00413F5B
00EC0090    8BE5                    MOV ESP,EBP
00EC0092    5D                      POP EBP
00EC0093    C3                      RETN

//使用MessageBoxA显示成功信息

0012FA6C   00000000  |hOwner = NULL
0012FA70   0012FA90  |Text = "Well done!:)"
0012FA74   00403D1D  |Title = ""
0012FA78   00000040  \Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL


八、总结

这个作品的设计理念上乘,尤其结合SMC有效防止爆破,有实际应用价值。假如算法和反调试、反分析再做加强,得分还能提高!


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (3)
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
伊邪那美 2017-6-15 13:07
2
0
好详细
雪    币: 425
活跃值: (385)
能力值: ( LV4,RANK:48 )
在线值:
发帖
回帖
粉丝
yyp 2019-12-18 17:29
4
0
我什么我在“二、分析主体流程”对 GetDlgItemTextA下断点后进行验证就跑飞了????
雪    币: 589
活跃值: (1215)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
mingyuexc 2020-9-7 21:37
5
0
我卡在反调试上面了,看了wp 之后,茅塞顿开,感谢师傅
游客
登录 | 注册 方可回帖
返回