當前位置:編程學習大全網 - 腳本源碼 - 怎麽做植物大戰僵屍可以造植物的修改器

怎麽做植物大戰僵屍可以造植物的修改器

遊戲修改器制作-黑客入門

工具:SoftICE、金山遊俠2002、VC++7.0、PE查看器、SPY++

測試平臺:Window2000 Professional SP2

首先我介紹壹下將會用到的工具:

1、 SoftICE(不用多說了吧,我想妳應該會用)

2、 金山遊俠2002(這個妳也應該會用)

3、 VC++7.0(不要求妳壹定會用,但至少應該會壹種編程工具)

4、 PE查看器(妳可以隨意找壹個,沒有也沒關系,我會教妳用SoftICE查看)

5、 SPY++(VC裏的壹個查看程序信息的工具,妳可以和別的,比如Delphi和C++Builder的WinSight32)

然後就是妳應該會的知識:

1、 匯編基礎

2、 壹些編程基礎,至少應該看懂我介紹的幾個API函數

3、 PE文件結構的基礎,不會也沒關系,我會解釋給妳

以上幾點妳都具備了的話我們就可以開始了。

我來介紹壹下我要教給妳的東西。想必大家都玩過PC遊吧,那麽也壹定用過壹些專用的遊戲修改器吧,比如暗黑,紅警,大富翁這些經典的遊戲都有它們專用的修改器,註意,我說的不是FPE之類的通用修改工具。

妳試沒試過用金山遊俠修改紅警二的金錢?如果有的話妳應該知道每玩壹次就要改壹次,因為這個遊戲是動態分配內存的,每次重新開始都會改變。所以妳會選擇到網上去下載壹個專用的修改器,那麽妳有沒有想過自己做壹上呢?想過?那妳為什麽不做?什麽不會?那就好辦了,看了這篇教程妳就會了:D費話少說,我來講壹下原理。

有壹些經常修改遊的朋友壹定會知道,不論遊戲中“物品”的內存地址是否是動態的,物品與物品之間相隔的距離都是不變的,我拿“楚留香新傳”為例,我先用金山遊俠查找內力值的內存地址,找到的結果是:79F695C,再查找物品“金創藥”的地址是:328D1DC,現在我用79F695C減去328D1DC,得到:4769780,這個數就是內力值與金創藥的偏移值,沒看懂?接著看呀,我還沒說完呢,現在重新再運行遊戲,查找內力值的地址,得到:798695C再查找金創藥得到的地址是:321D1DC,兩個值的內存地址都改變了,但是用妳內力值的地址減去金創藥的地址得到的結果是什麽?沒錯,還是4769780,也就是說,無論這兩個值的內存地址變成多少,它們之間的距離是永遠不變的,不光是這個遊戲,壹般的遊戲都是,至少我沒見過不是的:D

上面講的東西總結出壹個結論,那就是我們只要得到這兩個地址中的任何壹個,就可以得到另外壹個,只要妳知道它們之間的偏移量是多少。

我們第壹步要做的就是得到這個地址,但是內存中的地址是動態改變的,得到也沒有用,這裏我就教妳把它變成靜態的,叫它永遠都不變!我繼續拿“楚留香新傳”為例,如果妳有這個遊的話就跟我壹起做,沒有的也沒關系,只要看懂這幾個步驟就行了。開工!

首先進入遊戲,查找內值的地址,得到的是:798695C(不知道為什麽這上遊並不是每次重起都改變內存地址),按Ctrl+D打開SoftICE,下命令:BPM 798695C W(寫這個地址時則中斷),回到遊戲中,打開人物屬性面板,遊戲中斷了,在SofitICE中妳會看到這條指令:

0047EB17 MOV EAX [EDX+000003F4] 下命令:D EDX+3F4將看到內力值

0047EB1D PUSH EAX

………………………………

………………………………

從上面可看出0047EB17處的指令是將內力值的指針送到EAX寄存器中,這是壹個典型的尋址方式,設想壹下,我們是到了EDX中的基址,那麽無論什麽時候只要用EDX+3F4就可以輕松的得到內力值的地址,因為000003F4是壹個常量,它是不會改變的,改變的只是EDX中的地址,所以只要有辦法得到EDX中的值就什麽都好辦了,妳明白了沒有?如果還是不懂,那麽請再看壹遍。現在要做的就是如何得到這個值,下面我教給妳如何做:

