rover 发表于 2007-9-25 15:31:20

偶菜
看不懂
偶要好好学习了
...

fonge 发表于 2007-10-15 15:45:14

增加区块的程序实现...{-------------------------增加区块 -------------------------------}
{                                                                }
{                                                                }
{1.定义附加段填充数据                                            }
{                                                                }
{2.读取PE信息                                                      }
{                                                               }
{3.块填充大小=(待增加数据大小/区块物理对齐大小+1)*区块物理对齐大小      }
{                                                               }
{4.计算块各项属性                                                   }
{ A.读取区块信息                                                    }
{ B.块物理位置=最后一块的物理位置+最后一块物理大小                      }
{ C.映象中偏移=最后一块的映象中偏移+最后一块映象大中大小               }
{                                                               }
{5.增加块,定义块各项属性                                             }
{ A.增加块                                                         }
{ B.校正新节物理偏移                                                }
{ C.校正新节映象偏移                                             }
{ D.设置区块属性                                                   }
{ E.保存整个块表                                                   }
{                                                               }
{6.修正PE头信息                                                    }
{ A.校正内存映象大小=原野内存映象大小+已定义块映象大小                  }
{ B.更正块数=原块数目+1                                          }
{ C.保存修改过的映象头                                              }
{                                                               }
{7.定位到文件末尾,追加待增加数据,长度为物理大小                         }
{ A.填充数据到物理对齐                                             }
{ B.填充自定义数据                                                }
{                                                               }
{8.退出                                                            }
{*****************************************************************}

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
private
    { Private declarations }
public
    { Public declarations }
end;

var
Form1             : TForm1;

implementation

{$R *.dfm}
function AttachStart: DWORD; stdcall;   //我们定义的待填充数据
begin
asm
   mov eax,eax
end;
end;
function AttachEnd: DWORD; stdcall;
begin
end;

{-------------------------增加区块--------------------------------}
procedure AddSection(lFileName: string; lBackup: Boolean); //打开exe文件,是否备份
var
hFile             : THandle;          //文件句柄
ImageDosHeader    : IMAGE_DOS_HEADER; //DOS部首
ImageNtHeaders    : IMAGE_NT_HEADERS; //映象头
ImageSectionHeader: IMAGE_SECTION_HEADER; //块表
lPointerToRawData : DWORD;            //指向文件中的偏移
lVirtualAddress   : DWORD;            //指向内存中的偏移
i               : Integer;          //循环变量
BytesRead, ByteSWrite: Cardinal;      //读写用参数
AttachSize      : DWORD;            //附加段大小
AttachData      : Integer;          //附加段填充数据
begin

{1.定义附加段填充数据}
//定义附加段填充数据
AttachData := 0;

{2.读取PE信息}
//打开文件
hFile := CreateFile(PChar(lFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

//校验
if hFile = INVALID_HANDLE_VALUE then
begin
    ShowMessage('打开文件失败');
    exit;
end;

//确认备份
if lBackup then CopyFile(PChar(lFileName), PChar(lFileName + '.bak'), False);

try

    //读取DOS部首到ImageDosHeader
    ReadFile(hFile, ImageDosHeader, SizeOf(ImageDosHeader), BytesRead, nil);

    //校验
    if ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then
    begin
      ShowMessage('不是有效的PE文件!');
      exit;
    end;

    //指向映象头
    SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN);

    //读取映向头到ImageNtHeaders
    ReadFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), BytesRead, nil);

    //校验
    if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    begin
      ShowMessage('不是有效的PE文件');
      exit;
    end;

{3.块填充大小=(待增加数据大小/区块物理对齐大小+1)*区块物理对齐大小}
    //计算加入块对齐后大小
    AttachSize := ((Integer(@AttachEnd) - Integer(@AttachStart)) div ImageNtHeaders.OptionalHeader.FileAlignment + 1) * ImageNtHeaders.OptionalHeader.FileAlignment;

{4.计算块各项属性}
    //初始化文件中偏移和映象中偏移
    lPointerToRawData := 0;
    lVirtualAddress := 0;

    for i := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
    begin

    {A.读取区块信息}
      //读取块表中信息
      ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil);

    {B.块物理位置=最后一块的物理位置+最后一块物理大小}
      //计算文件中偏移
      if lPointerToRawData < ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData then
      lPointerToRawData := ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData;

    {C.映象中偏移=最后一块的映象中偏移+最后一块映象大中大小}
      //计算映象中偏移
      if lVirtualAddress < ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize then
      lVirtualAddress := ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize;
    end;

