吾爱破解2016安全挑战赛cm1分析

大概从这开始记录吧。。之前的wp清系统之前没有存GG了

首先打开程序看看界面
可以看到有弹框提示字符。。

吾爱破解2016安全挑战赛cm1分析_第1张图片
运行界面

IDA也可以轻松找到DialogFunc

吾爱破解2016安全挑战赛cm1分析_第2张图片
DialogFunc

但这题在按钮事件加了无数花。。大概看了一下就懒得看了

吾爱破解2016安全挑战赛cm1分析_第3张图片
花指令代码段

于是想到GetDlgItemText下断然后下访问断点的方式去找算法位置
最后找到是在RVA00001450的地方是算法函数的地址

吾爱破解2016安全挑战赛cm1分析_第4张图片
算法节选

对算法开始分析:

03301497    56              push esi                                 ; 计算流程开始
03301498    8BF7            mov esi,edi
0330149A    8D4E 01         lea ecx,dword ptr ds:[esi+0x1]
0330149D    8D49 00         lea ecx,dword ptr ds:[ecx]
033014A0    8A06            mov al,byte ptr ds:[esi]
033014A2    46              inc esi
033014A3    84C0            test al,al
033014A5  ^ 75 F9           jnz short 033014A0
033014A7    2BF1            sub esi,ecx                              ; 计算Serial长度,存esi
033014A9    8D46 ED         lea eax,dword ptr ds:[esi-0x13]          ; 长度-0x13h后送eax
033014AC    83F8 31         cmp eax,0x31                             ; 比较eax和0x31h的大小,即长度和0x31h+0x13h=0x44h
033014AF    0F87 AD040000   ja 03301962                              ; 实现了Serial长度在0x13h和0x44h之间的限制

上面这段实现了对Serial长度的限制,这里的限制是不能少于18位,不能多于68位,那么自然就有猜测是否分成两部分(18+?)进行验证,后面的分析也会证实这点。

首先的发现是对Name的处理:
在1200h的函数里面

03301200    55               push ebp
03301201    8BEC             mov ebp,esp
03301203    83EC 0C          sub esp,0xC
03301206    53               push ebx
03301207    8BD9             mov ebx,ecx
03301209    8BD3             mov edx,ebx
0330120B    895D FC          mov dword ptr ss:[ebp-0x4],ebx
0330120E    56               push esi
0330120F    33F6             xor esi,esi
03301211    57               push edi
03301212    33FF             xor edi,edi
03301214    8975 F8          mov dword ptr ss:[ebp-0x8],esi
03301217    8D4A 01          lea ecx,dword ptr ds:[edx+0x1]
0330121A    8D9B 00000000    lea ebx,dword ptr ds:[ebx]
03301220    8A02             mov al,byte ptr ds:[edx]                        ; 取一个字符
03301222    42               inc edx                                         ; edx自增
03301223    84C0             test al,al
03301225  ^ 75 F9            jnz short 03301220
03301227    2BD1             sub edx,ecx                                     ; 取Name长度
03301229    33C9             xor ecx,ecx
0330122B    8955 F4          mov dword ptr ss:[ebp-0xC],edx                  ; 长度存栈
0330122E    83FA 02          cmp edx,0x2
03301231    72 27            jb short 0330125A                               ; 长度小于2跳
03301233    8D5A FF          lea ebx,dword ptr ds:[edx-0x1]                  ; ebx = edx - 0x1
03301236    8B55 FC          mov edx,dword ptr ss:[ebp-0x4]                  ; edx取字串
03301239    8DA424 00000000  lea esp,dword ptr ss:[esp]
03301240    0FBE040A         movsx eax,byte ptr ds:[edx+ecx]                 ; eax取字符
03301244    03F0             add esi,eax                                     ; 累加到esi
03301246    0FBE440A 01      movsx eax,byte ptr ds:[edx+ecx+0x1]             ; eax再取字符
0330124B    83C1 02          add ecx,0x2                                     ; ecx计数器自增2
0330124E    03F8             add edi,eax                                     ; 第二个字符累加到edi
03301250    3BCB             cmp ecx,ebx
03301252  ^ 72 EC            jb short 03301240                               ; 若有两个及以上字符则回跳继续处理
03301254    8B55 F4          mov edx,dword ptr ss:[ebp-0xC]
03301257    8B5D FC          mov ebx,dword ptr ss:[ebp-0x4]
0330125A    3BCA             cmp ecx,edx
0330125C    73 07            jnb short 03301265                              ; 判断是否仍有字符
0330125E    0FBE0419         movsx eax,byte ptr ds:[ecx+ebx]
03301262    8945 F8          mov dword ptr ss:[ebp-0x8],eax
03301265    8D0437           lea eax,dword ptr ds:[edi+esi]
03301268    0345 F8          add eax,dword ptr ss:[ebp-0x8]                  ; 全部和加起来送eax
0330126B    5F               pop edi                                         ; 0019F728
0330126C    5E               pop esi                                         ; 0019F728
0330126D    5B               pop ebx                                         ; 0019F728
0330126E    8BE5             mov esp,ebp
03301270    5D               pop ebp                                         ; 0019F728
03301271    C3               retn

