工具:SoftICE,金山遊俠2002,VC++7.0,PE查看器,SPY++
測試平臺:Window2000專業版SP2。
首先,我來介紹壹下將要用到的工具:
1,SoftICE(不用說,我想妳應該會用吧)
2.金山遊俠2002(妳應該也會用這個)
3、VC++7.0(不要求妳會用,但至少要懂壹個編程工具)
4、PE查看器(可以隨便找壹個,沒有也沒關系,我教妳用SoftICE查看)
5.sp y++(VC中查看程序信息的工具,可以分享給他人,比如Delphi的WinSight32,C++Builder)。
接下來是妳應該知道的:
1,裝配基礎
2,壹些編程基礎,至少妳要懂幾個我介紹的API函數。
3、PE文件結構基礎,沒關系,我給妳講解壹下。
如果以上幾點妳都具備了,我們就可以開始了。
我來介紹壹下我想教妳的東西。大家壹定都玩過PC遊戲,所以妳壹定用過壹些特殊的遊戲修改器。比如暗黑破壞神、紅色警戒、大富翁等經典遊戲,都有自己特殊的修改器。請註意,我不是在談論壹般的修改工具,如FPE。
妳試過用金山遊俠修改紅衛兵二代的錢嗎?如果有,妳要知道每次玩都要換,因為這個遊戲是動態分配內存的,每次重新啟動都會換。所以妳會選擇在網上下載壹個專用修改器,那麽妳有沒有想過自己做壹個呢?想過嗎?那妳為什麽不做呢?什麽不會?那很容易處理。看完這個教程,妳就會知道:D廢話少說,讓我來說說原理。
壹些經常修改手遊的朋友會知道,無論遊戲中“物品”的內存地址是不是動態的,物品之間的距離都是不變的。我以《楚留香新傳》為例。我先用金山遊俠找內力值的內存地址,結果是:79F695C,然後“金創姚”的地址是:328D65438+。繼續,我還沒說完。現在再次運行遊戲,找到內力值的地址,得到:798695C。然後找到金創耀的地址,地址是:321D1DC。兩個值的內存地址都變了,但是妳內力值的地址減去金創耀的地址是什麽結果?沒錯,還是4769780,也就是說,無論這兩個值的內存地址變成什麽,它們之間的距離永遠不會變,不僅在這個遊戲裏,在壹般的遊戲裏,至少我沒見過。沒有:D
以上的事情總結出壹個結論,就是只要我們得到這兩個地址中的壹個,就可以得到另壹個,只要妳知道它們之間的偏移量。
我們要做的第壹步就是獲取這個地址,但是內存中的地址是動態變化的,獲取也沒有用。這裏我就教妳把它靜態化,讓它永遠不變!我就以《楚留香新傳》為例。如果妳有這次旅行,妳可以和我壹起去。如果沒有,也沒關系。理解這些步驟就行了。去工作吧!
首先進入遊戲,找到內部值的地址,得到:798695C(不知道為什麽這個上遊每次重啟都不改變內存地址),按Ctrl+D打開SoftICE,給出命令:BPM 798695C W(寫這個地址時中斷),返回遊戲,打開角色屬性面板,遊戲中斷。您將在Sofitece中看到以下說明:
0047 EB 17 moveax[EDX+000003 F4]指揮:D EDX+3F4會看到內力值。
0047EB1D推送EAX
………………………………
………………………………
從上面可以看出,0047EB17處的指令是將內力值的指針發送到EAX寄存器,這是典型的尋址方式。假設我們在EDX的基地址,那麽每當我們用EDX+3F4的時候,我們就很容易得到內力值的地址,因為000003F4是壹個常數,不會變,只有EDX的地址會變,所以只要。如果妳還是不明白,請再讀壹遍。我們現在要做的是如何得到這個值,我來教妳怎麽做:
我的解決方案是設計壹段代碼,把EDX的值存儲在壹個地址裏,然後運行這段代碼,然後回到遊戲原來的指令繼續執行。什麽?補丁技術?SMC?不管妳說什麽,只要它正常工作,壹切都會好的:D
實際操作:
首先,在程序中找壹個空白處存放我們設計的代碼。這很簡單。只要了解壹些PE文件結構的朋友都會知道,通常在數據段的末尾會有壹個緩沖區(。數據段)。我們可以在這個區域寫任何東西。當然,妳也可以用“90大法”找空白區域,但我還是推薦妳用我教妳的方法。如上所述,如果妳沒有PE文件查看工具,我可以教妳用SoftICE查看,非常簡單。只需給我壹個命令:MAP32“模塊名”,看我怎麽做。
Ctrl+D調出SoftICE,然後給出命令:MAP32 CrhChs。這時,妳應該看到EXE的每壹段信息,我們只需註意。數據部分。因為我們正在尋找數據段的結尾,所以我們將從下壹段開始查找,如下所示:
。數據004FB000
。rsrc 00507000
的下壹段。數據是。rsrc段,從00507000開始,也就是說基於00507000的下壹個字節是數據段的結尾。我選擇從00506950開始寫代碼。說了這麽久,我們的代碼是什麽樣子的?修改後的指令是什麽?別急,請看下面:
修改0047EB17之後的代碼:
0047EB17 JMP 00506950 //跳入我們的代碼並執行它。
0047EB1C NOP //因為這條指令原來的長度是6字節,但是修改後的長度是5字節,所以補充了壹條空指令。
0047EB1D推送EAX
//我們的代碼:
00506950 MOV DWORD PTR EAX,[EDX+00003F4] //恢復我們中斷的指令。
00506956 movdword ptr[0050691],EDX//在0050691保存EDX。
0050695C JMP 0047EB1D //返回原指令執行。
用SoftICE的A命令寫上面的代碼,OK!
現在我們來試試手術的效果。現在妳用金山遊俠搜索內力地址的地址。有什麽變化?那是當場。如果不改變,我們還用這麽努力嗎?記下這個地址,回到遊戲。Ctrl+D調出SoftICE,給出命令D *[00506961]+000003F4。您在數據窗口中看到了什麽?呵呵,對,我看到了妳剛記的地址,裏面的值就是內力值。試著改變壹下,回到遊戲裏,呵呵,內力值改變了:D
至此,我們已經完成了90%的工作,但也不要高興得太早。後面的%10比前面的%90用的時間要長得多,因為我們要通過編程來實現,因為妳不可能像剛才那樣每次都做!
現在我來說說編程的步驟:
首先用FindWindow函數獲取窗口句柄,然後用GetWindowThreadID函數從窗口句柄獲取本進程的ID,再用OpenProcess獲取進程的讀寫權限,最後用WriteProcessMemory和ReadProcessMemory讀寫內存。。。。呵呵,妳的修飾語說完了:d。
下面是我之前復制的修改器源程序片段。第壹部分是動態寫剛才的代碼,第二部分是讀取和修改內力值。因為沒時間整理測試,所以不能保證沒有錯誤。如果妳發現少了什麽,妳可以給我留言或者在QQ上給我寫信。代碼如下:
請註意幾點:
1.壹個字節壹個字節寫機器碼。
2、註意先寫好自己的代碼,然後在巡講中修改指令(下面的代碼不這麽做,因為不影響,但是要註意這個問題)
#定義MY_CODE5 0x00
#define MY_CODE6 0x90
//00506950
#define MY2_CODE1 0x8B
#define MY2_CODE2 0x82 //該部分是要編寫的機器碼的常量定義。
#定義MY2_CODE3 0xF4
#定義MY2_CODE4 0x03
#定義MY2_CODE5 0x00
#定義MY2_CODE6 0x00
#define MY3_CODE1 0x89
#define MY3_CODE2 0x15
#define MY3_CODE3 0x61
#定義MY3_CODE4 0x69
#define MY3_CODE5 0x50
#定義MY3_CODE6 0x00
#define MY4_CODE1 0xE9
#定義MY4_CODE2 0xBC
#define MY4_CODE3 0x81
#定義MY4_CODE4 0xF7
#定義MY4_CODE5 0xFF
// - //
DWORD a 1 = MY _ code 1;
DWORD A2 = MY _ CODE2
DWORD A3 = MY _ CODE3
DWORD A4 = MY _ CODE4
DWORD A5 = MY _ CODE5
DWORD A6 = MY _ CODE6
DWORD b 1 = MY2 _ code 1;
DWORD B2 = MY2 _ code 2;
DWORD B3 = MY2 _ code 3;//這部分是變量的定義。
DWORD B4 = MY2 _ CODE4
DWORD B5 = MY2 _ CODE5
DWORD B6 = MY2 _ code 6;
DWORD c 1 = MY3 _ code 1;
DWORD C2 = MY3 _ code 2;
DWORD C3 = MY3 _ code 3;
DWORD C4 = MY3 _ code 4;
DWORD C5 = MY3 _ CODE5
DWORD C6 = MY3 _ code 6;
DWORD d 1 = MY4 _ code 1;
DWORD D2 = MY4 _ code 2;
DWORD D3 = MY4 _ CODE3
DWORD D4 = MY4 _ code 4;
DWORD D5 = MY4 _ code 5;
// - //
HWND HWND =::FindWindow(" CRH class ",NULL);//獲取窗口句柄
if(hWnd ==FALSE)
MessageBox("遊戲沒有運行!");
其他
{
GetWindowThreadProcessId(hWnd & amp;hProcId);//從窗口句柄獲取進程ID
HANDLE nOK = open PROCESS(PROCESS _ ALL _ ACCESS | PROCESS _ termin ate | PROCESS _ VM _ OPERATION | PROCESS _ VM _ READ |
PROCESS_VM_WRITE,FALSE,hProcId);//打開進程並獲得讀取和權限。
if(nOK ==NULL)
MessageBox("打開進程時出錯");
其他
{
//0047EB17
WriteProcessMemory(nOK,(LPVOID)0x 0047 EB 17;A1,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0047 EB 18;A2,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0047 EB 19;3,1,空);
WriteProcessMemory(nOK,(LPVOID)0x0047EB1A,& amp4,1,空);
WriteProcessMemory(nOK,(LPVOID)0x0047EB1B,& ampA5,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0047 EB 1C;6,1,空);
//00506950
WriteProcessMemory(nOK,(LPVOID)0x 00506950;B1,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506951;B2,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506952;B3,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506953;B4,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506954;B5,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506955;B6,1,空);
//第二句
WriteProcessMemory(nOK,(LPVOID)0x 00506956;C1,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506957;C2,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506958;C3,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506959;C4,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0050695 a;C5,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0050695 b;C6,1,空);
//最後壹句
WriteProcessMemory(nOK,(LPVOID)0x 0050695 c;D1,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0050695d;D2,1,空);
WriteProcessMemory(nOK,(LPVOID)0x0050695E,& ampD3,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 0050695 f;D4,1,空);
WriteProcessMemory(nOK,(LPVOID)0x 00506960;D5,1,空);
close handle(nOK);//關閉進程句柄
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////
//讀取並修改內力值
DWORD hProcId
HWND HWND =::FindWindow(" CRH class ",NULL);
if(hWnd ==FALSE)
MessageBox(" No ");
其他
{
GetWindowThreadProcessId(hWnd & amp;hProcId);
HANDLE nOK = open PROCESS(PROCESS _ ALL _ ACCESS | PROCESS _ termin ate | PROCESS _ VM _ OPERATION | PROCESS _ VM _ READ |
PROCESS_VM_WRITE,FALSE,hProcId);
if(nOK ==NULL)
MessageBox("ProcNo!");
其他
{
DWORD buf 1;
DWORD寫;
BOOL OK=ReadProcessMemory(nOK,(LPCVOID)0x00506961,(LPVOID)amp;buf1,4,NULL);//閱讀我們EDX的基礎知識。
if(OK ==TRUE)
{
write = buf 1+0x 000003 f 4;//獲取內力值的地址
DWORD Writeed = 0x00//要修改的值
BOOL B =WriteProcessMemory(nOK,(LPVOID)write,& ampWriteed,1,NULL);
如果(B = =假)
MessageBox(" write no ");
}
}
close handle(nOK);
}
啊,我對我寫的東西麻木了。今天到此為止。知識不淵博難免會錯過壹些東西。請給我妳的建議。如果我不會或者不喜歡用VC,妳可以在QQ上和我交流。我可以教妳如何用Delphi,C++Builder,Win32Asm或者VC實現以上功能。
(如轉載此文,請不要更改內容和作者!)
作者:CrackYY
電子郵件:CoolYY@msn.com
OICQ:20651482
2001我從馮雲了解到了IDA。看到他在了解凱撒的遊戲資源,我覺得很好玩,我自己也開始學壹些東西。當時壹口氣了解了壹些遊戲資源,當然都不是很復雜,主要是臺灣省和日本的。
後來在首頁放了壹段時間,記得有不少感興趣的朋友,就沒來得及說了。現在來說說:)
工具當然是IDA+SoftIce。如果妳想寫自己的解壓程序,妳需要壹個習慣編輯器。當然我用的是VC。
其實資源破解並不是很復雜,大致有三種方法。
1,硬裂紋
通過觀察目標文件和反匯編代碼,分析資源壓縮或加密的格式,編寫程序讀取和修改文件,轉換成妳能識別的格式。
這是妳自己了解資源時最容易想到的方法。
具體來說,通過壹些特定的函數來確定遊戲的資源求解函數,比如fopen、createFile等文件相關的函數,然後拼命分析匯編代碼就可以了。
我之前的大部分資源都是這樣破解的。最好先用UEDIT分析實際文件。有些格式太簡單了。按照文件大小來看就行了。
這個方法,我解決過最復雜的就是魔幻傳奇系列了。當時感覺更像GIF,但又不太壹樣。因為沒有研究壓縮算法,所以沒有深究。但是後來在網上看到壹篇文章說這是壹個很常見的壓縮算法,有壹些解壓工具可以解決。◎ #% ...真的很不愉快(不過還好我只花了幾個小時就解決了遊戲。
2、轉儲
圖片加載後,直接從內存中導出。
這個方法也很容易想到。主要難點在於內存中資源的格式。對於3D遊戲來說可能更容易。畢竟紋理渲染是顯卡做的,不是軟件。
我知道有人這樣理解魔獸的資源,hook OpenGL的壹些功能。
我通過這種方式學習了壹些遊戲文本(漢字),而對於賽車遊戲,為了獲取全部遊戲文本,我特意說了遊戲清零。
3、直接調用遊戲的解碼函數進行解碼
類似於第二種方法,但是主動調用函數基本可以壹次性解綁所有資源,不需要遊戲通關。
當然不是讓妳調用遊戲的解包模塊。畢竟很多遊戲都不是dll的形式。
我們只能侵入遊戲進程內部,找壹個合適的時間(壹般是加載其他文件的時候,中斷跳轉,先完成我們的工作),調用內部函數,解鎖所有資源。
我就這樣解決了壹個遊戲。說起來,那個遊戲的資源壓縮率和rar差不多。
0.需求文檔
LZW壓縮算法是壹種新穎的壓縮方法,由萊姆普爾-齊夫-韋爾奇創立,並以他們的名字命名。它采用了高級的字符串表壓縮,將每個第壹個字符串放在壹個字符串表中,並使用壹個數字來表示該字符串。壓縮後的文件只存儲數字,不存儲字符串,大大提高了文件的壓縮效率。神奇的是,這個字符串表在壓縮或解壓縮時都能正確建立,壓縮或解壓縮後又被丟棄。
1.基本原則
首先建立壹個字符串表,將每個第壹次出現的字符串放入字符串表中,用壹個數字表示,這個數字與字符串在字符串表中的位置有關,這個數字存儲在壹個壓縮文件中。如果該字符串再次出現,它可以被代表它的數字替換,這個數字存儲在文件中。壓縮後丟棄字符串表。例如,如果“print”字符串在壓縮過程中用266表示,那麽每當它再次出現時就用266表示,並且“print”字符串將存儲在字符串表中。當解碼過程中遇到數字266時,可以從字符串表中找出266表示的字符串“print”,並根據解壓縮時的壓縮數據重新生成字符串表。
2.實現方法
A.初始化字符串表
在壓縮信息時,我們首先要建立壹個字符串表來記錄每壹個第壹次出現的字符串。壹個字符串表至少由兩個字符數組組成,壹個叫當前數組,壹個叫前綴數組,因為壹個文件中每個基本字符串的長度通常是2(但它所代表的實際字符串長度可以達到幾百甚至幾千),壹個基本字符串由當前字符及其前面的字符(也叫前綴)組成。前綴數組存儲的是字符串中的第壹個字符,當前數組存儲的是字符串中的最後壹個字符,位置相同,所以只要確定壹個下標,就可以確定它存儲的基本字符串,所以在壓縮數據時,用下標代替基本字符串。壹般來說,字符串表的大小是4096字節(即2的12次方),這意味著壹個字符串表最多可以存儲4096個基本字符串。在初始化時,字符串表開頭的所有字節都根據文件中的字符數被分配了編號。通常情況下,當前數組中的內容是元素的序號(即下標),比如第壹個元素是0,第二個元素是1。如果字符數是256,應該初始化到第258個字節,這個字節裏的值是257。其中數字256表示清除代碼,數字257表示文件的結束代碼。以下字節存儲文件中第壹次出現的字符串。還需要初始化concert前綴數組,數組中每個元素的值是任意的,但其位置壹般是1,即每個元素的初始位置初始化為0XFF,初始化的元素個數與當前數組相同,後續的元素存放在每個第壹次的字符串中。如果增加串表的長度,可以進壹步提高壓縮效率,但解碼速度會降低。
B.壓縮法
要了解壓縮方法,首先要了解幾個名詞,壹是字符流,二是碼流,三是當前碼,四是當前前綴。字符流是源文件中未壓縮的文件數據;碼流是壓縮後寫入文件的壓縮文件數據;當前代碼是剛從字符流中讀入的字符;當前前綴是剛剛讀到的字符前面的字符。
壓縮文件時,不管文件中有多少個字符,顏色值都要以字節為單位放入碼流中,每個字節代表壹種顏色。雖然在源文件中用壹個字節表示16色、四色和雙色時會浪費四位或更多位(因為壹個字節中的四位可以表示16色),但在使用LZW壓縮方法時,字節中的空閑位是可以恢復的。壓縮時,先從字符流中讀取第壹個字符作為當前前綴,然後取第二個字符作為當前碼,當前前綴和當前碼組成第壹個基本字符串(如果當前前綴為A,當前碼為B,則此字符串為AB),查字符串表,此時肯定找不到相同的字符串,然後將此字符串寫入字符串表, 將當前前綴放入前綴數組,將當前代碼放入當前數組,並將當前前綴發送到代碼流。 將當前代碼放入當前前綴,然後讀取下壹個字符,即當前代碼。這時就形成了壹個新的基本串(如果當前代碼是C,這個基本串就是BC)。查找字符串表。如果有這個字符串,則丟棄當前前綴中的值,將這個字符串在字符串表中的位置代碼(即下標)作為當前前綴,然後讀取下壹個字符作為當前代碼,形成新的基本字符串。可以看出,在壓縮過程中,前綴數組中的值就是碼流中的字符,大於字符數的碼肯定代表壹個字符串,小於等於字符數的碼就是字符本身。
C.清除代碼
事實上,壓縮壹個文件時,往往需要多次初始化字符串表。通常,第壹次出現在文件中的基本字符串的數量會超過4096。在壓縮過程中,只要字符串長度超過4096,就需要將當前前綴和當前代碼輸入到碼流中,並在碼流中添加壹個清零代碼初始化字符串表,按照上述方法繼續壓縮。
D.結束代碼
當所有壓縮完成後,壹個文件結束碼輸出到碼流中,其值為字符數加1。在256色文件中,結束代碼是257。
E.字節空間回收
文件輸出的碼流中的數據以數據包的形式存儲,所有代碼都以單元存儲,有效節省存儲空間。這就像壹個4位彩色(16色)文件。以字節存儲時,只能使用4位,其他4位都浪費了。以位存儲時,每個字節可以存儲兩種顏色代碼。實際上,在文件中,使用了變量存儲方法。從壓縮過程中可以看出,字符串表前綴數組中每個元素的值都是有規律的。在256色文件中,258-511元素中的值的範圍是0-510,可以用9位二進制數表示。512-1023元素的取值範圍是0-1022,可以用二進制數10來表示,1024-2047元素的取值範圍是0-2046,正好是165438。存儲可變位數的代碼時,基數為文件中的字符數加1,位數隨著代碼數的增加而增加,直到位數超過12(此時字符串表中的字符串數正好是12的2次方,即4096)。基本方法是:碼流中每增加壹個字符,就要判斷該字符所在字符串在字符串表中的位置(即下標)是否超過當前的位數冪2,壹旦超過當前的位數冪,位數就增加1。例如,在4位文件中,初始代碼存儲為5位,第壹個代碼放在第壹個字節的低5位,第二個代碼的低3位放在高3位,第二個字節的低2位放在第二個代碼的高2位,依此類推。對於壹個8位(256色)文件,位數的基數是9,壹個代碼至少應該放在兩個字節中。
F.壓縮範圍
下面是文件編碼的壹個例子。如果妳留心的話,會發現這是壹種很奇妙的編碼方式,以及為什麽壓縮後不再需要字符串表,解碼時可以根據碼流信息重新創建字符串表。
字符串:1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,…
當前綴:21,1,1,1,2,3,4,1,2,3,4,5,9,…
當前前綴:1,2,1,1,260,1,258,3,4,1,258,262,4,5,…
當前數組:2,1,1,1,3,4,1,4,5,9,…
數組下標:258,259,260,261,262,263,264,265,266,267,…
碼流:1,2,1,260,258,3,4,262,4,5,…
3.測試文檔
描述:
選擇時,請選擇1-3的數據。如果選擇其他數據,將會出現錯誤。
使用文件
進入程序後,選擇是壓縮、解壓還是退出程序。
壓縮文件:
1)提示:“輸入文件名?”輸入:d: \ cc \ test.txt。
2)提示:“壓縮文件名?”輸入:test.lzw
3)顯示:“正在壓縮………”“*”表示文件壓縮的進度。
註意:如果輸入的文件不存在,將重復提示,直到輸入正確的文件位置和文件名。生成的test.lzw將存儲在程序所在的根目錄下。
例如,如果程序放在D:\cc\中,生成的文件也在D:\cc\中。
解壓:
1)提示:“輸入文件名?”輸入:test.lzw
2)提示:“壓縮文件名?”輸入:test.txt
3)顯示:“展開…………”“*”表示文件解壓縮的進度。
註意:如果輸入的文件不存在,將重復提示,直到輸入正確的文件位置和文件名。生成的test.lzw將存儲在程序所在的根目錄下。
Ani (Applicedon Startins沙漏)文件是MS-Windows的壹個動畫光標文件,其文件擴展名為“.阿尼”。它壹般由四部分組成:文本描述區、信息區、時間控制區和數據區,即壹個列表塊。Anih塊、速率塊和列表塊。
下面以ANI文件的文件內容(數據e)和標準結構圖為例(圖):
1.叢(0000-006D)是WND0WS95 & NTANI文件的文本描述區。
如果妳想為妳開發的ANI文件提供壹點文字描述,並添加妳的版權信息,同時要有ANI文件播放軟件的識別,這是妳唯壹的選擇。如果覺得麻煩或者沒什麽可寫的,可以把這個塊裏的內容全部去掉,把塊的大小設為0。記住,“塊ID”
“a列表”和“塊大小”為12字節,不得更改、移動或刪除,否則後果自負。
也許是為了將文本描述信息系統化,ACONLIST塊內部有幾個子塊。本例中使用的兩個塊是:INFOINAM塊(提供本文檔的解釋)和IART塊(用於插入版本信息)。說實話,妳可以用在AVI文件中插入自定義塊的方法來添加自己的自定義塊,結果只是被ANI播放軟件當成了“垃圾”。
0000-0003:多媒體文件ID: RIFF
0004-0007;文件大小(2052小時字節)-8字節
0008- 000F:列表塊標識符,標記文本描述區的開始。
0010-0013:列表塊的大小(5Ah字節)
0014-001b: Infoinam塊標識符,標記文件描述中信息子塊的開始。
001C-001C-001F:info inam塊大小(20h字節)
0020-003F:文件描述信息子塊的內容是“應用啟動沙漏”。
0040-0043: IART塊識別碼,它標誌著版權描述信息的開始。
0044-0047: IART塊大小(26h字節)
0048- 006D:版權信息在“微軟公司,版權1995”塊的內容中。
2.從(006E-0099)?