某应用的加解密

   这是某个应用检测程序中提出的 “解密” 函数,既然知道了 “解密” 推断出加密就不是太大的问题;本文不附加 “加密” 过程各位有兴趣可以自己私聊慢慢琢磨;

   这是某个0应用中的 license 文件解密用到的函数,具体是什么我本人也不是很清楚,反正当时正好有那么一点点的小小的兴趣,有点小意思搞一搞它的攻破实现【你应该在相隔很长的时间后,随便网上找一套应用拿来搞,练手恢复熟练度,不然的话到时候各种遗忘就会有那么一点点的尴尬】,哪个应用具有几层不同的保护。

   不要老想着干坏事,你看搞安全的有那么一帮大佬天天去攻击别个的网站或系统,大佬们也没干什么坏事还好心的提醒对方你该怎么做怎么做,但是我们玩这个东西是为了什么?是为了能够在系统做瀑布设计的时候能够尽量的考虑这些方方面面的问题,减少我方系统被恶意攻破的可能,如果你连别人怎么搞你的都不知道,你说你的系统一定能够防护这不是纯扯淡吗?装逼还是要有限度的,最讨厌讨厌装逼侠了,光嘴上嚎叫着理论谁不会啊,但,那,还要你何用?

技术难点

    1:加密狗(obj or static_lib 静态LINK到程序的)【攻破替换DLL是不可能的】(而且还没有U狗【牌子、型号一概不知】)

    2:多个许可文件都采取不同的加密,例:A license / DES+ECB 加解密用 DOG序列号的INT的字符串形式做KEY加解密

    ...

    这倒不是说攻破上会有多麻烦,只是有点让人蛋疼,但是本人似乎发现了一个小小的秘密~哟,几年前我娱乐的琢磨弄了一个“应用”的攻破实验,里面的加解密算法居然跟下面的代码差不多,我突然在想是不是一个程序猿换了公司,唯一的区别是从C#换成了C/C++;这或许就叫做一种缘分吧!我突然莫名其妙的有股忍俊不禁的笑意~~~~!

    ...

解决方案

    1、它上狗我打狗

    2、它解密我逆向推演加密

    ...(是不是有点快意恩仇,践行江湖的赶脚)

    在逆向它那部分解密代码的时候,其实我的内心是各种抗拒的;因为我想你就不能写一个循环,你看你这个代码多冗余?当时我的内心活动是写这串代码的 “程序员” 到底有多菜多水水?但是转过来一想,技术人员都是很懒的,而且还是玩 C/C++ 的应该不至于这么的水水,所以或许就是 “矛与盾” 之间的关系,虽然它或许不懂得更好的防护方法,但是写这类的 “人工插花插绿” 代码,足够让逆向的人内心煎熬~!这或许是一种不错且有效的笨办法。

    ...

    这个应用暴露了很多问题 若应用的提供方能够进行合理的保护 相信我并不会那么就轻易的直捣黄龙;例它在应用中留下太多显要可以定位需攻破的代码的大致区域,显然这已造成了纵然 “static link” 的加密狗的代码被 “强行打掉” 的风险变得逐渐加剧【这加密狗 “static link” 的代码技术秀的不行不行的,例:不用JMP 用 “PUSH X RET; JMP”,真的有那么一点点的秀~,!】...       ...

   本文不是让你搞破解只是本人随便的摆摆没啥别的意思,这东西不神奇也不神秘虽然看上去很 geek 但是比起做 “架构/框架” 我个体还是喜欢做 “架构/框架”~~~!!

   ...

    遇到与上述汇编代相同部分就可以确定是这种类型的狗了,你可以参考上面上张图的攻破办法打掉狗【而且足够足够可靠,你只需要设置返回值就可以了,注意一点:你一旦按上述的方法打掉狗,那么加密狗的序列号就永远都是0】,另外一点前提是它是进行了 “obj or static_lib” 静态LINK编译的同时一定是这个狗才有效的。

