吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9315|回复: 24
收起左侧

[原创工具] 发布一个DELPHI写的PE ZERO ADD(就是增加空白区段的工具附原代码)

 关闭 [复制链接]
下雪天 发表于 2008-11-6 22:24
12.JPG
发布一个DELPHI写的PE ZERO  ADD(就是增加空白区段的工具附原代码)
这是我第一次写,有个小小的BUG,就是自定义的区段名是乱码,希望达人能够解决。
网上有汇编版本工具
和C版本的代码
这个弄的不好, 不支持文件拖拽,希望有达人扩充一下。大家一起进步。
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    ChxBackup: TCheckBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  SecData: integer;
  arrText: array of Char;//自定义的区段实现
  arrChar: array of Char;//自定义的区段拷贝


implementation

{$R *.dfm}    function AttachStart: dword; stdcall; //我们定义的待填充数据
 asm
    push $12345678        //保存OEP地址
       ret
end;
         function AttachEnd: dword; stdcall;
begin 
end;






  {-------------------------增加区块--------------------------------}
procedure AddSection(lFileName,secname,secsize: 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; //循环变量
    p: integer;//自定义区段的字符串的长
    S: String;//除去自定义区段空格


    BytesRead, ByteSWrite: Cardinal; //读写用参数
    AttachSize: dword; //附加段大小
    AttachData, ChangeData: integer; //附加段填充数据
    OEP: integer; //使用过程中用到的OEP
    lpBuffer: array[0..1024 * 400] of byte; {数据存储缓冲区}
    StartEN, SizeEN, StartCr: dword; //PE修改后的物理地址和大小
    ret: boolean;

begin
    

  //定义附加段填充数据
 AttachData := 0;
 S := Trim(secname);//除去自定义区段空格
 AttachSize := strtoint(secsize);//获取自定义的长度
 p :=Length(S);//得到自定义区段名字长度
 SetLength(arrText, p+2); //动态数组初始化
 SetLength(arrChar,p);

 arrText[0] :='.';
 for   i:=0   to   p-1  do
    begin
    arrText[i+1] :=secname[i+1] //动态数组下标从0开始,String类数组下标从1开始
    end;
    arrText[p+1] := #0;

   //打开文件
    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);
    ret := 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;
{********************************}
{OEP=基址+原EP}
        OEP := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint;

 {********************************}




   //初始化文件中偏移和映象中偏移
        lPointerToRawData := 0;
        lVirtualAddress := 0;

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

      //读取块表中信息
            ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil);

{********************************}
{查找原EP所在区段(原EP所在区段),记录物理偏移(初始地址),物理大小(长度)}
        if ImageNtHeaders.OptionalHeader.AddressOfEntryPoint > ImageSectionHeader.VirtualAddress then;
            begin
                StartEN := ImageSectionHeader.PointerToRawData;
                SecData := StartEN;
                SizeEN := ImageSectionHeader.SizeOfRawData; 
                StartCr := ImageNtHeaders.OptionalHeader.ImageBase + ImageSectionHeader.VirtualAddress;
           end;

 {********************************}

  //计算文件中偏移
            if lPointerToRawData < ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData then
                lPointerToRawData := ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData;

      //计算映象中偏移
      if lVirtualAddress < ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize
 then

                lVirtualAddress := ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize;
        end;

{增加块,定义块各项属性}


        Move(arrText, ImageSectionHeader.Name, p+2);

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

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

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

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

    //保存区块信息
        WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil);
 //校正内存映象大小
    ImageNtHeaders.OptionalHeader.SizeOfImage := ImageNtHeaders.OptionalHeader.SizeOfImage + ImageSectionHeader.Misc.VirtualSize;
  //更
    //校正块数目
      Inc(ImageNtHeaders.FileHeader.NumberOfSections);

    //定位到映象头
      SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN);

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

    //定位到新节开始处
       SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN);

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

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

    
        WriteFile(hFile, OEP, 4, ByteSWrite, nil); //跳回OEP

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

    finally

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

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

 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//设置文件的新区段段的属性为;读+写+可执行

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

procedure SetSectionAttrib(strFileName: string; StartEN: integer);
var
    dwBuffer: dword; {文件读取缓冲区}
    pe_header: IMAGE_NT_HEADERS; {PE文件头指针}
    iNumberOfSections: integer; {保存区块数目}
    dwSecTableBase: dword; {保存区块头文件首址}
    dwPEHeaderBase: dword; {保存PE文件头文件首址}
    iLoop: integer; {循环变量}
    pSectionTable: IMAGE_SECTION_HEADER; {保存各区块表指针}
    dwSectionAttrib: dword; {保存段属性}
    fsWrite: TFileStream; {写文件文件流}