{5.增加块,定义块各项属性}
{A.增加块}
    //新建区块,名为.EN
    Move('.EN'#0, ImageSectionHeader.Name, 5);

    //设法初始属性
    ImageSectionHeader.Misc.VirtualSize := AttachSize;
    ImageSectionHeader.VirtualAddress := lVirtualAddress;
    ImageSectionHeader.SizeOfRawData := AttachSize;
    ImageSectionHeader.PointerToRawData := lPointerToRawData;
    ImageSectionHeader.PointerToRelocations := 0;
    ImageSectionHeader.PointerToLinenumbers := 0;
    ImageSectionHeader.NumberOfRelocations := 0;

{B.校正新节物理偏移}
    //校正新节物理偏移(物理区块对齐)
    if ImageSectionHeader.VirtualAddress mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then
      ImageSectionHeader.VirtualAddress := (ImageSectionHeader.VirtualAddress div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment;

{C.校正新节映象偏移}
    //校正新节映象偏移(映象中区块对齐)
    if ImageSectionHeader.Misc.VirtualSize mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then
      ImageSectionHeader.Misc.VirtualSize := (ImageSectionHeader.Misc.VirtualSize div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment;

{D.设置区块属性}
    //设置区块属性
    ImageSectionHeader.Characteristics := $E00000E0;

{E.保存整个块表}
    //保存区块信息
    WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil);

{6.修正PE头信息}
{A.校正内存映象大小=原野内存映象大小+已定义块映象大小}
    //校正内存映象大小
    ImageNtHeaders.OptionalHeader.SizeOfImage := ImageNtHeaders.OptionalHeader.SizeOfImage + ImageSectionHeader.Misc.VirtualSize;

{B.更正块数=原块数目+1}
    //校正块数目
    Inc(ImageNtHeaders.FileHeader.NumberOfSections);

{C.保存修改过的映象头}
    //定位到映象头
    SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN);

    //保存校正过的映象头
    WriteFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), ByteSWrite, nil);

{7.定位到文件末尾,追加待增加数据,长度为物理大小}
{A.填充数据到物理对齐}
    //定位到新节开始处
    SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN);

    //用00数据填充满新节
    for i := 1 to AttachSize do
    begin
      WriteFile(hFile, PByte(@AttachData)^, 1, ByteSWrite, nil);
    end;

{B.填充自定义数据}
    //指向新节开始处
    SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN);

    //填充我们定义的数据示例
    WriteFile(hFile, PByte(@AttachStart)^, Integer(@AttachEnd) - Integer(@AttachStart), ByteSWrite, nil);

    //没有异常,显示增加区块成功!
    ShowMessage('增加区块成功!');
finally

{8.退出}
    //关闭文件
    CloseHandle(hFile);
end;

end;
{*************************Func end*********************************}


procedure TForm1.Button1Click(Sender: TObject);
begin
AddSection(Edit1.text, true);//Edit1.text为文件路径,true表示备份
end;

[ 本帖最后由 fonge 于 2007-10-15 15:47 编辑 ]

yingfeng 发表于 2007-10-15 18:00:24

两位版主大大都是BD高手,呵呵

学习,感叹呀!/:L

sislcb 发表于 2007-10-19 12:02:31

支持fonge,太强悍了

晚秋之夜 发表于 2008-1-27 22:43:59

学习了,佩服高手!

bigdinosaur 发表于 2008-3-21 13:33:27

两位版主大大都是高手,我要学习。

wxkjgd 发表于 2008-6-28 21:46:55

楼主厉害!/:good

阳小子 发表于 2008-7-2 20:44:41

谢谢楼主的分享,收藏了再慢慢看了。

lgjxj 发表于 2008-7-15 00:20:40

当初入门的时候好像还是一个层次的,现在看来差距大啊 /:014

dying 发表于 2008-7-17 01:21:59

吓到我了。。/:013 太牛了
页: 1 [2] 3
查看完整版本: 活动之一PE自定义