[原創]■■易格式初步研究筆記■■

看雪資料發表於2004-11-01

易格式初步研究筆記


作者:monkeycz
電子信箱:coffin13@183.ha.cn
QQ:53719349

如有任何問題,請與我聯絡。倉促之作,必有不少錯誤,等待您的釜正,謝謝。

====================================================================

10月15日
1。凌晨的時候終於完成0.50版。順手傳到了易語言論壇。
2。休息休息,測試測試。
3。開始研究常量資料段的結構。
4。稍微研究了一下程式碼資料段,感覺能夠在較高的抽象上反編譯出來。

10月16日
1。繼續研究常量資料段的結構。感覺不是很複雜。
2。稍微看了一看視窗資料段的內容,感覺――滿頭漿糊,一點都不明白。

10月17日
1。DllCmd在編譯為易格式的時候,並不儲存引數,根據程式碼進行呼叫。也就是說呼叫的時候沒有在易格式內部進行引數檢查,只是編譯的時候進行檢查。
2。沒有在程式中被呼叫的DllCmd,編譯的時候並不封裝到易格式內,只儲存在原始碼中。
3。在常量資料段中,所有的文字常量以文字內容起始,以0x00結尾。
4。在常量資料段中,所有的檔案常量以0x0001起始,後面跟著檔案長度資料(DWord),然後是檔案的內容。沒有結尾。
5。被呼叫的DllCmd,如果沒有庫名,m_nDllFileNameConstOffset項為空。
6。被呼叫的DllCmd,如果沒有庫中的對應名稱,m_nDllCmdNameConstOffset項為命令名。
7。釋出了0.52版。同時又傳到了看雪論壇一份。
8。努力研究視窗資料段,搞不明白。今天估計是沒戲了。
9。關於視窗資料段的一點想法:沒有被呼叫的窗體不會被記錄到視窗資料段(和DllCmd一樣,這也能算是“全編譯”的一個側面證據吧);沒有在設計中改變的屬性的窗體被儲存到資料段中,好像不儲存屬性資料(待證)。

10月18日
1。研究窗體資料段毫無頭緒。
2。換換口味,研究一下重定位資訊。

10月19日
1。繼續研究重定位資訊。

10月20日
1。似乎明白了編譯後的程式碼對支援庫中的命令的呼叫方式。
2。@hlpfn資料段是執行時從核心支援庫中載入進來的(REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]),應該在核心支援庫中是一張表。然後透過重定位在執行的時候作為服務呼叫。
3。我也應該能寫一個易格式的可執行檔案編譯器。
4。還是不明白重定位的方法。
5。領養了一隻小貓(說是偷的也行,說是搶的也行),可愛的小傢伙。

10月21日
1。今天真是美妙的一天。套用金田一著名的臺詞:“一切迷底都解開了”。
2。昨天關於@hlpfn的推測是正確的。@hlpfn資料段正如其名,介面資料段。所有執行時呼叫的服務函式地址全部是在這張表中記錄的。服務的呼叫方式應該是這樣的:EAX中放置支援庫、DllCmd順序編號,EBX放置呼叫的命令編號(由服務提供)。然後Call一個地址,這個地址中放置有服務呼叫語句(類似於jmp dword ptr [0000000C]),其中的間接轉跳地址在裝載的時候經過重定位,呼叫介面資料段中的服務地址。介面資料段中不同的地址指標之指向的服務如下(重定位之前指向@hlpfn資料段的偏移):
-----------------------------------------------------------------------
0C     | krnln內部呼叫
-----------------------------------------------------------------------
08     | 呼叫其他支援庫中的命令
-----------------------------------------------------------------------
20     | 銷燬從系統申請到的自由記憶體,記憶體地址一般置入EBX後壓棧
-----------------------------------------------------------------------
04     | 呼叫DllCmd
-----------------------------------------------------------------------
2C     | 建立視窗
-----------------------------------------------------------------------
30     | 把一處地址壓棧(多是指向ret指令),供24號服務呼叫
-----------------------------------------------------------------------
24     | 結束當前程式
-----------------------------------------------------------------------
28     | 進入訊息迴圈
-----------------------------------------------------------------------

例如:

:004031C9 55                      push ebp
:004031CA 8BEC                    mov ebp, esp       ;為申請區域性變數做準備。易語言從棧中分配記憶體。
:004031CC 6A00                    push 00000000
:004031CE 6A00                    push 00000000
:004031D0 6A00                    push 00000000
:004031D2 6801030080              push 80000301
:004031D7 6A00                    push 00000000
:004031D9 6800000000              push 00000000
:004031DE 6804000080              push 80000004
:004031E3 6A00                    push 00000000
:004031E5 6800000000              push 00000000      ;重定位資訊框提示資訊的常量
:004031EA 6803000000              push 00000003
:004031EF BB00030000              mov ebx, 00000300  ;命令序號,300在這裡是訊息框的序號,2FC是輸入框,168是到文字,等等
:004031F4 E852000000              call 0040324B      ;轉跳到服務呼叫命令

