(譯) 在可執行檔案中新增選單項 - by Fenri
在可執行檔案中新增選單項 - by Fenri
原文來源:
The Codebreakers-Magazine
Issue 2 - 2003
http://www.reverse-engineering.net
http://codebreakers.anticrack.de
http://codebreakers.reverse-engineering.net
(C) The Reverse-Engineering-Network
2003
21st July 2003
寫這篇短文是因為有許多人在anticrack.de 的REA論壇提出了這個問題.我希望藉此機會提供一些有用的資訊去幫助他們。我用一個簡單的Hello World應用程式示範,它使用MS VC++編寫。
任務: 新增允許的‘開啟’ 選單項和變灰的‘關閉’ 選單項在退出選單項之前。
工具: hex editor (例如 Hiew), 大腦(如你平常一般使用)
Ok, 開始工作
使用你熟悉和慣用的十六進位制編輯工具(如Hiew)開啟Hello.exe, 直接到資源區(.rsrc). 如果使用hiew 則按F8, 再按F6,進入.rsrc。(譯註:使用EXESCOPE 參見.rsrc中的pointer to RAW data也表示這個偏移值). 這樣,你就看到了IMAGE_RESOURCE_DIRECTORY(資源目錄),它的結構如下:
typedef struct _IMAGE_RESOURCE_DIRECTORY {
ULONG Characteristics;
ULONG TimeDateStamp;
USHORT MajorVersion;
USHORT MinorVersion;
USHORT NumberOfNamedEntries;
USHORT NumberOfIdEntries;
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
ULONG = 4 bytes, USHORT = 2 bytes 共16個位元組
這些東西對我們沒什麼大用,但你需要知道,哪裡是後面資料的開始. 因此,向前16個位元組你會看到一些IMAGE_RESOURCE_DIRECTORY _ENTRies (資源目錄入口地址), 它的結構:
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
ULONG Name;
ULONG OffsetToData;
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
以十六進位制格式,你將看到(類似的資料):
(譯註:為便於分析,翻譯時使用了win2003下的 NOTEPAD 5.2 作為演示樣例)
xx 00 00 00 xx 00 00 xx xx 00 00 00 xx 00 00 xx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
00008000h: 00 00 00 00 00 00 00 00 04 00 00 00 00 00 08 00 ;
00008010h: 03 00 00 00 50 00 00 80 04 00 00 00 A8 00 00 80 ;
03 00 00 00-50 00 00 80 - 04 00 00 00-A8 00 00 80
1 2 3 4 5 6 7 8
...
每個 IMAGE_RESOURCE_DIRECTORY _ENTRY(資源目錄入口) 是 8 位元組長。在給出的例項資料中,前8個位元組(03-80)對於我們來說並不重要(它通常用於: 圖示Icon, 選單Menu, 對話方塊Dialog...),但位元組從‘04’到‘80’(參見上面的示意資料,即9-16位)是非常重要的。
從9-16位,其中前4個位元組代表名稱(對於我們沒有用),第5-8位位元組代表偏移量,如果這個重要的標誌位即資料的最高位是1, 表示指向另一個IMAGE_RESOURCE_DIRECTORY(資源目錄), 否則,它指向IMAGE_RESOURCE_DATA_ENTRY(真正我們需要發現的位置)。
在我們的例子中,資料是 800000A8 (A8 00 00 80),最重要的標識位被設定為1(資料最高位),這表示,A8是從.rsrc區段開始到一個IMG_RES_DIR(資源目錄)的偏移量。
經檢測,資源段開始的偏移是8000,則在80A6處放置的是另一個IMG_RES_DIR(資源目錄),就像前面提過的,它也不重要,繼續跳過16位元組,你能看到下一個IMG_RES_DIR_ENTRY(資源目錄入口)。
000080a0h: 09 00 00 00 48 02 00 80-00 00 00 00 00 00 00 00 ;
000080b0h: 04 00 00 00 00 00 01 00-01 00 00 00 60 02 00 80 ;
跳過前4個位元組,它代表名字,後4個位元組是80000260 (60 02 00 80),標誌位依然是1,那繼續到8260(8000+260), 那裡是下一個IMG_RES_DIR(資源目錄),再跳過16位元組,又是一個IMG_RES_DIR_ENTRY(資源目錄入口),跳過4位元組(名字), 看到資料是00000440.
00008260h: 00 00 00 00 00 00 00 00 04 00 00 00 00 00 01 00 ;
00008270h: 04 08 00 00 40 04 00 00 00 00 00 00 00 00 00 00 ;
好了,標誌位為0,因此在00008440(8000+440)處就是我們要找的目標了-IMAGE_RESOURCE_DATA_ENTRY(資源資料入口),它的結構是
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
ULONG OffsetToData;
ULONG Size;
ULONG CodePage;
ULONG Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
只有前兩個域對我們來說是重要的,資料是 0011750 (資料偏移)和 330 (尺寸),我們一會兒要用到這些資料,因此記下IMAGE_RESOURCE_DATA_ENTRY(資源資料入口)的地址,在我們的例項中是8440.
00008440h: 50 17 01 00 30 03 00 00 E4 04 00 00 00 00 00 00 ; P...0...&.......
資料偏移 尺寸
(譯註:當尺寸第二位不為0時,資料偏移地址應減去該值 11750-300=0e750,原文未說明,經觀察發現,可能不正確,更多細節,參見有關技術資料)
現在,到了0E750,你應該可以在這裡看見選單資源:
0000e750h: 00 00 00 00 10 00 87 65 F6 4E 28 00 26 00 46 00 ; ......‡e&N(.&.F.
0000e760h: 29 00 00 00 00 00 01 00 B0 65 FA 5E 28 00 26 00 ; ).......°eú^(.&.
0000e770h: 4E 00 29 00 09 00 43 00 74 00 72 00 6C 00 2B 00 ; N.)...C.t.r.l.+.
0000e780h: 4E 00 00 00 00 00 02 00 53 62 00 5F 28 00 26 00 ; N.......Sb._(.&.
選單項的結構
00 00|00 00|10 00| 87 65 F6 4E 28 00 26 00 46 00 ;
屬性 ID 選單項名稱
前兩個位元組 C 不知道用途,可能僅起分隔符作用
3-4位元組 - 屬性 (描述見後)
5-6位元組 - 選單項的ID (對於彈出選單,此項不代表ID)
從第7位元組開始 C 選單項名稱 (當是彈出選單時,名字從第5個位元組開始)
注意一個例外: 在開始的選單項之前,有兩個空(Null)位元組作為開始標識
特性 C 我僅僅列出比較重要的屬性,完整的列表無法從winuser.h或網站上獲知
0800 C Separator (分隔符)
0000 C Enabled (允許)
0001 C Grayed (變灰)
0002 C Disabled (禁止)
0010 C Popup (彈出)
0080 C End (結束)
選單項的分割符,看起來象這樣:
00 00 | 00 08 | 00 00
屬性 名稱字串 (僅僅兩個空位元組)
例如,選單項如下
00 00 00 00 | 90 00 | 26 00 46 00 69 00 6C 00 65 00
00 00 | 80 00 | 69 00 45 00 26 00 78 00 69 00 74 00
你可以看到第一個選單項的屬性是 90 = 80 | 10 表示是彈出選單項,並且結束。
第二個屬性僅是 80 = End. 它不是彈出選單, 因此它肯定是子選單。
現在,我們要加選單項,首先應該知道它象是什麼樣子,如一個OPEN選單項應該象這樣:
00 00 | 00 00 |70 00| 26 00 4F 00 70 00-65 00 6E 00
屬性 ID & O p e n
你看,ID是 0070, 但它可以是任何未被使用的值. ‘O’字元前的(&)號將使得‘O’具有下劃線以及可以鍵入字母‘O’來啟用相關選單項
現在再設定一個‘Close’關閉選單項:
00 00 | 01 00 |71 00 | 26 00-43 00 6C 00-6F 00 73 00-65 00
屬性 ID & C l o s e
你可以看到,屬性是0001(表示灰色),ID值是自定義的。
在我的演示程式中(一個簡單的Hello World應用程式示範,僅有2個選單項,它使用MS VC++編寫)我在發現我的選單資源後的位置找到了一塊空間(通常是被‘0’填充的區域),在
6960,因此我寫了一個檔案選單,插入‘Open’和‘Close’選單項. 最後是一個退出選單項‘Exit’ ,它們的樣子如下:
00 00 00 00-90 00 26 00-46 00 69 00-6C 00 65 00
00 00 00 00-70 00 26 00-4F 00 70 00-65 00 6E 00
00 00 01 00-71 00 26 00-43 00 6C 00-6F 00 73 00
65 00 00 00-80 00 69 00-45 00 26 00-78 00 69 00
74 00 00 00
現在w, 寫下6960,它指向一個44(十六進位制)位元組的區域,
現在,回到剛才提到的那個地址(在演示的NOTEPAD裡是0E750,在我的HELLO WORLD裡是61F0,指向的地址是000067C8,尺寸是22),你應該已經記下來了,將它的內容改為新的地址(從 000067C8 到 00006960,尺寸. 然後改變尺寸,從 22 到 44)。現在儲存程式再執行它,我是可以看見我的‘Open’和‘Close’選單項了。如何,你明白了嗎?
有一件事情需要提醒你,當你希望在一個可執行檔案中,新增選單項時,可能需要改變相關的段(section)尺寸,這方面的資料,你可以比較容易的在網上查到。如果你高興,你可以在某個程式的‘退出’選單項前加上一道分隔符.
感謝你們大家
作者:FENRI
有關資料,請參見:
可知行檔案格式(The Portable Executable File Format - by Johannes Plachy)
PE檔案內部結構(Peering Inside the PE: A Tour of the Win32 Portable Executable File Format- by Matt Pietrek)
你應該看看這些資料,很不錯。
相關文章
- Qtum如何新增執行選項(或配置檔案)2018-07-16QT
- 圓形可滑動選單(可以動態新增選單項)2012-12-07
- Win10系統怎麼在右鍵選單新增“顯示/隱藏檔案”選項2017-03-05Win10
- objc系列譯文(6.3):Mach-O 可執行檔案2013-11-21OBJMac
- Oracle單例項+ASM新增控制檔案2015-07-22Oracle單例ASM
- 在html檔案中執行php程式碼2016-01-21HTMLPHP
- Java執行exe,bat等可執行檔案2008-07-27JavaBAT
- 從C檔案到可執行elf檔案2013-09-24
- 在Xcode專案中執行Python檔案2018-01-15XCodePython
- Mach-O 可執行檔案2018-02-27Mac
- maven 打包可執行 jar 檔案2016-09-29MavenJAR
- MATLAB生成可執行檔案2013-08-19Matlab
- JCEF 如何修改右鍵選單項(JCEF在右鍵選單中新增開發者選項-show dev tools)2016-10-21dev
- ubuntu 把檔案設定為可執行檔案2017-03-15Ubuntu
- cmake中新增 -g編譯選項2020-10-08編譯
- 在網頁如何呼叫客戶端的可執行檔案2017-12-03網頁客戶端
- 關於在DOS下可執行檔案中裝入或執行一些程式 (2千字)2001-10-25
- 建立可執行檔案build.sh2018-06-29UI
- Linux可執行的檔案(轉)2007-08-11Linux
- 從cmake解決clion編譯生成的可執行檔案(.exe)不可執行的問題2024-06-06編譯
- matlab (.m)檔案生成 windows 可執行(.exe)檔案2017-05-10MatlabWindows
- Win10系統怎麼在開始選單新增休眠選項2018-05-12Win10
- extjs 裡執行多行選中,和單行選中的操作2015-11-04JS
- 核心編譯選單中相關選項的意義(轉)2007-08-10編譯
- wine-在mac上執行exe執行檔案2024-06-17Mac
- 從原始檔到可執行檔案:原始檔的預處理、編譯、彙編、連結2022-05-03編譯
- 在CocosStudio中自建的檔案中沒有錨點的選項2017-01-08
- C語言判斷檔案是否存在,判斷檔案可讀可寫可執行2018-09-15C語言
- python2 反編譯pyinstaller打包的可執行exe檔案2020-10-07Python編譯
- 把可執行jar打包成exe檔案2018-10-10JAR
- 怎麼生成可執行的.jar檔案???????????2003-12-01JAR
- 0171-建立核心可執行檔案2024-07-13
- win10右鍵選單的顯示/隱藏檔案項怎麼自己新增2017-05-22Win10
- windows滑鼠右鍵選單新增檔案-開啟方式2022-06-18Windows
- 在Xcode中手動新增pch檔案2015-11-02XCode
- Wpf應用程式作為一個單獨的可執行檔案2018-10-24
- 【原創】將Java程式變成可執行檔案的簡單方法2009-04-15Java
- win10系統怎麼在右鍵選單新增BitLocker加密選項2018-11-08Win10加密