• 标 题:Installshield5.0反编译破解软件安装序列号一例 (14千字)
  • 作 者:smartsl
  • 时 间:2002-10-21 21:36:27
  • 链 接:http://bbs.pediy.com

工具:ISDCC v2.10(Modified)
破解者:smartsl
时间:2002-10-21
软件:XXXXXX管理系统 2000

首先,在安装目录找到一个setup.ins文件,用原版的isdcc21.exe反编译出错,提示
!!!!Unknown opcode (0x168) at (0xD0D)
幸好这个isdcc的作者提供有源码,找到decode.c里面有这行:
    if (decodeTable[opcode] == NULL)
      error("\n!!!!Unknown opcode (0x%x) at (0x%x)\n", opcode, tell(fd));
再看看decodetable.h这个文件,里面很多类似下面的定义:
static char* rawDecodeTable[][4] = {
......
{(char*) 0x0068, "PlaceWindow", (char*) 4, (char*) (*parseSystemFunction)},
......
};
搜索一下发现没有0x0168的定义,不管它,加上一行,后面的参数个数只好慢慢试,直到不出错为止,试出来应该是3个参数。
同样,需要再加一个0x0167的定义,参数个数也是3。
这样,就可以正常反编译了。
因为不知道这两个函数名,暂时定为:
{(char*) 0x0168, "UnknowFunction_1", (char*) 3, (char*) (*parseSystemFunction)},
{(char*) 0x0167, "UnknowFunction_2", (char*) 3, (char*) (*parseSystemFunction)},


反编译后大体浏览一下,很多lNumberXX、lStringXX的临时变量,因为这个基本是按顺序执行的,而这个软件安装出现license提示后马上就要输入序号,否则弹出提示框,不向下继续安装。所以在前面就能找到如下关键点:

004E58:015D:        SilentReadData(string1, "szName", 1, pString2, lNumber3);
004E71:015D:        SilentReadData(string1, "szCompany", 1, pString3, lNumber3);
004E8D:015D:        SilentReadData(string1, "szSerial", 1, pString4, lNumber3);

这段在function1()里面,function1()在function103()里面,如下:
    // ------------- FUNCTION function103 --------------
    function function103()
        number lNumber0;
        string lString0;
        string lString1;
    begin
002872:0013:        string4 = "";
00287A:0013:        string5 = "";
002882:0013:        lString0 = "";
00288A:0013:        lString1 = "";
002892:00B5:        function1(lString0, lString1, string4, string5, string6);
0028A9:0021:        lNumber0 = LAST_RESULT;
0028B1:012F:        return(lNumber0);
0028B8:00B8:        return;
    end;

function103()又在function89()里面,这回发现找到地方了,下面列出关键的一段:
这段完整的程序是:
    // ------------- FUNCTION function89 --------------
    function function89()
        number lNumber0;
        number lNumber1;
        number lNumber2;
        number lNumber3;
        number lNumber4;
        number lNumber5;
        number lNumber6;
        number lNumber7;
        number lNumber8;
        number lNumber9;
        string lString0;
        string lString1;
        string lString2;
        string lString3;
        string lString4;
        string lString5;
        string lString6;
        string lString7;
        string lString8;
        string lString9;
    begin
001143:0021:        lNumber5 = 0;

label17: //Ref: 001181  0011BA 
001151:00B5:        function100();
001159:0021:        lNumber0 = LAST_RESULT;
001161:0128:        lNumber8 = lNumber0 = 12;
001173:0022:        if (lNumber8 = 0) then
                        goto label18;
                    endif;
001181:002C:        goto label17;

label18: //Ref: 001173  001275 
00118A:00B5:        function101();                    ;显示"license.txt"
001192:0021:        lNumber0 = LAST_RESULT;
00119A:0128:        lNumber8 = lNumber0 = 12;
0011AC:0022:        if (lNumber8 = 0) then
                        goto label19;
                    endif;
0011BA:002C:        goto label17;

label19: //Ref: 0011AC 
0011C3:0021:        number49 = 0;
0011CD:0021:        number42 = 0;