我的辦法就是設計壹段代碼,把EDX中的值存放到壹個地址中,然後運行這段代碼,再返回遊戲的原有指令繼續執行,什麽?補丁技術?SMC?隨妳怎麽說啦,只要運行正常就壹切OK啦:D

實際操作:

首先在程序中找壹段空白處來存放我們設計的代碼,很簡單,只要懂得壹些PE文件結構的朋友都會知道,壹般在EXE文件的數據段(.data段)的結尾都會有壹段緩沖區,我們可以在這段區域中寫任何東西,當然妳也可以用“90大法”找壹段空白區,但我還是推薦妳用我教給妳的方法。上同我提到,如果妳沒有PE文件查看工具我可以教妳用SoftICE查看,而且很簡單,只要壹個命令:MAP32 “模塊名”,看壹下我是怎麽做的妳就知道了。

Ctrl+D呼收出SoftICE,然後下命令:MAP32 CrhChs,這時妳應該看到EXE各個段的信息,我們要註意的只是.data段,既然要找的是數據段的結尾,那麽我們就從下壹個段開始向上找,如下:

.data 004FB000

.rsrc 00507000

.data的下壹個段是.rsrc段,它是從00507000開始的,也就是說以00507000為基礎向上壹個字節就是數據段的結尾,我所擇從00506950處開始寫代碼,說了這麽半天那麽我們的代碼到底是什麽樣子呢?修改後的指令又是什麽樣的呢?別急,請看下面:

修改0047EB17後代碼:

0047EB17 JMP 00506950 //跳到我們的代碼中去執行

0047EB1C NOP //由於這條指令原來的長度是6字節,而修改後的長度是5個字節,所以用壹個空指令補上

0047EB1D PUSH EAX

//我們的代碼:

00506950 MOV DWORD PTR EAX,[EDX+00003F4] //恢復我們破壞的指令

00506956 MOV DWORD PTR [00506961],EDX //把EDX保存以00506961中去

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、 註意要先寫入自己的代碼,然後再修改遊中的指令(下面的代碼沒有這樣做,因為不影響,但是妳應該註意這個問題)

#define MY_CODE5 0x00

#define MY_CODE6 0x90

//00506950

#define MY2_CODE1 0x8B

#define MY2_CODE2 0x82 //這部分是要寫入的機器碼的常量定義

#define MY2_CODE3 0xF4

#define MY2_CODE4 0x03

#define MY2_CODE5 0x00

#define MY2_CODE6 0x00

#define MY3_CODE1 0x89

#define MY3_CODE2 0x15

#define MY3_CODE3 0x61

#define MY3_CODE4 0x69

#define MY3_CODE5 0x50

#define MY3_CODE6 0x00

#define MY4_CODE1 0xE9

#define MY4_CODE2 0xBC

#define MY4_CODE3 0x81

#define MY4_CODE4 0xF7

#define MY4_CODE5 0xFF

//-----------------------------------------------------------------------------//

DWORD A1 =MY_CODE1;

DWORD A2 =MY_CODE2;

DWORD A3 =MY_CODE3;

DWORD A4 =MY_CODE4;

DWORD A5 =MY_CODE5;

DWORD A6 =MY_CODE6;

DWORD B1 =MY2_CODE1;

DWORD B2 =MY2_CODE2;

DWORD B3 =MY2_CODE3; //這部分是變量的定義

DWORD B4 =MY2_CODE4;

DWORD B5 =MY2_CODE5;

DWORD B6 =MY2_CODE6;

DWORD C1 =MY3_CODE1;

DWORD C2 =MY3_CODE2;

DWORD C3 =MY3_CODE3;

DWORD C4 =MY3_CODE4;

DWORD C5 =MY3_CODE5;

DWORD C6 =MY3_CODE6;

DWORD D1 =MY4_CODE1;

DWORD D2 =MY4_CODE2;

DWORD D3 =MY4_CODE3;

DWORD D4 =MY4_CODE4;

DWORD D5 =MY4_CODE5;

//--------------------------------------------------------------------------//

HWND hWnd =::FindWindow("CRHClass",NULL); //得到窗口句柄

if(hWnd ==FALSE)

MessageBox("遊戲沒有運行!");

else

{

GetWindowThreadProcessId(hWnd,&hProcId); // 從窗口句柄得到進程ID

HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|

PROCESS_VM_WRITE,FALSE,hProcId); //打開進程並得到讀與權限

if(nOK ==NULL)

MessageBox("打開進程時出錯");

else

{

//0047EB17

WriteProcessMemory(nOK,(LPVOID)0x0047EB17,&A1,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0047EB18,&A2,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0047EB19,&A3,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0047EB1A,&A4,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0047EB1B,&A5,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0047EB1C,&A6,1,NULL);

//00506950

WriteProcessMemory(nOK,(LPVOID)0x00506950,&B1,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506951,&B2,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506952,&B3,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506953,&B4,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506954,&B5,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506955,&B6,1,NULL);

//第二句

WriteProcessMemory(nOK,(LPVOID)0x00506956,&C1,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506957,&C2,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506958,&C3,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506959,&C4,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0050695A,&C5,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0050695B,&C6,1,NULL);

//最後壹句

WriteProcessMemory(nOK,(LPVOID)0x0050695C,&D1,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0050695D,&D2,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0050695E,&D3,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x0050695F,&D4,1,NULL);

WriteProcessMemory(nOK,(LPVOID)0x00506960,&D5,1,NULL);

CloseHandle(nOK); //關閉進程句柄

}

}

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//讀取並修改內力值

DWORD hProcId;

HWND hWnd =::FindWindow("CRHClass",NULL);

if(hWnd ==FALSE)

MessageBox("No");

else

{

GetWindowThreadProcessId(hWnd,&hProcId);

HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|

PROCESS_VM_WRITE,FALSE,hProcId);

if(nOK ==NULL)

MessageBox("ProcNo!");

else

{

DWORD buf1;

DWORD write;

BOOL OK=ReadProcessMemory(nOK,(LPCVOID)0x00506961,(LPVOID)&buf1,4,NULL); //讀取我們保存EDX中的基礎

if(OK ==TRUE)

{

write =buf1+0x000003F4; //得到內力值的地址

DWORD Writeed =0x00; //要修改的數值

BOOL B =WriteProcessMemory(nOK,(LPVOID)write,&Writeed,1,NULL);

if(B==FALSE)

MessageBox("WriteNo");

}

}

CloseHandle(nOK);

}

啊,寫的我手都麻啦,今天就到這裏了,才疏學淺難免會有遺漏,請大家指教,如果我不會或不喜歡用VC的話,妳可以在QQ上與我交流,我可以教妳如何用Delphi、C++Builder、Win32Asm或VC實同上面的功能。

(如轉載本篇文章請不要改動內容及作者!)

作者:CrackYY

Email:CoolYY@msn.com

OICQ:20651482

2001年,從雲風那兒得知了IDA這種好東東,看到他在解愷撒的遊戲資源,覺得好玩,也開始自己解壹些東東,當時壹口氣解了壹些遊戲的資源,當然,都不是很復雜的,主要是臺灣和日本的

後來在主頁上放過壹段時間,記得感興趣的朋友還挺多的,壹直沒時間說,現在大概聊壹下做法吧:)

工具當然是IDA+SoftIce,要自己寫解壓程序的話,還要有習慣的編輯器,我當然是用VC

其實,資源破解,並不是很復雜,方法大致有3種

1,硬性破解

通過觀察目標文件和反匯編代碼,分析出資源壓縮或者加密的格式,寫程序讀取改文件,並轉換成壹種自己可以識別的格式就OK了

這是自己動手解資源時最容易想到的做法

具體來說,也就是通過壹些特定函數,譬如 fopen、createFile這樣的文件相關函數,確定遊戲的解資源函數,然後就拼命的分析匯編代碼就OK了

我前期大部分資源都是這樣破解的,最好先用UEDIT分析壹下實際的文件,有些格式太簡單了,通過文件大小,用看的就可以了

這種方法,我解過的最復雜的就是神奇傳說系列,當時就感覺和GIF比較像,但又不太壹樣,因為對壓縮算法沒研究,所以就沒深究了,不過後來從網上看到文章說,那是壹個很通用的壓縮算法,壹些解壓工具就可以可以解開的,◎#¥%……真是不爽(不過還好,我只花了幾個小時就解開那個遊戲而已

2,Dump

等圖片載入後,直接從內存中導出

這種做法也很容易想到的,主要難點在於內存中資源的格式問題,可能對3D遊戲來說,這種解法比較容易壹些,畢竟紋理渲染這些,是顯卡完成的,不是軟件實現的