……

:0040324B FF250C000000            jmp dword ptr [0000000C]  ;重定位到介面資料段,呼叫krnln內部服務。


3。發現了EcE的一個很低階的Bug,居然在計算m_aryReLocationItem中的成員的時候,拔高低位弄反了。結果前幾天我根據錯誤的結果死活都搞不明白究竟是如何重定位的。真是失敗!因為這樣一個錯誤浪費好些天的時間。不過因禍得福,如果不是一開始沒有搞明白如何重定位,估計線在我對@hlpfn資料段還不是很明白。立即修改EcE,終於計算出正確的結果,看起來舒服多了,和預想中的一樣。如果是在@code資料段中的重定位資訊,低三位記錄了當前重定位項在重定位的時候的基址,高29位記錄了當前重定位項記錄的需要重定位的資料在當前資料段中的偏移。重定位後的地址=[[頭資訊偏移+SECTION_INFO[當前段].m_nRecordOffset+RELOCATION_INF.m_dwOffset]+SECTION_INFO[m_btType].m_nRecordOffset]。
4。EcE更新到0.53版了,唯一更新的內容就是計算重定位資訊的Bug。
5。這樣的話,一切都很明瞭了,除了視窗資料段外。
6。現在應該可以寫一個非官方的易格式可執行檔案編譯器了,可以是完全不同的開發方式,完全不同的編譯方式,但是生成的可執行檔案是易格式的,同時還需要支援庫中的命令和核心支援庫的裝載。
7。如果要寫一個反編譯器的話,雖然不能反彙編到原始碼的樣子,但只要對呼叫了支援庫中的什麼命令、怎麼呼叫的、引數是什麼,已經可以知道了。反編譯後的程式碼應該抽象度比較高,更容易被看懂,因為應易語言編寫的程式的幾乎所有功能都是透過呼叫支援庫來實現的。
8。一個非技術性的問題:如果寫出了非官方的編譯器和反編譯器,不知道吳濤會有什麼想法,更不知道對易語言的發展有何影響。我不希望有壞的方面的影響,畢竟易語言是個好東西,我喜歡它,希望能夠繼續發展下去。但是經過分析,總覺得如果這樣的話,也許會有壞的影響,所以還是先考慮一下再說,或者問問公司裡的人的意思。
9。熄燈了,昨天領養回來的小貓也爬在我的棉拖鞋上睡著了。睡覺去,終於可以安心的睡個好覺了。至於視窗資料段的問題和其他非技術性的問題,明天再說吧。

10月22號
1。@hlpfn裡面的服務指標是動態從裝載器中載入的,所有命令全部是支援庫提供的(DllCmd除外),也就是說,易格式的跨平臺還是很有道理的。不過這個“平臺”應該是指作業系統,跨硬體平臺就現在的技術是不行了。如果從Windows移植到Linux中,應該只需要透過一個轉換器轉換一下就可以了,不需要重新編譯。當然如果使用了外部的DllCmd,就不一定了。

10月23號
1。易格式對支援庫(核心支援庫)的依賴太密切了,幾乎任何操作(除了數值操作和邏輯操作)都是透過呼叫核心支援庫中的服務來實現的,連呼叫DllCmd也要(把引數壓棧,把DllCmd命令名稱對EAX賦值)透過服務,這必然會造成速度上的滯緩(雖然可能感覺不出來)。這種方法對於程式在作業系統間的移植很有好處,不過付出的代價也不小。
2。易語言編譯究竟能否算是全編譯呢?的確它編譯出的程式的執行不是透過解釋原始碼或者中間程式碼來實現的,所有的命令被全部編譯為機器程式碼,這應該就算是全編譯了。但是它生成的程式我認為不能算是原生應用程式。畢竟裡面到處充斥著對核心支援庫服務的呼叫。同樣是呼叫,這就和原生應用程式對系統API的呼叫性質不同。它屬於更高階抽象的呼叫。不是和作業系統緊密結合的,而是獨立於作業系統的。從另一種意義上來說,核心支援庫的服務也算是一種解釋執行,不過它是更低階的解釋(相比於其他透過解釋執行的程式),只獨立與作業系統,沒有抽象到虛擬執行。不過這顯然是為了在作業系統間移植而做出的一種選擇,並非技術上的不成熟。
3。又發現了一個EcE的Bug。真是疏忽,居然在讀取DataDirectory的成員VirtualAddress和isize的時候相互弄反了。修改了一下,現在是0.54版。
4。那隻小貓居然不會自己洗臉,真是崩潰!髒死了,難道要我給他洗澡?現在它吃的比我還好,太不公平了。還沒想好給它起什麼名字,叫貓仔?是不是難聽了點?我一向不會起名字。

