onmiuncai 发表于 2016-7-24 19:15

Alive iPhone Video Converter 算法分析及注册机源码

再来一篇算法分析,如有不对,欢迎指正。


今天的算法分析的目标是 Alive iPhone Video Converter,Borland Delphi 6.0 - 7.0



输入用户名与随意注册码,弹出出错框后F12暂停,回溯来到下面这个地方



然后从段首下好断点,开始逐步分析,把关键的字符都标记好,具体分析如下

0048809C/$55            push ebp
0048809D|.8BEC          mov ebp,esp
0048809F|.6A 00         push 0x0
004880A1|.6A 00         push 0x0
004880A3|.6A 00         push 0x0
004880A5|.6A 00         push 0x0
004880A7|.6A 00         push 0x0
004880A9|.53            push ebx
004880AA|.56            push esi
004880AB|.894D F8       mov ,ecx
004880AE|.8955 FC       mov ,edx                        ;ntdll.KiFastSystemCallRet
004880B1|.8BF0          mov esi,eax
004880B3|.8B45 FC       mov eax,
004880B6|.E8 B9C9F7FF   call MP4Conve.00404A74
004880BB|.8B45 F8       mov eax,                        ;注册码
004880BE|.E8 B1C9F7FF   call MP4Conve.00404A74
004880C3|.33C0          xor eax,eax
004880C5|.55            push ebp
004880C6|.68 93814800   push MP4Conve.00488193
004880CB|.64:FF30       push dword ptr fs:
004880CE|.64:8920       mov dword ptr fs:,esp
004880D1|.33DB          xor ebx,ebx
004880D3|.33D2          xor edx,edx                              ;ntdll.KiFastSystemCallRet
004880D5|.8B45 FC       mov eax,                        ;用户名
004880D8|.E8 EBCAF7FF   call MP4Conve.00404BC8
004880DD|.85C0          test eax,eax
004880DF|.7E 0B         jle short MP4Conve.004880EC
004880E1|.8D45 F8       lea eax,
004880E4|.8B55 FC       mov edx,
004880E7|.E8 80C5F7FF   call MP4Conve.0040466C
004880EC|>8D4D F4       lea ecx,                        ;注册码
004880EF|.8B55 FC       mov edx,                        ;用户名
004880F2|.8BC6          mov eax,esi
004880F4|.E8 2F010000   call MP4Conve.00488228                   ;关键CALL
004880F9|.8B55 F4       mov edx,                        ;这里出现可疑字符串
004880FC|.8B45 F8       mov eax,                        ;假码
004880FF|.E8 EC06F8FF   call MP4Conve.004087F0                   ;strcmp
00488104|.85C0          test eax,eax
00488106|.75 41         jnz short MP4Conve.00488149            ;关键跳
00488108|.8B55 FC       mov edx,
0048810B|.8BC6          mov eax,esi
0048810D|.E8 26FBFFFF   call MP4Conve.00487C38
00488112|.84C0          test al,al
00488114|.74 62         je short MP4Conve.00488178
00488116|.B3 01         mov bl,0x1
00488118|.6A 40         push 0x40
0048811A|.8D55 F0       lea edx,
0048811D|.A1 149E4A00   mov eax,dword ptr ds:
00488122|.8B00          mov eax,dword ptr ds:
00488124|.E8 53D2FDFF   call MP4Conve.0046537C
00488129|.8B45 F0       mov eax,
0048812C|.E8 53C9F7FF   call MP4Conve.00404A84
00488131|.50            push eax                                 ; |Title = NULL
00488132|.68 A4814800   push MP4Conve.004881A4                   ; |Registered successfully, Thanks for your registration.
00488137|.A1 149E4A00   mov eax,dword ptr ds:          ; |
0048813C|.8B00          mov eax,dword ptr ds:               ; |
0048813E|.8B40 30       mov eax,dword ptr ds:          ; |
00488141|.50            push eax                                 ; |hOwner = NULL
00488142|.E8 65F2F7FF   call <jmp.&user32.MessageBoxA>         ; \MessageBoxA