CPU Disasm
地址        十六进制数据            指令                                       注释
011410BE  |>  53            PUSH EBX
011410BF  |.  8B1D C4001501 MOV EBX,DWORD PTR DS:[<&MSVCR90.fgets>]
011410C5  |.  55            PUSH EBP
011410C6  |.  8D4424 30     LEA EAX,[ESP+30]
011410CA  |.  6A 64         PUSH 64
011410CC  |.  50            PUSH EAX
011410CD  |.  FFD3          CALL EBX
011410CF  |.  83C4 0C       ADD ESP,0C
011410D2  |.  85C0          TEST EAX,EAX
011410D4  |.- 74 24         JZ SHORT 011410FA
011410D6  |.  8D7C24 2C     LEA EDI,[ESP+2C]
011410DA  |.  8D9B 00000000 LEA EBX,[EBX]
011410E0  |>  46            /INC ESI
011410E1  |.  83C7 64       |ADD EDI,64
011410E4  |.  83FE 2A       |CMP ESI,2A
011410E7  |.  55            |PUSH EBP
011410E8  |.- 7F 3D         |JG SHORT 01141127
011410EA  |.  6A 64         |PUSH 64
011410EC  |.  57            |PUSH EDI
011410ED  |.  FFD3          |CALL EBX
011410EF  |.  83C4 0C       |ADD ESP,0C
011410F2  |.  85C0          |TEST EAX,EAX
011410F4  |.- 75 EA         \JNZ SHORT 011410E0
011410F6  |.  8B7C24 14     MOV EDI,DWORD PTR SS:[ESP+14]
011410FA  |>  55            PUSH EBP
011410FB  |.  FF15 AC001501 CALL DWORD PTR DS:[<&MSVCR90.fclose>]
01141101  |.  83C4 04       ADD ESP,4
01141104  |.  83FE 2A       CMP ESI,2A
01141107  |.- 7D 2E         JGE SHORT 01141137
01141109  |.  B8 04000000   MOV EAX,4
0114110E  |>  5B            POP EBX
0114110F  |.  5D            POP EBP
01141110  |.  5F            POP EDI
01141111  |.  5E            POP ESI
01141112  |.  8B8C24 A41300 MOV ECX,DWORD PTR SS:[ESP+13A4]
01141119  |.  33CC          XOR ECX,ESP
0114111B  |.  E8 1EE00000   CALL 0114F13E
01141120  |.  81C4 A8130000 ADD ESP,13A8
01141126  |.  C3            RETN
01141127  |>  FF15 AC001501 CALL DWORD PTR DS:[<&MSVCR90.fclose>]
0114112D  |.  83C4 04       ADD ESP,4
01141130  |.  B8 03000000   MOV EAX,3
01141135  |.- EB D7         JMP SHORT 0114110E
01141137  |>  0FB68C24 7F08 MOVZX ECX,BYTE PTR SS:[ESP+87F]
0114113F  |.  0FB69424 8008 MOVZX EDX,BYTE PTR SS:[ESP+880]
01141147  |.  0FB68424 8108 MOVZX EAX,BYTE PTR SS:[ESP+881]
0114114F  |.  8B35 B0001501 MOV ESI,DWORD PTR DS:[<&MSVCR90.atol>]
01141155  |.  80E9 14       SUB CL,14
01141158  |.  884C24 1C     MOV BYTE PTR SS:[ESP+1C],CL
0114115C  |.  0FB68C24 8208 MOVZX ECX,BYTE PTR SS:[ESP+882]
01141164  |.  80EA 14       SUB DL,14
01141167  |.  2C 14         SUB AL,14
01141169  |.  885424 1D     MOV BYTE PTR SS:[ESP+1D],DL
0114116D  |.  0FB69424 8308 MOVZX EDX,BYTE PTR SS:[ESP+883]
01141175  |.  884424 1E     MOV BYTE PTR SS:[ESP+1E],AL
01141179  |.  0FB68424 8408 MOVZX EAX,BYTE PTR SS:[ESP+884]
01141181  |.  80E9 14       SUB CL,14
01141184  |.  884C24 1F     MOV BYTE PTR SS:[ESP+1F],CL
01141188  |.  0FB68C24 8508 MOVZX ECX,BYTE PTR SS:[ESP+885]
01141190  |.  80EA 14       SUB DL,14
01141193  |.  2C 14         SUB AL,14
01141195  |.  885424 20     MOV BYTE PTR SS:[ESP+20],DL
01141199  |.  0FB69424 8608 MOVZX EDX,BYTE PTR SS:[ESP+886]
011411A1  |.  884424 21     MOV BYTE PTR SS:[ESP+21],AL
011411A5  |.  0FB68424 8708 MOVZX EAX,BYTE PTR SS:[ESP+887]
011411AD  |.  80E9 14       SUB CL,14
011411B0  |.  884C24 22     MOV BYTE PTR SS:[ESP+22],CL
011411B4  |.  8D4C24 1C     LEA ECX,[ESP+1C]
011411B8  |.  80EA 14       SUB DL,14
011411BB  |.  2C 14         SUB AL,14
011411BD  |.  51            PUSH ECX
011411BE  |.  885424 27     MOV BYTE PTR SS:[ESP+27],DL
011411C2  |.  884424 28     MOV BYTE PTR SS:[ESP+28],AL
011411C6  |.  C64424 29 00  MOV BYTE PTR SS:[ESP+29],0
011411CB  |.  FFD6          CALL ESI
011411CD  |.  0FB69424 8C08 MOVZX EDX,BYTE PTR SS:[ESP+88C]
011411D5  |.  0FB68C24 8E08 MOVZX ECX,BYTE PTR SS:[ESP+88E]
011411DD  |.  8907          MOV DWORD PTR DS:[EDI],EAX
011411DF  |.  0FB68424 8D08 MOVZX EAX,BYTE PTR SS:[ESP+88D]
011411E7  |.  80EA 14       SUB DL,14
011411EA  |.  885424 20     MOV BYTE PTR SS:[ESP+20],DL
011411EE  |.  0FB69424 8F08 MOVZX EDX,BYTE PTR SS:[ESP+88F]
011411F6  |.  2C 14         SUB AL,14
011411F8  |.  884424 21     MOV BYTE PTR SS:[ESP+21],AL
011411FC  |.  8D4424 20     LEA EAX,[ESP+20]
01141200  |.  80E9 14       SUB CL,14
01141203  |.  80EA 14       SUB DL,14
01141206  |.  50            PUSH EAX
01141207  |.  884C24 26     MOV BYTE PTR SS:[ESP+26],CL
0114120B  |.  885424 27     MOV BYTE PTR SS:[ESP+27],DL
0114120F  |.  C64424 28 00  MOV BYTE PTR SS:[ESP+28],0
01141214  |.  FFD6          CALL ESI
01141216  |.  8B4C24 20     MOV ECX,DWORD PTR SS:[ESP+20]
0114121A  |.  0FB69424 9408 MOVZX EDX,BYTE PTR SS:[ESP+894]
01141222  |.  8901          MOV DWORD PTR DS:[ECX],EAX
01141224  |.  0FB68424 9508 MOVZX EAX,BYTE PTR SS:[ESP+895]
0114122C  |.  0FB68C24 9608 MOVZX ECX,BYTE PTR SS:[ESP+896]
01141234  |.  80EA 14       SUB DL,14
01141237  |.  2C 14         SUB AL,14
01141239  |.  885424 24     MOV BYTE PTR SS:[ESP+24],DL
0114123D  |.  0FB69424 9708 MOVZX EDX,BYTE PTR SS:[ESP+897]
01141245  |.  884424 25     MOV BYTE PTR SS:[ESP+25],AL
01141249  |.  0FB68424 9808 MOVZX EAX,BYTE PTR SS:[ESP+898]
01141251  |.  80E9 14       SUB CL,14
01141254  |.  884C24 26     MOV BYTE PTR SS:[ESP+26],CL
01141258  |.  8D4C24 24     LEA ECX,[ESP+24]
0114125C  |.  80EA 14       SUB DL,14
0114125F  |.  2C 14         SUB AL,14
01141261  |.  51            PUSH ECX
01141262  |.  885424 2B     MOV BYTE PTR SS:[ESP+2B],DL
01141266  |.  884424 2C     MOV BYTE PTR SS:[ESP+2C],AL
0114126A  |.  C64424 2D 00  MOV BYTE PTR SS:[ESP+2D],0
0114126F  |.  FFD6          CALL ESI
01141271  |.  8B5424 1C     MOV EDX,DWORD PTR SS:[ESP+1C]
01141275  |.  83C4 0C       ADD ESP,0C
01141278  |.  8902          MOV DWORD PTR DS:[EDX],EAX
0114127A  |.  33C0          XOR EAX,EAX
0114127C  |.- E9 8DFEFFFF   JMP 0114110E
01141281  |>  8B8C24 AC1300 MOV ECX,DWORD PTR SS:[ESP+13AC]
01141288  |.  5F            POP EDI
01141289  |.  5E            POP ESI
0114128A  |.  33CC          XOR ECX,ESP
0114128C  |.  B8 01000000   MOV EAX,1
01141291  |.  E8 A8DE0000   CALL 0114F13E
01141296  |.  81C4 A8130000 ADD ESP,13A8
0114129C  \.  C3            RETN 

   上述代码是摘要出的调用解密的函数的部分表明了从调用 fgets 函数读取所有的字符串,后续是怎么进行解密的,而且让人有些遗憾的是它把从license 文件中读入的数据全部拷贝到了函数栈上面。

