影子系统激活算法初步 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

    By 小飞 lankerr

    废话少说,直入主题,

影子系统激活算法初步

    主程序将输入的激活码发送到驱动中验证,强行修改返回值是不起作用的。

    用OD载入PowerMaster.exe,程序用了三种花指令来隐藏对DeviceIoControl调用,其间还有四次异常处理,两次为单步来反调试器,只要去下个StrongOD.dll,即OD的插件就可以躲过检查。外壳程序调用DeviceIoControl时,ControlCode为7C320,InBuff中为输入的注册码,长度为0x1E即30个字符(必须是大写),不过我们在输入的是如:123456789F-123456789L-123456789Y程序会将中间的’-‘号删除,然后到驱动SnpShot.sys中验证。OD是不能跟踪到系统内核的,要用SoftIce(开始我走了弯路,我用Wdasm来反汇编SnpShot.sys找不到IRP分派,用SoftIce跟踪DeviceIoControl的调用才到SnpShot.sys中,后来学用IDA时,反汇编才看到了IRP分派情况)。

    真正进入主题,驱动中怎么验证计算激活码?

    分两步

    一、 将激活码用‘查表法’求模得到一个串。

    二、 将上面的串用一加密算法得出一加密串,然后与一长为0x10的串比较,相等则激活成功。

    那么我们先说怎样用‘查表法’得出这个串。

    a:如下图,我们输入下图这个串“123456789F123456789L123456789Y”

    b:用到的表为

    CString   GhostKey="D54X379EPJWCYKN1TUFH82VABLSM6QGR"; //查表用到的表,共32个字符

    方式为依为返回激活码每个字符在上表中的序数,如1的序数为15,F的序数为21。

    C代码:

    //=========================================

    //

    //   查表法返回相应字符的序号

    //

    //=========================================

    int CMy2008Dlg::ScanKeyTable(char T)

    {

    int   i=0;

    for(i=0;i<32;i++)

    {

    if(T == GhostKey.GetAt(i))

    return i;

    }

    return 0;

    }

    c:将上面返回的值,进行5次循环,求余数,返回‘0’或‘1’,作为下一函数的参数。在这我没用C代码,因为IDIV指令好像没有用C来表示的,还有位移指如rol等也不能C来表示….,函数名之所以叫BB0Mod,是因为在驱动中这个Function地址后三位是BB0

    int CMy2008Dlg::BB0Mod(int iii, int sn)

    {

    __asm

    {

    cdq

    mov eax,iii

    mov ecx,8

    idiv ecx

    mov ecx,edx

    mov dl,1

    shl dl,cl

    mov eax,sn

    and dl,al

    neg dl

    sbb edx,edx

    neg edx

    mov iii,edx

    }

    return iii;

    }

    d:将循环次数对8求余,根据上面的返回值‘1’或‘0’决定是‘与’或是‘或’操作。这里要用到一新字串:

    unsigned char XorKey[56]="x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"

    "x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00";长度不需要这么长的,我测试用多写了。

    void CMy2008Dlg::DDEMod(int KeySnMod, int kkk)

    {

    __asm

    {

    mov eax,kkk

    cdq

    push 8

    pop  ecx

    idiv ecx

    mov ebx,1

    mov ecx,edx

    shl bl,cl

    lea ecx,XorKey

    add eax,ecx

    cmp KeySnMod,0

    jz  AndByte

    or  [eax],bl

    jmp DDEmodReturn

    AndByte:

    not bl

    and [eax],bl

    DDEmodReturn:

    }

    return;

    }

    查表和以及上面两个函数调用情况如下:

    For(int j=0;j<30;j++)

    {

    :ScanKeyTable(char T);

    For(int i=0;i<5;i++)

    {

    BB0Mod(int iii, int sn);

    DDEMod(int KeySnMod, int kkk);

    }

    }

    e:上面执行结束后,情况如下图

    }

    激活码”123456789F123456789L123456789Y”生成”AF 12 11 78 A1 46 BE 4A E0 85 9A FC 11 81”,这所以后面的计算,是因为下面的操作会将81后面的字符填为0,可能是不纳入计算(事实上好像是只计算0x10长度大小),

电脑资料

影子系统激活算法初步》(http://meiwen.anslib.com)。速个调用如下:

    void CMy2008Dlg::OnCalc()

    {

    UpdateData(TRUE);

    CString showMsg;

    CString ActiveKey;

    ActiveKey=m_Key1+m_Key2+m_Key3;

    int   KeySn=0;

    int   KeySnMod=0;

    int   kkk=0;

    CString temp;

    for(int j=0;j<30;j++)

    {

    KeySn = ScanKeyTable(ActiveKey.GetAt(j));

    temp.Format("%02d  ",KeySn);

    showMsg+=temp;

    for(int j=0;j<5;j++)

    {

    //     __asm int 3

    KeySnMod = BB0Mod(j,KeySn);

    DDEMod(KeySnMod,kkk);

    kkk++;

    temp.Format("%d ",KeySnMod);

    showMsg+=temp;

    }

    temp.Format("",KeySn,KeySnMod);

    showMsg+=temp;

    }

    // showMsg.Format("%s,字串长:%d",ActiveKey,GhostKey.GetLength());

    ::MessageBox(NULL,showMsg,"显示字符",0x1040);

    char showBuff[512];

    ::wsprintf(showBuff,"%02X %02X %02X %02X %02X %02X %02X %02X-%02X %02X %02X %02X %02X %02X %02X %02X

    %02X %02X %02X %02X %02X %02X %02X %02X",

    XorKey[0],XorKey[1],

    XorKey[2],XorKey[3],

    XorKey[4],XorKey[5],

    XorKey[6],XorKey[7],

    XorKey[8],XorKey[9],

    XorKey[10],XorKey[11],

    XorKey[12],XorKey[13],

    XorKey[14],XorKey[15],

    XorKey[16],XorKey[17],

    XorKey[18],XorKey[19],

    XorKey[20],XorKey[21],

    XorKey[22],XorKey[23]);

    ::MessageBox(NULL,showBuff,"显示Xor字符",0x1040);

    }

    以上完了成第一步了。到这有一些想法:

    一、 影子系统2008在互联网上至今没注册机,全是修改SYS驱动文件达到激活目的,可能是不能做出注册机,或是通用性差。

    二、 激活码经过一系列变化,再和指写的内容比较,如不想修改SYS文件,好像只能穷举。用密码工具扫描这个SYS文件时,提示是MD5,经以分析加密函数,发现只是大量的进位乘计算,将结果用于新的计算,进行32循环,看样不是MD5。除非知道用于比较的内存串计算方法,否则还是只能穷举。

    三、 ……很多

最新文章