【標題:Tag&Rename 1.7 文章二 :此軟體的註冊碼演算法。( 進來看看 8^) )】
【標題:Tag&Rename 1.7 文章二 :此軟體的註冊碼演算法。( 進來看看
8^) )】
==========================================================================================
軟體 :Tag&Rename 1.7
軟體簡介 :一個可以修改MP3 和 VQF 音樂檔案中的TAG說明的程式。目前尚未支援MP3最新的ID3v2
但是,仍然是一個很好用的編輯工具。
下載處 :軟體主頁: http://www.softpointer.com/tr.htm
==========================================================================================
本文作者 :McNy@Work
日期 :2000年11月11日 --> 2000年11月13日
Email :mcny_work@yahoo.com
(郵件主題請以"WANTED:McNycn"開始,注意英文字母大小寫,否則我將收不到喔!)
-------------------------
我寫了一個註冊碼測試器(若你輸入的S/N為正確的註冊碼,它會告訴你,否則只會顯示你的"註冊碼
生成串")。 實在沒多大用途,不過有興趣的話,可以試看看。會一擊即中也說不得! (請使用
下面地址下載。)
(不過,可以改編成窮舉法算碼器,不過不知道要算多久才有結果(日月可計吧!)。
想要源程式可與我聯絡)
<無法從瀏覽器直接下載!!需要使用Flashget,Netants,...等工具進行下載(但不支援斷點續傳)>
網址 : http://www.geocities.com/mcny_work (只有兩個頁面,正在建造中,施工緩慢)
下載地址: http://www.geocities.com/mcny_work/file/2000/tagren17_kt.zip
(使用方法:請看readme.txt)
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~
終於將本文輸完了(有點神經衰退了 8^) )。看雪學院、論壇給我的幫助,實在是太多太多了!!
在此,感謝看雪與來訪論壇的各位大俠。並以【 Tag&Rename 1.7 文章一】、【二】 獻給大家。。。
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~
【目錄】
§========§
§ 一、前言 §
§ 二、正文 §
§ 三、後記 §
§ 四、附錄 §
§========§
----------------------------------【一、前言】--------------------------------------------
下面程式碼是取自『Tag&Rename 1.7 文章一』的『第二部分』,有見過那篇文章的朋友或許會有印象。
本文的演算法,是從程式碼 **(C3)** 處的call逐漸向上追蹤所得。起始點是call內部深處所呼叫的
CompareStringA 。(注:直接bpx CompareStringA 並不能截住!因為實際上是調
用CompareStringA + 0D 的地址。 所以bpx應該是設在CompareStringA再加 0D 的地址。)
由於涉及演算法的核心程式碼冗長(不少於600行)。經筆者整理以後,本文用C++來演示。
(由於筆者程式設計水平實在有限,希望大家能夠幫忙最佳化。。。,不勝感激。)
...
017F:0045655F
MOV EAX,ESI
017F:00456561
CALL 00402F68
017F:00456566
LEA EDX,[EBP-04]
017F:00456569
LEA EAX,[EBP-18]
017F:0045656C
CALL 00456460 ///由輸入S/N,產生"註冊碼生成串"的
///主要呼叫。
017F:00456571
MOV DL,01
017F:00456573
MOV EAX,[00410060]
017F:0045657D
MOV [EBP-08],EAX
017F:00456580
LEA EAX,[EBP-08]
017F:00456583
CALL 00456404
017F:00456588
MOV EDX,[EBP-04]
017F:0045658B
MOV EAX,[EBP-08]
017F:0045658E
MOV ECX,[EAX]
**(C3)** 017F:00456590 CALL NEAR [ECX+50]
//比較"註冊碼生成串'和兩百餘個
//"正確的串"。
//若全部不匹配返回EAX=FFFFFFFF
//(內部會呼叫 Kernel32!CompareStringA)
017F:00456593
INC EAX
**(A3)** 017F:00456594 JZ 0456598
/// EAX=0 時跳轉。我們改這裡!!!
==> 017F:00456598 MOV BL,01
/// 若上一行不跳轉,則註冊碼正確。
017F:0045659B
CALL 00402F68
017F:004565A0
XOR EAX,EAX
....
----------------------------------【二、正文】--------------------------------------------
Tag&Rename 1.7 使用了一個不可逆的註冊碼演算法。我們輸入的註冊碼S/N,運用該演算法產生一個
“註冊碼生成串”。再將我們的“註冊碼生成串”與程式中的“內部比較串”(實質上是程式設計時,事先
由正確的註冊碼所產生的“註冊碼生成串”)進行比較,若有其中一個“內部比較串”與之相同,則注
冊成功!
(一)產生“註冊碼生成串”的步驟:< 我們輸入S/N: 1234567890 >
1)讀入使用者輸入的S/N (並去除 S/N 的空格字首與字尾!) // eg: S/N = " SN-0001
45678-8890 "
a)S/N可以是任何的英文字母、數字、標點符號
// ==> S/N = "SN-0001 45678-8890"
b)S/N長度<=45
2)將S/N 放入char sn_area[0] 中,並以 0x80 作為串結束符。在 sn_area[0x38] 處放入(串長*
8 ) 。
( 見 **(D1)** )
3)呼叫不可逆演算法,產生“註冊碼生成串”:
A)進行位操作.
B)進行'和'操作 //!!! 是這裡造成本演算法的不可逆!!!
// 見**(D4)**
C)改變Ap4[0] (指向A[] ) , 重複A)到C)直到FOR 迴圈結束
// 見**(D3)**
D)將B[]與改變後的A[]相加(注意相加時的指標),結果放入A[] // 見**(D5)**
E)人為地將A[]分成四組(每一組4個位元組〕。逐個將每個小組變成字串,將結果加入outputsn 串尾。
最後一組字串必須加入outputsn兩次。(最後產生一個近似四十個字元的字串)
F) outputsn 就是我們求得的"註冊碼生成串",我們就是用它與程式內所有的"內部比較串'比較。
(二)為什麼此演算法不可逆?
A) 首先必須闡明: 整個演算法中,只有兩個主要變數: sn_area[] ,A[] 。
sn_area[] 的內容,在我們輸入S/N 後便確定下來了(不會再改變) 。
只有 A[] 的內容,會在演算法中不斷的改變!!
(其餘的常量都是TagRename 程式的內定值,不可擅自篡改! 8^) )
B)假設現在seed=63, 這是最後一個迴圈了。我們會進行以下操作.
// 見 **(XX)** 處
但是,為了方便闡述,我們臨時將幾個變數名做了一點調整:
//這是正向過程的最後一個迴圈。
buf1= Ap3[0] | (~ Ap2[0]);
buf1= buf1 ^ Ap1[0];
buf2=buf1+Ap4_old[0]+sna[0]+mydef[seed]+Ap3[0];
// <=關鍵
Ap4_new[0]=buf2;
// Ap4_new[0], Ap4_old[0] 皆指向A[]
// sna[0]包含我們所輸入的S/N
可見,這一次迴圈中只有Ap4_new[0]被改變.
若我們要作一個逆過程(從一個'內部比較串"找其正確註冊碼),則必須從已知的
Ap4_new[0]求得原來的Ap4_old[0],好讓程式不斷的迴圈下去。逆過程如下:
//這是逆過程的第一個迴圈。
buf1= Ap3[0] | (~ Ap2[0]);
//位操作不變。
buf1= buf1 ^ Ap1[0];
Ap4_old[0]=Ap4_new[0]-( buf1+sna[0]+mydef[seed]+Ap3[0]
); // <=關鍵
我們知道,這個逆過程中 Ap4_old[0] 是未知的。必須算出它的值,我們才
能繼續算下去,一直到迴圈結束,得到正確的註冊碼。
然而,這裡有一個矛盾!!因為 sna[0] 中存放的是我們輸入的註冊碼(在逆過程中,
當然是指正確的註冊碼。 即:若此處的註冊碼與當初生成“內部比較串”時的註冊碼不同,
則必定不會得到我們所期望的結果!)。可是,我們並不知道正確的註冊碼是什麼,
所以 sna[0]在逆過程中也應該是未知的!!
只有一個等式,卻有兩個未知數,當然無解啦! (本想寫個序號產生器,才花那麼多時間去分析
程式碼,這回可真是 '偷雞不著蝕把米' 8^( )
(三)VC++程式碼(區域性):〔想要源程式可與我聯絡〕
//++++++++++++++++++++++++Tag&Rename 1.7 演算法(VC++)++++++++++++++++++++++++++++++++++++++++++++++++++
///Compile successful in VC++6.0
///假定 int 和 char 的長度都為 4 個位元組
//我們輸入的S/N串會放入sn_area[]中。
//假設我們輸入的S/N 為 1234567890 ,則sn_area[]如下。
//注意:必需以0x80作為串的結束符!! 而且 sn_area[0x38]處必需放入'串長x8'
//此列中 sn_area[0x38]=0x50
//我們人為的將它分成16個區(用十六進位制數0-F表示)
**(D1)**
char sn_area[64]={
0x31,0x32,0x33,0x34,
0x35,0x36,0x37,0x38, 0x39,0x30,0x80,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x50,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
};
//都是常數,用來選擇sn_area的某一區
int sna_select[64]={ 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
0x1,0x6,0xB,0x0,0x5,0xA,0xF,0x4,0x9,0xE,0x3,0x8,0xD,0x2,0x7,0xC,
0x5,0x8,0xB,0xE,0x1,0x4,0x7,0xA,0xD,0x0,0x3,0x6,0x9,0xC,0xF,0x2,
0x0,0x7,0xE,0x5,0xC,0x3,0xA,0x1,0x8,0xF,0x6,0xD,0x4,0xB,0x2,0x9
};
//都是常數,用來進行四則運算.
int mydef[64]= {0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,
0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,0x6B901122,0xFD987193,0xA679438E,0x49B40821,
0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,0xD62F105D,0x02441453,0xD8A1E681,0xE7D3FBC8,
0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,
0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,
0x289B7EC6,0xEAA127FA,0xD4EF3085,0x04881D05,0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,
0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,
0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391
};
//我們人為的將A[]、B[]各分成四組.(每4個位元組一組)
**(D2)**
//A[]和B[]的初始值都一樣, 但是A[]會在迴圈 **(D1)** 中不斷改變.
char A[16]={0x01,0x23,0x45,0x67, 0x89,0xAB,0xCD,0xEF, 0xFE,0xDC,0xBA,0x98, 0x76,0x54,0x32,0x10};
char B[16]={0x01,0x23,0x45,0x67, 0x89,0xAB,0xCD,0xEF, 0xFE,0xDC,0xBA,0x98, 0x76,0x54,0x32,0x10};
CString outputsn; //所求得的'註冊碼生成串'。
int p1,p2,p3,p4; //使用它們來指定要使用A[]的哪個部分。
__inline bool CTagRen17snDlg::checkfor1targ()
{
int i,buf1,seed;
int *Ap1,*Ap2,*Ap3,*Ap4,*sna; //
p1=0x08; //Initialize the Started A[n] order
p2=0x0c;
p3=0x04;
p4=0;
for (seed=0;seed<64;seed++) //seed=0
--> 63 **(D3)**
{
Ap1=(int*)&A[p1];
//注意:這裡強制將char指標變成int指標,所以看到的資料會顛倒。
//舉例,A[p1]的內容=
01 23 45 67
//
Ap1[0] = 67 45 23 01
Ap2=(int*)&A[p2];
Ap3=(int*)&A[p3];
Ap4=(int*)&A[p4];
sna=(int*)&sn_area[sna_select[seed]*4];
//注意:這裡也強制將char指標變成int指標。
//Here start
if(seed<16)
//這裡就不用多說了吧,都是一些位操作.
{
buf1= Ap3[0] & Ap1[0];
buf1= ((~Ap3[0])& Ap2[0]) | buf1;
}
else if(seed<32)
{
buf1= Ap2[0] & Ap3[0];
buf1= ((~Ap2[0])& Ap1[0]) | buf1;
}
else if (seed<48)
{
buf1= Ap3[0] ^ Ap1[0];
buf1= buf1 ^ Ap2[0];
}
else
{
buf1= Ap3[0] | (~ Ap2[0]); //
**(XX)**
buf1= buf1 ^ Ap1[0];
}
buf1=buf1+Ap4[0]+sna[0]+mydef[seed]+Ap3[0];
//<=該死的東西!! **(D4)**
Ap4[0]=buf1;
//整個for迴圈只改變A[]中的某一組
///改變p1,p2,p3,p4
if (p1==0) p1=0x0c;
else p1=p1-4;
if (p2==0) p2=0x0c;
else p2=p2-4;
if (p3==0) p3=0x0c;
else p3=p3-4;
if (p4==0) p4=0x0c;
else p4=p4-4;
}//for_end
///
int *pa,*pb;
for (i=0;i<4;i++) //Final Add
{
pa=(int*)&A[i*4];
//注意:這裡也強制將char指標變成int指標。**(D5)**
pb=(int*)&B[i*4];
pa[0]=pa[0]+pb[0];
}
///將pa[]的內容(共十六位元組,分成四位元組一組)轉換成字串(四十個字元/或近四十個字元)。
char aaaa[50];
outputsn.Empty();
for (i=0;i<4;i++)
{
pa=(int*)&A[i*4];
_itoa(pa[0],aaaa,16);
//注意:若pa[0]中的內容以0為前導,前導0不轉換!
//舉例:pa[0]=00A5D41E
,則aaaa='A5D41E'
outputsn=outputsn+aaaa;
}
outputsn=outputsn+aaaa;
//A[]的最後一組要多加一次!!(這樣便構成
//
四十個字元/或近四十個字元)
outputsn.MakeUpper();
m_disbox1.SetWindowText(outputsn);
//此時,outputsn=註冊碼生成串
//舉例: 我們輸入S/N="1234567890" ,則 outputsn='EA4DC7F7799A0A3742C7EB089D297F529D297F52'
// 若S/N="AF00-12345-0000-1234" , 則 outputsn='5D94F02772BF9C521E723D981E74F9391E74F939'
//
//下面省略。。。--比較註冊碼生成串與所有的內部比較串(兩百餘個),若有其中一個內部比較串與
// 註冊碼生成串相同,則所輸入的
S/N 正確。註冊成功。
...
...
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
----------------------------------【正文完】----------------------------------------------
----------------------------------【三、後記】--------------------------------------------
其實,並非只有 Tag&Rename 1.5/1.6/1.7 使用這個演算法。SoftPointer 這個公司的另一個軟體
Advanced Ra-Renamer v.1.1 ( 軟體功能:修改Realplayer音樂檔案(*.ra)的TAG )也使用同一個演算法,
是一摸一樣的演算法!!所不同的唯有“內部比較串”!!
另一個破解方法:我們只需要將眾多內部比較串中的其中一個,改成我們自己的比較串,那麼用
自己的SN 便能註冊成功了!(然而,我懷疑會有幾個人這樣做。這畢竟有
點畫蛇添足。既然要對程式本身作修改,改變跳轉不是更加簡單省事??!)
----------------------------------【四、附錄】--------------------------------------------
//(僅供參考)
//幾個Tag&Rename1.5/1.6/1.7的內部比較串。1.7版本有兩百餘個比較串。(這裡不按原順序排列)
target_TAG[0] ="6BD7B460BF475A6B5415F1F97F19F2CD7F19F2CD"; //<=在程式的第一次比較,可以看到本串。
target_TAG[1] ="30FE82633BADBA6CFC08C0033DABE1E83DABE1E8";
target_TAG[2] ="E1E93D3A7BEF3F49B2A4AFC19A50F9B59A50F9B5";
target_TAG[3] ="603D7D9D717D8C9023A94720FC9345E0FC9345E0";
target_TAG[4] ="CD8816613549E28B2B12DB1D7B70DCF47B70DCF4";
target_TAG[5] ="458FC6FF176FAB84A09166ECA5D41EA5D41E";
//<=串長不一定是四十個字元!!
target_TAG[6] ="9298C14667EE91844C2E8AD8AA14FEF6AA14FEF6";
target_TAG[7] ="CEC148A772B83DE7C0E5F77EBA087B4EBA087B4";
target_TAG[8] ="A59469F69BBCF2E4276506C8E227368AE227368A";
target_TAG[9] ="EFF5E1F96337AAA215CA0F98E64DCE1DE64DCE1D";
target_TAG[10]="FA221E4FEC7662907D3BDE10A20B0074A20B0074";
target_TAG[11]="BFB419C3679775538D5B24282BD3FDA52BD3FDA5";
target_TAG[12]="A2F2A07D860EA1B2542236D87D317FE57D317FE5";
target_TAG[13]="9F5E527C3BA802D4AB41E6BD89F36EC189F36EC1";
target_TAG[14]="510718DA8965364AD3AFA44144D297044D2970";
target_TAG[15]="E296E8B3B6EC79FBBF686E98E8849A28E8849A2";
//幾個RA-Renamer1.1 的內部比較串,約有 180 個比較串。
target_RA[0] ="728F0122AB2B16CBAF6BD4C7F3ACE41EF3ACE41E";
target_RA[1] ="5711D97055A3AA85DBB00844AC126969AC126969";
target_RA[2] ="D70BB2A0156DA6ED975853569B1741969B174196";
==========================================================================================
全文結束(有不對的地方,還望大家多多指正與包涵!)
相關文章
- 【標題:Tag&Rename 1.7 文章一 :跟蹤,並且製作Loader。(適合初學者)】2000-11-11
- FolderView 1.7
註冊演算法分析 (14千字)2015-11-15View演算法
- 給自己的軟體製作註冊碼2020-11-14
- C#實現無法破解的軟體註冊碼演算法2013-02-22C#演算法
- 第七章-尋找軟體的註冊碼2015-11-15
- 一個軟體的MD5註冊演算法【原創】2004-12-29演算法
- Instant Source 註冊演算法分析+註冊器原始碼2015-11-15演算法原始碼
- 菜鳥破解之軟體自己顯示註冊碼2015-11-15
- Flutter 1.7 來了,看看有什麼新變化2019-07-11Flutter
- 標
題:UltraISO7me註冊方法分析2004-04-25AI
- 公司寶商標註冊|你想擁有自己的商標嗎?商標註冊流程解析2021-10-14
- .NET Core中介軟體的註冊和管道的構建(2)---- 用UseMiddleware擴充套件方法註冊中介軟體類2016-08-08套件
- .NET Core中介軟體的註冊和管道的構建(1)---- 註冊和構建原理2016-08-04
- 註冊碼演算法 (2千字)2001-01-14演算法
- 序列號查詢工具KCNScrew解決多個軟體的註冊問題2022-05-17
- CRM中介軟體裡CRM local changes的註冊管理2020-02-05
- Oracle 叢集軟體資源的手工註冊(zt)2019-06-25Oracle
- XnViewMP 註冊碼啟用版:mac電腦強大的看圖軟體2023-12-13ViewMac
- LanSee 註冊演算法2015-11-15演算法
- 註冊碼演算法入門!----菜鳥篇2015-11-15演算法
- 加密保護軟體 WinLicense 註冊常見問題(一):許可證2019-03-26加密
- iPhone8很快要來?蘋果在中國香港註冊彩色2016-09-24iPhone蘋果
- 共享軟體中註冊部分的簡單實現(轉)2007-08-15
- Emeditor 註冊碼2017-08-14
- WebStorm註冊碼2014-04-29WebORM
- 有用過velocity的嗎? 有個問題,進來看看吧2003-11-10
- ChinaZip v2.0的註冊碼演算法(初學者)2000-11-30演算法
- C#基於RSA加密演算法實現軟體註冊實戰演練2019-01-12C#加密演算法
- 計算機軟體水平考試測試系統3.0註冊演算法分析2015-11-15計算機演算法
- 程式設計演算法題來看看大家各種不同的答案2019-05-11程式設計演算法
- 財智證券結算軟體2.5 破解註冊碼分析!使用ollydbg 破解註冊動畫!高手莫入! (1千字)2001-11-20動畫
- 財智老闆通3.04註冊版---註冊演算法分析2003-03-16演算法
- 進位專家註冊演算法分析及序號產生器C原始碼2004-08-19演算法原始碼
- 標 題:DirectMediaXtra.x32 V2.01 註冊碼的計算 (13千字)2015-11-15
- supercleaner註冊演算法分析2015-11-15演算法
- EmEditor v3 Version 3.09 漢化版註冊碼演算法分析
(8千字)2001-01-09演算法
- 公司寶商標註冊|OPPO註冊OCAR商標被駁回,商標駁回處理方法2021-11-01
- 小弟為共享軟體作者製作的管理軟體註冊的動態連結庫 (轉)2007-12-05