#pragma once

#include <vector>
#include <string>
#include <iostream>
#include <malloc.h>

int flen(FILE* file)
{
    fseek(file, 0, SEEK_END);
    return ftell(file);
}

typedef unsigned char byte;

int BCIL_asm_procedure()

    // ESP = 00A1E824
    char serialnum[] = "0912409360"; 
    char usercount[] = "0100";
    char totaltime[] = "02460";

    byte esp_87f = 'D';
    byte esp_880 = 'M';
    byte esp_881 = 'E';

    byte esp_882 = 'F';
    byte esp_883 = 'H';
    byte esp_884 = 'D';
    byte esp_885 = 'M';
    byte esp_886 = 'G';
    byte esp_887 = 'J';

    byte esp_1c;
    byte esp_1d;
    byte esp_1e;
    byte esp_1f;
    byte esp_20;
    byte esp_21;
    byte esp_22;
    byte esp_27;
    byte esp_28;
    byte esp_29;

    int ds_edi;
    _asm // DEMJHDM
    { // 10+1
        mov ecx,dword ptr[esp_87f]
        mov edx,dword ptr[esp_880]
        mov eax,dword ptr[esp_881]
        mov esi,dword ptr[atol] 
        sub    cl,14h 
        mov byte ptr[esp_1c],cl
        mov ecx,dword ptr[esp_882]
        sub dl,14h
        sub al,14h
        mov byte ptr[esp_1d],dl
        mov edx,dword ptr[esp_883]
        mov byte ptr[esp_1e],al
        mov eax,dword ptr[esp_884]
        sub cl,14h
        mov byte ptr[esp_1f],cl
        mov ecx,dword ptr[esp_885]
        sub dl,14h
        sub al,14h
        mov byte ptr[esp_20],dl
        mov edx,dword ptr[esp_886]
        mov byte ptr[esp_21],al
        mov eax,dword ptr[esp_887]
        sub cl,14h
        mov byte ptr[esp_22],cl
        //
        lea ecx,dword ptr[serialnum]// dword ptr[esp_1c]
        sub dl,14h
        sub al,14h
        push ecx // 栈扩大32bit(填充位置从 esp_23 扩展到 esp_27)
        mov byte ptr[esp_27],dl
        mov byte ptr[esp_28],al
        mov byte ptr[esp_29],'\0' // NULL字占位符
        // 调用atoi函数,这里push进入的
        call esi // call atoi(dword ptr[esp+1c])
    }
    byte esp_88c = 'D';
    byte esp_88d = 'E';
    byte esp_88e = 'D';
    byte esp_88f = 'D';

    byte esp_26;
    _asm // 4+1
    {
        mov edx,dword ptr[esp_88c]
        mov ecx,dword ptr[esp_88e]
        mov dword ptr[ds_edi], eax
        mov eax,dword ptr[esp_88d]
        sub dl,14h
        mov byte ptr[esp_20], dl
        mov edx,dword ptr[esp_88f]
        sub al,14h
        mov byte ptr[esp_21],al
        lea eax,dword ptr[usercount] // dword ptr[esp_20]
        sub cl,14h
        sub dl,14h
        push eax // [esp+20]
        mov byte ptr[esp_26],cl 
        mov byte ptr[esp_27],dl
        mov byte ptr[esp_28],'\0'
        call esi // call atoi(dword ptr[esp_20])
    }
    byte esp_894 = 'D';
    byte esp_895 = 'F';
    byte esp_896 = 'H';
    byte esp_897 = 'J';
    byte esp_898 = 'D';

    byte esp_24;
    byte esp_25;
    byte esp_2b;
    byte esp_2c;
    byte esp_2d;

    int ds_ecx;
    _asm // 用户时间
    { // 5+1
        mov ecx,dword ptr[esp_20]
        mov edx,dword ptr[esp_894]
        mov dword ptr[ds_ecx],eax // 
        mov eax,dword ptr[esp_895]
        mov ecx,dword ptr[esp_896]
        sub dl,14h
        sub al,14h
        mov byte ptr[esp_24],dl
        mov edx,dword ptr[esp_887]
        mov byte ptr[esp_25],al
        mov eax,dword ptr[esp_898]
        sub cl,14h
        mov byte ptr[esp_26],cl
        lea ecx,dword ptr[totaltime]// dword ptr[esp_24]
        sub dl,14h
        sub al,14h
        push ecx
        mov byte ptr[esp_2b],dl
        mov byte ptr[esp_2c],al
        mov byte ptr[esp_2d],'\0'
        call esi
    }
}

