delphi 给EXE文件增加区段
unit uStudyPE; interface
uses
Classes, SysUtils, Windows, uPERec; type TImage_Section_headerList = class; TStudyPE = class
private
FFileStream: TFileStream;
FNewStream: TMemoryStream;
FImage_Dos_Header: PImage_DOS_Header;
FImage_NT_Headers: PImage_NT_Headers;
FImage_Section_HeaderList: TImage_Section_headerList;
public
constructor Create;
destructor Destroy; override;
public
procedure LoadPE(AFileName: string);
property Image_Dos_Header: PImage_DOS_Header read FImage_Dos_Header;
property Image_NT_Headers: PImage_NT_Headers read FImage_NT_Headers;
property Image_Section_HeaderList: TImage_Section_headerList read FImage_Section_HeaderList;
end; TImage_Section_headerList = class(TList)
public
procedure FreeAllItems();
destructor Destroy; override;
end; implementation
{ TStudyPE }
const
Image_Dos_Header_len = SizeOf(TImage_dos_header);
Image_NT_Headers_len = SizeOf(TImage_NT_Headers);
Image_Section_Header_len = SizeOf(TImage_Section_Header); constructor TStudyPE.Create;
begin
inherited Create;
New(FImage_Dos_Header);
New(FImage_NT_Headers);
FImage_Section_HeaderList := TImage_Section_headerList.Create;
FNewStream := TMemoryStream.Create;
end; destructor TStudyPE.Destroy;
begin
Dispose(FImage_Dos_Header);
Dispose(FImage_NT_Headers);
FImage_Section_HeaderList.Free;
FNewStream.Free;
inherited;
end; procedure TStudyPE.LoadPE(AFileName: string);
var e_lfanew: DWORD;
pSecHeader: PImage_Section_header;
nNumberOfSections: word;
i: integer;
nDosStubLen: integer;
nSizeOfImage: DWORD;
LImage_Section_header: TImage_Section_Header;
Rva: DWORD;
vaSize: DWORD; SizeOfHeaders: DWORD; // 一般是 $400
NewSectionSize: DWORD; // 新增区段大小 begin if Assigned(FFileStream) then
begin
FFileStream.Free;
end; NewSectionSize := $; FFileStream := TFileStream.Create(AFileName, fmOpenRead);
FFileStream.Read(FImage_Dos_Header^, Image_Dos_Header_len); // 读 DOS 头,64字节 FNewStream.Size := FFileStream.Size + NewSectionSize; // 新文件大小
FNewStream.Write(FImage_Dos_Header^, Image_Dos_Header_len); // 将 DOS 头写入新文件 e_lfanew := FImage_Dos_Header.e_lfanew; // 获取 Image_NT_Headers 的位置
nDosStubLen := e_lfanew - Image_Dos_Header_len; // DOS 汇编代码区域长度 // 将 DOS 汇编代码写入新文件,写完后 FFileStream.Position 正好在 Image_NT_Header 的位置上
FFileStream.Read((Pbyte(FNewStream.Memory) + Image_Dos_Header_len)^, nDosStubLen);
FNewStream.Position := Image_Dos_Header_len + nDosStubLen; FFileStream.Read(FImage_NT_Headers^, Image_NT_Headers_len); // 获取 Image_NT_Headers
SizeOfHeaders := FImage_NT_Headers.Image_Optional_Header32.SizeOfHeaders; nNumberOfSections := FImage_NT_Headers.Image_File_Header.NumberOfSections; // 区段数量
FImage_NT_Headers.Image_File_Header.NumberOfSections := nNumberOfSections + ; // 增加区段数量 nSizeOfImage := FImage_NT_Headers.Image_Optional_Header32.SizeOfImage;
FImage_NT_Headers.Image_Optional_Header32.SizeOfImage := nSizeOfImage + NewSectionSize; // 修改 EXE 所占内存大小
FNewStream.Write(FImage_NT_Headers^, Image_NT_Headers_len); // 将 Image_NT_Headers 写入新文件 FImage_Section_HeaderList.FreeAllItems; for i := to nNumberOfSections - do
begin
New(pSecHeader);
FImage_Section_HeaderList.Add(pSecHeader);
FFileStream.Read(pSecHeader^, Image_Section_Header_len);
FNewStream.Write(pSecHeader^, Image_Section_Header_len); // 将各个 Image_Section_Header 写入新文件
end; LImage_Section_header := pSecHeader^; // 给新区段命名
LImage_Section_header.Name[] := ord('.');
LImage_Section_header.Name[] := ord('N');
LImage_Section_header.Name[] := ord('E');
LImage_Section_header.Name[] := ord('W');
LImage_Section_header.Name[] := ord('T');
LImage_Section_header.Name[] := ord('E');
LImage_Section_header.Name[] := ord('S');
LImage_Section_header.Name[] := ord('T'); // 用最后一个区段作参考计算新增区段的 VirtualAddress,PointerToRawData 的值
// VirtualAddress 是在EXE中虚拟地址
// PointerToRawData 新区段在文件中的位置
Rva := pSecHeader.VirtualAddress;
vaSize := ((pSecHeader.Misc.VirtualSize + $FFF) div $) * $;
LImage_Section_header.VirtualAddress := Rva + vaSize; // 新区段的虚拟地址 Rva := pSecHeader.PointerToRawData;
vaSize := ((pSecHeader.Misc.VirtualSize + $1FF) div $) * $;
LImage_Section_header.PointerToRawData := Rva + vaSize; // 新区段的文件中的位置 LImage_Section_header.Misc.VirtualSize := NewSectionSize;
LImage_Section_header.SizeOfRawData := NewSectionSize;
LImage_Section_header.Characteristics := $; // 区段的属性(读,写,执行) // 要计算位置是否够放新 Section, 未完成,本例所改的 exe 是可以的。 if ((SizeOfHeaders - FFileStream.Position) < Image_Section_Header_len) then
begin
raise Exception.Create('区段位置不够,本Demo无法操作!');
// 为了简单,所以这样操作了。实际上是可以的,只是每个区段都得重新计算虚拟地址与在文件中的地址
end; FNewStream.Write(LImage_Section_header, Image_Section_Header_len); // 将新增 Image_Section_Header 写入新文件 // 将源文件剩下的数据写入新文件
FFileStream.Seek(SizeOfHeaders, soBeginning);
FFileStream.Read((Pbyte(FNewStream.Memory) + SizeOfHeaders)^, FFileStream.Size - SizeOfHeaders);
FNewStream.SaveToFile('new.exe'); end; { TImage_Section_headerList } destructor TImage_Section_headerList.Destroy;
begin
FreeAllItems;
inherited;
end; procedure TImage_Section_headerList.FreeAllItems;
var
p: PImage_Section_header;
begin
for p in self do
Dispose(p);
Clear;
end; end.
uStudyPE.pas
unit uPERec; interface
uses
Classes, SysUtils, Windows; type
// Windows 单元中有这些结构,而我为了学习,从书上重新操作了一遍 PImage_DOS_Header = ^TImage_DOS_Header;
TImage_DOS_Header = packed record
e_magic: WORD; // DOS signature:4D5A ('MZ')
e_cblp: WORD;
e_cp: WORD;
e_crlc: WORD;
e_cparhdr: WORD;
e_minalloc: WORD;
e_maxalloc: WORD;
e_ss: WORD;
e_sp: WORD;
e_csum: WORD;
e_ip: WORD;
e_cs: WORD;
e_lfarlc: WORD;
e_ovno: WORD;
e_res: array [ .. ] of WORD;
e_oemid: WORD;
e_oeminfo: WORD;
e_res2: array [ .. ] of WORD;
e_lfanew: DWORD; // offset to NT hearder
end; TImage_Optional_Header32 = _Image_Optional_Header32;
TImage_File_Header = _Image_File_Header; PImage_NT_Headers = ^TImage_NT_Headers;
TImage_NT_Headers = packed record
Signature: DWORD; // PE Signature: 50450000 ('PE'00)
Image_File_Header: TImage_File_Header;
Image_Optional_Header32: TImage_Optional_Header32;
end; PImage_File_Header = ^TImage_File_Header;
_Image_File_Header = packed record
Machine: WORD;
NumberOfSections: WORD;
TimeDateStamp: DWORD;
PointerToSymbolTable: DWORD;
NumberOfSymbols: DWORD;
SizeOfOptionalHeader: WORD;
Characteristics: WORD;
end; const
Image_NumberOf_Directory_Entries = ; type TImage_Data_Directory = _Image_Data_Directory; PImage_Optional_Header32 = ^TImage_Optional_Header32;
_Image_Optional_Header32 = packed record
Magic: WORD;
MajorLinkerVersion: BYTE;
MinorLinkerVersion: BYTE;
SizeOfCode: DWORD;
SizeOfInitializedData: DWORD;
SizeOfUninitializedData: DWORD;
AddressOfEntryPoint: DWORD;
BaseOfCode: DWORD;
BaseOfData: DWORD;
ImageBase: DWORD;
SectionAlignment: DWORD;
fileAlignment: DWORD;
MajorOperatingSystemVersion: WORD;
MinorOperatingSystemVersion: WORD;
MajorImageVersion: WORD;
minorImageVersion: WORD;
MajorSubsystemVersion: WORD;
MinorSubsystemVersion: WORD;
Win32VersionValue: DWORD;
SizeOfImage: DWORD;
SizeOfHeaders: DWORD;
checkSum: DWORD;
Subsystem: WORD;
DllCharacteristics: WORD;
SizeOfStackReserve: DWORD;
SizeOfStackCommit: DWORD;
sizeOfHeapReserve: DWORD;
sizeofHeapcommit: DWORD;
LoaderFlags: DWORD;
NumberOfRvaAndSizes: DWORD;
Image_Data_Directory: array [ .. Image_NumberOf_Directory_Entries - ] of TImage_Data_Directory;
end; _Image_Data_Directory = packed record
VirtualAddress: DWORD;
Size: DWORD;
end;
const
Image_SizeOf_Short_Name = ; type TMisc = packed record
case integer of
:(PhysicalAddress: DWORD);
:(VirtualSize: DWORD);
end;
// 此为 C 语言 union 格式 改写而成
//
// union {
// DWORD PhysicalAddress;
// DWORD VirtualSize;
// } Misc;
//
// PImage_Section_Header = ^TImage_Section_Header;
TImage_Section_Header = packed record
Name: array [ .. Image_SizeOf_Short_Name - ] of BYTE;
Misc: TMisc;
VirtualAddress: DWORD;
SizeOfRawData: DWORD;
PointerToRawData: DWORD;
PointerToRelocations: DWORD;
PointerToLineNumbers: DWORD;
NumberOfRelocations: WORD;
NumberofLineNumbers: WORD;
Characteristics: DWORD;
end; implementation
end.
uPERec.pas
delphi 给EXE文件增加区段的更多相关文章
- 在delphi的exe文件中嵌入另外一个exe文件
http://www.cnblogs.com/dabiao/archive/2009/11/28/delphi.html 1.创建rc文件.可以用任意文本编辑器来写.文件格式为:"资源名 资 ...
- 如何用DELPHI编程修改外部EXE文件的版本信
右击里面有修改 点开直接修改就可以了吧. DELPHI 里程序的版本信息怎么是灰色的,无法更改 耐心读以下说明,应该能解决你的问题,如果不能解决,请Hi我~ 如何给自己的dll文件添加版本信息呢? 首 ...
- delphi编写提取exe文件的ICO图标
http://www.duote.com/tech/4/11797.html delphi编写提取exe文件的ICO图标 7.0分 出处:天下网吧 时间:2011-08-05 人气:2390 核心提示 ...
- 常用EXE文件反编译工具
PE Explorer V1.99 R5 绿色汉化特别版_强大的可视化汉化集成工具 功能极为强大的可视化汉化集成工具,可直接浏览.修改软件资源,包括菜单.对话框.字符串表等: 另外,还具备有 W32D ...
- 转载:常见EXE文件反编译工具
PE Explorer V1.99 R5 绿色汉化特别版_强大的可视化汉化集成工具 功能极为强大的可视化汉化集成工具,可直接浏览.修改软件资源,包括菜单.对话框.字符串表等: 另外,还具备有 W32D ...
- 减小Delphi的Exe文件大小(11种方法)
一般来说,由Delphi生成的EXE文件,要比其由它编程语言生成的体积大一些.这主要是由于使用VCL的原因(当然,VCL是有许多优点的!) 以下是减小EXE文件大小的几种途径: 01) 使用加壳工具( ...
- WinExec打开exe文件
1,WinExec(): WinExec主要运行EXE文件,不能运行其他类型的文件.不用引用特别单元. 原型:UINT WinExec(exePath,ShowCmd) 示例,我想要用记事 ...
- 常用EXE文件反编译工具【转】
http://www.cnblogs.com/happyday56/p/3740108.html PE Explorer V1.99 R5 绿色汉化特别版_强大的可视化汉化集成工具 功能极为强大的可视 ...
- Delphi 使用CHM文件制作系统帮助文档(上下文感知帮助的制作)
一.基础知识简介 使用帮助提示窗口或状态栏只能提供简单.单一的帮助,无法对某一模块或应用程序整体提供系统的 帮助,因此运行Windows应用程序,需要帮助时一般都可以通过执行帮助菜单获 ...
随机推荐
- linux下mongodb安装、服务器、客户端、备份、账户命令
在linux环境安装mongoDB: 一般认为偶数版本为稳定版 如 1.6.x,奇数版本为开发版如1.7.x 32bit的mongoDB最大能存放2g的数据,64bit没有限制 方法1: 终端执行: ...
- Android TabLayout 在宽屏幕上tab不能平均分配的问题解决
当TabLayout 在宽屏幕的设备上,如平板横屏的时候,tab的宽度超过一定值后,就不在平均分配宽度,而是居中显示.此时设置 app:tabMode="fixed"或者 top_ ...
- 解决cors跨域的filter
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; im ...
- 关于block的循环引用的问题
在block的循环引用的问题上我们都知道如果在block内部修改外部的变量的时候,要加__block以防止循环引用的问题,但是如果block是当前对象的一个属性的时候,要修改当前对象的一个属性的时候就 ...
- spark2.1:读取hive中存储的多元组(string,double)失败
这两天和同事一起在想着如何把一个表的记录减少,表记录包含了:objectid(主小区信息),gridid(归属栅格),height(高度),rsrp(主小区rsrp),n_objectid(邻区),n ...
- 在Windows环境中使用Nginx, Consul, Consul Template搭建负载均衡和服务发现服务
搭建负载均衡和服务发现服务的目的 随着网站业务的不断提升,单个服务器的性能越来越难满足客户的业务需求,所以很多情况下,需要使用多服务器实例和负载均衡器来满足业务需要. Nginx 什么是Nginx N ...
- Myeclipse修改设置Default VM Arguments
打开Windows-> Preferences 然后选择右侧菜单的Java->Installed JREs 点击右侧的jdk,然后点击"Edit"按钮 Default ...
- 初探java对象比较
判断两个对象的属性值是否相等的方法, class Book{ private String title; private double price; public Book(String title, ...
- IOS开发---视频录制
今天研究了一下使用app录制视频的功能,感觉还是挺简单的.使用了AVFoundation框架,代码比较死,按步骤调用就行. 分享一下今天做的Demo的步骤 一,初始化输入设备,这里涉及到前,后摄像头: ...
- 关于自定义view--实现自定义水波纹效果
开发中的东西太多,怕自己忘记了,简单记录一下. 声明:此控件借鉴了大佬的想法,在此感谢大佬提供的支持,我只是把大佬的想法拿出来而已. ok,废话到此结束,看效果: 分析一下,我们可以看到,图中有两个圆 ...