全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1231
推到 Plurk!
推到 Facebook!

從問題到結果 ――EXE2SWF的開發手記

 
kunying
一般會員


發表:17
回覆:28
積分:19
註冊:2002-03-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-16 02:28:54 IP:211.74.xxx.xxx 未訂閱
從問題到結果 ――EXE2SWF的開發手記 出處:電腦愛好者 責任編輯:zwg [02-3-26 15:57] 作者:Daffodil 從問題到結果 ——EXE2SWF的開發手記 隨著Macromedia Flash 5的閃亮推出,Flash在網路多媒體應用方面已經佔據了不可動搖的地位,再加上中國閃客們的無私勞動,許多經典歌曲,比如“東北人”、“第一次” 等等都有了Flash版本的MTV,真是別有一番情趣。然而,網路上許多Flash作品都是EXE形式的,雖然方便了沒有安裝Flash插件的朋友,但是EXE形式的Flash不能用於網頁製作,更不用說分析Action什麽的了。由於手邊沒有免費的EXE2SWF工具,於是決定自己DIY一個,一顯Programmer本色! 一、開發工具 我用到的開發工具有Delphi6,最好用的RAD工具; UltraEdit,強大的16進制編輯工具;ShowGood三國系列中的財神到.swf、桃源結義.swf、神啊救救我吧.exe、割須棄袍.exe;最後就是思考,最有力也是最根本的工具。^_^ 二、基本思路 首先我設想了一個基本思路:EXE形式的Flash包含兩部分,Flash播放器和跟在播放器後面的Swf文件,因爲BMP2EXE、MP32EXE等軟體都是這麽做的。是不是這樣呢?我們動手看一看吧! 用UltraEdit打開“財神到.swf”和“桃源結義.swf”分析文件頭,非常明顯,文件頭都包括相同的ASCII碼“FWS”,估計這是Flash文件的識別字。用UltraEdit打開“神啊救救我吧.exe”,文件全長1183046位元組。按下Ctrl F調出搜索對話方塊,在Find What後填入“FWS”並且勾上“Find ASCII”,搜索。果不其然,在5c000處找到了“FWS”,接著的部分也和“財神到.swf”中的非常相似,可見假設很有可能是正確的。順藤摸瓜,查看兩個.swf文件的文件尾,都是若干個00加上40 00 00 00的形式,然而“神啊救救我吧.exe”的文件尾卻是若干個00加上40 00 00 00再加上120d3e處的56 34 12 FA 3E 4D 0C 00。最後這八個位元組會是什麽呢?再打開“割須棄袍.exe”,發覺它的最後八個位元組是56 34 12 FA 82 F5 12 00。聰明的你一定猜到56 34 12 FA是EXE形式Flash文件的識別字了吧?經過檢查其他EXE形式的Flash,事實證明了這個猜測是正確的。至於3E 4D 0C 00是什麽呢?不妨把它當作一個32位元整數,注意到低位元組和高位元組的逆序,3E 4D 0C 00就應該等於00 0C 4D 3E,也就是十進位的806206。OK!至此我們已經獲取了足夠多的資訊,接著就看看有什麽巧合吧!顛來倒去,不難發現,把“神啊救救我吧.exe”中swf部分的結束位址120d3e減去起始地址5c000,不就正好得到806206? 接下來要辦的事情就簡單了,我們動手證實一下。還是利用UltraEdit,把5c000至120d3e之間的資料粘貼出來,保存爲一個.swf文件,用IE打開一看,這不就是久違了的陳小春的歌嗎?呵呵,大功告成! 順便說一句,如果好奇的話,你還可以把0至5c000的資料直接保存成.exe文件看看,呵呵,驚奇吧,就是Flash 5中的Standalone Player! 三、編寫程式 在正式編寫程式之前,我想先花一些時間介紹Delphi 中的文件流操作。如果你已經對這個非常熟悉了,可以跳過去,直接閱讀後文的代碼。否則,請花一點時間看一看,這對於你閱讀下面的代碼非常有幫助。 在Delphi中,所有流物件的基類爲TStream類,其中定義了所有流的共同屬性和方法。那什麽是流呢?簡單來說,流就是建立在面向物件基礎上的一種抽象的處理資料的工具。流中定義了一些處理資料的基本操作,如讀取資料、寫入資料等,程式師只是面對流進行所有操作的,不用關心流的另一頭資料的真正流向。我們程式中將要使用TFileStream,它是TStream最常用的派生類。使用 TFileStream操作文件要比Object Pascal基本文件操作方便得多。TFileStream的基本操作是這樣的:首先create一個實例,然後用try...finally TFileStream.free的格式操作,“...”部分可以用TFileStream的ReadBuffer、 Seek、 WriteBuffer、CopyFrom方法來操作文件流。此外,流不但可以處理文件,還可以處理動態記憶體、網路資料等多種資料形式。編寫程式時善加利用流,將會大大提高編程的效率。 好了,現在讓我們正式開工。首先我們先設計表單。打開Delphi,首先在表單上添加兩個Button、兩個Edit、一個OpenDialog以及若干個Label工具,介面設計以及控制項 Name屬性,其他的採用預設值。 btnOpen是用來打開硬碟上EXE形式的Flash文件的,雙擊之,添加如下的代碼: procedure TForm1.btnOpenClick(Sender: TObject); begin // 通過OpenDialog讓用戶選擇EXE形式的Flash if OpenDialog.Execute then begin edtSourceExe.Text := OpenDialog.FileName; // 自動生成.swf格式的檔案名,方便用戶 edtTargetSwf.Text := ChangeFileExt(edtSourceExe.Text, '.swf'); end; end; btnConvert是用來轉換文件格式的按鈕,雙擊之,添加如下代碼: procedure TForm1.btnConvertClick(Sender: TObject); var // 分別處理EXE、SWF文件的文件流 SourceStream, DestinyStream: TFileStream; // SWF文件的大小 SwfFileSize: Cardinal; begin // 打開EXE形式的原始檔案 SourceStream := TFileStream.Create(edtSourceExe.Text, fmOpenRead or fmShareExclusive); try // 讀取文件標誌 SourceStream.Seek(- 2 * sizeof(integer), soFromEnd); SourceStream.ReadBuffer(SwfFileSize, sizeof(integer)); // 判斷讀到的文件標誌是否和FA123456相同 // 借此判斷是否是Macromedia官方格式的Flash文件 if SwfFileSize = $FA123456 then begin // 讀取SWF文件的大小 SourceStream.ReadBuffer(SwfFileSize, sizeof(SwfFileSize)); SourceStream.Seek(- SwfFileSize - 2 * sizeof(integer), soFromEnd); // 打開目標SWF文件 DestinyStream := TFileStream.Create(edtTargetSwf.Text, fmCreate); try // 從EXE文件流中讀取資料 DestinyStream.CopyFrom(SourceStream, SwfFileSize); ShowMessage('File has been converted successfully!'); finally // OK,釋放文件流 DestinyStream.Free; end; end else ShowMessage('Unknown type of executable flash file!'); finally // OK,釋放文件流 SourceStream.Free; end; end; 程式比較簡單,參考代碼中的注釋,相信程式很好理解。現在按下F9運行,打開一個EXE形式的Flash文件,按下Convert鍵,相應的SWF形式的Flash便生成了,我們的目的也就達到了。原理分析清楚了,再做一個SWF2EXE也是很簡單的事情,只需要在文件頭部依次追加Macromedia Flash 5中的Standalone Player、SWF文件、FA123456標誌以及SWF文件長度即可。 下面給出簡單的示例代碼,僅供參考: function Swf2Exe(Source, Destiny, Linker: string): string; var // Source、Destiny、Linker分別是swf、exe和Standalone Player的檔案名 SourceStream, DestinyStream, LinkStream: TFileStream; flag: Cardinal; SwfFileSize: integer; begin result := 'something error'; // 建立EXE文件 DestinyStream := TFileStream.Create(Destiny, fmCreate); try // 追加Standalone Player LinkStream := TFileStream.Create(Linker, fmOpenRead or fmShareExclusive); try DestinyStream.CopyFrom(LinkStream, 0); finally LinkStream.Free; end; // 追加SWF文件 SourceStream := TFileStream.Create(Source, fmOpenRead or fmShareExclusive); try DestinyStream.CopyFrom(SourceStream, 0); // 追加FA123456標誌 flag := $FA123456; DestinyStream.WriteBuffer(flag, sizeof(integer)); // 追加SWF文件長度 SwfFileSize := SourceStream.Size; DestinyStream.WriteBuffer(SwfFileSize, sizeof(integer)); result := ''; finally SourceStream.Free; end; finally DestinyStream.Free; end; end; 至此,SWF與EXE互相轉換的程式全部完成了。程式能夠正確識別Flash4以及Flash5生成的EXE形式的Flash文件。不可否認,這個程式也不是萬能的,網路中仍然存在一些非Macromedia官方的EXE形式的Flash文件。如果你掌握了文件分析的本領,那麽這應該也不是什麽難事吧? 程式在Delphi6、Windows98/2000下調試通過。 ________________________ 「有時候你以為天要塌下來了,其實是因為你站歪了!」
------
________________________
「有時候你以為天要塌下來了,其實是因為你站歪了!」
系統時間:2024-05-13 5:10:25
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!