史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 作業系統操作技術文件
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2003-12-12, 01:29 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 Installshield5.0反編譯破解軟體安裝序列號一例

工具: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=-
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
 



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 12:03 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1