从上面的分析来看,我们首先要分析的是004880F4 这个call,所以,下好断点,F7步入,然后依然老样子,把注释做好,方便分析


00488228/$55            push ebp
00488229|.8BEC          mov ebp,esp
0048822B|.6A 00         push 0x0
0048822D|.6A 00         push 0x0
0048822F|.6A 00         push 0x0
00488231|.6A 00         push 0x0
00488233|.6A 00         push 0x0
00488235|.6A 00         push 0x0
00488237|.6A 00         push 0x0
00488239|.6A 00         push 0x0
0048823B|.53            push ebx
0048823C|.56            push esi
0048823D|.57            push edi                                 ;ntdll.7C930228
0048823E|.8BD9          mov ebx,ecx
00488240|.8955 FC       mov ,edx                        ;name ASCII "kkapskok"
00488243|.8BF8          mov edi,eax
00488245|.8B45 FC       mov eax,
00488248|.E8 27C8F7FF   call MP4Conve.00404A74
0048824D|.33C0          xor eax,eax
0048824F|.55            push ebp
00488250|.68 83834800   push MP4Conve.00488383
00488255|.64:FF30       push dword ptr fs:
00488258|.64:8920       mov dword ptr fs:,esp
0048825B|.8D45 FC       lea eax,
0048825E|.BA 9C834800   mov edx,MP4Conve.0048839C                ;Ae2G0I|hl
00488263|.E8 2CC6F7FF   call MP4Conve.00404894
00488268|.8B45 FC       mov eax,                        ;strcat ASCII "kkapskokAe2G0I|hl"
0048826B|.E8 1CC6F7FF   call MP4Conve.0040488C
00488270|.8BF0          mov esi,eax
00488272|.D1FE          sar esi,1
00488274|.79 03         jns short MP4Conve.00488279
00488276|.83D6 00       adc esi,0x0
00488279|>8D45 F0       lea eax,
0048827C|.50            push eax
0048827D|.8BCE          mov ecx,esi
0048827F|.BA 01000000   mov edx,0x1
00488284|.8B45 FC       mov eax,
00488287|.E8 58C8F7FF   call MP4Conve.00404AE4
0048828C|.8B45 F0       mov eax,                        ;name ASCII "kkapskok"
0048828F|.50            push eax
00488290|.8D45 EC       lea eax,
00488293|.50            push eax
00488294|.8B45 FC       mov eax,                        ;ASCII "kkapskokAe2G0I|hl"
00488297|.E8 F0C5F7FF   call MP4Conve.0040488C
0048829C|.8BC8          mov ecx,eax                              ;11h -> 17位
0048829E|.8D56 01       lea edx,dword ptr ds:         ;edx 9位
004882A1|.8B45 FC       mov eax,
004882A4|.E8 3BC8F7FF   call MP4Conve.00404AE4
004882A9|.8B55 EC       mov edx,                        ;从第9位开始取 ASCII "Ae2G0I|hl"
004882AC|.8D45 FC       lea eax,
004882AF|.59            pop ecx                                  ;kernel32.7C816037
004882B0|.E8 23C6F7FF   call MP4Conve.004048D8
004882B5|.8D45 F8       lea eax,                        ;name ASCII "kkapskok"
004882B8|.50            push eax
004882B9|.B9 0A000000   mov ecx,0xA                              ;ecx 10位
004882BE|.BA 01000000   mov edx,0x1
004882C3|.8B45 FC       mov eax,                        ;ASCII "Ae2G0I|hlkkapskok"
004882C6|.E8 19C8F7FF   call MP4Conve.00404AE4
004882CB|.8D45 F4       lea eax,                        ;截取前面10位 Ae2G0I|hlk
004882CE|.50            push eax
004882CF|.8B45 FC       mov eax,                        ;ASCII "Ae2G0I|hlkkapskok"
004882D2|.E8 B5C5F7FF   call MP4Conve.0040488C
004882D7|.8BC8          mov ecx,eax                              ;11h -> 17位
004882D9|.BA 06000000   mov edx,0x6                              ;edx 6位
004882DE|.8B45 FC       mov eax,
004882E1|.E8 FEC7F7FF   call MP4Conve.00404AE4
004882E6|.837D F4 00    cmp ,0x0                        ;从第6位开始取 ASCII "I|hlkkapskok"
004882EA|.75 10         jnz short MP4Conve.004882FC
004882EC|.8D45 F4       lea eax,
004882EF|.BA 9C834800   mov edx,MP4Conve.0048839C                ;Ae2G0I|hl
004882F4|.8B4D F8       mov ecx,                        ;kernel32.7C816040
004882F7|.E8 DCC5F7FF   call MP4Conve.004048D8
004882FC|>53            push ebx
004882FD|.8B4D F4       mov ecx,                        ;ASCII "I|hlkkapskok"
00488300|.8B55 F8       mov edx,                        ;ASCII "Ae2G0I|hlk"
00488303|.8BC7          mov eax,edi                              ;ntdll.7C930228
00488305|.E8 DEF7FFFF   call MP4Conve.00487AE8                   ;继续跟进CALL
0048830A|.8D45 E8       lea eax,
0048830D|.50            push eax
0048830E|.8B03          mov eax,dword ptr ds:               ;ASCII "1000B0C56F149F9170F0818"
00488310|.B9 05000000   mov ecx,0x5                              ;ecx 5位
00488315|.BA 01000000   mov edx,0x1
0048831A|.E8 C5C7F7FF   call MP4Conve.00404AE4
0048831F|.FF75 E8       push                            ;ASCII "1000B"
00488322|.68 B0834800   push MP4Conve.004883B0                   ;-
00488327|.8D45 E4       lea eax,
0048832A|.50            push eax
0048832B|.8B03          mov eax,dword ptr ds:
0048832D|.B9 05000000   mov ecx,0x5                              ;ecx 5位
00488332|.BA 06000000   mov edx,0x6
00488337|.E8 A8C7F7FF   call MP4Conve.00404AE4
0048833C|.FF75 E4       push                            ;ASCII "0C56F"
0048833F|.68 B0834800   push MP4Conve.004883B0                   ;-
00488344|.8D45 E0       lea eax,
00488347|.50            push eax
00488348|.8B03          mov eax,dword ptr ds:
0048834A|.B9 05000000   mov ecx,0x5                              ;ecx 5位
0048834F|.BA 0B000000   mov edx,0xB
00488354|.E8 8BC7F7FF   call MP4Conve.00404AE4
00488359|.FF75 E0       push                            ;ASCII "149F9"
0048835C|.8BC3          mov eax,ebx
0048835E|.BA 05000000   mov edx,0x5
00488363|.E8 E4C5F7FF   call MP4Conve.0040494C
00488368|.33C0          xor eax,eax
0048836A|.5A            pop edx                                  ;kernel32.7C816037
0048836B|.59            pop ecx                                  ;kernel32.7C816037
0048836C|.59            pop ecx                                  ;kernel32.7C816037
0048836D|.64:8910       mov dword ptr fs:,edx               ;ntdll.KiFastSystemCallRet
00488370|.68 8A834800   push MP4Conve.0048838A
00488375|>8D45 E0       lea eax,
00488378|.BA 08000000   mov edx,0x8
0048837D|.E8 76C2F7FF   call MP4Conve.004045F8
00488382\.C3            retn