begin
     {以读写方式建立文件流}
    fsWrite := TFileStream.Create(strFileName, fmOpenReadWrite);
     {文件流指针移动到新EXE头部字段}
    fsWrite.Seek($3C, soFromBeginning);
    dwBuffer := 0;
     {读取PE文件头文件地址}
    fsWrite.ReadBuffer(dwBuffer, 4);
    dwPEHeaderBase := dwBuffer;
     {文件指针指向PE 文件头}
    fsWrite.Seek(dwBuffer, soFromBeginning);
     {读入pe文件头到内存}
    fsWrite.ReadBuffer(pe_header, SizeOf(IMAGE_NT_HEADERS));
     {取区块数目}
    iNumberOfSections := pe_header.FileHeader.NumberOfSections;
    {获取区块表头文件地址:}
    dwSecTableBase := dwPEHeaderBase + SizeOf(IMAGE_NT_HEADERS);
     {分别读取各个区块的信息到内存}
  for iLoop := 0 to iNumberOfSections - 1 do
    begin
         {文件指针指向第iLoop区块表}
        fsWrite.Seek(dwSecTableBase, soFromBeginning);
         {读入区块表信息}
        fsWrite.ReadBuffer(pSectionTable, SizeOf(IMAGE_SECTION_HEADER));
            {读取区块数据文件地址}
        if pSectionTable.PointerToRawData = StartEN then
        begin

            fsWrite.Seek(dwSecTableBase + 36, soFromBeginning);
            dwSectionAttrib := $E00000E0;
            fsWrite.WriteBuffer(dwSectionAttrib, SizeOf(dword));
            fsWrite.Free;
            ShowMessage('修改区段属性成功');
             break;
        end;
    end;
end;




procedure TForm1.Button1Click(Sender: TObject);
var
 FileName,EdtASN,EdtASS :string;
 Backup:Boolean;
begin
  FileName:=Trim(edit1.Text);
  EdtASN:=edit2.Text;
  EdtASS:=edit3.Text;
  Backup:=ChxBackup.Checked;
  if not FileExists(FileName) then
    MessageBox(Handle,'请输入有效的文件名!',PChar(Caption),MB_ICONERROR+MB_OK)
  else if Length(edit2.Text)=0 then
    MessageBox(Handle,'请输入新区段名称!',PChar(Caption),MB_ICONERROR+MB_OK)
  else if Length(edit3.Text)=0 then
    MessageBox(Handle,'请输入输入新区段大小!',PChar(Caption),MB_ICONERROR+MB_OK)
  else
  AddSection(Edit1.text,Edit2.text,Edit3.text,true); //增加区段头
    SetSectionAttrib(Edit1.text, SecData); //  设置区段属性
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
     with TOpenDialog.Create(Self) do
    try
        Filter := '可执行文件 (*.exe)|*.exe';
        if Execute then
    begin
            Edit1.text := FileName;
        end;
  finally
       Free;
      end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
     close;
end;

end.

DELPHI版ZEROADD.rar

184.69 KB, 下载次数: 93, 下载积分: 吾爱币 -2 CB

免费评分

参与人数 1威望 +2 收起 理由
zzage + 2 学习一下!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 下雪天 发表于 2008-11-7 00:10
居然没人理睬,伤心ING。
杜大 发表于 2008-11-7 00:18
原帖由 下雪天 于 2008-11-7 00:10 发表
居然没人理睬,伤心ING。

论坛才刚升级,我也是才进来,还有好多人还不知道了
szwkq 发表于 2008-11-7 00:35
poco0101 发表于 2008-11-7 01:02
这个是用来干什么的啊
swl 发表于 2008-11-7 08:06
好工具,楼主辛苦了。
 楼主| 下雪天 发表于 2008-11-7 18:03

一上来就这么热情。开心啊。。。
小生我怕怕 发表于 2008-11-7 18:06
下雪写这个写得很辛苦的啊!
marvell 发表于 2008-11-7 19:15
顶个.....顶个  下雪自己写的啊 辛苦 辛苦  = =
 楼主| 下雪天 发表于 2008-11-7 23:05

刚才请教了看雪论坛大牛
终于解决了区段乱码的问题
Move(arrText, ImageSectionHeader.Name, p+2);
Move(arrText[0], ImageSectionHeader.Name, p+2);
就可以了
下面这个是重新编译过的
不出现区段乱码了
呵呵

[ 本帖最后由 下雪天 于 2008-11-7 23:13 编辑 ]

DELPHI版ZEROADD.rar

184.67 KB, 下载次数: 59, 下载积分: 吾爱币 -2 CB

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-1 07:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表