这个函数简单的进行了一个ASCII累加的处理
之后取了这个累加和的奇偶作为后续算法的一部分

然后就是对Serial前18位的处理了
这18位被分成了2 * 3 * 3这样的形式处理
每两位生成一个数,参考官方给的Name为360的Serial的前18位:

323031303330213032

每两个为一组,然后3 * 3组,于是:

32 30 31
30 33 30
21 30 32
联想到ascii码的我。。

问题在于这里有个21,那么看看汇编吧

汇编里对应处理的部分如下:

033014FE    E8 FDFCFFFF      call 03301200
03301503    83E0 01          and eax,0x1                                     ; 判断奇偶用,奇数结果为1,偶数为0
03301506    C785 58FFFFFF 03>mov dword ptr ss:[ebp-0xA8],0x3
03301510    8D8D 58FFFFFF    lea ecx,dword ptr ss:[ebp-0xA8]
03301516    8985 3CFFFFFF    mov dword ptr ss:[ebp-0xC4],eax                 ; 奇偶结果存在ebp-0xC4
0330151C    C785 5CFFFFFF 03>mov dword ptr ss:[ebp-0xA4],0x3
03301526    E8 D5FAFFFF      call 03301000
0330152B    32C0             xor al,al                                       ; 清空al
0330152D    8885 6BFFFFFF    mov byte ptr ss:[ebp-0x95],al                   ; ebp-0x95清零
03301533    0FB6C0           movzx eax,al                                    ; eax清零
03301536    32FF             xor bh,bh
03301538    8985 64FFFFFF    mov dword ptr ss:[ebp-0x9C],eax                 ; ebp-0x9C清零
0330153E    8D0440           lea eax,dword ptr ds:[eax+eax*2]
03301541    0FB6FF           movzx edi,bh                                    ; edi清零
03301544    83C9 FF          or ecx,-0x1
03301547    8D3407           lea esi,dword ptr ds:[edi+eax]                  ; esi清零
0330154A    8A5475 E8        mov dl,byte ptr ss:[ebp+esi*2-0x18]             ; dl取Serial一个字符
0330154E    8AC2             mov al,dl
03301550    2C 30            sub al,0x30
03301552    3C 09            cmp al,0x9                                      ; 判断是否是数字0~9
03301554    77 08            ja short 0330155E                               ; 不是跳走
03301556    0FBECA           movsx ecx,dl
03301559    83E9 30          sub ecx,0x30
0330155C    EB 1E            jmp short 0330157C
0330155E    8AC2             mov al,dl                                       ; 不是数字的话判断是否是字母A~F
03301560    2C 41            sub al,0x41
03301562    3C 05            cmp al,0x5
03301564    77 08            ja short 0330156E
03301566    0FBECA           movsx ecx,dl
03301569    83E9 37          sub ecx,0x37
0330156C    EB 0E            jmp short 0330157C
0330156E    8AC2             mov al,dl                                       ; 再不是的话就是小写的a~f
03301570    2C 61            sub al,0x61
03301572    3C 05            cmp al,0x5
03301574    77 06            ja short 0330157C
03301576    0FBECA           movsx ecx,dl
03301579    83E9 57          sub ecx,0x57
0330157C    81E1 01000080    and ecx,0x80000001                              ; 检查奇偶
03301582    79 05            jns short 03301589
03301584    49               dec ecx
03301585    83C9 FE          or ecx,-0x2
03301588    41               inc ecx
03301589    8A5C75 E9        mov bl,byte ptr ss:[ebp+esi*2-0x17]             ; 第二个字符
0330158D    83CA FF          or edx,-0x1                                     ; 往下还是和刚刚一套判断
03301590    8AC3             mov al,bl
03301592    2C 30            sub al,0x30
03301594    3C 09            cmp al,0x9
03301596    77 08            ja short 033015A0
03301598    0FBED3           movsx edx,bl
0330159B    83EA 30          sub edx,0x30
0330159E    EB 1E            jmp short 033015BE
033015A0    8AC3             mov al,bl
033015A2    2C 41            sub al,0x41
033015A4    3C 05            cmp al,0x5
033015A6    77 08            ja short 033015B0
033015A8    0FBED3           movsx edx,bl
033015AB    83EA 37          sub edx,0x37
033015AE    EB 0E            jmp short 033015BE
033015B0    8AC3             mov al,bl
033015B2    2C 61            sub al,0x61
033015B4    3C 05            cmp al,0x5
033015B6    77 06            ja short 033015BE
033015B8    0FBED3           movsx edx,bl
033015BB    83EA 57          sub edx,0x57
033015BE    66:0F6ECA        movd mm1,edx
033015C2    0f5bc9           cvtdq2ps xmm1,xmm1
033015C5    3B8D 3CFFFFFF    cmp ecx,dword ptr ss:[ebp-0xC4]                 ; 当Serial奇数位数字奇偶与Name的ascii码之和奇偶不同时
033015CB    74 0A            je short 033015D7                               ; Serial偶数位数值取负值
033015CD    0F57C0           xorps xmm0,xmm0
033015D0    F3:0F5CC1        subss xmm0,xmm1
033015D4    0F28C8           movaps xmm1,xmm0
033015D7    8B8D 64FFFFFF    mov ecx,dword ptr ss:[ebp-0x9C]
033015DD    3B8D 58FFFFFF    cmp ecx,dword ptr ss:[ebp-0xA8]                 ; 循环结束条件
033015E3    0F8D 79030000    jge 03301962
033015E9    8B95 5CFFFFFF    mov edx,dword ptr ss:[ebp-0xA4]
033015EF    3BFA             cmp edi,edx                                     ; 循环结束条件2
033015F1    0F8D 6B030000    jge 03301962
033015F7    8BC2             mov eax,edx
033015F9    FEC7             inc bh                                          ; bh作计数器
033015FB    8B95 60FFFFFF    mov edx,dword ptr ss:[ebp-0xA0]
03301601    0FAFC1           imul eax,ecx
03301604    03C7             add eax,edi
03301606    F3:0F110C82      movss dword ptr ds:[edx+eax*4],xmm1
0330160B    8D0449           lea eax,dword ptr ds:[ecx+ecx*2]
0330160E    80FF 03          cmp bh,0x3                                      ; 共3次 处理6个字符
03301611  ^ 0F82 2AFFFFFF    jb 03301541                                     ; 回去处理下两个字符
03301617    8A85 6BFFFFFF    mov al,byte ptr ss:[ebp-0x95]
0330161D    04 01            add al,0x1                                      ; al是又一个计数器
0330161F    8885 6BFFFFFF    mov byte ptr ss:[ebp-0x95],al
03301625    3C 03            cmp al,0x3                                      ; 又是3次 于是一共是18个
03301627  ^ 0F82 06FFFFFF    jb 03301533

