|
論壇說明 | 標記討論區已讀 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-12, 02:39 AM | #1 |
榮譽會員
|
我對DLL脫殼的一點見解。。
老大,您好!
很高興和您交流!我的一點見解,不成體統,請勿見笑。。 一般外殼都是加在PE文件最後,所以脫殼後獲得的真正的重定位表所指向的地方的RVA跟脫殼前是一樣的,哪位要是寫個加殼的東西將外殼加在PE文件所有節前面或中間(指外殼實體放在PE最前面或中間),不知道給脫殼又要增加多少麻煩。。建議D.Boy試試吧。。 加殼的DLL處理重定位表有n中方法,一般的有下面4種情況: 1、完整的保留了原重定位表,RVA也沒有變化(即在加殼的程序中 後看到的重定位表就原來真正的重定位表,我原來發給您的我 寫的加殼例子就是這樣); 2、原重定位表的RVA進行了加密,但重定位資料沒有加密(即將原 重定位資料做了搬移); 3、對原重定位表的RVA和重定位資料都進行了加密處理; 4、對原重定位表的RVA和重定位資料、以及原程序中被重定位項所 指向的資料同時進行了加密。 以上幾種情況中,都有可能在原重定位表中增加了外殼的重定位資料,所以脫殼後還要將外殼的重定位項去掉。當然,如果不是真正脫掉外殼(保留脫殼後的外殼屍體)去不去掉也無所謂,若真正脫了殼,一定要去掉,否則PE裝載時可能會報告:Windows錯誤,xxxxxxxx的位址不能為Write。 另外,DLL載入時候,基位址一般跟編譯器產生的基位址是不同的,所以脫殼後的程序中被原重定位項所指向的地方是已經重定位了的資料。所以,還要將這些地方還原為編譯器產生的資料。方法可以寫一個程序,掃瞄獲得的「真正的原重定位表」取得這些地方資料並減去脫殼時候的基位址,再加上編譯器產生時候的基位址(重定位項的內容一共有7種情況,但在PE中只能看到0和3這兩種情況,0---沒有什麼意義;3---對32位都要修正,即PE文件在重定位表中每項所指向的地方肯定是個32位的位址)。 第一種情況,是最簡單的,因為完全保留了原來的重定位表,所以重定位的程序讓PE裝載器給完成了。脫殼後只要將獲得得原來的重定位資料複製到脫殼後的程序的重定位表中,再按照上面的方法修正重定位項所指的地方的資料就可以了。 第二種情況,跟第一種情況不同之處是:對原程序重定位項所指向的地方,由外殼程序完成重定位。那麼關鍵的就是找到真正的原來的重定位表。可以通過追蹤外殼程序,找到外殼解密後的重定位表的位址,然後將這些資料複製下來放入脫殼後的重定位表中,再按照上面的方法修正重定位項所指的地方的資料就可以了。對於這種情況,也可以通過經驗直接檢視加殼後的程序的16進制資料,直接找到重定位表(這個好像要靠運氣)。 第三種情況,跟第二種區別不大,也可以通過追蹤外殼得到解密後的重定位資料。再按照上面的方法修正重定位項所指的地方的資料,再將我們獲得的真的重定位表資料放入脫殼後的程序的重定位表中就可以了。 第四種情況稍微複雜些,也是通過追蹤外殼得到解密後的重定位資料。然後還要看看外殼怎樣將重定位項所指向的資料還原的,並將這個還原方法同上面的「修正重定位項所指的地方的資料」結合起來修復這些資料。再將我們獲得的真的重定位表資料放入脫殼後的程序的重定位表中。 錯誤疏漏指出,懇請高手們指正! 附上我原來自己分析得重定位表的說明: ;------------------------------------------------------------- 以下部分是由Relocation表分析得出的結果:(以前沒有找到資料啊,只有自己瞎琢磨。。,現在看了看羅雲彬大俠的書,總算分析得差不多,結構名字我就不改了,可能關鍵字跟專業我的文件不太一致,各位見笑了。。) -- 重定位表格式: 重定位表以1000h大小為分隔段,因為ItemOffset最長為12位,即剛好為1000h。 IMAGE_RELOC STRUCT RVirtualAddress dd 0 SizeOfBlock dd 0 Type1 dw 0 ;其中:Bit15-Bit12 為類型type ;Bit11--Bit0 為ItemOffset IMAGE_RELOC ENDS -- 舉例: -- 如果某文件重定位表如下: 00 10 00 00 0E 00 00 00 01 30 08 30 00 00 以上說明:00001000h為本段RVirtualAddress;0000000Eh為本段重定位表的字元長度。 3001h為第一個重定位項,類型是3; 3008h為第二個重定位項,類型是3; 0000h為第三個重定位項,類型是0,對於這種全0的項,很多PE中都有,好像沒用。??? 如果還有更多索引,將重複上面資料結構,直到RVirtualAddress為NULL。 RVA的計算: RVA = RVirtualAddress + ItemOffset = RVirtualAddress + (Type1 & 0FFFh) 對於第一項:RVA = 00001000h + (3001h & 0FFFh) = 00001001h,即要對(ImageBase+1001)的4字元(一個32位的位址)進行重定位。 ;------------------------------------------------------------- Spring.W 2002/11/15 |
送花文章: 3,
|