1. 程式人生 > >C/C++殼與彙編殼的不同以及DLL殼相對於EXE殼的難點

C/C++殼與彙編殼的不同以及DLL殼相對於EXE殼的難點

這個月主要是學習PE檔案以及殼。革命尚未成功,先記下遇到的難點吧。C/C++殼與彙編殼的不同與DLL殼相對於EXE殼的難點看起來是不同的話題,但兩者有一定的關聯性,暫且放在一起吧。而且後面一個難題我還在攻克中,不能提供答案,只能讓人思索。

C/C++殼與彙編殼的不同

很奇怪的一件事,我發現大多數殼都是彙編寫的,C/C++殼很少。當然不可否認的是,殼主要是指標的操作(加殼程式還得算上檔案IO),彙編相對於C/C++操縱指標起來更加得心應手。尤其是彙編可以直接操縱堆疊,由此有了兩大優勢:一、方便資料定址,二、方便堆疊平衡。

再加上操縱PE檔案有許多現成的彙編程式碼可供參考(羅雲彬寫的Windows環境下32位彙編程式設計有專門的PE檔案一章),除錯殼也只能用匯編(除非有人能成功使得C/C++殼的pdb除錯符檔案可用,這想來應該是件浩大的工程)。

這樣算來,無怪乎大多數殼是用匯編寫的了。不過能熟練用匯編寫程式的人畢竟是少數,C/C++相比於其它高階語言,算得上是最接近彙編的了。對我而言,在C/C++殼基礎上可以方便的重構,雖然有學好彙編的想法,但是真正學好彙編不是短期內能完成的事情。

(以上是個人看法,實際情況不得而知)

DLL殼相對於EXE殼的難點

由於C/C++殼與彙編殼的不同,C/C++程式設計師寫起殼來比彙編程式設計師遇到的困難更多一些,尤其是在支援DLL加殼上。

我現在試圖使一個現成的C/C++殼支援DLL,遇到困難如下:

一、重定位

這個問題的描述就引用Writing your packer一文中的話吧

Since the stub is a parasite, and since it will have to be

located in a spot at the original application's convenience,

we will have to be relocating it dynamically in the packer

application. To help with this we will make the stub with

relocation records. These are usually used for dlls when

they can't be loaded at their preferred address.

......

If you're an avid ASM coder, many things are more

straightforward since you can take care to produce

positionindependent

code.

不解釋,你懂的。

二、堆疊平衡

引用《加密與解密》一書的話描述這個問題

編寫加殼軟體時,必須保證外殼初始化的現場環境(各暫存器值)與原程式的現場環境是相同的(主要是ESP、EBP等重要的暫存器值)。加殼程式初始化時儲存各暫存器的值,外殼執行完畢,再恢復各暫存器內容,最後再跳到原程式執行。

......

可以把整個外殼當作一個函式或子程式來理解,這個過程遵守堆疊平衡的原理。

我現在的問題就是執行到原程式的OEP,堆疊平衡被破壞了。大眼瞪小眼,有些不知所措的感覺。

三、DLL相對於EXE的特點,DLL的入口點在整個過程中至少執行兩次。一次是開始時,用來對DLL做一些初始化。至少還有一次是在退出時,用來清理DLL再退出。

因此對於殼而言,退出時再次進入入口點,外殼跳過相關的初始化程式碼。

由於沒有完成這方面工作,我測試加殼DLL退出時在解壓縮部分報錯,提示訪問非法地址。

目前遇到以上三個難題,第一個已經解決,但是不清楚是否有副作用。也許在真正解決完這個問題的路上會碰到更多的難題也不一定。