可以看到其实也并不是ASCII码。。2个数的前一个是用来和前面运算过的Name的ASCII累加和的奇偶进行比较的,如果这两个奇偶不同,那么后面一个数就取负值。

另外值得一提的是cvtdq2ps是压缩有符号双字整数转换成压缩单精度浮点值的作用

于是我们可以看到算法从这18位生成了一个矩阵:

2 0 1
0 3 0
-1 0 2

那我们接下来关心的部分就是这个矩阵将会如何处理了
但是由于有很多xmm寄存器的调用。。于是我从od转了x32dbg,地址会有一定改变不要在意QAQ

接下来首先程序在内存中放了一些数

吾爱破解2016安全挑战赛cm1分析_第5张图片
内存

整理出来大概是两个3 * 3矩阵

1 0 1
0 2 0
-1 0 1


1 0 0
0 1 0
0 0 1

继续看汇编。。
接下来首先用了个循环把两个矩阵放到了其他地方
然后进行了矩阵乘法运算
下面是相关代码,从两个矩阵的取值方式很容易看出是矩阵乘法了

02A61141 | 33 F6                | xor esi,esi                           |
02A61143 | 85 DB                | test ebx,ebx                          |
02A61145 | 0F 8E 93 00 00 00    | jle 2A611DE                           |
02A6114B | EB 03                | jmp 2A61150                           |
02A6114D | 8D 49 00             | lea ecx,dword ptr ds:[ecx]            |
02A61150 | 33 D2                | xor edx,edx                           |
02A61152 | 0F 57 DB             | xorps xmm3,xmm3                       |
02A61155 | 39 51 04             | cmp dword ptr ds:[ecx+4],edx          |
02A61158 | 7E 5D                | jle 2A611B7                           |
02A6115A | 8B 5D FC             | mov ebx,dword ptr ss:[ebp-4]          |
02A6115D | 8B 45 08             | mov eax,dword ptr ss:[ebp+8]          |
02A61160 | 3B 3B                | cmp edi,dword ptr ds:[ebx]            |
02A61162 | 7D 19                | jge 2A6117D                           |
02A61164 | 8B 4B 04             | mov ecx,dword ptr ds:[ebx+4]          |
02A61167 | 3B D1                | cmp edx,ecx                           |
02A61169 | 7D 12                | jge 2A6117D                           |
02A6116B | 8B 43 08             | mov eax,dword ptr ds:[ebx+8]          | eax:第一个矩阵地址
02A6116E | 0F AF CF             | imul ecx,edi                          |
02A61171 | 03 CA                | add ecx,edx                           |
02A61173 | F3 0F 10 04 88       | movss xmm0,dword ptr ds:[eax+ecx*4]   | xmm0取第一个矩阵的数(按行)
02A61178 | 8B 45 08             | mov eax,dword ptr ss:[ebp+8]          |
02A6117B | EB 03                | jmp 2A61180                           |
02A6117D | 0F 28 C2             | movaps xmm0,xmm2                      |
02A61180 | 3B 10                | cmp edx,dword ptr ds:[eax]            |
02A61182 | 7D 16                | jge 2A6119A                           |
02A61184 | 8B 48 04             | mov ecx,dword ptr ds:[eax+4]          |
02A61187 | 3B F1                | cmp esi,ecx                           |
02A61189 | 7D 0F                | jge 2A6119A                           |
02A6118B | 8B 40 08             | mov eax,dword ptr ds:[eax+8]          | eax:输入矩阵地址
02A6118E | 0F AF CA             | imul ecx,edx                          |
02A61191 | 03 CE                | add ecx,esi                           |
02A61193 | F3 0F 10 0C 88       | movss xmm1,dword ptr ds:[eax+ecx*4]   | xmm1取输入矩阵的数(按列)
02A61198 | EB 03                | jmp 2A6119D                           |
02A6119A | 0F 28 CA             | movaps xmm1,xmm2                      |
02A6119D | 8B 45 08             | mov eax,dword ptr ss:[ebp+8]          |
02A611A0 | 42                   | inc edx                               | edx计数器+=1
02A611A1 | F3 0F 59 C1          | mulss xmm0,xmm1                       | 两数相乘
02A611A5 | F3 0F 58 C3          | addss xmm0,xmm3                       | xmm3的内容累加到xmm0
02A611A9 | 0F 28 D8             | movaps xmm3,xmm0                      | xmm3存入本次运算结果
02A611AC | 3B 53 04             | cmp edx,dword ptr ds:[ebx+4]          |
02A611AF | 7C AF                | jl 2A61160                            |
02A611B1 | 8B 5D F8             | mov ebx,dword ptr ss:[ebp-8]          |
02A611B4 | 8B 4D FC             | mov ecx,dword ptr ss:[ebp-4]          |
02A611B7 | 8B 55 0C             | mov edx,dword ptr ss:[ebp+C]          |
02A611BA | 3B 3A                | cmp edi,dword ptr ds:[edx]            |
02A611BC | 7D 11                | jge 2A611CF                           |
02A611BE | 3B F3                | cmp esi,ebx                           |
02A611C0 | 7D 0D                | jge 2A611CF                           |
02A611C2 | 8B 42 08             | mov eax,dword ptr ds:[edx+8]          |
02A611C5 | 0F AF DF             | imul ebx,edi                          |
02A611C8 | 03 DE                | add ebx,esi                           |
02A611CA | F3 0F 11 1C 98       | movss dword ptr ds:[eax+ebx*4],xmm3   | 结果送00752618
02A611CF | 8B 5A 04             | mov ebx,dword ptr ds:[edx+4]          |
02A611D2 | 46                   | inc esi                               |
02A611D3 | 89 5D F8             | mov dword ptr ss:[ebp-8],ebx          |
02A611D6 | 3B F3                | cmp esi,ebx                           |
02A611D8 | 0F 8C 72 FF FF FF    | jl 2A61150                            |
02A611DE | 47                   | inc edi                               |
02A611DF | 3B 3A                | cmp edi,dword ptr ds:[edx]            |
02A611E1 | 0F 8C 5A FF FF FF    | jl 2A61141                            |

这里运算的结果是

1 0 3
0 6 0
-3 0 1

可以验证确实是矩阵乘法

接下来这个结果矩阵又和前面提到的第二个矩阵进行了加法运算:

02A61071 | 33 C9                | xor ecx,ecx                           |
02A61073 | 85 F6                | test esi,esi                          |
02A61075 | 7E 61                | jle 2A610D8                           |
02A61077 | 3B 38                | cmp edi,dword ptr ds:[eax]            |
02A61079 | 7D 16                | jge 2A61091                           |
02A6107B | 8B 50 04             | mov edx,dword ptr ds:[eax+4]          |
02A6107E | 3B CA                | cmp ecx,edx                           |
02A61080 | 7D 0F                | jge 2A61091                           |
02A61082 | 8B 40 08             | mov eax,dword ptr ds:[eax+8]          | eax:矩阵乘法结果地址
02A61085 | 0F AF D7             | imul edx,edi                          |
02A61088 | 03 D1                | add edx,ecx                           |
02A6108A | F3 0F 10 04 90       | movss xmm0,dword ptr ds:[eax+edx*4]   | xmm0取上次结果矩阵的数
02A6108F | EB 03                | jmp 2A61094                           |
02A61091 | 0F 28 C2             | movaps xmm0,xmm2                      |
02A61094 | 8B 45 08             | mov eax,dword ptr ss:[ebp+8]          |
02A61097 | 3B 38                | cmp edi,dword ptr ds:[eax]            |
02A61099 | 7D 16                | jge 2A610B1                           |
02A6109B | 8B 50 04             | mov edx,dword ptr ds:[eax+4]          |
02A6109E | 3B CA                | cmp ecx,edx                           |
02A610A0 | 7D 0F                | jge 2A610B1                           |
02A610A2 | 8B 40 08             | mov eax,dword ptr ds:[eax+8]          | eax:第二个矩阵的地址
02A610A5 | 0F AF D7             | imul edx,edi                          |
02A610A8 | 03 D1                | add edx,ecx                           |
02A610AA | F3 0F 10 0C 90       | movss xmm1,dword ptr ds:[eax+edx*4]   | xmm1取第二个矩阵的数
02A610AF | EB 03                | jmp 2A610B4                           |
02A610B1 | 0F 28 CA             | movaps xmm1,xmm2                      |
02A610B4 | 3B 3B                | cmp edi,dword ptr ds:[ebx]            |
02A610B6 | 7D 15                | jge 2A610CD                           |
02A610B8 | 3B CE                | cmp ecx,esi                           |
02A610BA | 7D 11                | jge 2A610CD                           |
02A610BC | 8B 43 08             | mov eax,dword ptr ds:[ebx+8]          | eax:存结果的地址
02A610BF | F3 0F 58 C1          | addss xmm0,xmm1                       | 两数相加
02A610C3 | 0F AF F7             | imul esi,edi                          |
02A610C6 | 03 F1                | add esi,ecx                           |
02A610C8 | F3 0F 11 04 B0       | movss dword ptr ds:[eax+esi*4],xmm0   | 存结果
02A610CD | 8B 73 04             | mov esi,dword ptr ds:[ebx+4]          |
02A610D0 | 41                   | inc ecx                               |
02A610D1 | 8B 45 FC             | mov eax,dword ptr ss:[ebp-4]          |
02A610D4 | 3B CE                | cmp ecx,esi                           |
02A610D6 | 7C 9F                | jl 2A61077                            |
02A610D8 | 47                   | inc edi                               |
02A610D9 | 3B 3B                | cmp edi,dword ptr ds:[ebx]            |
02A610DB | 7C 94                | jl 2A61071                            |

为了接下来方便描述,这里用X代指输入生成的矩阵,A为第一个矩阵,B为第二个矩阵。那么刚刚的运算可以表示成:

C = X * A
D = C + B

而程序接下来又各调用了一次乘法和加法的函数,这次的运算对象有所改变,用算式表示如下:

E = A * A
F = E + X

接下来程序对D和F进行逐位比较,出现不等直接飞走

02A61890 | 33 C9                | xor ecx,ecx                           |
02A61892 | 83 FE 09             | cmp esi,9                             |
02A61895 | 0F 8D C7 00 00 00    | jge 2A61962                           |
02A6189B | 83 F9 03             | cmp ecx,3                             |
02A6189E | 0F 8D BE 00 00 00    | jge 2A61962                           |
02A618A4 | 8D 14 31             | lea edx,dword ptr ds:[ecx+esi]        |
02A618A7 | F3 0F 10 0C 97       | movss xmm1,dword ptr ds:[edi+edx*4]   |
02A618AC | 0F 2E CA             | ucomiss xmm1,xmm2                     |
02A618AF | 9F                   | lahf                                  |
02A618B0 | F6 C4 44             | test ah,44                            |
02A618B3 | 0F 8B A9 00 00 00    | jnp 2A61962                           |
02A618B9 | F3 0F 10 04 93       | movss xmm0,dword ptr ds:[ebx+edx*4]   |
02A618BE | 0F 2E C2             | ucomiss xmm0,xmm2                     |
02A618C1 | 9F                   | lahf                                  |
02A618C2 | F6 C4 44             | test ah,44                            |
02A618C5 | 0F 8B 97 00 00 00    | jnp 2A61962                           |
02A618CB | 0F 2E C8             | ucomiss xmm1,xmm0                     |
02A618CE | 9F                   | lahf                                  |
02A618CF | F6 C4 44             | test ah,44                            |
02A618D2 | 0F 8A 8A 00 00 00    | jp 2A61962                            |
02A618D8 | 41                   | inc ecx                               |
02A618D9 | 83 F9 03             | cmp ecx,3                             |
02A618DC | 7C B4                | jl 2A61892                            |
02A618DE | 83 C6 03             | add esi,3                             |
02A618E1 | 83 FE 09             | cmp esi,9                             |
02A618E4 | 7C AA                | jl 2A61890                            |

那么到这里第一部分的分析结束,大致用算式表示一下就是:

X * A + B = A * A + X
其中A、B已知,求X


接下来是后半部分的算法分析:
首先在内存中放了一块这样的“数组”

07 01 04 00 03 08 02 05 06


吾爱破解2016安全挑战赛cm1分析_第6张图片
内存

由于是mov的直接数,觉得肯定是用上了,于是先记着

02A61350 | 0F BE 04 1F         | movsx eax,byte ptr ds:[edi+ebx]       | 取Name字符
02A61354 | 25 03 00 00 80      | and eax,80000003                      | 模4
02A61359 | 79 05               | jns 2A61360                           |
02A6135B | 48                  | dec eax                               |
02A6135C | 83 C8 FC            | or eax,FFFFFFFC                       |
02A6135F | 40                  | inc eax                               |
02A61360 | 83 F8 03            | cmp eax,3                             |
02A61363 | 77 3C               | ja 2A613A1                            |
02A61365 | FF 24 85 AC 13 A6 0 | jmp dword ptr ds:[eax*4+2A613AC]      | switch 改变call的参数
02A6136C | 83 F9 02            | cmp ecx,2                             |
02A6136F | 76 30               | jbe 2A613A1                           |
02A61371 | 33 C9               | xor ecx,ecx                           | ecx清零
02A61373 | EB 21               | jmp 2A61396                           |
02A61375 | 83 F9 08            | cmp ecx,8                             |
02A61378 | 73 27               | jae 2A613A1                           |
02A6137A | B9 01 00 00 00      | mov ecx,1                             | ecx置1
02A6137F | EB 15               | jmp 2A61396                           |
02A61381 | 83 F9 06            | cmp ecx,6                             |
02A61384 | 73 1B               | jae 2A613A1                           |
02A61386 | B9 02 00 00 00      | mov ecx,2                             | ecx置2
02A6138B | EB 09               | jmp 2A61396                           |
02A6138D | 85 C9               | test ecx,ecx                          |
02A6138F | 74 10               | je 2A613A1                            |
02A61391 | B9 03 00 00 00      | mov ecx,3                             | ecx置3
02A61396 | E8 E5 FE FF FF      | call 2A61280                          |
02A6139B | 8B 0D 1C 3F A7 02   | mov ecx,dword ptr ds:[2A73F1C]        |
02A613A1 | 47                  | inc edi                               |
02A613A2 | 3B FE               | cmp edi,esi                           |
02A613A4 | 72 AA               | jb 2A61350                            |
02A61280 | FF 24 8D F8 12 A6 0 | jmp dword ptr ds:[ecx*4+2A612F8]      | switch 根据ecx选择处理方式
02A61287 | 8B 0D 1C 3F A7 02   | mov ecx,dword ptr ds:[2A73F1C]        |
02A6128D | 8A 81 0D 3F A7 02   | mov al,byte ptr ds:[ecx+2A73F0D]      |
02A61293 | 88 81 10 3F A7 02   | mov byte ptr ds:[ecx+2A73F10],al      |
02A61299 | 83 E9 03            | sub ecx,3                             |
02A6129C | 89 0D 1C 3F A7 02   | mov dword ptr ds:[2A73F1C],ecx        |
02A612A2 | 83 F9 0A            | cmp ecx,A                             | A:'\n'
02A612A5 | 73 08               | jae 2A612AF                           |
02A612A7 | C6 81 10 3F A7 02 0 | mov byte ptr ds:[ecx+2A73F10],0       |
02A612AE | C3                  | ret                                   |
02A612AF | E9 CC 08 00 00      | jmp 2A61B80                           |
02A612B4 | 8B 0D 1C 3F A7 02   | mov ecx,dword ptr ds:[2A73F1C]        |
02A612BA | 8A 81 11 3F A7 02   | mov al,byte ptr ds:[ecx+2A73F11]      |
02A612C0 | 88 81 10 3F A7 02   | mov byte ptr ds:[ecx+2A73F10],al      |
02A612C6 | 41                  | inc ecx                               |
02A612C7 | EB D3               | jmp 2A6129C                           |
02A612C9 | 8B 0D 1C 3F A7 02   | mov ecx,dword ptr ds:[2A73F1C]        |
02A612CF | 8A 81 13 3F A7 02   | mov al,byte ptr ds:[ecx+2A73F13]      |
02A612D5 | 88 81 10 3F A7 02   | mov byte ptr ds:[ecx+2A73F10],al      |
02A612DB | 83 C1 03            | add ecx,3                             |
02A612DE | EB BC               | jmp 2A6129C                           |
02A612E0 | 8B 0D 1C 3F A7 02   | mov ecx,dword ptr ds:[2A73F1C]        |
02A612E6 | 8A 81 0F 3F A7 02   | mov al,byte ptr ds:[ecx+2A73F0F]      |
02A612EC | 88 81 10 3F A7 02   | mov byte ptr ds:[ecx+2A73F10],al      |
02A612F2 | 49                  | dec ecx                               |
02A612F3 | EB A7               | jmp 2A6129C                           |

