苏紫方璇 发表于 2018-1-22 14:18

无聊逆算法-易我分区表医生3.0

昨天看了@zhaozdy 大神的追码帖子,(指路:https://www.52pojie.cn/thread-689921-1-1.html),感觉这软件的算法应该不会太难,今天闲着没事,神舞幻想也通关了,于是就来看一看。
正如原帖所说,这软件貌似vc6编写的,无壳,重启验证,对我这种小白比较友好。
下面进入正题,用OD打开这软件。
呃。。。下一步该干啥了,忘记了。好长时间不做逆向,我都忘记了:keai。
不过没关系,我会抄,大神的帖子不是说了么,关键Call在0x42558F这里,Ctrl+G转到这条地址,回车进去然后下断,慢慢跟。


具体算法解释见注释(反汇编看不下去可以试试看最后的注册机代码):
003E1200 >81EC 68080000   sub esp,0x868
003E1206    53            push ebx
003E1207    55            push ebp
003E1208    B0 F2         mov al,0xF2
003E120A    56            push esi
003E120B    8BB424 78080000 mov esi,dword ptr ss:         ; PtdWin.00425594
003E1212    884424 2F       mov byte ptr ss:,al
003E1216    884424 3C       mov byte ptr ss:,al
003E121A    B3 BA         mov bl,0xBA
003E121C    B2 9B         mov dl,0x9B
003E121E    B1 BE         mov cl,0xBE
003E1220    B0 C1         mov al,0xC1
003E1222    57            push edi
003E1223    85F6            test esi,esi                           ; 注册名不为空
003E1225    C74424 14 04C46>mov dword ptr ss:,0xAA6BC404
003E122D    66:C74424 18 1E>mov word ptr ss:,0xC61E
003E1234    66:C74424 1A 7F>mov word ptr ss:,0x4E7F
003E123B    C64424 1C A6    mov byte ptr ss:,0xA6
003E1240    C64424 1D 1A    mov byte ptr ss:,0x1A
003E1245    885C24 1E       mov byte ptr ss:,bl
003E1249    C64424 1F E9    mov byte ptr ss:,0xE9
003E124E    885424 20       mov byte ptr ss:,dl
003E1252    C64424 21 20    mov byte ptr ss:,0x20
003E1257    C64424 22 1B    mov byte ptr ss:,0x1B
003E125C    C64424 23 67    mov byte ptr ss:,0x67
003E1261    C74424 24 DAA6A>mov dword ptr ss:,0x62A9A6DA
003E1269    66:C74424 28 46>mov word ptr ss:,0x7546
003E1270    66:C74424 2A 33>mov word ptr ss:,0x4333
003E1277    C64424 2C A2    mov byte ptr ss:,0xA2
003E127C    C64424 2D AA    mov byte ptr ss:,0xAA
003E1281    C64424 2E 3E    mov byte ptr ss:,0x3E
003E1286    C64424 2F FC    mov byte ptr ss:,0xFC
003E128B    C64424 30 15    mov byte ptr ss:,0x15
003E1290    884C24 31       mov byte ptr ss:,cl
003E1294    C64424 32 78    mov byte ptr ss:,0x78
003E1299    C74424 34 C0B91>mov dword ptr ss:,0xC417B9C0
003E12A1    66:C74424 38 63>mov word ptr ss:,0x6863
003E12A8    66:C74424 3A 3F>mov word ptr ss:,0x493F
003E12AF    C64424 3C A7    mov byte ptr ss:,0xA7
003E12B4    C64424 3D CC    mov byte ptr ss:,0xCC
003E12B9    884C24 3E       mov byte ptr ss:,cl
003E12BD    C64424 3F C8    mov byte ptr ss:,0xC8
003E12C2    C64424 41 17    mov byte ptr ss:,0x17
003E12C7    C64424 42 83    mov byte ptr ss:,0x83
003E12CC    C64424 43 9C    mov byte ptr ss:,0x9C
003E12D1    C74424 44 3BD0A>mov dword ptr ss:,0x5DA3D03B
003E12D9    66:C74424 48 4E>mov word ptr ss:,0x134E
003E12E0    66:C74424 4A 3A>mov word ptr ss:,0x4D3A
003E12E7    885C24 4C       mov byte ptr ss:,bl
003E12EB    C64424 4D 2B    mov byte ptr ss:,0x2B
003E12F0    C64424 4E 91    mov byte ptr ss:,0x91
003E12F5    C64424 4F DA    mov byte ptr ss:,0xDA
003E12FA    C64424 50 EA    mov byte ptr ss:,0xEA
003E12FF    C64424 51 73    mov byte ptr ss:,0x73
003E1304    C64424 52 3B    mov byte ptr ss:,0x3B
003E1309    884424 53       mov byte ptr ss:,al
003E130D    C74424 54 D98C7>mov dword ptr ss:,0xC6738CD9
003E1315    66:C74424 58 1B>mov word ptr ss:,0x9D1B
003E131C    66:C74424 5A 25>mov word ptr ss:,0x4825
003E1323    885424 5C       mov byte ptr ss:,dl
003E1327    C64424 5D FE    mov byte ptr ss:,0xFE
003E132C    884424 5E       mov byte ptr ss:,al
003E1330    C64424 5F 57    mov byte ptr ss:,0x57
003E1335    C64424 60 9A    mov byte ptr ss:,0x9A
003E133A    C64424 61 CB    mov byte ptr ss:,0xCB
003E133F    C64424 62 E4    mov byte ptr ss:,0xE4
003E1344    C64424 63 18    mov byte ptr ss:,0x18
003E1349    0F84 08020000   je hd06.003E1557
003E134F    8B8424 80080000 mov eax,dword ptr ss:
003E1356    85C0            test eax,eax                           ; 注册码不为空
003E1358    0F84 F9010000   je hd06.003E1557
003E135E    8BFE            mov edi,esi
003E1360    83C9 FF         or ecx,-0x1                              ; |
003E1363    33C0            xor eax,eax                              ; |
003E1365    F2:AE         repne scas byte ptr es:             ; |strlen
003E1367    F7D1            not ecx                                  ; |
003E1369    49            dec ecx                                  ; |
003E136A    81F9 FD030000   cmp ecx,0x3FD                            ; 注册名长度小于3FD
003E1370    0F87 E1010000   ja hd06.003E1557
003E1376    8BFE            mov edi,esi
003E1378    83C9 FF         or ecx,-0x1
003E137B    F2:AE         repne scas byte ptr es:
003E137D    F7D1            not ecx
003E137F    49            dec ecx                                  ; 取注册名长度
003E1380    8D8424 78040000 lea eax,dword ptr ss:
003E1387    8BE9            mov ebp,ecx
003E1389    894424 64       mov dword ptr ss:,eax
003E138D    8BFE            mov edi,esi
003E138F    83C9 FF         or ecx,-0x1
003E1392    33C0            xor eax,eax
003E1394    32D2            xor dl,dl
003E1396    33DB            xor ebx,ebx
003E1398    885424 10       mov byte ptr ss:,dl
003E139C    F2:AE         repne scas byte ptr es:
003E139E    F7D1            not ecx
003E13A0    2BF9            sub edi,ecx
003E13A2    8BC1            mov eax,ecx
003E13A4    8BF7            mov esi,edi
003E13A6    8B7C24 64       mov edi,dword ptr ss:
003E13AA    C1E9 02         shr ecx,0x2
003E13AD    F3:A5         rep movs dword ptr es:,dword ptr ds>
003E13AF    8BC8            mov ecx,eax
003E13B1    83E1 03         and ecx,0x3
003E13B4    F3:A4         rep movs byte ptr es:,byte ptr ds:[>; 把注册名放进esp+478
003E13B6    33F6            xor esi,esi
003E13B8    85ED            test ebp,ebp
003E13BA    7E 1C         jle short hd06.003E13D8
003E13BC    029434 78040000 add dl,byte ptr ss:       ; for循环
003E13C3    885424 10       mov byte ptr ss:,dl
003E13C7    8B4C24 10       mov ecx,dword ptr ss:          ; (计算B)=注册名ascii相加(8bit)
003E13CB    81E1 FF000000   and ecx,0xFF
003E13D1    03D9            add ebx,ecx                              ; ebx(计算A)=上面结果相加
003E13D3    46            inc esi
003E13D4    3BF5            cmp esi,ebp
003E13D6^ 7C E4         jl short hd06.003E13BC
003E13D8    B9 80000000   mov ecx,0x80
003E13DD    33C0            xor eax,eax
003E13DF    8DBC24 78020000 lea edi,dword ptr ss:
003E13E6    F3:AB         rep stos dword ptr es:
003E13E8    8B8424 80080000 mov eax,dword ptr ss:
003E13EF    8D8C24 78020000 lea ecx,dword ptr ss:
003E13F6    51            push ecx
003E13F7    8B10            mov edx,dword ptr ds:
003E13F9    8B40 04         mov eax,dword ptr ds:
003E13FC    899424 7C020000 mov dword ptr ss:,edx
003E1403    898424 80020000 mov dword ptr ss:,eax         ; push注册码前八位
003E140A    E8 A1FCFFFF   call hd06.#4111                        ; 查表转数字(16进制文本转为数字)
003E140F    8BE8            mov ebp,eax
003E1411    33D2            xor edx,edx
003E1413    8A9434 77040000 mov dl,byte ptr ss:       ; 取注册码最后一位
003E141A    8B4424 10       mov eax,dword ptr ss:          ; kernel32.7C8024BC
003E141E    8BCD            mov ecx,ebp
003E1420    25 FF000000   and eax,0xFF
003E1425    03CA            add ecx,edx                              ; ecx=返回结果+注册名最后一位
003E1427    03DD            add ebx,ebp                              ; ebx=返回结果+计算A
003E1429    03C1            add eax,ecx                              ; eax=计算B+ecx
003E142B    33D2            xor edx,edx
003E142D    03C3            add eax,ebx                              ; eax=eax+ebx
003E142F    B9 05000000   mov ecx,0x5
003E1434    F7F1            div ecx                                  ; eax/5
003E1436    8D7C24 78       lea edi,dword ptr ss:
003E143A    55            push ebp                                 ; call返回数据
003E143B    68 20303E00   push hd06.003E3020                     ; % 8x-
003E1440    C1E2 04         shl edx,0x4                              ; edx=左移四位(上面计算eax/5的余数 即 eax%5)
003E1443    8D4414 1C       lea eax,dword ptr ss:      ; eax=查表地址(edx+0x1c)
003E1447    8B5414 28       mov edx,dword ptr ss:      ; edx=查表数据(edx+0x28)
003E144B    8B48 04         mov ecx,dword ptr ds:         ; ecx=查表数据(eax+4)
003E144E    33D3            xor edx,ebx                              ; edx^=ebx
003E1450    33CB            xor ecx,ebx                              ; ecx^=ebx
003E1452    895424 70       mov dword ptr ss:,edx
003E1456    8B50 08         mov edx,dword ptr ds:         ; edx=查表数据eax+8
003E1459    8B00            mov eax,dword ptr ds:               ; eax=查表数据eax
003E145B    894C24 74       mov dword ptr ss:,ecx
003E145F    33C3            xor eax,ebx                              ; eax^=ebx
003E1461    B9 80000000   mov ecx,0x80
003E1466    894424 7C       mov dword ptr ss:,eax
003E146A    33C0            xor eax,eax
003E146C    F3:AB         rep stos dword ptr es:
003E146E    8D8C24 80000000 lea ecx,dword ptr ss:
003E1475    33D3            xor edx,ebx                              ; edx^=ebx
003E1477    51            push ecx
003E1478    895424 7C       mov dword ptr ss:,edx
003E147C    FF15 0C213E00   call dword ptr ds:[<&MSVCRT.sprintf>]    ; msvcrt.sprintf
003E1482    83C4 0C         add esp,0xC
003E1485    8D5C24 68       lea ebx,dword ptr ss:
003E1489    BD 04000000   mov ebp,0x4                              ; 按储存顺序输出字符串即为注册码
003E148E    8B13            mov edx,dword ptr ds:
003E1490    8D8424 78040000 lea eax,dword ptr ss:
003E1497    52            push edx
003E1498    68 20303E00   push hd06.003E3020
003E149D    50            push eax
003E149E    FF15 0C213E00   call dword ptr ds:[<&MSVCRT.sprintf>]    ; msvcrt.sprintf
003E14A4    8DBC24 84040000 lea edi,dword ptr ss:
003E14AB    83C9 FF         or ecx,-0x1
003E14AE    33C0            xor eax,eax
003E14B0    83C4 0C         add esp,0xC
003E14B3    F2:AE         repne scas byte ptr es:
003E14B5    F7D1            not ecx
003E14B7    2BF9            sub edi,ecx
003E14B9    8D5424 78       lea edx,dword ptr ss:
003E14BD    8BF7            mov esi,edi
003E14BF    8BFA            mov edi,edx
003E14C1    8BD1            mov edx,ecx
003E14C3    83C9 FF         or ecx,-0x1
003E14C6    F2:AE         repne scas byte ptr es:
003E14C8    8BCA            mov ecx,edx
003E14CA    4F            dec edi
003E14CB    C1E9 02         shr ecx,0x2
003E14CE    F3:A5         rep movs dword ptr es:,dword ptr ds>
003E14D0    8BCA            mov ecx,edx
003E14D2    83C3 04         add ebx,0x4
003E14D5    83E1 03         and ecx,0x3
003E14D8    4D            dec ebp
003E14D9    F3:A4         rep movs byte ptr es:,byte ptr ds:[>
003E14DB^ 75 B1         jnz short hd06.003E148E
003E14DD    8D4424 78       lea eax,dword ptr ss:
003E14E1    50            push eax
003E14E2    FF15 34213E00   call dword ptr ds:[<&MSVCRT._strupr>]    ; strupr转为大写
003E14E8    8D7C24 7C       lea edi,dword ptr ss:
003E14EC    83C9 FF         or ecx,-0x1
003E14EF    33C0            xor eax,eax
003E14F1    83C4 04         add esp,0x4
003E14F4    F2:AE         repne scas byte ptr es:
003E14F6    8BB424 80080000 mov esi,dword ptr ss:
003E14FD    F7D1            not ecx
003E14FF    49            dec ecx
003E1500    8BFE            mov edi,esi
003E1502    88440C 77       mov byte ptr ss:,al
003E1506    83C9 FF         or ecx,-0x1
003E1509    F2:AE         repne scas byte ptr es:
003E150B    F7D1            not ecx
003E150D    49            dec ecx
003E150E    8D7C24 78       lea edi,dword ptr ss:
003E1512    8BD1            mov edx,ecx
003E1514    83C9 FF         or ecx,-0x1
003E1517    F2:AE         repne scas byte ptr es:
003E1519    F7D1            not ecx
003E151B    49            dec ecx
003E151C    3BCA            cmp ecx,edx
003E151E    75 37         jnz short hd06.003E1557
003E1520    33FF            xor edi,edi
003E1522    33ED            xor ebp,ebp
003E1524    85D2            test edx,edx
003E1526    7E 1B         jle short hd06.003E1543
003E1528    8D4C24 78       lea ecx,dword ptr ss:
003E152C    8BC6            mov eax,esi
003E152E    2BCE            sub ecx,esi
003E1530    8BF2            mov esi,edx
003E1532    33D2            xor edx,edx
003E1534    8A1401          mov dl,byte ptr ds:
003E1537    03FA            add edi,edx
003E1539    33D2            xor edx,edx
003E153B    8A10            mov dl,byte ptr ds:
003E153D    03EA            add ebp,edx
003E153F    40            inc eax
003E1540    4E            dec esi
003E1541^ 75 EF         jnz short hd06.003E1532
003E1543    33C0            xor eax,eax
003E1545    3BFD            cmp edi,ebp
003E1547    5F            pop edi                                  ; 0012FABC
003E1548    5E            pop esi                                  ; 0012FABC
003E1549    5D            pop ebp                                  ; 0012FABC
003E154A    5B            pop ebx                                  ; 0012FABC
003E154B    0F94C0          sete al
003E154E    81C4 68080000   add esp,0x868
003E1554    C2 0800         retn 0x8
003E1557    5F            pop edi                                  ; 0012FABC
003E1558    5E            pop esi                                  ; 0012FABC
003E1559    5D            pop ebp                                  ; 0012FABC
003E155A    33C0            xor eax,eax
003E155C    5B            pop ebx                                  ; 0012FABC
003E155D    81C4 68080000   add esp,0x868
003E1563    C2 0800         retn 0x8



这里总结下,注册码主要利用注册名和注册码的前八位作为钥匙与自身所带的数据异或生成各组注册码。没有涉及到复杂的大型加解密算法


附注册机源码一份,需要的自行编译(本机win10 64 1709+VS2015编译成功)(代码写的烂)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


unsigned char data = {
        0x04, 0xC4, 0x6B, 0xAA, 0x1E, 0xC6, 0x7F, 0x4E, 0xA6, 0x1A, 0xBA, 0xE9, 0x9B, 0x20, 0x1B, 0x67,
        0xDA, 0xA6, 0xA9, 0x62, 0x46, 0x75, 0x33, 0x43, 0xA2, 0xAA, 0x3E, 0xFC, 0x15, 0xBE, 0x78, 0xF2,
        0xC0, 0xB9, 0x17, 0xC4, 0x63, 0x68, 0x3F, 0x49, 0xA7, 0xCC, 0xBE, 0xC8, 0xF2, 0x17, 0x83, 0x9C,
        0x3B, 0xD0, 0xA3, 0x5D, 0x4E, 0x13, 0x3A, 0x4D, 0xBA, 0x2B, 0x91, 0xDA, 0xEA, 0x73, 0x3B, 0xC1,
        0xD9, 0x8C, 0x73, 0xC6, 0x1B, 0x9D, 0x25, 0x48, 0x9B, 0xFE, 0xC1, 0x57, 0x9A, 0xCB, 0xE4, 0x74 };


int main()
{
        char szName;
        char szCode;
        printf("输入注册名:");
        scanf("%s", szName);
        getchar();
        printf("输入注册码前八位:");
        scanf("%s", szCode);
        getchar();

        int calcA=0, calcB = 0;
        int nlen = strlen(szName);
        for (int i = 0; i < nlen; i++)
        {
                calcB += szName;
                calcB &= 0xff;
                calcA += calcB;
        }
        int nCode = strtol(szCode, NULL, 16);
        int eax, ebx, ecx, edx;
        int outA, outB, outC, outD;
        ebx = nCode + calcA;
        eax = calcB + nCode + szName;
        eax += ebx;
        edx = (eax % 5)<<4;
        int nBase = edx;
        memcpy(&edx, &data, 4);
        memcpy(&ecx,&data, 4);
        edx ^= ebx;
        ecx ^= ebx;
        outA = edx;
        outB = ecx;
        memcpy(&edx, &data, 4);
        memcpy(&eax, &data, 4);
        eax ^= ebx;
        outD = eax;
        edx ^= ebx;
        outC = edx;
        sprintf(szCode,"%8x-%8x-%8x-%8x-%8x", nCode, outA, outB, outC, outD);
        strupr(szCode);
        printf("注册码:%s\n", szCode);
        getchar();
        return 0;
}

最后附一张成功的图



最后的最后,先感谢小赵大神的帖子为我指引方向,找到的最关键的算法call(跪求小赵大神别打我)。
真的是好长时间没做逆向了,最开始算法看的一脸懵逼,后来静下心来慢慢看才有所收获。


真·最后,如果觉得此贴对你有帮助,请给我评个分,评分不减自己的分数。如果有什么疑问或者本贴所述有错误,还请各位回帖指出,谢谢。

苏紫方璇 发表于 2018-1-23 10:49

wt547788 发表于 2018-1-23 00:03
膜拜大佬,大佬想个办法把文库弄一弄,看看有没有办法能查阅完整版需要付费的资料。

这个我不会{:1_925:}

610100 发表于 2018-1-22 14:52

膜拜大神,膜拜会分析算法的。
好厉害啊!

wushaominkk 发表于 2018-1-22 14:53

这么多勋章亮瞎了我的眼,感谢楼主分享!

Ps出来的小赵 发表于 2018-1-22 15:06

我要抱大腿……根部……

byh3025 发表于 2018-1-22 15:13

算法分析的真的很详细

zjls9933 发表于 2018-1-22 15:40

膜拜大神,膜拜会分析算法的。
好厉害啊!

rsgdxp 发表于 2018-1-22 17:14

感谢分享 。。。。。。。。。。。。。。

sscld 发表于 2018-1-22 17:30

感谢楼主分享。。。。

tianya0908 发表于 2018-1-22 20:39

谢谢楼主分享

linuxprobe 发表于 2018-1-22 23:57

代码太多了,没有耐心慢慢看。
页: [1] 2
查看完整版本: 无聊逆算法-易我分区表医生3.0