大概從這開始記錄吧侯嘀。。之前的wp清系統(tǒng)之前沒有存GG了
首先打開程序看看界面
可以看到有彈框提示字符康吵。。
IDA也可以輕松找到DialogFunc
但這題在按鈕事件加了無數(shù)花访递。晦嵌。大概看了一下就懶得看了
于是想到GetDlgItemText下斷然后下訪問斷點(diǎn)的方式去找算法位置
最后找到是在RVA00001450的地方是算法函數(shù)的地址
對(duì)算法開始分析:
03301497 56 push esi ; 計(jì)算流程開始
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 ; 計(jì)算Serial長(zhǎng)度,存esi
033014A9 8D46 ED lea eax,dword ptr ds:[esi-0x13] ; 長(zhǎng)度-0x13h后送eax
033014AC 83F8 31 cmp eax,0x31 ; 比較eax和0x31h的大小拷姿,即長(zhǎng)度和0x31h+0x13h=0x44h
033014AF 0F87 AD040000 ja 03301962 ; 實(shí)現(xiàn)了Serial長(zhǎng)度在0x13h和0x44h之間的限制
上面這段實(shí)現(xiàn)了對(duì)Serial長(zhǎng)度的限制惭载,這里的限制是不能少于18位,不能多于68位响巢,那么自然就有猜測(cè)是否分成兩部分(18+描滔?)進(jìn)行驗(yàn)證,后面的分析也會(huì)證實(shí)這點(diǎn)踪古。
首先的發(fā)現(xiàn)是對(duì)Name的處理:
在1200h的函數(shù)里面
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] ; 取一個(gè)字符
03301222 42 inc edx ; edx自增
03301223 84C0 test al,al
03301225 ^ 75 F9 jnz short 03301220
03301227 2BD1 sub edx,ecx ; 取Name長(zhǎng)度
03301229 33C9 xor ecx,ecx
0330122B 8955 F4 mov dword ptr ss:[ebp-0xC],edx ; 長(zhǎng)度存棧
0330122E 83FA 02 cmp edx,0x2
03301231 72 27 jb short 0330125A ; 長(zhǎng)度小于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計(jì)數(shù)器自增2
0330124E 03F8 add edi,eax ; 第二個(gè)字符累加到edi
03301250 3BCB cmp ecx,ebx
03301252 ^ 72 EC jb short 03301240 ; 若有兩個(gè)及以上字符則回跳繼續(xù)處理
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
這個(gè)函數(shù)簡(jiǎn)單的進(jìn)行了一個(gè)ASCII累加的處理
之后取了這個(gè)累加和的奇偶作為后續(xù)算法的一部分
然后就是對(duì)Serial前18位的處理了
這18位被分成了2 * 3 * 3這樣的形式處理
每?jī)晌簧梢粋€(gè)數(shù)含长,參考官方給的Name為360的Serial的前18位:
323031303330213032
每?jī)蓚€(gè)為一組,然后3 * 3組伏穆,于是:
32 30 31
30 33 30
21 30 32
聯(lián)想到ascii碼的我拘泞。。
問題在于這里有個(gè)21枕扫,那么看看匯編吧
匯編里對(duì)應(yīng)處理的部分如下:
033014FE E8 FDFCFFFF call 03301200
03301503 83E0 01 and eax,0x1 ; 判斷奇偶用陪腌,奇數(shù)結(jié)果為1,偶數(shù)為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 ; 奇偶結(jié)果存在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一個(gè)字符
0330154E 8AC2 mov al,dl
03301550 2C 30 sub al,0x30
03301552 3C 09 cmp al,0x9 ; 判斷是否是數(shù)字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 ; 不是數(shù)字的話判斷是否是字母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] ; 第二個(gè)字符
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] ; 當(dāng)Serial奇數(shù)位數(shù)字奇偶與Name的ascii碼之和奇偶不同時(shí)
033015CB 74 0A je short 033015D7 ; Serial偶數(shù)位數(shù)值取負(fù)值
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] ; 循環(huán)結(jié)束條件
033015E3 0F8D 79030000 jge 03301962
033015E9 8B95 5CFFFFFF mov edx,dword ptr ss:[ebp-0xA4]
033015EF 3BFA cmp edi,edx ; 循環(huán)結(jié)束條件2
033015F1 0F8D 6B030000 jge 03301962
033015F7 8BC2 mov eax,edx
033015F9 FEC7 inc bh ; bh作計(jì)數(shù)器
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個(gè)字符
03301611 ^ 0F82 2AFFFFFF jb 03301541 ; 回去處理下兩個(gè)字符
03301617 8A85 6BFFFFFF mov al,byte ptr ss:[ebp-0x95]
0330161D 04 01 add al,0x1 ; al是又一個(gè)計(jì)數(shù)器
0330161F 8885 6BFFFFFF mov byte ptr ss:[ebp-0x95],al
03301625 3C 03 cmp al,0x3 ; 又是3次 于是一共是18個(gè)
03301627 ^ 0F82 06FFFFFF jb 03301533
可以看到其實(shí)也并不是ASCII碼铡原。。2個(gè)數(shù)的前一個(gè)是用來和前面運(yùn)算過的Name的ASCII累加和的奇偶進(jìn)行比較的商叹,如果這兩個(gè)奇偶不同燕刻,那么后面一個(gè)數(shù)就取負(fù)值。
另外值得一提的是cvtdq2ps是壓縮有符號(hào)雙字整數(shù)轉(zhuǎn)換成壓縮單精度浮點(diǎn)值的作用
于是我們可以看到算法從這18位生成了一個(gè)矩陣:
2 0 1
0 3 0
-1 0 2
那我們接下來關(guān)心的部分就是這個(gè)矩陣將會(huì)如何處理了
但是由于有很多xmm寄存器的調(diào)用剖笙。卵洗。于是我從od轉(zhuǎn)了x32dbg,地址會(huì)有一定改變不要在意QAQ
接下來首先程序在內(nèi)存中放了一些數(shù)
整理出來大概是兩個(gè)3 * 3矩陣
1 0 1
0 2 0
-1 0 1
1 0 0
0 1 0
0 0 1
繼續(xù)看匯編弥咪。过蹂。
接下來首先用了個(gè)循環(huán)把兩個(gè)矩陣放到了其他地方
然后進(jìn)行了矩陣乘法運(yùn)算
下面是相關(guān)代碼,從兩個(gè)矩陣的取值方式很容易看出是矩陣乘法了
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:第一個(gè)矩陣地址
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取第一個(gè)矩陣的數(shù)(按行)
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取輸入矩陣的數(shù)(按列)
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計(jì)數(shù)器+=1
02A611A1 | F3 0F 59 C1 | mulss xmm0,xmm1 | 兩數(shù)相乘
02A611A5 | F3 0F 58 C3 | addss xmm0,xmm3 | xmm3的內(nèi)容累加到xmm0
02A611A9 | 0F 28 D8 | movaps xmm3,xmm0 | xmm3存入本次運(yùn)算結(jié)果
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 | 結(jié)果送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 |
這里運(yùn)算的結(jié)果是
1 0 3
0 6 0
-3 0 1
可以驗(yàn)證確實(shí)是矩陣乘法
接下來這個(gè)結(jié)果矩陣又和前面提到的第二個(gè)矩陣進(jìn)行了加法運(yùn)算:
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:矩陣乘法結(jié)果地址
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取上次結(jié)果矩陣的數(shù)
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:第二個(gè)矩陣的地址
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取第二個(gè)矩陣的數(shù)
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:存結(jié)果的地址
02A610BF | F3 0F 58 C1 | addss xmm0,xmm1 | 兩數(shù)相加
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 | 存結(jié)果
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為第一個(gè)矩陣,B為第二個(gè)矩陣扳躬。那么剛剛的運(yùn)算可以表示成:
C = X * A
D = C + B
而程序接下來又各調(diào)用了一次乘法和加法的函數(shù)脆诉,這次的運(yùn)算對(duì)象有所改變甚亭,用算式表示如下:
E = A * A
F = E + X
接下來程序?qū)和F進(jìn)行逐位比較,出現(xiàn)不等直接飛走
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 |
那么到這里第一部分的分析結(jié)束击胜,大致用算式表示一下就是:
X * A + B = A * A + X
其中A亏狰、B已知,求X
接下來是后半部分的算法分析:
首先在內(nèi)存中放了一塊這樣的“數(shù)組”
07 01 04 00 03 08 02 05 06
由于是mov的直接數(shù)偶摔,覺得肯定是用上了暇唾,于是先記著
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的參數(shù)
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 根據(jù)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碼值對(duì)上面的字串進(jìn)行了一定的操作
具體操作就是將0的位置和四個(gè)可選位置數(shù)的值進(jìn)行了替換
觀察可以發(fā)現(xiàn)(上面一段的函數(shù)里有線索)其實(shí)還是個(gè)3 * 3的矩陣
7 1 4
0 3 8
2 5 6
四個(gè)位置自然也就是上下左右,360對(duì)應(yīng)ASCII是0x33,0x36,0x30
模4后分別是3辰斋、2策州、0
而矩陣的變化是先4 0交換
然后8 0交換,最后還是8 0交換
所以可知3表示0左移亡呵,2表示下移抽活,0表示上移,剩下的1也就是0右移
然后锰什。下硕。看到這就已經(jīng)想到拼圖游戲了汁胆。梭姓。0表示的是空位那種
接下來的代碼又開始跳到那一段位移的函數(shù)了,算法如下:
02A61910 | 0F BE 4C 05 B4 | movsx ecx,byte ptr ss:[ebp+eax-4C] | 取Serial后半段一個(gè)字符
02A61915 | 8D 41 D0 | lea eax,dword ptr ds:[ecx-30] | 去掉30嫩码,取數(shù)字部分
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 |
函數(shù)2A613C0內(nèi):
02A613C0 | B8 56 55 55 55 | mov eax,55555556 | eax置0x55555556
02A613C5 | F7 E9 | imul ecx | ecx是輸入數(shù)铸题,與eax相乘
02A613C7 | 56 | push esi |
02A613C8 | 8B F2 | mov esi,edx | edx給esi(imul后edx:eax存結(jié)果)
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 |
這里解釋一下算法:
首先取輸入的數(shù)字铡恕,ASCII->Number后傳入函數(shù)
函數(shù)內(nèi)首先將數(shù)字處理成3 * x + y的形式
esi存放x(乘數(shù)),ecx存放y(余數(shù))丢间,eax存放3 * x(02A613DE之前)以及原數(shù)字(02A613DE之后探熔,判斷用這個(gè))
然后程序根據(jù)這三個(gè)寄存器的值進(jìn)行判斷如何進(jìn)行位移
給出的Serial運(yùn)行完后內(nèi)存變成了這樣:
02A73F10 01 02 03 04 05 06 07 08 00 00 00 00 08 00 00 00 ...........
前八位變成了按順序排列,后面的代碼也是在驗(yàn)證這一點(diǎn):
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 |
也就是說最終目標(biāo)是使得給出的矩陣的前八位變成順序排列即可
那么還有一種方式可以通過驗(yàn)證烘挫,即012345678
分析到此完畢~ 去年太水還做不出护糖,這兩天想起來于是把題目肝了下來Orz