可以看到这两段代码通过Name字符的ASCII码值对上面的字串进行了一定的操作
具体操作就是将0的位置和四个可选位置数的值进行了替换

观察可以发现(上面一段的函数里有线索)其实还是个3 * 3的矩阵

7 1 4
0 3 8
2 5 6

四个位置自然也就是上下左右,360对应ASCII是0x33,0x36,0x30
模4后分别是3、2、0

而矩阵的变化是先4 0交换
然后8 0交换,最后还是8 0交换

所以可知3表示0左移,2表示下移,0表示上移,剩下的1也就是0右移

然后。。看到这就已经想到拼图游戏了。。0表示的是空位那种

接下来的代码又开始跳到那一段位移的函数了,算法如下:

02A61910 | 0F BE 4C 05 B4      | movsx ecx,byte ptr ss:[ebp+eax-4C]    | 取Serial后半段一个字符
02A61915 | 8D 41 D0            | lea eax,dword ptr ds:[ecx-30]         | 去掉30,取数字部分
02A61918 | 83 F8 08            | cmp eax,8                             | 和8比较
02A6191B | 77 08               | ja 2A61925                            | 大于跳
02A6191D | 83 C1 D0            | add ecx,FFFFFFD0                      | 不还是-0x30吗。。
02A61920 | E8 9B FA FF FF      | call 2A613C0                          |
02A61925 | 80 C3 01            | add bl,1                              |
02A61928 | 0F B6 C3            | movzx eax,bl                          |
02A6192B | 3B C6               | cmp eax,esi                           |
02A6192D | 72 E1               | jb 2A61910                            |

函数2A613C0内:

02A613C0 | B8 56 55 55 55      | mov eax,55555556                      | eax置0x55555556
02A613C5 | F7 E9               | imul ecx                              | ecx是输入数,与eax相乘
02A613C7 | 56                  | push esi                              |
02A613C8 | 8B F2               | mov esi,edx                           | edx给esi(imul后edx:eax存结果)
02A613CA | C1 EE 1F            | shr esi,1F                            | esi右移0x1F位
02A613CD | 03 F2               | add esi,edx                           | esi += edx
02A613CF | 8D 04 76            | lea eax,dword ptr ds:[esi+esi*2]      | eax = esi + esi * 2
02A613D2 | 2B C8               | sub ecx,eax                           | ecx = ecx - eax
02A613D4 | 83 FE 02            | cmp esi,2                             |
02A613D7 | 7F 70               | jg 2A61449                            |
02A613D9 | 83 F9 02            | cmp ecx,2                             |
02A613DC | 7F 6B               | jg 2A61449                            |
02A613DE | 03 C1               | add eax,ecx                           | eax = eax + ecx
02A613E0 | 80 B8 10 3F A7 02 0 | cmp byte ptr ds:[eax+2A73F10],0       |
02A613E7 | 74 60               | je 2A61449                            |
02A613E9 | 83 F8 02            | cmp eax,2                             |
02A613EC | 7E 14               | jle 2A61402                           |
02A613EE | 80 B8 0D 3F A7 02 0 | cmp byte ptr ds:[eax+2A73F0D],0       |
02A613F5 | 75 0B               | jne 2A61402                           |
02A613F7 | B9 02 00 00 00      | mov ecx,2                             | ecx置2
02A613FC | 5E                  | pop esi                               |
02A613FD | E9 7E FE FF FF      | jmp 2A61280                           |
02A61402 | 83 F9 02            | cmp ecx,2                             |
02A61405 | 7D 14               | jge 2A6141B                           |
02A61407 | 80 B8 11 3F A7 02 0 | cmp byte ptr ds:[eax+2A73F11],0       |
02A6140E | 75 0B               | jne 2A6141B                           |
02A61410 | B9 03 00 00 00      | mov ecx,3                             | ecx置3
02A61415 | 5E                  | pop esi                               |
02A61416 | E9 65 FE FF FF      | jmp 2A61280                           |
02A6141B | 83 FE 02            | cmp esi,2                             |
02A6141E | 7D 11               | jge 2A61431                           |
02A61420 | 80 B8 13 3F A7 02 0 | cmp byte ptr ds:[eax+2A73F13],0       |
02A61427 | 75 08               | jne 2A61431                           |
02A61429 | 33 C9               | xor ecx,ecx                           | ecx清零
02A6142B | 5E                  | pop esi                               |
02A6142C | E9 4F FE FF FF      | jmp 2A61280                           |
02A61431 | 85 C9               | test ecx,ecx                          |
02A61433 | 7E 14               | jle 2A61449                           |
02A61435 | 80 B8 0F 3F A7 02 0 | cmp byte ptr ds:[eax+2A73F0F],0       |
02A6143C | 75 0B               | jne 2A61449                           |
02A6143E | B9 01 00 00 00      | mov ecx,1                             | ecx置1
02A61443 | 5E                  | pop esi                               |
02A61444 | E9 37 FE FF FF      | jmp 2A61280                           |
02A61449 | 5E                  | pop esi                               |
02A6144A | C3                  | ret                                   |

这里解释一下算法:

首先取输入的数字,ASCII->Number后传入函数
函数内首先将数字处理成3 * x + y的形式
esi存放x(乘数),ecx存放y(余数),eax存放3 * x(02A613DE之前)以及原数字(02A613DE之后,判断用这个)
然后程序根据这三个寄存器的值进行判断如何进行位移

给出的Serial运行完后内存变成了这样:

02A73F10 01 02 03 04 05 06 07 08 00 00 00 00 08 00 00 00 ...........

前八位变成了按顺序排列,后面的代码也是在验证这一点:

02A61931 | 0F B6 CA            | movzx ecx,dl                          |
02A61934 | 8A 81 10 3F A7 02   | mov al,byte ptr ds:[ecx+2A73F10]      |
02A6193A | 3A 81 0F 3F A7 02   | cmp al,byte ptr ds:[ecx+2A73F0F]      |
02A61940 | 7C 07               | jl 2A61949                            |
02A61942 | FE C2               | inc dl                                |
02A61944 | 80 FA 08            | cmp dl,8                              |
02A61947 | 72 E8               | jb 2A61931                            |

也就是说最终目标是使得给出的矩阵的前八位变成顺序排列即可
那么还有一种方式可以通过验证,即012345678


分析到此完毕~ 去年太水还做不出,这两天想起来于是把题目肝了下来Orz

你可能感兴趣的:(吾爱破解2016安全挑战赛cm1分析)