分析完之后,我们来总结一下这个CALL做了哪些事,记录一下。
1.00488240 获取了用户名,0048825E 这个地址获取了一个常量字符串” Ae2G0I|hl“用户名 与 Ae2G0I|hl 连接组成新的字符串,通过esi寄存器 sar esi,1 截取一半字符串,然后取后面字符串与前面的另一半连接,再次组成新的字符串。
2. 004882B9 截取了0Ah == 10位 出来,变成了新的字符串,压入堆栈保存。
3.再次对此字符串 从第6位开始截取到完,变成了又一串新的字符串,堆栈保存。
注意这个地址00488305,过了这个call 后会发现生成一串可疑字符串。这个我们不知道来路,所以这个CALL稍后还得继续分析,我们接着看下面的,
4.依然把这个可疑字符串5个一段,分成了 3段,只取前面15个字符,并用"-"连接。从前面还没进CALL之前我们得知其实这个就是真码,所以我们要对00488305进行分析。




00487AE8/$55            push ebp
00487AE9|.8BEC          mov ebp,esp
00487AEB|.83C4 E0       add esp,-0x20
00487AEE|.53            push ebx
00487AEF|.56            push esi
00487AF0|.57            push edi                                 ;ntdll.7C930228
00487AF1|.33DB          xor ebx,ebx
00487AF3|.895D E0       mov ,ebx
00487AF6|.895D F0       mov ,ebx
00487AF9|.894D F8       mov ,ecx                        ;ASCII "lsooAe2"
00487AFC|.8955 FC       mov ,edx                        ;ASCII "G0I|hlsooA"
00487AFF|.8B45 FC       mov eax,
00487B02|.E8 6DCFF7FF   call MP4Conve.00404A74
00487B07|.8B45 F8       mov eax,                        ;kernel32.7C816040
00487B0A|.E8 65CFF7FF   call MP4Conve.00404A74
00487B0F|.33C0          xor eax,eax
00487B11|.55            push ebp
00487B12|.68 047C4800   push MP4Conve.00487C04
00487B17|.64:FF30       push dword ptr fs:
00487B1A|.64:8920       mov dword ptr fs:,esp
00487B1D|.8B45 F8       mov eax,                        ;kernel32.7C816040
00487B20|.E8 67CDF7FF   call MP4Conve.0040488C
00487B25|.8945 F4       mov ,eax                        ;ASCII "lsooAe2" 获取长度
00487B28|.837D F4 00    cmp ,0x0
00487B2C|.75 0D         jnz short MP4Conve.00487B3B
00487B2E|.8D45 F8       lea eax,
00487B31|.BA 1C7C4800   mov edx,MP4Conve.00487C1C                ;Think Space
00487B36|.E8 31CBF7FF   call MP4Conve.0040466C
00487B3B|>33F6          xor esi,esi
00487B3D|.BB 00010000   mov ebx,0x100                            ;ebx = 100
00487B42|.8D45 F0       lea eax,
00487B45|.50            push eax
00487B46|.C745 E4 00010>mov ,0x100
00487B4D|.C645 E8 00    mov byte ptr ss:,0x0
00487B51|.8D55 E4       lea edx,
00487B54|.33C9          xor ecx,ecx
00487B56|.B8 307C4800   mov eax,MP4Conve.00487C30                ;%1.2x
00487B5B|.E8 641EF8FF   call MP4Conve.004099C4                   ;转成ASCII "100"
00487B60|.8B45 FC       mov eax,                        ;ASCII "G0I|hlsooA"
00487B63|.E8 24CDF7FF   call MP4Conve.0040488C
00487B68|.8BF8          mov edi,eax                              ;ASCII "G0I|hlsooA"获取长度
00487B6A|.85FF          test edi,edi                           ;ntdll.7C930228
00487B6C|.7E 60         jle short MP4Conve.00487BCE
00487B6E|.C745 EC 01000>mov ,0x1                        ;计数
00487B75|>8B45 FC       /mov eax,                     ;ASCII "G0I|hlsooA"
00487B78|.8B55 EC       |mov edx,
00487B7B|.0FB64410 FF   |movzx eax,byte ptr ds:   ;逐个取字
00487B80|.03C3          |add eax,ebx                           ;EBX初始化100,循环后去上一次的结果
00487B82|.B9 FF000000   |mov ecx,0xFF
00487B87|.99            |cdq
00487B88|.F7F9          |idiv ecx
00487B8A|.8BDA          |mov ebx,edx                           ;ebx = (eax+100[第2次开始为上次结果]) mod 0xff
00487B8C|.3B75 F4       |cmp esi,                     ;ASCII "lsooAe2" 长度
00487B8F|.7D 03         |jge short MP4Conve.00487B94
00487B91|.46            |inc esi                                 ;计数("lsooAe2" 长度)
00487B92|.EB 05         |jmp short MP4Conve.00487B99
00487B94|>BE 01000000   |mov esi,0x1
00487B99|>8B45 F8       |mov eax,                     ;kernel32.7C816040
00487B9C|.0FB64430 FF   |movzx eax,byte ptr ds:   ;逐个取字
00487BA1|.33D8          |xor ebx,eax                           ;取出的字符与前面计算的字符 xor
00487BA3|.8D45 E0       |lea eax,
00487BA6|.50            |push eax
00487BA7|.895D E4       |mov ,ebx
00487BAA|.C645 E8 00    |mov byte ptr ss:,0x0
00487BAE|.8D55 E4       |lea edx,
00487BB1|.33C9          |xor ecx,ecx
00487BB3|.B8 307C4800   |mov eax,MP4Conve.00487C30               ;%1.2x
00487BB8|.E8 071EF8FF   |call MP4Conve.004099C4                  ;把结果转成ASCII
00487BBD|.8B55 E0       |mov edx,
00487BC0|.8D45 F0       |lea eax,
00487BC3|.E8 CCCCF7FF   |call MP4Conve.00404894
00487BC8|.FF45 EC       |inc
00487BCB|.4F            |dec edi                                 ;循环 ASCII "G0I|hlsooA"的长度
00487BCC|.^ 75 A7         \jnz short MP4Conve.00487B75
00487BCE|>8B45 08       mov eax,                        ;最后组合成 100+计算的结果
00487BD1|.8B55 F0       mov edx,
00487BD4|.E8 4FCAF7FF   call MP4Conve.00404628
00487BD9|.33C0          xor eax,eax
00487BDB|.5A            pop edx                                  ;kernel32.7C816037
00487BDC|.59            pop ecx                                  ;kernel32.7C816037
00487BDD|.59            pop ecx                                  ;kernel32.7C816037
00487BDE|.64:8910       mov dword ptr fs:,edx               ;ntdll.KiFastSystemCallRet
00487BE1|.68 0B7C4800   push MP4Conve.00487C0B
00487BE6|>8D45 E0       lea eax,
00487BE9|.E8 E6C9F7FF   call MP4Conve.004045D4
00487BEE|.8D45 F0       lea eax,
00487BF1|.E8 DEC9F7FF   call MP4Conve.004045D4
00487BF6|.8D45 F8       lea eax,
00487BF9|.BA 02000000   mov edx,0x2
00487BFE|.E8 F5C9F7FF   call MP4Conve.004045F8
00487C03\.C3            retn


通过上面的分析再来总结一下这个CALL,把上一层的CALL堆栈保存的2个字符串进行处理,将取10位的字符串作为循环开始处理,逐个取字,与EBX初始化100h进行相加然后与FF求余,得出的结果在与第二个字符串逐个取字进行XOR,最后把结果保存给初始化的EBX,然后把 初始化的100与结果转ASCII相连接。



注意这里,因为当第2个字符串比第1个字符串段,所以这里做了个判断,若小于第一个字符串后,则从新从第一位开始取值与前面的第一个结果进行XOR。
最终循环完计算的结果就是出CALL后的那串可疑字符串,到此,我们就把算法的部分全部分析完了。下面是易语言的源码与注册机,有兴趣的朋友可以自己动动手分析分析。






quintionmon 发表于 2016-8-13 21:27

好强大,看起来还不错啊。厉害人物!
页: [1]
查看完整版本: Alive iPhone Video Converter 算法分析及注册机源码