10月24日
1。看了幾段易語言浮點運算的彙編程式碼。
2。修正了前面寫的幾處原先判斷錯誤的地方。比如20服務的功能以前就判斷錯了。
3。託人給貓仔洗了澡,從灰貓變成白貓了。晚上抱它去一個朋友家,回來的時候它居然尿在我身上了。又要洗衣服了,苦啊!

10月25日
1。碌碌無為的一天。好像唯一干的正事,就是在寫易盟的一個模組。

10月26日――10月27日
1。幫別人脫了個殼,好像叫什麼“軟體保護神”的。感覺現在流行的加殼工具對易格式可執行檔案除了壓縮方面還有用外,保護方面就差多了。易格式作為一個整體是不可分割的。並且僅僅是借住在PE格式裡面的。所以即使PE原體被加殼軟體壓縮加密過了,但是易格式的裝載器還是需要一份完整的易格式映象來裝載執行的。也就是說,在裝載器準備裝載的時候,當前被加殼保護的易格式可執行檔案的易格式部分已經有一份完整的映象在記憶體中等待裝載了。否則它不可能被執行。所以只要在這個時候把這份映象從記憶體中複製出來就可以了。這樣我們就有了程式的“核心”。剩下要做的工作就是要給他找一副“骨骼”――生成一個.ecode段足以放下被複製出來的易格式的易語言編譯出來PE原體,並把我們的植入到“骨骼”中的相應位置(.ecode段中),然後再給他正一正血脈――修復重定位資訊和裝載資訊(因為一般我們提取易格式的時候,它已經被裝載器裝入過了,也就是說已經經過重定位了),包括PE部分的裝載資訊(這個一般不用改),易格式頭部分的裝載資訊(一般也不用改)和各資料段中的重定位資訊(這個手工做起來可是一項浩繁的工程,如果你面對的是一個大程式的成千上萬條的重定位資訊,你需要做的就是,高喊一聲“My God!”,然後慢慢一個個的核對修改那些淘氣的東西)。經過這番大手術,我們終於有了――一隻沒殼的――烏龜:)
2。計劃有空再寫一些東西,計劃中的有:易格式動/靜態提取器,PE骨骼生成器,易格式合成器,易格式重定位自動修復器。反正都是一些相關的軟體。
3。26日黃昏的時候,大概5點左右吧,我同寢室的一個同學因為和老師發生矛盾,被那個老師夥同其他的幾個老師毆打後,送到了保衛處。等我得到訊息趕去,那群學校保安極度猖狂,對我們大肆辱罵挑釁,最後數十名保安當著我們學校老師的面把我們給毆打了。我還沒有太大的事,但是我的同學卻受傷嚴重,被送到了醫院。據檢查,身上多處外傷,包括眼睛,滿臉都是淤血,更慘的是,鼻骨多處骨折,鼻中隔被撕裂了一個洞,還少了一塊軟骨。其情慘不忍睹。據醫生說,從未見有人下手這樣狠的。學校保安真不是東西!據說這樣的事情以前也屢有發生,只是未有過這麼嚴重的。現在我那個同學還在醫院裡痛苦的躺著。據說學校竟然要開除那位同學!…………我無話可說!實在是無話可說!這還是一所代表著知識與文明高等學府的所作所為麼!不知道事情明天會怎樣。最近很多時間要處理這件事了,筆記估計會斷斷續續的。嚴重鄙視那些缺乏做人最基本的良知,瘋狂殘暴,心理扭曲變態的狗一樣的東西。沒想到平日裡只是在報紙和電視上當作股市看的事情,有一天就會突然的發生在我身邊的同學的身上。希望我的朋友能儘快好起來,同時不受處分,而兇手也要受到應有的制裁!
4。26日晚上我在醫院陪了一個晚上,今天基本上又都奔波於學校和醫院之間,所以兩天的筆記就合起來寫了。


====================================================================

(未完待續)

後記:

不好意思浪費了大家寶貴的時間看完了這麼長的一篇東西,說了很多廢話,內容也不是太實用,只是希望能有人用的上。幾天裡斷斷續續寫的,詞不達意,錯誤多多,希望有達人予以指正,謝謝。

相關文章