|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-21, 12:22 AM | #1 |
榮譽會員
|
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=- |
送花文章: 3,
|