#define CIPHERDIFFVALKEY 0x14

int BCIL_clang_procedure(const char* serialnum, const char* usernum, const char* totaltime)
{
    char buf[11]; 
    auto parse = [&buf](const char* p, int len) -> bool 
    {
        if (!p && len <= 0)
        {
            return false;
        }
        buf[len] = '\0';
        for (int i = 0; i < len; i++)
        {
            char asc = p[i];
            if (asc != '\0')
            {
                asc -= CIPHERDIFFVALKEY;
            }
            buf[i] = asc;
        }
        return true;
    };
    if (parse(serialnum, 10)) 
    {
        printf("序列号:%s\n", buf);
    }
    buf[0] = (usernum[0] - CIPHERDIFFVALKEY); // esp+88c = dl
    buf[1] = (usernum[1] - CIPHERDIFFVALKEY); // esp+88d = al
    buf[2] = (usernum[2] - CIPHERDIFFVALKEY); // esp+88e = cl
    buf[3] = (usernum[3] - CIPHERDIFFVALKEY); // esp+88f = dl_2
    buf[4] = '\0';
    printf("用户数:%s\n", buf);
    if (parse(totaltime, 5))
    {
        printf("有效时间:%s\n", buf);
    }
    return 0;
}

int main(int argc, char* argv[])
{
    BCIL_clang_procedure("DMEFHDMGJD", "DEDD", "DFHJD");
    return getchar();
}

猜你喜欢

转载自blog.csdn.net/liulilittle/article/details/82344148