我了解到的有些人解魔獸的資源就是這樣解開的,hook OpenGL的壹些函數

我這樣解過壹些遊戲的文本(漢化用的文字),賽車遊戲的,為了獲取所有遊戲文本,特地將那款遊戲通關的說

3,直接調用遊戲的解碼函數解碼

和第2種做法類似,但是主動調用函數,基本上可以壹次將所有資源全部解開,不需要遊戲通關

當然,不是讓妳調用遊戲的解包模塊,畢竟很多遊戲都不是dll形式的

只能侵入到遊戲進程內部,找壹個合適的時機(壹般是載入其他文件的時候,中斷跳轉壹下,先把我們的事做完),調用內部函數,解開所有的資源

我解過壹款遊戲就是用這種方法,說起來,那款遊戲的資源壓縮率和rar差不多

0. 需求文檔

LZW壓縮算法是壹種新穎的壓縮方法,由Lemple-Ziv-Welch 三人***同創造,用他們的名字命名。它采用了壹種先進的串表壓縮,將每個第壹次出現的串放在壹個串表中,用壹個數字來表示串,壓縮文件只存貯數字,則不存貯串,從而使文件的壓縮效率得到較大的提高。奇妙的是,不管是在壓縮還是在解壓縮的過程中都能正確的建立這個串表,壓縮或解壓縮完成後,這個串表又被丟棄。

1. 基本原理

首先建立壹個字符串表,把每壹個第壹次出現的字符串放入串表中,並用壹個數字來表示,這個數字與此字符串在串表中的位置有關,並將這個數字存入壓縮文件中,如果這個字符串再次出現時,即可用表示它的數字來代替,並將這個數字存入文件中。壓縮完成後將串表丟棄。如"print" 字符串,如果在壓縮時用266表示,只要再次出現,均用266表示,並將"print"字符串存入串表中,在解碼時遇到數字266,即可從串表中查出266所代表的字符串"print",在解壓縮時,串表可以根據壓縮數據重新生成。

2. 實現方法

A. 初始化串表

在壓縮信息時,首先要建立壹個字符串表,用以記錄每個第壹次出現的字符串。壹個字符串表最少由兩個字符數組構成,壹個稱為當前數組,壹個稱為前綴數組,因為在文件中每個基本字符串的長度通常為2(但它表示的實際字符串長度可達幾百甚至上千),壹個基本字符串由當前字符和它前面的字符(也稱前綴)構成。前綴數組中存入字符串中的首字符,當前數組存放字符串中的尾字符,其存入位置相同,因此只要確定壹個下標,就可確定它所存貯的基本字符串,所以在數據壓縮時,用下標代替基本字符串。壹般串表大小為4096個字節(即2 的12次方),這意味著壹個串表中最多能存貯4096個基本字符串,在初始化時根據文件中字符數目多少,將串表中起始位置的字節均賦以數字,通常當前數組中的內容為該元素的序號(即下標),如第壹個元素為0,第二個元素為1,第15個元素為14 ,直到下標為字符數目加2的元素為止。如果字符數為256,則要初始化到第258個字節,該字節中的數值為257。其中數字256表示清除碼,數字257 為文件結束碼。後面的字節存放文件中每壹個第壹次出現的串。同樣也要音樂會 前綴數組初始化,其中各元素的值為任意數,但壹般均將其各位置1,即將開始位置的各元素初始化為0XFF,初始化的元素數目與當前數組相同,其後的元素則要存入每壹個第壹次出現的字符串了。如果加大串表的長度可進壹步提高壓縮效率,但會降低解碼速度。

B. 壓縮方法

了解壓縮方法時,先要了解幾個名詞,壹是字符流,二是代碼流,三是當前碼,四是當前前綴。字符流是源文件文件中未經壓縮的文件數據;代碼流是壓縮後寫入文件的壓縮文件數據;當前碼是從字符流中剛剛讀入的字符;當前前綴是剛讀入字符前面的字符。

文件在壓縮時,不論文件字符位數是多少,均要將顏色值按字節的單位放入代碼流中,每個字節均表示壹種顏色。雖然在源文件文件中用壹個字節表示16色、4色、2色時會出現4位或更多位的浪費(因為用壹個字節中的4位就可以表示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,正好用11位的二進制數表示,第2048-4095元素中值的範圍是0-4094,正好用12位的二進制數表示。用可變位數存貯代碼時,基礎位數為文件字符位數加1,隨著代碼數的增加,位數也在加大,直到位數超過為12(此時字符串表中的字符串個數正好為2 的12次方,即4096個)。 其基本方法是:每向代碼流加入壹個字符,就要判別此字符所在串在串表中的位置(即下標)是否超過2的當前位數次方,壹旦超過,位數加1。如在4位文件中,對於剛開始的代碼按5位存貯,第壹個字節的低5位放第壹個代碼,高三位為第二個代碼的低3位,第二個字節的低2位放第二個代碼的高兩位,依次類推。對於8位(256色)的文件,其基礎位數就為9,壹個代碼最小要放在兩個字節。

F. 壓縮範圍

以下為文件編碼實例,如果留心您會發現這是壹種奇妙的編碼方法,同時為什麽在壓縮完成後不再需要串表,而且還在解碼時根據代碼流信息能重新創建串表。

字 符 串: 1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,…

當 前 碼: 2,1,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的數據,如果選了其他的數據就出錯了。

4. 使用文檔

在進入程序後,通過選擇是壓縮、解壓縮還是退出程序。

壓縮文件:

1)提示:“Input file name?” 輸入:D:\cc\test.txt

2)提示:“Compressed file name?” 輸入:test.lzw

3)顯示:“Compressing………” 及 “*”表示文件壓縮的進度。

說明:如果輸入的文件不存在,將會重復提示,直到輸入正確文件位置和文件名。生成的test.lzw將會存放在程序所在的根目錄下。

如:程序放在D:\cc\下,則生成文件也在D:\cc\.

解壓縮:

1)提示:“Input file name?” 輸入:test.lzw

2)提示:“Compressed file name?” 輸入:test.txt

3)顯示:“Expand………” 及 “*”表示文件解壓縮的進度。

說明:如果輸入的文件不存在,將會重復提示,直到輸入正確文件位置和文件名。生成的test.lzw將會存放在程序所在的根目錄下。

ANI(APPlicedon Startins Hour Glass)文件是 MS-Windows的動畫光標文件,其文件擴展名為“.ani”。它壹般由四部分構成:文字說明區、信息區、時間控制區和數據區,即 ACONLIST塊。anih塊、rate塊和 LIST塊。

以下就是作為例子的文件內容(數據E)及ANI文件標準結構圖(圖):

1. 從(0000-006D)是 Wnd0WS 95& NT ANI文件的文字說明區部分

如妳想對妳開發的ANI文件提供壹點文字說明,並加入妳的版權信息,且同時它們又要被ANI文件播放軟件承認時,這是妳唯壹的選擇。要是妳覺得這樣做很麻煩,或者沒什麽好寫時,那妳完全可以去掉本塊中的全部內容,並將塊的大小置為0。切記,“塊識別碼

‘ ACONLIST’”和標識“塊的大小”這兩部分,***計 12字節,絕對不能被更改、移動及刪除,否則後果自負。

可能為了讓文字說明信息系統化,在ACONLIST塊內部包容了若幹子塊,本例中用到的兩個分別是:INFOINAM塊(提供本文件的解釋說明)和IART塊(用於插入版本信息)。說實在,諸位可以運用在 AVI文件中插入自定義塊的方法,加入自己的自定義塊,其結果只是ANI播放軟件把它當作壹個“JUNK”罷了。

0000-0003:多媒體文件識別碼:RIFF

0004-0007;文件大小( 2052h字節)-8字節

0008- 000F: ACONLIST塊識別碼,它是文字說明區開始的標誌

0010-0013:ACONLIST塊的大小(5Ah字節)

0014-001B:INFOINAM塊識別碼,標誌文件說明信息子塊的開始

001C- 001F: INFOINAM塊的大小( 20h字節)

0020-003F :文件說明信息子塊的內容“Application startingHour Glass”

0040-0043:IART塊識別碼,標誌版權說明信息於決的開始

0044-0047:IART塊的大小(26h字節)

0048- 006D:版權說明信息於塊的內容“Microsoft Corporation,Copyright 1995”

2.從(006E-0099)?

  • 上一篇:bamboo怎麽讀
  • 下一篇:盆栽的熊掌花多久澆壹次水?壹次澆多少?
  • copyright 2024編程學習大全網