SoftIce45_for_win9x的安裝序列碼獲取及序列碼生成機編寫(無實際意義,純粹好玩) (9千字)
標題:SoftIce45_for_win9x的安裝序列碼獲取及序列碼生成機編寫
作者:leafred
主頁:http://leafred.126.com/
工具:isDcc v1.22,TRW2000
如有錯誤歡迎來信指正(leafspring@21cn.com)
以前搞破解,都用TRW2000,今天為了搞一個程式,結果TRW2000總是出錯,無奈想起SoftIce,高高興興的下載完SoftIce,準備安裝,沒想到是要序列碼的,誰叫我們會Crack呢,自己來動手找吧。哈哈,來破解Crack工具,有點滑稽吧。
先用isDcc來把setup.ins給反編譯出來,當然了,setup.ins是在SoftIce安裝時在系統臨時目錄下找到的了。包括後面要提到的動態庫。
首先是想能直接從反編譯的檔案總給找到,來個“The serial number you entered is not valid for this product”搜尋,鐺的一聲,彈出一個提示Search
string not found!,心一沉,看來要費點勁了。
慢慢看吧。
嗯,這個宣告prototype UTILITY.DigitCheck(string);可疑,從字面上看數字檢查,很想序列碼檢查哎,先看看誰呼叫它吧。
找到一下這段程式碼,發現是function143呼叫,再找function143誰呼叫,發現果真是此處進行序列碼檢查。
首先看看呼叫function143的地方:
abel187: //Ref: 00667F
006699:0152: RegDBGetKeyValueEx(lString0, "Onomatopoeia",
lNumber1, lString1, lNumber3);
====》取得序列碼,先從登錄檔獲取初始值,讓我們進行修改,原來沒有當然輸入新值了。
。。。。。。
label188: //Ref: 0066D0
====》先進行資料初步校驗
0066FF:00B4: NMINST32.ValidCookie(2, 0, lString1);
006711:0021: lNumber5 = LAST_RESULT;
006719:0128: lNumber5 = lNumber5 = 1;
00672B:0022: if (lNumber5 = 0) then
goto label190;
endif;
=====》初步校驗透過,進行正式檢查
006739:00B5: function143(lString3);
。。。。。。
現在再來看函式
// ------------- FUNCTION function143 --------------
function function143(pString0)
====》省略掉變數宣告
。。。。。
begin
0067BE:002F: StrLength(pString0); ==》獲取長度
0067C3:0021: lNumber1 = LAST_RESULT;
0067CB:0128: lNumber1 = lNumber1 != 14;
=====》長度不等於14 ?
0067DD:0022: if (lNumber1 = 0) then
=======》 No,等於14,OK下一步檢查
goto label192;
endif;
====》Yes,不等於14,返回0,這裡可以知道輸入的字元共12位,因為還含兩個“-”
0067EB:012F: return(0);
label192: //Ref: 0067DD
=====》取第一個框裡的字元
0067F8:0030: StrSub(lString1, pString0, 0, 4);
=====》取第二個框裡的字元
00680A:0030: StrSub(lString2, pString0, 5, 6);
=====》取第三個框裡的字元
00681C:0030: StrSub(lString3, pString0, 12, 2);
00682E:0124: lString6 = lString1 + lString2;
006839:0124: lString0 = lString6 + lString3;
====》以上程式碼合併輸入的內容,去掉“-”
006844:0031: StrFind(lString0, "-");
=====》還含有“-”嗎?
00684D:0128: lNumber1 = LAST_RESULT >= 0;
00685F:0022: if (lNumber1 = 0) then
====》No,不含了,OK繼續檢查
goto label193;
endif;
====》還含“-”,返回0,由此看出我們輸入的字元不可含有“-”
00686D:012F: return(0);
====》現在開始裝載UTILITY.dll了
label193: //Ref: 00685F
00687A:0125: lString5 = SUPPORTDIR ^ "UTILITY.dll";
006890:00B2: UseDLL(lString5);
006895:0021: lNumber1 = LAST_RESULT;
00689D:0128: lNumber1 = lNumber1 = 0;
0068AF:0022: if (lNumber1 = 0) then
goto label194;
endif;
======》呼叫UTILITY.dll的DigitCheck來檢查
0068BD:00B4: UTILITY.DigitCheck(lString0);
0068C5:0021: lNumber0 = LAST_RESULT;
0068CD:00B3: UnUseDLL(lString5);
label194: //Ref: 0068AF
0068D6:0128: lNumber1 = lNumber0 = 1;
0068E8:0022: if (lNumber1 = 0) then
goto label195;
endif;
0068F6:012F: return(1);
0068FF:002C: goto label196;
OK,至此我們已經知道它如何進行序列號檢查的,首先進行ValidCookie,透過則檢查長度,長度也透過進行最後的DigitCheck。
我們現在可以把上面用來檢查的兩個動態庫搞過來反彙編,慢慢讀程式,我現在就不這樣做了,我直接用TRW2000了,不要installshiled防TRW2000哦。
老一套了,用hmemcpy中斷,幾個F12來到此處:
017F:01541C44 LEA EAX,[ESP+0C]
017F:01541C48 PUSH EAX
017F:01541C49 PUSH DWORD 01555820
017F:01541C4E CALL 0154AAA0
在這裡我們來個D EAX看看,發現是第一個框裡的前三位數字,其實往上看看我們就可以看到前三個數字被移到ESP+0C處的程式碼。它是先移到ESP+10處,然後把ESP減4,POP一個值了。不就是用ESP+0C來引用嗎。
再D 01555820,發現是許多數字組合,再跟進去,發現0154AAA0是用來判斷EAX的內容是不是在01555820中的某個數字組合中。
下面還有幾處,只要有一處找到,就可以了。
因此可以知道前三個數字必須在這些數字組合中,具體的是:
230 400 401 410 411 420 421 430 431 480 481 510 930 931 950 951 ==》第一處
231 401 411 421 431 481 511 931 951 ===》第二處,一下還有幾處全部沒有,也就是說它現在只使用兩處,下面的幾處可能是保留給將來版本使用。
好了,現在再隨便挑一個,重新輸入再進入,(當然也可以直接改了)
來到此處:
017F:01541CA1 CALL 0154A5F0
關鍵所在,F8進入。
017F:0154A64E PUSH DWORD 01556C20
017F:0154A653 CALL `KERNEL32!LoadLibraryA`
017F:0154A659 MOV ESI,EAX
017F:0154A65B TEST ESI,ESI
017F:0154A65D JNZ 0154A693
====》裝載UTILITY.dll
。。。。。
017F:0154A693 PUSH DWORD 01554588
017F:0154A698 PUSH ESI
017F:0154A699 CALL `KERNEL32!GetProcAddress`==》獲取DigitCheck入口
017F:0154A69F TEST EAX,EAX
017F:0154A6A1 JZ 0154A6B1
017F:0154A6A3 LEA ECX,[ESP+0C]
017F:0154A6A7 PUSH ECX
017F:0154A6A8 CALL EAX ======》此處進入DigitCheck了!!!!!
017F:0154A6AA ADD ESP,BYTE +04
進入017F:0154A6A8 CALL EAX
。。。。。。
017F:01BC1136 CALL 01BC11D0
=====》此處功能是查表求得8個數字(包含對非數字的特殊處理)
017F:01BC113B CALL 01BC1280
=====》利用上面的8個數字,再查表得8個數字。
。。。。。。
=====》01BC91B0處存放的是上面求得的8個數字
017F:01BC114A MOV AL,[ECX+01BC91B4]===》後四位
017F:01BC1150 MOV DL,[ECX+01BC91B0]===》前四位
017F:01BC1156 XOR AL,DL ===》先XOR ECX+4與ECX處數字(ECX從0到3)
017F:01BC1158 MOV DL,[01BC91B7] ===》最後一位
017F:01BC115E OR AL,DL ====》 再OR最後一位
017F:01BC1160 OR AL,30===》再OR 0x30
017F:01BC1162 CMP AL,39 ===》判斷是否為數字
017F:01BC1164 MOV [ECX+01BC91B8],AL
017F:01BC116A JNG 01BC1174
017F:01BC116C ADD AL,07 ===》 加7轉為字母(A-Z)
017F:01BC116E MOV [ECX+01BC91B8],AL
017F:01BC1174 MOV AL,[ECX+01BC91B8]
017F:01BC117A MOV DL,[ECX+01BC9188]
017F:01BC1180 CMP AL,DL ====》與輸入的後四位比較
017F:01BC1182 JZ 01BC118A
017F:01BC1184 OR AL,20 ===》不分大小寫
017F:01BC1186 CMP AL,DL
017F:01BC1188 JNZ 01BC119C
017F:01BC118A INC ECX
017F:01BC118B CMP ECX,BYTE +04
017F:01BC118E JL 01BC114A
017F:01BC1190 MOV [01BC91AC],ECX
017F:01BC1196 MOV EAX,01
017F:01BC119B RET
至此,我們完全清楚它幹什麼了,我們可以在017F:01BC1180 中斷。
每次修改DL讓它與AL相等,並幾下AL值四次AL的值就是正確的後四位。
也就是說它根據我們輸入的東西,判一下前三位,然後進行計算,算出後四位,再與輸入的後四位比較,正確,則透過。
因而,也就有了序列碼生成機(不知可有更好的名字,因為它不能叫做序號產生器了)的概念。
程式碼如下:(僅僅要你輸入前八位數值,不帶“-”)
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
unsigned int tab[8][10] = {
{15,1,11,3,8,4,13,7,12,0},
{10,12,1,8,2, 0 ,9, 15, 5, 11},
{9 ,5, 12, 2, 7, 6, 15, 4 , 14, 10},
{3, 4, 12, 11,1, 0, 13 ,8, 0, 14},
{13 ,1, 6,11 ,8 ,10 ,14 ,4,3, 12},
{7,11,6,10,5,9,4,8,0,3},
{0,12,3,15,10,8,2,12,4,6},
{9, 5, 13, 1,3,11,12 ,4, 2 ,8}
} ; //索引表
char *fthree[] ={
"230" ,"231","400","401","410","411" ,"420",
"421", "430", "431",
"480", "481","510","511","930","931",
"950","951"
}; //前三個字元範圍
unsigned char fthreelen = 18;
char regcode[4],getcode[80];
int i,j;
unsigned int itmp;
unsigned int code[8] ={0,0,0,0,0,0,0,0} ;
printf("SoftIce4.5 for Win9x serial number Generater\n");
printf("Written by Leafred\n");
printf("Http://leafred.126.com/\n");
printf("\nPlease Input the initial 8 letters:\n");
do {
gets(getcode);
if(strlen(getcode) != 8)
printf("Please Input the initial 8 letters:\n");
else
break;
} while(1) ;
for(i=0 ;i < fthreelen ; i++)
if(! strncmp(getcode,fthree[i],3)) break;
if(! (i < fthreelen)){
printf("\nFirst three letters must in:\n");
for(i=0;i< fthreelen;i++)
printf("%s ",fthree[i]);
printf("\n");
return 0 ;
}
strupr(getcode);
//第一個CALL
for(i=0;i<8;i++){
itmp = getcode[i] ;
if(itmp >='0' && itmp <= '9')
itmp = 132;
else if(itmp >= 'A' && itmp <=
'F')
itmp = 129;
else if(itmp >= 'G' && itmp <=
'Z')
itmp = 1;
else if(itmp >= 'a' && itmp <=
'f')
itmp = 130;
else if(itmp >= 'g' && itmp <=
'z')
itmp = 2;
else
itmp = 16;
if(!(itmp & 4))break;
code[i] = getcode[i] & 0xf;
}
//對前8各輸入有字母處理
if(i < 8)
{
i--;
j = 7;
do{
if(i>=0){
code[j]=code[i];
i--;
}
else
code[j]
= 0;
j--;
if(j < 0)
break;
}while (1) ;
}
//查表取值
for(i=0;i<8;i++)
code[i] = tab[i][code[i]];
//最後一步
for(i=0;i<4;i++){
regcode[i] = code[i] ^ code[i+4];
regcode[i] |= code[7];
regcode[i] |= 0x30 ;
if(regcode[i] > 0x39)regcode[i] += 7;
}
printf("Your serial number is:\n");
printf("%c%c%c%c-%s%c%c-%c%c\n",getcode[0],getcode[1],getcode[2],getcode[3],getcode+4,regcode[0],regcode[1],regcode[2],regcode[3]);
return 0;
}
相關文章
- m序列的生成--閒來無事寫程式碼2021-09-09
- 實際序列密碼2020-07-19密碼
- ASP.NET獲取CPU序列號,硬碟序列號ID,獲取網路卡編號2007-06-25ASP.NET硬碟
- MyEclipse序列號生成程式碼2011-03-03Eclipse
- SoftICE4.05 for win9x的安裝序列號破解(1) (11千字)2001-05-19
- 教你用vbs指令碼獲取網路卡MAC,CPUID,硬碟序列號的實現程式碼2022-06-15指令碼MacUI硬碟
- python編碼的意義2016-10-09Python
- LAMP純原始碼編譯安裝日誌2017-11-15LAMP原始碼編譯
- RAC安裝時需要執行4個指令碼及意義2013-12-05指令碼
- 皮兄,網際金典3的InstallShield序列號破解。 (9千字)2001-04-28
- 如何獲取BIOS序列號2010-07-20iOS
- 高併發環境下生成序列編碼重複問題分析2023-03-13
- Go語言序列化(Gob編碼)2015-08-28Go
- 利用 Redis 生成序列號的功能實現編號自增2024-04-24Redis
- DRF-Serializers序列化器元件原始碼分析及改編2024-10-28元件原始碼
- matlab 生成隨機數序列2018-06-24Matlab隨機
- HTML5中有序列表和無序列表的寫法2019-11-25HTML
- 序列生成;及合併總數分析2013-08-12
- 找最大數;及序列生成分析2013-08-13
- exonerate結果整理,獲取target序列2016-09-17
- DRF-Serializers序列化器元件原始碼分析及改編su2024-10-29元件原始碼
- java安全編碼指南之:序列化Serialization2020-11-01Java
- js將字串轉換為編碼序列程式碼例項2017-04-04JS字串
- Windows xp 安裝序列號2016-08-31Windows
- 最長公共子序列的程式碼實現2017-02-13
- js獲取元素的實際尺寸程式碼例項2017-04-14JS
- 序列生成函式2022-12-19函式
- 基於序列模型的隨機取樣2019-09-04模型隨機
- Lambda Pro v2.0安裝序列號破解(1) (16千字)2001-12-08
- Installshield5.0反編譯破解軟體安裝序列號一例 (14千字)2015-11-15編譯
- 序列化篇 生成xml 以及讀取xml2024-03-16XML
- 序列密碼的加密與解密2020-07-19密碼加密解密
- 基於 “typesys” 實現序列指令碼框架2020-07-08指令碼框架
- 編寫安裝配置mail服務指令碼2017-11-07AI指令碼
- 淺析 SplitChunksPlugin 及程式碼分割的意義2023-03-07Plugin
- 在centos7下獲取 主機板 cpu 硬碟序列號2024-08-30CentOS硬碟
- 十分鐘搞定Keras序列到序列學習(附程式碼實現)2017-10-03Keras
- drf: 序列化和反序列化, Django Rest_Framework 介紹也安裝及使用。2024-03-25DjangoRESTFramework