label20: //Ref: 0012C2  00132C  0013DA  00161C  001682 
0011DB:0022:        if (number42 = 0) then
                        goto label21;
                    endif;
0011E9:002A:        MessageBox("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff!", -65534);

label21: //Ref: 0011DB 
00120E:0128:        lNumber8 = number49 > 3;
001220:0022:        if (lNumber8 = 0) then
                        goto label22;
                    endif;
00122E:012F:        return(-1);

label22: //Ref: 001220 
00123B:00B5:        function103();
001243:0021:        lNumber0 = LAST_RESULT;
00124B:0128:        lNumber8 = lNumber0 = 12;
00125D:0022:        if (lNumber8 = 0) then
                        goto label23;                    ;按"继续"按钮就跳
                    endif;
00126B:0021:        number42 = 1;
001275:002C:        goto label18;

label23: //Ref: 00125D 
00127E:0119:        number49 = number49 + 1;
00128B:002F:        StrLength(string6);                ;序列号长度
001290:0021:        lNumber8 = LAST_RESULT;
001298:0128:        lNumber8 = lNumber8 != 14;                ;长度不是14位
0012AA:0022:        if (lNumber8 = 0) then
                        goto label24;                    ;为假则跳(长度就是14位)
                    endif;
0012B8:0021:        number42 = 1;
0012C2:002C:        goto label20;

label24: //Ref: 0012AA 
0012CB:007A:        GetByte(lNumber8, string6, 0);            ;取序列号第1位
0012D8:0128:        lNumber8 = lNumber8 != 56;                ;56='8'
0012EA:007A:        GetByte(lNumber9, string6, 1);            ;取序列号第2位
0012F7:0128:        lNumber9 = lNumber9 != 45;                ;45='-'
001309:0126:        lNumber8 = lNumber8 || lNumber9;
001314:0022:        if (lNumber8 = 0) then
                        goto label25;                    ;为假则跳(不用解释了:))
                    endif;
001322:0021:        number42 = 1;
00132C:002C:        goto label20;

label25: //Ref: 001314 
001335:0021:        number38 = 0;                    ;循环变量初始化(i=0;)

label26: //Ref: 001413 
001343:0128:        lNumber8 = number38 <= 11;                ;12位的循环(i<12;)
001355:0022:        if (lNumber8 = 0) then
                        goto label28;                    ;循环结束,跳出
                    endif;
001363:0119:        lNumber8 = number38 + 2;
001370:007A:        GetByte(lNumber8, string6, lNumber8);        ;serial[i+2]
00137B:0128:        lNumber8 = lNumber8 < 48;                ;<'0'
00138D:0119:        lNumber9 = number38 + 2;
00139A:007A:        GetByte(lNumber9, string6, lNumber9);        ;serial[i+2]
0013A5:0128:        lNumber9 = lNumber9 > 57;                ;>'9'
0013B7:0126:        lNumber8 = lNumber8 || lNumber9;
0013C2:0022:        if (lNumber8 = 0) then
                        goto label27;                    ;检查是数字就跳
                    endif;
0013D0:0021:        number42 = 1;
0013DA:002C:        goto label20;                    ;####################################
                                    ;    GetByte(lOutput,&str,i);
label27: //Ref: 0013C2                          ;    SetByte(&str,i,lInput);
0013E3:0119:        lNumber8 = number38 + 2;                ;####################################
0013F0:007A:        GetByte(lNumber8, string6, lNumber8);
0013FB:007B:        SetByte(string15, number38, lNumber8);        ;serial后面12位-->string15
001406:0119:        number38 = number38 + 1;                ;循环变量递增(i++;)
001413:002C:        goto label26;

label28: //Ref: 001355 
00141C:007B:        SetByte(string15, 12, 0);                ;<---序列号全是数字就到这里,string15[12]='\0';
00142B:0021:        number39 = 0;
001435:0021:        number38 = 0;

label29: //Ref: 0014C3 
001443:0128:        lNumber8 = number38 <= 5;                ;循环开始
001455:0022:        if (lNumber8 = 0) then
                        goto label30;                    ;循环结束
                    endif;
001463:007A:        GetByte(lNumber8, string15, number38);        ;
00146E:007B:        SetByte(string12, number39, lNumber8);        ;string12是string15的前3个奇数位
001479:0119:        lNumber8 = number39 + 3;
001486:0119:        lNumber9 = number38 + 1;
001493:007A:        GetByte(lNumber9, string15, lNumber9);
00149E:007B:        SetByte(string13, lNumber8, lNumber9);        ;string13从第4位起是string15的前3个偶数位
0014A9:0119:        number39 = number39 + 1;
0014B6:0119:        number38 = number38 + 2;
0014C3:002C:        goto label29;                    ;循环继续

label30: //Ref: 001455 
0014CC:007A:        GetByte(lNumber8, string15, 11);
0014D9:007B:        SetByte(string12, 3, lNumber8);
0014E6:007A:        GetByte(lNumber8, string15, 9);
0014F3:007B:        SetByte(string12, 4, lNumber8);
001500:007A:        GetByte(lNumber8, string15, 8);
00150D:007B:        SetByte(string12, 5, lNumber8);            ;设置string12的4、5、6位为string15的第12、10、9位
00151A:007A:        GetByte(lNumber8, string15, 6);
001527:007B:        SetByte(string13, 0, lNumber8);
001534:007A:        GetByte(lNumber8, string15, 10);
001541:007B:        SetByte(string13, 1, lNumber8);
00154E:007A:        GetByte(lNumber8, string15, 7);
00155B:007B:        SetByte(string13, 2, lNumber8);            ;设置string13的1、2、3位为string15的第7、11、8位
001568:0021:        number38 = 0;

label31: //Ref: 00163F 
001576:0128:        lNumber8 = number38 <= 5;                ;循环开始
001588:0022:        if (lNumber8 = 0) then
                        goto label33;                    ;循环结束
                    endif;
001596:007A:        GetByte(number46, string12, number38);
0015A1:011A:        number43 = number46 - 48;
0015AE:007A:        GetByte(number47, string13, number38);
0015B9:011A:        number44 = number47 - 48;
0015C6:0167:        UnknowFunction_2(lNumber8, string10, number43);    ;???
0015D1:011B:        lNumber8 = lNumber8 * 10;
0015DE:0119:        lNumber8 = lNumber8 + number38;
0015E9:0167:        UnknowFunction_2(number45, string11, lNumber8);    ;???
0015F4:0128:        lNumber8 = number45 != number44;
001604:0022:        if (lNumber8 = 0) then
                        goto label32;                    ;相等就跳
                    endif;
001612:0021:        number42 = 1;
00161C:002C:        goto label20;                    ;不满足条件,返回

label32: //Ref: 001604 
001625:0119:        number48 = number45 + 48;
001632:0119:        number38 = number38 + 1;
00163F:002C:        goto label31;                    ;循环继续

label33: //Ref: 001588  0016BB  0017A6 
001648:0021:        number42 = 0;
001652:00B5:        function104();                    ;<---
00165A:0021:        lNumber0 = LAST_RESULT;
001662:0128:        lNumber8 = lNumber0 = 12;
001674:0022:        if (lNumber8 = 0) then
                        goto label34;
                    endif;
001682:002C:        goto label20;

label34: //Ref: 001674  001734  00176D 
00168B:00B5:        function105();
001693:0021:        lNumber0 = LAST_RESULT;
00169B:0128:        lNumber8 = lNumber0 = 12;
0016AD:0022:        if (lNumber8 = 0) then
                        goto label35;
                    endif;
0016BB:002C:        goto label33;

label35: //Ref: 0016AD 
0016C4:0128:        lNumber8 = lNumber0 = 12;
0016D6:0023:        StrCompare(string9, "Custom");
0016E4:0128:        lNumber9 = LAST_RESULT != 0;
0016F6:0127:        lNumber8 = lNumber8 && lNumber9;
001701:0023:        StrCompare(string9, "");
001709:0128:        lNumber9 = LAST_RESULT != 0;
00171B:0127:        lNumber8 = lNumber8 && lNumber9;
001726:0022:        if (lNumber8 = 0) then
                        goto label36;
                    endif;
001734:002C:        goto label34;

label36: //Ref: 001726 
00173D:00B5:        function106();
001745:0021:        lNumber0 = LAST_RESULT;
00174D:0128:        lNumber8 = lNumber0 = 12;
00175F:0022:        if (lNumber8 = 0) then
                        goto label37;
                    endif;
00176D:002C:        goto label34;

label37: //Ref: 00175F 
001776:00B5:        function107();
00177E:0021:        lNumber0 = LAST_RESULT;
001786:0128:        lNumber8 = lNumber0 = 12;
001798:0022:        if (lNumber8 = 0) then
                        goto label38;
                    endif;
0017A6:002C:        goto label33;

label38: //Ref: 001798 
0017AF:012F:        return(0);
0017B8:00B8:        return;
    end;

其中function101()是显示"license.txt"的,这个进去看看就知道:
    // ------------- FUNCTION function101 --------------
    function function101()
        number lNumber0;
        string lString0;
        string lString1;
        string lString2;
        string lString3;
    begin
00278F:0125:        lString3 = SUPPORTDIR ^ "license.txt";
0027A5:0013:        lString0 = "";
0027AD:0013:        lString1 = "";
0027B5:0013:        lString2 = "";
0027BD:00B5:        function27(lString0, lString1, lString2, lString3);
0027D1:0021:        lNumber0 = LAST_RESULT;
0027D9:012F:        return(lNumber0);
0027E0:00B8:        return;
    end;

其他的我的注释就写得很清楚了
最后有一个关键循环比较的地方用到了这个未知函数,因为跟上面反复用到的两个GetByte()和SetByte()很像,所以就猜测着去作.用到了一个变量string11,在全部反编译里面搜索发现,仅这一次调用,初始化处在前面开头:
000DC5:0021:    number40 = 0;
000DCF:0021:    number38 = 0;

label2: //Ref: 000E96 
000DDD:0128:    number52 = number38 <= 9;
000DEF:0022:    if (number52 = 0) then
                    goto label5;
                endif;
000DFD:0119:    number40 = number40 + 1;
000E0A:0021:    number39 = 0;

label3: //Ref: 000E80 
000E18:0128:    number52 = number39 <= 9;
000E2A:0022:    if (number52 = 0) then
                    goto label4;
                endif;
000E38:011B:    number52 = number38 * 10;
000E45:0119:    number52 = number52 + number39;
000E50:0119:    number53 = number40 + number39;
000E5B:0123:    number53 = number53 % 10;
000E68:0168:    UnknowFunction_1(string11, number52, number53);
000E73:0119:    number39 = number39 + 1;
000E80:002C:    goto label3;

label4: //Ref: 000E2A 
000E89:0119:    number38 = number38 + 1;
000E96:002C:    goto label2;

这些算法都很简单,仔细看就行.
最后附上我做的注册机主要源码,可以结合起来分析:
#define MAXINPUTLEN 12
char szFormat[] = "8-%s";
char serial[MAXINPUTLEN+1],s1[MAXINPUTLEN+1]="123456789012";
int t1[6]={0,2,4,11,9,8},t2[6]={6,10,7,1,3,5},MagicTable[10]={6,2,9,5,1,4,1,3,8,7};
int i,x,y;

for(i=0;i<6;i++)
{
    //x=t3[i];//DEBUG
    x=rand()%10;
    y=MagicTable[x]*10+i;
    s1[t1[i]]=48+x;
    s1[t2[i]]=48+(y/10+y%10+1)%10;
}

sprintf(serial,szFormat,s1);

最后,我们可以认为
UnknowFunction_1()    ===>    SetByte()
UnknowFunction_2()    ===>    GetByte()
于是可以在decodetable.h里面加上这两行
{(char*) 0x0167, "GetByte__", (char*) 3, (char*) (*parseSystemFunction)},
{(char*) 0x0168, "SetByte__", (char*) 3, (char*) (*parseSystemFunction)},
这就是前面那个ISDCC v2.10(Modified)的来源,加上"__"是为了跟原有的函数区别开来,我现在反正不知道区别是什么.

-=over=-