如何修改可執行檔或DLL中的圖標icon ? |
答題得分者是:jackkcg
|
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
lcsboy
版主 ![]() ![]() ![]() ![]() ![]() 發表:87 回覆:622 積分:394 註冊:2002-06-18 發送簡訊給我 |
|||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 各位大大,我知道利用ExtractIcon()API函数可以获得可执行档或DLL档的 Icon,如果我自己有一个图标ICON,想将原来可执行档或DLL中的icon换掉, 那么我该怎么做呢?可否提供简单的范例?谢谢!!!以下內容「轉貼」自 Platform SDK 關鍵字「Updating Resources」
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
我刚才先试了一下RaynorPao大大提供的方法,
但在
// Locate the dialog box resource in the .EXE file.
hRes = FindResource(hExe, "AboutBox", RT_DIALOG);
if (hRes == NULL)
{
ErrorHandler("Could not locate dialog box.");
}
这个地方就过不去了。
我是将hRes = FindResource(hExe, "AboutBox", RT_DIALOG);
改成了hRes = FindResource(hExe, "AppIcon", RT_ANIICON);
结果找不到,我又换了RT_GROUP_ICON,RT_ICON,结果还是不行,
这是为什么呢?请PaynorPao大大指点一下可以吗?谢谢!!!
(如果这个方法可行,我觉得这个方法好一点) 我看了lcsboy版主提供的资料,是介绍PE档内资源的具体分布和结构情况,
非常的详细,使我知道了不少的知识,我再试试您提供的这个方法怎么样,
非常感谢您的帮助,谢谢!!!
|
||
frankiech
中階會員 ![]() ![]() ![]() 發表:7 回覆:78 積分:52 註冊:2002-08-29 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 改成了hRes = FindResource(hExe, "AppIcon", RT_ANIICON); 结果找不到,我又换了RT_GROUP_ICON,RT_ICON,结果还是不行, 这是为什么呢?请PaynorPao大大指点一下可以吗?谢谢!!! (如果这个方法可行,我觉得这个方法好一点)hRes=FindResource(hExe, MAKEINTRESOURCE(n), RT_GROUP_ICON); 備註:n 代表原本這個 icon 在 rc 檔中的 id 如果你想讀取別人 exe 或 dll 檔案中的 icon 的話 一開始一定無法知道你要讀取 icon 的 id (除非你用 vc 以 resource 檔案的方式開啟~~就可以看到) 因此~~你可以利用「列舉」的方式 找出所有符合的 icon -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
非常感谢RaynorPao大大的指点,但现在还是有问题: HRSRC hResLoad; // handle to loaded resource
HANDLE hExe; // handle to existing .EXE file
HRSRC hRes; // handle/ptr. to res. info. in hExe
HANDLE hUpdateRes; // update resource handle
char *lpResLock; // pointer to resource data
BOOL result;
// Load the .EXE file that contains the dialog box you want to
//copy.
hExe = LoadLibrary("C:\\My Documents\\test.exe");
if (hExe == NULL)
{
Application->MessageBox("Could not load
exe.","Warning",MB_OK);
} // Locate the dialog box resource in the .EXE file.
for(int n=0;n<10000000;n )
{
hRes = FindResource(hExe,MAKEINTRESOURCE(n),RT_GROUP_ICON);
if(hRes!=NULL)break;
}
if (hRes == NULL)
{
Application->MessageBox("Could not locate dialog box.","Warning",MB_OK);
} 我已经列举到10000000还是不行,如果再往下加下去,程式检测的时间
会变的更长,有什么办法可以解决吗?再指点一下小弟我,谢谢!!!
|
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 非常感谢RaynorPao大大的指点,但现在还是有问题: 我已经列举到10000000还是不行,如果再往下加下去,程式检测的时间 会变的更长,有什么办法可以解决吗?再指点一下小弟我,谢谢!!!建議你先跳過這個問題 先確定用 vc 開啟你的 text.exe (用 resource file 的方式開啟) 看能不能找到你要的 icon 然後記下它的 id 先用這個 id 繼續接下來的流程 等一切都正常了 再來試「列舉」 -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
轉貼資料 對PE資源的研究心得 前言:沒什?好說的,發現這方面的資料全是英文的,於是我一邊研究,一邊翻譯,一邊寫出自己的心得。
希望大家尊重我的勞動成果,轉貼保持完整。
資源一般使用樹來保存,通常包含3層,在NT下,最高層是類型,然後是名字,最後是語言。 一個PE文件是否包含資源檔案,通常檢測塊表(Section Table)中是否含有'.rsrc',不過這個方法對有些PE文件無效。
一個類型表結構如下 ——————————————————————————
| RESOURCE DIRECTORY |
——————————————————————————
| RESOURCE DATA |
——————————————————————————
資源表1(Resource File Layout)
其中的資原始目錄(RESOURCE DIRECTORY)結構如下: —————————————————————————— | RESOURCE FLAGS |
——————————————————————————
| TIME/DATE STAMP |
——————————————————————————
| MAJOR VERSION |MINOR VERSION |
——————————————————————————
| # NAME ENTRY |# ID ENTRY |
——————————————————————————
| RESOURCE DIR ENTRIES |
——————————————————————————
資源表2(Resource Table Entry)
在DELPHI中的申明 { Resources }
PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;
IMAGE_RESOURCE_DIRECTORY = packed record
Characteristics : DWORD;
TimeDateStamp : DWORD;
MajorVersion : WORD;
MinorVersion : WORD;
NumberOfNamedEntries : WORD;
NumberOfIdEntries : WORD;
end
其中: RESOURCE FLAGS 通常設置?0
TIME/DATE STAMP 資源編譯器建立此資源的時間/日期,可能?0
MAJOR/MINOR VERSION 版本資訊
# NAME ENTRY 使用名字的資源條目的個數,包含一個使用名字的目錄條目的陣列。
# ID ENTRY
使用ID數位的資源條目的個數,包含一個32位元的整數ID號,同用名字一樣。
這個目錄緊接著會是一個不定長度的目錄條目,不管用的名字還是ID,都是用昇冪排列。
這個不定長度的目錄結構如下: 31 0 ——————————————————————
| NAME RVA/INTEGER ID |
——————————————————————
| E | DATA ENTRY RVA/SUBDIR RVA |
——————————————————————
資源表3(Resource Directory Entry)
在DELPHI中的申明: PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;
IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record
Name: DWORD; // Or ID: Word (Union)
OffsetToData: DWORD;
INTEGER ID 包含一個識別資源的整數ID
如果在根目錄,這個ID表示的意義如下
資源類型
1: cursor
2: bitmap
3: icon
4: menu
5: dialog
6: string table
7: font directory
8: font
9: accelerators
10: unformatted resource data
11: message table
12: group cursor
14: group icon
16: version information
NAME RVA 名字的相對實際地址,包含一個31位的相對資源的Image Base的地址。表的形式見表4
E 一位的不可缺少的識別碼(mask 80000000h) 如果這位?0,則?Resource Data Entries,其中DATA RVA = 31位的(mask 7fffffffh) 資料條目的地址。結構見表5
如果這位?1,則表示接另一個子目錄(Subdirectory Entry)。
{ 此函數檢驗 offset 是一個字串名還是一個目錄 } { IMAGE_RESOURCE_NAME_IS_STRING
= IMAGE_RESOURCE_DATA_IS_DIRECTORY
= $80000000 }
function HighBitSet(L: Longint): Boolean;
begin
Result := (L and IMAGE_RESOURCE_DATA_IS_DIRECTORY) < > 0;
end;
{ 下面兩個函數用於去掉E位元剩下的值或者指標 } {IMAGE_OFFSET_STRIP_HIGH = $7FFFFFFF;}
function StripHighBit(L: Longint): Longint;
begin
Result := L and IMAGE_OFFSET_STRIP_HIGH;
end;
function StripHighPtr(L: Longint): Pointer; begin
Result := Pointer(L and IMAGE_OFFSET_STRIP_HIGH);
end;
每一個資原始目錄名?如下格式 ——————————————————————
| LENGTH | UNICODE STRING |
——————————————————————
| LENGTH | UNICODE STRING |
——————————————————————
表4(Resource Directory String Entry)
在DELPHI中的申明 PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U;
IMAGE_RESOURCE_DIR_STRING_U = packed record
Length : WORD;
NameString : array [0..0] of WCHAR;
end;
LENGTH 就是字串的長度
UNICODE STRING
Unicode的字串.
資源資料表結構: —————————————
| DATA RVA |
—————————————
| SIZE |
—————————————
| CODEPAGE |
—————————————
| RESERVED |
—————————————
表5(Resource Data Entry)
在DELPHI中的申明 PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY;
IMAGE_RESOURCE_DATA_ENTRY = packed record
OffsetToData : DWORD;
Size : DWORD;
CodePage : DWORD;
Reserved : DWORD;
end;
DATA RVA 資源的相對實際地址,包含一個32位相對于資源Image Base的地址。
SIZE
資源的大小。
CODEPAGE
沒什?說的,好像?解碼方面設置的。
RESERVED
一定?0
好了,差不多資源這部分分析玩了,其他部分我還在研究:) 使用 軟體工具
抓出及更換exe或dll裡的resource
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=19181 pexsetup試用版(視窗除錯組譯軟體)
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=19619 參考看看
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
RaynorPao大大,按照您说的直接用ID名可以过去,但在下面的地方受阻: // Open the file to which you want to add the dialog box resource.
hUpdateRes = BeginUpdateResource("C:\\My Documents\\\\test1.exe", FALSE);
if (hUpdateRes == NULL)
{
Application->MessageBox("Could not open file for writing.","Warning",MB_OK);
} 总提示“打不开文件”,我换了几个目录和可执行档都是同样的错误,
您看这能是什么问题呢? 盼指教,谢谢!!!
|
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: RaynorPao大大,我已经用VC打开test.exe档案,看到里面的ICON的ID了, 我马上测试一下您提供的程式的下面部分。啊,幸福!!! (1)如何從 vc 中看某個 exe or dll 的 resource?? (1.1)開啟 vc (1.2)選擇 file/open 出現「開啟檔案」的 dialog box (1.3)把「檔案類型」combobox 改成「所有文件(*.*)」 (1.4)把「Open as」combobox 改成「Resource」 (1.5)然後點選你要開啟的檔案(*.exe or *.dll) (1.6)按下「開啟」button 後,就可以看到了
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言:引言: RaynorPao大大,我已经用VC打开test.exe档案,看到里面的ICON的ID了, 我马上测试一下您提供的程式的下面部分。啊,幸福!!!(3)如何列舉出 *.exe or *.dll 中的 resource type & name?? 嗯~~我怕這頁貼不下了~~我貼到下一篇吧
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: RaynorPao大大,按照您说的直接用ID名可以过去,但在下面的地方受阻: hUpdateRes = BeginUpdateResource("C:\\My Documents\\\\test1.exe", FALSE);我的可以啊~~
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: RaynorPao大大您好,我快要疯了, 按照您贴的代码,我在BCB中测试,结果问题和前面我说的 一样,这是怎么回事?难道和操作系统有关吗?(我的是WIN98) 如果您有时间可以的话,可以将您的BCB原始码发给我吗? 我看看问题究竟出在什么地方呢?真是奇怪了。先谢谢您。基本上~~我上面寫的程式碼 在 vc 或 bcb 中執行是沒有什麼差別的 我先問你一個問題喔
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
I_Love_You你好: 我必須告訴你一個不好的消息~~經過我的測試以後
我發現以現行的方式~~要 update *.ime 的 resource 似乎是不可能的
在 M$DN or M$ Platform SDK 中有提到
包括 LoadLibrary, BeginUpdateResource...等這些 function
都是針對 DLL/EXE 所設計的
所以~~我之前用 vc 寫的 DLL/EXE 都可以成功的 update
但是~~一碰到你寄來的 IME 就不行了 可能是因為你一開始貼在網站上的標題
「如何修改可執行檔或dll中的圖示icon」
所以~~我一直認為你要修改的是某一個 DLL/EXE
也難怪~~我這邊試「可以」~~你那邊試「不行」
對於這點「誤解」~~我覺得很「沈重」 另外~~我有一個小問題~~想要問你
你一定要從程式碼中~~動態改 IME 的 icon 嗎??
如果「不是」的話~~可直接使用 vc 修改
然後再 save 就可以了 如果「是」的話~~那這個問題
可能又要重頭開始了~~
因為~~我昨天有試過幾個關於 resource 的工具(包括 vc)
發現這些工具有辦法直接抓到 IME 裡面的 resource
因此~~我就很好奇~~他們是怎麼做的??
(好奇的原因~~是因為我前面說過~~只要不是 DLL/EXE
是無法使用 LoadLibrary...這類的 function 來達成目的)
然後~~我就去看了 jackkcg 大大所提供的資料
發現~~可能按照那種方式會比較可行 因為~~那份文件裡面是針對 resource 在檔案中的資料結構做說明
也就是說~~只要能夠在檔案中~~先找到 resource 的標記 ".rsrc"
然後再依據 Resource Directory, Resource Data.....等資料結構
一層一層往下找,最後應該可以找到 icon 的實體資料
既然找到了 icon 的實體資料了~~那就可以直接修改了
因此~~我想像中的程式碼流程~~應該會是這樣 CreateFile(.....); //取得 IME file 的 handle
ReadFile(.....); //將 IME file 檔案內容載入至記憶體中
.....................; //尋找 resource 的標記、資料結構、找到 icon 的實體資料
.....................; //直接修改 icon 的實體資料
WriteFile(.....); //將記憶體中的內容寫回 IME file 我現在很直覺的認為~~如果這種方式可以達成的話
那以後也就可以讀/寫 DLL/EXE 以外類型檔案中的 resource 了
照理說~~可以成為一個滿通用的 solution 吧?? 另外~~如果要直接對 icon 的實體資料做修改的話
你可以會需要以下的資料~~這是 icon 的資料結構 The ICO file starts with an ICONDIR structure. The ICONDIR structure is defined as:
typedef struct
{
WORD idReserved; // Reserved
WORD idType; // resource type (1 for icons)
WORD idCount; // how many images?
ICONDIRENTRY idEntries[1]; // entries for each image (idCount of 'em)
} ICONDIR, *LPICONDIR; The ICONDIRENTRY structure is defined as:
typedef struct
{
BYTE bWidth; // Width of the image
BYTE bHeight; // Height of the image (times 2)
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
DWORD dwImageOffset; // where in the file is this image
} ICONDIRENTRY, *LPICONDIRENTRY; 備註:其實我現在也還在研究上述的理論是否可行
我可能還會花一些時間來實作看看~~因為這個題目還滿有趣的 -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
||
jieshu
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言: I_Love_You你好: 我必須告訴你一個不好的消息~~經過我的測試以後 我發現以現行的方式~~要 update *.ime 的 resource 似乎是不可能的 在 M$DN or M$ Platform SDK 中有提到 包括 LoadLibrary, BeginUpdateResource...等這些 function 都是針對 DLL/EXE 所設計的 所以~~我之前用 vc 寫的 DLL/EXE 都可以成功的 update 但是~~一碰到你寄來的 IME 就不行了 Researching & Developing --Delphi有個Demo→Resxplor目錄裡,可以做到這樣的事,不曉得BCB有沒有此Demo或許你可以將他改成BCB版的吧。
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料
*********************************************************************
資源檔案在DELPHI中的使用-1
*********************************************************************
資 源 是 存 放 在 擴 展 名.RES 的 文 件 裏 的 二 進 制 數 據 結 構, 在DELPHI 中 資 源 文 件 可 以 使 用 圖 象 編 輯 器 來 制 作(IMAGE EDITOR), 或 者 使 用 其 他 的 工 具。 如:BORLAND 公 司 提 供 的RAD PACK FOR DELPHI 中 的RESOURCE WORKSHOP 來 創 建。 資 源 文 件 中 通 常 存 放 的 是 應 用 程 序 可 以 隨 時 存 取 的 一 些 對 象, 包 括:ICON、CURSOR、BITMAP、FONT 等 近 十 種。 大 部 分 的 資 源 在 通 常 的 情 況 下 可 以 保 留 在 磁 盤 當 中, 直 到 程 序 需 要 使 用 它 們 時 才 將 其 調 入, 可 以 大 大 的 節 省 內 存 資 源, 同 樣, 資 源 文 件 也 是 可 以 共 享 的, 即: 多 個 程 序 可 以 共 享 一 個 資 源 文 件, 進 而 減 少 了 在 應 用 程 序 之 間 代 碼 重 複 的 現 象, 使 程 序 的 代 碼 得 到 很 大 的 優 化, 因 此 在 應 用 程 序 中 使 用 資 源 文 件 有 獨 立 制 作、 方 便、 隨 時 修 改 而 不 需 要 對 應 用 程 序 代 碼 做 任 何 修 改 的 好 處。 一 般 來 說, 一 個 應 用 程 序 的 所 有 資 源 都 存 放 在 一 個RES 文 件 裏, 然 後 在DELPHI 進 行 編 譯 的 階 段 將 資 源 文 件 的 內 容 與 最 終 的EXE 文 件 合 並 在 一 起, 因 此 編 譯 後 的RES 文 件 並 沒 有 什 ? 作 用, 僅 僅 提 供 用 來 查 閱 使 用, 在 分 發 應 用 時 不 必 把RES 文 件 分 發 給 最 終 用 戶。 當 然, 不 同 的 資 源 可 以 分 別 放 在 不 同 的 資 源 文 件 當 中, 而 且 資 源 文 件 越 小 調 入 內 存 的 速 度 越 快。 在 這 裏 還 要 說 明 的 一 點 是: 在 修 改 了 原 來 的 資 源 文 件 之 後, 在 原 來 編 譯 的EXE 文 件 中 加 入 的 資 源 不 會 隨 之 而 更 新, 只 有 在 重 新 進 行 編 譯 以 後, 才 能 將 新 的 資 源 加 入 到 新 的EXE 文 件 當 中 去。 下 面 我 們 通 過 兩 個 例 子 來 說 明 在DELPHI 中 如 何 使 用 資 源 文 件( 在 這 裏 我 們 不 講 述 資 源 文 件 的 制 作 方 法)。 一、 如 何 在DELPHI 中 使 用 定 制 的 光 標。
在 使 用DELPHI 進 行 編 程 時, 有 一 個 很 重 要 的 對 象 ─ ─TSCREEN, 它 是 用 來 管 理 和 操 縱 運 行 時 期 屏 幕 的 不 可 視 構 件。 它 的CURSOR 屬 性 是 用 來 指 定 各 個 不 同 的 構 件 光 標 形 狀, 聲 名 ?: PROPERTY CURSORS[INDEX:INTEGER]:HCURSOR;
這 個 只 讀 的 特 性 返 回 應 用 程 序 支 持 的 光 標 組 成 的 一 個HCURSOR 類 型 的 數 組, 它 存 儲 了 屏 幕 上 所 有 的 鼠 標 光 標 的 身 份 代 碼(HCURSOR 就 是 光 標 的HANDLE 句 柄), 數 組 下 標 從0 開 始, 在DELPHI 預 定 義 了 一 些 代 表 不 同 光 標 的 常 量, 它 的 值 是 從0 到-17, 您 可 以 直 接 指 定 程 序 使 用 的 光 標。 如: FORM1.CURSOR:=-3 表 示FORM1 采 用 的 光 標 是CRCROSS( 十 字)。 大 家 可 能 都 會 發 現 構 件 的CURSOR 的 屬 性 最 多 提 供 十 八 種 常 用 的CURSOR 值, 這 在 很 多 的 情 況 下 是 不 夠 的, 如: 當 光 標 進 入 一 個PANEL 面 板 時 光 標 的 形 狀 ? 一 只 手, 那 ?PANEL 的CURSOR 就 不 能 滿 足 這 種 要 求, 這 時 就 需 要 我 們 自 定 義 一 個 手 的 光 標 並 將 其 賦 給PANEL 的CURSOR 屬 性。 如 何 實 現 則 可 以 按 以 下 步 驟 進 行: 使 用 資 源 文 件 編 輯 器(IMAGE EDITOR 或 者RESOURCE WORKSHOP) 編 寫 資 源 文 件。
定 義 一 個 光 標 常 量, 注 意 這 個 常 量 不 能 與DELPHI 中 提 供 的 光 標 常 量 相 沖 突。
在FORMCREATE 事 件 中 使 用WINDOWS API 當 中 的LOADCURSOR 函 數 來 載 入 自 定 義 的CURSOR。
在 程 序 中 將 自 定 義 的CURSOR 分 配 給PANEL 的CURSOR 屬 性。
下 面 說 明 如 何 將 自 定 義 的 一 只 手 的 鼠 標 光 標 賦 給PANEL1 的CURSOR 屬 性。 首 先 使 用IMAGE EDITOR 建 立 一 個HAND.RES 的 文 件。 之 後 按 如 下 書 寫 程 序 代 碼: implementation {$R *.DFM} const Crhand=2; procedure TForm1.FormCreate(Sender: TObject); begin screen.cursors[crhand]:=loadcursor(Hinstance,'hand'); panel1.cursor:=crhand; end;
除 了 編 寫 上 面 的 代 碼 以 外, 我 們 還 需 要 做 的 一 項 工 作 是 將 資 源 文 件 加 入 到 項 目 文 件 當 中 去, 編 譯 指 令 中 的{$R filename} ? 指 令 讓 我 們 來 增 加 資 源 文 件, 讓 我 們 來 看 一 看 項 目 文 件 的 代 碼。 program PCUR; uses Forms, HAND in 'HAND.pas' {Form1};
{$R *.RES}// 這 裏 的* 意 義 ? 在 程 序 編 譯 以 後 會 ? 生 一 個 與 項 目 文 件 同 名 的 資 源 文 件, 在 這 裏 ?PCUR.RES 文 件, 這 部 分 是 自 動 ? 生 的。 {$R hand.res}// 這 部 分 是 我 們 自 己 加 入 的 自 定 義 資 源 文 件, 這 兩 個 資 源 文 件(HAND.RES 和//PCUR.RES 中 的 資 源 都 會 附 加 在 可 執 行 文 件PCUR.EXE 的 後 面。 begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
二、 資 源 文 件 在 編 寫 動 畫 程 序 中 的 應 用
上 面 的 例 子 使 用 的 是 在 資 源 文 件 中 存 儲 的CURSOR 資 源 , 在 下 面 的 例 子 中 我 們 將 使 用 的 是 在 資 源 文 件 中 提 供 的ICON 資 源 來 編 寫 一 個 小 小 的 動 畫 程 序。 在 這 裏 動 畫 的 ? 生 是 利 用 定 時 器 在 一 定 的 時 間 間 隔 內 ? 生TIMER 事 件 將 存 儲 在 資 源 文 件 中 的ICON 依 次 的 繪 制 在FORM 的 同 一 處 而 ? 生 的。 這 時 要 用 到 畫 布CANVAS 的DRAW 方 法, 其 聲 明 如 下: procedure Draw(X, Y: Integer; Graphic: TGraphic); 在 這 個 方 法 當 中 的 參 數GRAPHIC 可 以 ?:BITMAPS、ICONS、METAFILES。 具 體 的 實 現 方 法 ?: 建 立DEMO.RES 文 件, 其 中 含 有 名 ?ICON1 —ICON6 的ICON。 並 將DEMO.RES 加 到 項 目 原 代 碼 中 去( 如: 上 面 例 子 的 方 法)。 動 畫 程 序 的 具 體 代 碼 如 下: unit donghua; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) Image1: TImage; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation var wicon:array[0..5]of Ticon; // 建 立TICON 類 型 的 數 組 存 儲ICON 文 件 idx:integer; {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); var iconname:string; piconame:pchar; begin piconame:=stralloc(7); // 建 立PCHAR 類 型 的 字 符 串 for idx:=0 to 5 do begin wicon[idx]:=ticon.create;// 建 立TICON 型 對 象 iconname:='icon' inttostr(idx); strpcopy(piconame,iconname); // 將STRING 類 型 轉 換 成PCHAR 類 型 wicon[idx].handle:=loadicon(hinstance,piconame); // 調 用WINDOWS API 中 的LOADICON 函 數 // 載 入 資 源 中 的ICON end; strdispose(piconame);//PCHAR 類 型 的 刪 除 form1.canvas.draw(3,3,wicon[1]); // 調 用DRAW 的 方 法 在FORM 上 畫 出ICON1 idx:=1; form1.setbounds(0,0,100,100); // 固 定FORM 的 大 小 和 位 置 end; procedure TForm1.Timer1Timer(Sender: TObject); // 形 成 動 畫 的 定 時 器 事 件 begin idx:=idx 1; if idx=6then idx:=1; form1.canvas.draw(3,3,wicon[0]); form1.canvas.draw(3,3,wicon[idx]); end; end.
以 上 可 以 作 ? 一 個 通 用 的 動 畫 程 序, 我 們 只 需 要 修 改 不 同 的ICON 以 及 增 加IDX 的 大 小 就 可 以 編 出 不 同 的 動 畫 應 用( 同 樣 在 資 源 中 可 以 有 其 他 形 式 的 圖 形 如:BITMAPS 這 時 需 要 動 態 創 建 的 是TBITMAPS 對 象 而 不 是TICON 對 象)。 在 兩 個 例 子 中 我 們 都 用 到 了WINDOWS API 函 數, 這 些 函 數 在WINDOWS 單 元 中 均 有 說 明 在 這 裏 不 加 贅 述。
*********************************************************************
以 上 可 以 作 ? 一 個 通 用 的 動 畫 程 序, 我 們 只 需 要 修 改 不 同 的ICON 以 及 增 加IDX 的 大 小 就 可 以 編 出 不 同 的 動 畫 應 用( 同 樣 在 資 源 中 可 以 有 其 他 形 式 的 圖 形 如:BITMAPS 這 時 需 要 動 態 創 建 的 是TBITMAPS 對 象 而 不 是TICON 對 象)。 在 兩 個 例 子 中 我 們 都 用 到 了WINDOWS API 函 數, 這 些 函 數 在WINDOWS 單 元 中 均 有 說 明 在 這 裏 不 加 贅 述。 以 上 的 兩 個 例 子 只 是 資 源 文 件 的 一 點 點 應 用, 要 真 正 的 掌 握 資 源 文 件 在 程 序 設 計 中 的 強 大 作 用, 還 要 靠 自 己 在 實 踐 中 不 斷 的 總 結。 以 上 程 序 在WINDOWS95 下 的DELPHI2.0 中 編 譯 通 過。 作 者: 李 旭 東( 李 曉 東)
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
I_Love_You
一般會員 ![]() ![]() 發表:18 回覆:87 積分:21 註冊:2002-07-24 發送簡訊給我 |
|||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://www.pconline.com.cn/pcedu/empolder/gj/vc/10207/76114.html 把exe裏面的資源通通取出來
出處:PConline
責任編輯:zwg
[02-7-15 17:08] 作者:king_koo 作者:李建國
版權所有:廣東南海市昭信科技有限公司-李建國
轉載請與作者聯繫 一、前言 不知大家用過exescope沒有,那是日本鬼子寫的一個很有用的東西,它能把exe等pe格式(portable executable)文件的資源(圖示、點陣圖、對話方塊、聲音等等)分析出來,並能改寫回去。當然vc的ide也有類似功能。大家是不是覺得很神秘?其實只要弄清了pe文件的結構,你也可以寫一個類似的工具出來。下面是我近 來對pe文件的分析經驗,給大家作參考。同時希望看到有中國人能寫出比日本鬼子更牛的分析工具來。 二、重要的資料結構 PE格式簡要說明:(更詳細的資料見http://vcangle.8u8.com文件格式專頁)
PE文件總結構如下表:
DOS MZ header ;dos頭
DOS stub ;dos附加段
PE header ;NT頭
Section table ;節表
Section 1 ;第一節
Section 2 ;
Section ...
Section n ;第n節
其中NT頭:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;//PE文件頭標誌 :"PE\0\0"。
IMAGE_FILE_HEADER FileHeader; //PE文件物理分佈的資訊
IMAGE_OPTIONAL_HEADER32 OptionalHeader;//PE文件邏輯分佈的資訊
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
節表資料結構:(可參考winnt.h)
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//節表名稱,如“.text”
union { DWORD PhysicalAddress; //物理位址
DWORD VirtualSize; //真實長度
} Misc;
DWORD VirtualAddress; //RVA
DWORD SizeOfRawData; //物理長度
DWORD PointerToRawData; //節基於文件的偏移量
DWORD PointerToRelocations; //重定位的偏移
DWORD PointerToLinenumbers; //行號表的偏移
WORD NumberOfRelocations; //重定位項數目
WORD NumberOfLinenumbers; //行號表的數目
DWORD Characteristics; //節屬性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 2.2點陣圖文件格式。由文件頭,點陣圖資訊和資料段組成。
typedef struct tagBITMAPFILEHEADER { // bmfh文件頭
WORD bfType; //"BM"
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFO { // bmi----點陣圖資訊
BITMAPINFOHEADER bmiHeader; // ----點陣圖資訊頭
RGBQUAD bmiColors[1];// ----調色板*
} BITMAPINFO;
typedef struct tagBITMAPINFOHEADER{ // bmih 點陣圖資訊頭
DWORD biSize; //該結構大小
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage; //點陣圖資料大小
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER; //該結構後緊接著就是DATA了。
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://www.pconline.com.cn/pcedu/empolder/gj/vc/10207/75758.html 初探WINDOWS下IME編程
出處:PConline
責任編輯:zwg
[02-7-13 16:09] 作者:king_koo 作者:李建國
版權所有:廣東南海市昭信科技有限公司-李建國
轉載請與作者聯繫 大家知道,DELPHI許多控制項有IME屬性。這?好用的東西VC可沒自帶,怎?辦呢?其實,可通過註冊表,用API實現。下面說一下本人對IME的研究結果。 本文示例程式運行結果如上圖 1、將用到的API RegOpenKey:打開註冊表一鍵
RegQueryValue:查詢一鍵值
RegQueryValueEx:同上
RegCloseKey:關閉打開的鍵 LoadKeyboardLayout:裝載輸入法
ActivateKeyboardLayout:啟動輸入法 2、IME資訊在註冊表中的位置 在HKEY_USERS:".DEFAULT\keyboard layout\preload"放的是已安裝的輸入法,下有幾個以數位?名的子鍵,內容是輸入法代號(keyboard layout),如"e0040804",其中左4位元是設備代碼(device identifier),右4位元是語言代碼(language identifier)。例如上面:左e004指智慧ABC,右0804指大陸中文。(詳見MSDN) 在HKEY_LOCAL_MACHINE:"System\CurrentControlSet\Control\Keyboard Layouts\"放的是已註冊的輸入法。他的子鍵名?輸入法代號(keyboard layout),內容?該輸入法的ime文件,名稱等資訊。 3、主要思路 我們可先把已裝的輸入法枚舉出來(從註冊表),用戶選擇其一後,再啟動該輸入法。
兩關鍵函數: HKL LoadKeyboardLayout(LPCTSTR pwszKLID,UINT Flags); 第一個參數是待打開的輸入法代號,如"e0040804"(智慧ABC);
第二個參數是標誌位元,如KLF_ACTIVATE(啟動)。 HKL ActivateKeyboardLayout(HKL hkl,UINT Flags);
第一個參數是打開的輸入法控制碼(由LoadKeyboardLayout返回);
第二個參數是標誌位元,如KLF_SETFORPROCESS。(詳見MSDN)
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://www.5xsoft.com/data/200109/2409240501.htm 關於PE可執行文件的修改(1) [ 作者: ilsy 添加時間: 2001-9-24 9:25:08 ] 原創:ilsy(ILSY) 在windows 9x、NT、2000下,所有的可執行文件都是基於Microsoft設計的一種新的文件格式Portable Executable File Format(可移植的執行體),即PE格式。有一些時候,我們需要對這些可執行文件進行修改,下面文字試圖詳細的描述PE文件的格式及對PE格式文件的修改。
1、PE文件框架構成
DOS MZ header
DOS stub
PE header
Section table
Section 1
Section 2
Section ...
Section n
上表是PE文件結構的總體層次分佈。所有 PE文件(甚至32位的 DLLs) 必須以一個簡單的 DOS MZ header 開始,在偏移0處有DOS下可執行文件的“MZ標誌”,有了它,一旦程式在DOS下執行,DOS就能識別出這是有效的執行體,然後運行緊隨 MZ header 之後的 DOS stub。DOS stub實際上是個有效的EXE,在不支援 PE文件格式的作業系統中,它將簡單顯示一個錯誤提示,類似於字串 " This program cannot run in DOS mode " 或者程式師可根據自己的意圖實現完整的 DOS代碼。通常DOS stub由彙編器/編譯器自動生成,對我們的用處不是很大,它簡單調用中斷21h服務9來顯示字串"This program cannot run in DOS mode"。
緊接著 DOS stub 的是 PE header。 PE header 是PE相關結構 IMAGE_NT_HEADERS 的簡稱,其中包含了許多PE裝載器用到的重要域。可執行文件在支援PE文件結構的作業系統中執行時,PE裝載器將從 DOS MZ header的偏移3CH處找到 PE header 的起始偏移量。因而跳過了 DOS stub 直接定位到真正的文件頭 PE header。
PE文件的真正內容劃分成塊,稱之?sections(節)。每節是一塊擁有共同屬性的資料,比如“.text”節等,那?,每一節的內容都是什?呢?實際上PE格式的文件把具有相同屬性的內容放入同一個節中,而不必關心類似“.text”、“.data”的命名,其命名只是?了便於識別,所有,我們如果對PE格式的文件進行修改,理論上講可以寫入任何一個節內,並調整此節的屬性就可以了。
PE header 接下來的陣列結構 section table(節表)。 每個結構包含對應節的屬性、文件偏移量、虛擬偏移量等。如果PE文件裏有5個節,那?此結構陣列內就有5個成員。
以上就是PE文件格式的物理分佈,下面將總結一下裝載一PE文件的主要步驟:
1、 PE文件被執行,PE裝載器檢查 DOS MZ header 裏的 PE header 偏移量。如果找到,則跳轉到 PE header。
2、PE裝載器檢查 PE header 的有效性。如果有效,就跳轉到PE header的尾部。
3、緊跟 PE header 的是節表。PE裝載器讀取其中的節資訊,並採用文件映射方法將這些節映射到記憶體,同時付上節表裏指定的節屬性。
4、PE文件映射入記憶體後,PE裝載器將處理PE文件中類似 import table(引入表)邏輯部分。
上述步驟是一些前輩分析的結果簡述。
2、PE文件頭概述
我們可以在winnt.h這個文件中找到關於PE文件頭的定義:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
//PE文件頭標誌 :“PE\0\0”。在開始DOS header的偏移3CH處所指向的地址開始
IMAGE_FILE_HEADER FileHeader; //PE文件物理分佈的資訊
IMAGE_OPTIONAL_HEADER32 OptionalHeader; //PE文件邏輯分佈的資訊
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //該文件運行所需要的CPU,對於Intel平臺是14Ch
WORD NumberOfSections; //文件的節數目
DWORD TimeDateStamp; //文件創建日期和時間
DWORD PointerToSymbolTable; //用於調試
DWORD NumberOfSymbols; //符號表中符號個數
WORD SizeOfOptionalHeader; //OptionalHeader 結構大小
WORD Characteristics; //文件資訊標記,區分文件是exe還是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic; //標誌字(總是010bh)
BYTE MajorLinkerVersion; //連接器版本號
BYTE MinorLinkerVersion; //
DWORD SizeOfCode; //代碼段大小
DWORD SizeOfInitializedData; //已初始化資料塊大小
DWORD SizeOfUninitializedData; //未初始化資料塊大小
DWORD AddressOfEntryPoint; //PE裝載器準備運行的PE文件的第一個指令的RVA,若要改變整個執行的流程,可以將該值指定到新的RVA,這樣新RVA處的指令首先被執行。(許多文章都有介紹RVA,請去瞭解)
DWORD BaseOfCode; //代碼段起始RVA
DWORD BaseOfData; //資料段起始RVA
DWORD ImageBase; //PE文件的裝載地址
DWORD SectionAlignment; //塊對齊
DWORD FileAlignment; //文件塊對齊
WORD MajorOperatingSystemVersion;//所需作業系統版本號
WORD MinorOperatingSystemVersion;//
WORD MajorImageVersion; //用戶自定義版本號
WORD MinorImageVersion; //
WORD MajorSubsystemVersion; //win32子系統版本。若PE文件是專門?Win32設計的
WORD MinorSubsystemVersion; //該子系統版本必定是4.0否則對話方塊不會有3維立體感
DWORD Win32VersionValue; //保留
DWORD SizeOfImage; //記憶體中整個PE映射體的尺寸
DWORD SizeOfHeaders; //所有頭 節表的大小
DWORD CheckSum; //校驗和
WORD Subsystem; //NT用來識別PE文件屬於哪個子系統
WORD DllCharacteristics; //
DWORD SizeOfStackReserve; //
DWORD SizeOfStackCommit; //
DWORD SizeOfHeapReserve; //
DWORD SizeOfHeapCommit; //
DWORD LoaderFlags; //
DWORD NumberOfRvaAndSizes; //
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
//IMAGE_DATA_DIRECTORY 結構陣列。每個結構給出一個重要資料結構的RVA,比如引入位址表等
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; //表的RVA地址
DWORD Size; //大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
怎樣?程式打補丁(一)───基礎篇
聲明:
一.本文實用于初學者,需要具備一定的彙編和系統底層的知識。
二.本文只是?了讓廣大網友共同提高一些基礎知識,本人決無賣弄之意,只供需要這方面知識的讀者閱讀,如果你是高手,或者不需要這方面知識,請跳過。
三.本文的實例均?普通程式,如有雷同,敬請諒解。
四.本文歡迎傳抄轉載,如果是商業用途,請聯繫本人。http://www.zoudan.com zoudan@sina.com
打補丁是常見的一種軟體升級和更新手段。打補丁的形式很多,本文所述的方式基本上?修改原程式二進位碼的方式,適用於Windows95之後的平臺(Win32)。
Windows95(Win32)以後的可執行文件都是PE格式,.exe、.ocx、.dll.等等都是常見的PE格式的文件映射,看一個文件是否?PE文件,不是看它的副檔名,而是看它的文件頭中是否有PE文件頭標示和具體的文件內容。比如常見的軟體"追捕"中那個wry.dll,就不是一個PE格式的Dll(動態連接庫)文件,通常用16進制編輯軟體打開文件首部觀察便可得知。關於PE文件的具體格式和教程不是本文的描述範圍,大家可以查閱相關的資料,我網站上那篇"關於95下的可執行文件加密研究"中也有比較詳盡的描述。
PE文件是一個程式碼、資料的集合。其中的程式碼是該執行文件本身的,它可能通過動態連接的形式訪問其他附屬的程式或者動態連接庫,通常一個程式文件中包含了大量的系統調用和對其他程式及動態連接庫的調用。 言歸正傳,無論是破解,程式改良或者程式升級,在改動不大,且沒有根源程式參考的情況下,最直接的方法就是更改PE可執行文件。大家都知道我製作的補丁程式,基本上就是直接修改程式文件,使之達到我們需要得到的功能。 一個PE可執行文件中通常有很多段(section),分別描述不通的資料結構和代碼。最基本的幾種段有.code(.text)(代碼段)、.data(資料段)、.rdata、.rscs(資源)等等,這些段的名稱可以是程式自定,決定它們屬性的不是他的名稱,而是PE文件頭中的描述。有很多查看PE文件結構和內容的軟體,我向大家推薦Borland C自帶的一個叫Tdump的小軟體,很簡單和方便,在現在的Borland C Builder和Borland C中都有,大家可以用他來瞭解PE文件的內部資訊。 一般來說,修改資源段中的東西最?簡單。那些對話方塊、字串、點陣圖等等。修改這些資源很容易,因?有很多這方面的軟體,最常見的就是VC ,只要用VC用資源修改方式打開程式文件,所有這個程式相關的資源就會很容易的修改了。大家可以隨便找幾個程式來試試手,挪挪對話方塊,改改屬性,編輯文字,畫畫點陣圖,很容易上手和熟悉。
修改程式文件的其他地方就沒有修改資源段容易了,程式當然都是彙編機器代碼,資料也是未知的結構。關於怎樣看懂、跟蹤、瞭解程式的運作就是一件非常經驗的事情,不同的程式不同的方法,沒有定式,它們唯一的共同點就是都是彙編代碼,都能用軟體反彙編和動態調試。這也已經超出了本文的範疇,我想它需要扎實的彙編基礎,系統底層知識以及豐富的程式調試經驗,不可能在很快的時間內掌握。這需要耐心,長時間的實戰以及積累。在此我向大家推薦我常用的工具,靜態的反彙編可以用IDA pro,使用該軟體你會發現枯燥乏味的彙編代碼變得井井有條,且多了很多幫助理解的注釋,當然還有很多重要程式庫的符號,比如MFC庫類,標準C庫等等。該程式是最好的反彙編工具,?我們讀懂苦澀的機器指令提供了良好的互動環境。光靜態分析彙編代碼無疑是極其困難的,光靠眼睛看不可能看到寄存器,記憶體單元資料等等和程式運行息息相關的東西。關鍵是彙編代碼苦澀難懂,動態的調試就成了我們深入瞭解程式、調試程式、探測程式的最重要的手段。我所提到的動態調試是彙編級別的,並非任何高階語言。值得提到的是有些程式帶有調試符號資訊,那會?我們動態調試提供很大很大的便利,不過一般Release版本都不會把調試資訊鏈結到最終的程式文件中,粗心的程式師有可能犯這個錯誤。總之,彙編級的調試一般來說都非常的艱苦,不過動態調試和靜態閱讀相結合還是會使效率提高很多。動態調試的軟體很多,而且都支援彙編級別的調試。一般集成變成環境都帶有這種工具,比如VC ,C Builder等等。專業調試軟體有W32dasm、Trw、Soft-ice等等,在這個領域裏,Soft-ice無疑是絕對的佼佼者。我覺得幾乎沒有Soft-ice觸及不到的深度,Soft-ice?我們瞭解系統的任何一個細節提供了可能,從DOS時代到windows時代,Soft-ice無疑是動態調試領域最重要的工具。好話說得夠多了,我不是在?它打廣告,實事的確如此,網上很容易下載到它的各種版本。Soft-ice雖然很厲害,但是對初學者來說的確不容易掌握,且更需要扎實的底層基礎。掌握了它就?掌握了系統的最底層提供了可能,這無疑是個核武器。
關於具體怎?放置補丁程式,用DLL動態連接庫方式編制複雜的補丁程式等等細節問題我將在以後的文章中介紹,請各位網友密切留意。
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||
jieshu
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言: 非常jieshu大大指点信息,我在BCB中找了一下没有您说的这个目录和这样的范例, 您如果有时间可以将您说的Demo→Resxplor目录下这样的范例压缩一下发给我参考吗?谢谢您,谢谢!!!我放在會員專用區,不曉得你可不可以下載,位址如下 http://delphi.ktop.com.tw/loadfile.php?TOPICID=7122641&CC=159299
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |