⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitpacker.~pas

📁 一款delphi+arm写的压缩壳. 反破解方面做的不是很好.但压缩性能和兼容性非常不错.
💻 ~PAS
📖 第 1 页 / 共 2 页
字号:
unit Unitpacker;

interface

uses
  windows,
 JwaWinnt, JwaWinBase, JwaWintype, JwaWinUser,
  Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ShellAPI, ComCtrls, StdCtrls,

  aplibu,
  PkDataQueueUnit,
  PEHeaderUnit,
  UtilUnit, Gauges, ExtCtrls, Menus, Buttons, ImgList;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    RichEdit1: TRichEdit;
    Panel1: TPanel;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    cbBackup: TCheckBox;
    cbClearImp: TCheckBox;
    leSrcFn: TLabeledEdit;
    PB: TGauge;
    imgIcon: TImage;
    leSectionName: TLabeledEdit;
    CheckBox1: TCheckBox;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    ImageList1: TImageList;
    Panel2: TPanel;
    Panel3: TPanel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Timer1: TTimer;
    Label4: TLabel;
    Label5: TLabel;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);

    
    procedure BitBtn2Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    SrcFn: String;
    BackFn: String;
    PkSectionName: String;
    procedure WithDropFiles(var Msg: TMessage); message WM_DROPFILES;
    procedure ShowMsg(Msg: String);
    procedure UpdateUi;
    function BackupFile(const FileName: String): integer;
    procedure DoPack;
  public
    { Public declarations }
  end;
  function CallBack(w0, w1, w2 : DWORD;
                           cbparam : Pointer) : DWORD;cdecl;
var
  Form1: TForm1;
type
  TPEAnalyst = class
  private
    FPEHeader: TPEHeader;
    FFileSize: Cardinal;
    FHasTls: Bool;
    FHasOverlay: Bool;
    FOverlayOffset: Cardinal;
    FOverlaySize: Cardinal;
    function GetHeaderSize: Cardinal;
    function GetImageSize: Cardinal;
    function GetSectionCount: Cardinal;
    function GetSectionHeaders(Index: Cardinal): PImageSectionHeader;
    function GetPEHeaderPtr: Pointer;
    function GetImageBase: Cardinal;
    procedure SetImageBase(const Value: Cardinal);
    function GetEntryPointRVA: Cardinal;
    procedure SetEntryPointRVA(const Value: Cardinal);
    function GetDataDirectory(Index: Cardinal): PImageDataDirectory;
    function GetDataDirectoryCount: Cardinal;
    function LastRawDataOffset: Cardinal;
    function HasDllFlag: Bool;
  public           
    constructor Create;
    destructor Destroy; override;
    function Assign(PEPtr: Pointer; FileSize: Cardinal): Bool;
    function AddSection(Length: Cardinal): PImageSectionHeader;  
    function OffsetInSection(Offset: Cardinal): Cardinal;
    function OffsettoRVA(Offset: Cardinal): Cardinal;
    function RVAInSection(RVA: Cardinal): Cardinal;
    function RVAtoOffset(RVA: Cardinal): Cardinal;
    function RVAtoPtr(RVA: Cardinal): Pointer;
    procedure UpdateImageSize;
    procedure DeleteSection(Index: Cardinal);
    property PEHeader: TPEHeader read FPEHeader;
    property PEHeaderPtr: Pointer read GetPEHeaderPtr;
    property DataDirectorys[Index: Cardinal]: PImageDataDirectory read GetDataDirectory;
    property SectionHeaders[Index: Cardinal]: PImageSectionHeader read GetSectionHeaders;
    property ImageBase: Cardinal read GetImageBase write SetImageBase;
    property ImageSize: Cardinal read GetImageSize;
    property HeaderSize: Cardinal read GetHeaderSize;
    property FileSize: Cardinal read FFileSize;
    property EntryPointRVA: Cardinal read GetEntryPointRVA write SetEntryPointRVA;
    property SectionCount: Cardinal read GetSectionCount;
    property DataDirectoryCount: Cardinal read GetDataDirectoryCount;
    property HasTls: Bool read FHasTls;
    property HasOverlay: Bool read FHasOverlay;
    property OverlayOffset: Cardinal read FOverlayOffset;
    property OverlaySize: Cardinal read FOverlaySize;
    property IsDll: Bool read HasDllFlag;
  end;
implementation

{$R *.dfm}
function TPEAnalyst.AddSection(Length: Cardinal): PImageSectionHeader;
var
  i: Cardinal;
  LastOffset, LastSize: Cardinal;
begin
  result := nil;
  if not FPEHeader.AddSection(result) then exit;
  if Length > 0 then
    result.Misc.VirtualSize := FPEHeader.CalcSectionAilgnment(Length)
  else
    result.Misc.VirtualSize := FPEHeader.FA;
  LastOffset := 0;
  LastSize := 0;
  if SectionCount > 1 then
  for i := 0 to SectionCount - 2 do
    if LastOffset < SectionHeaders[i]^.PointerToRawData then
    begin
      LastOffset := SectionHeaders[i]^.PointerToRawData;
      LastSize := SectionHeaders[i]^.SizeOfRawData;
    end
    else if (LastOffset = SectionHeaders[i]^.PointerToRawData) and
       (LastSize < SectionHeaders[i]^.SizeOfRawData) then
    begin
      LastOffset := SectionHeaders[i]^.PointerToRawData;
      LastSize := SectionHeaders[i]^.SizeOfRawData;
    end;
  result.SizeOfRawData := Length;
  result.PointerToRawData := LastOffset + FPEHeader.CalcFileAilgnment(LastSize);
  if result.PointerToRawData = 0 then
    result.PointerToRawData := HeaderSize;
  UpdateImageSize;
end;

function TPEAnalyst.Assign(PEPtr: Pointer; FileSize: Cardinal): Bool;
begin
  FFileSize := FileSize;
  result := FPEHeader.Assign(PEPtr);
  if not result then exit;
  FHasTls := DataDirectorys[9].VirtualAddress <> 0;
  FOverlayOffset := LastRawDataOffset;
  FHasOverlay := FOverlayOffset < FileSize;
  if FHasOverlay then
    FOverlaySize := FileSize - FOverlayOffset
  else
  begin
    FOverlayOffset := 0;
    FOverlaySize := 0;
  end;
end;

constructor TPEAnalyst.Create;
begin
  inherited;
  FPEHeader := TPEHeader.Create;
  FFileSize := 0;
end;

destructor TPEAnalyst.Destroy;
begin
  FPEHeader.Free;
  inherited;
end;

function TPEAnalyst.GetDataDirectory(Index: Cardinal): PImageDataDirectory;
begin
  result := FPEHeader.DataDirectorys[Index];
end;

function TPEAnalyst.GetEntryPointRVA: Cardinal;
begin
  result := FPEHeader.OptionalHeader32.AddressOfEntryPoint;
end;

function TPEAnalyst.GetHeaderSize: Cardinal;
begin
  result := FPEHeader.HeaderSize;
end;

function TPEAnalyst.GetImageBase: Cardinal;
begin
  result := FPEHeader.OptionalHeader32.ImageBase;
end;

function TPEAnalyst.GetImageSize: Cardinal;
begin
  result := FPEHeader.OptionalHeader32.SizeOfImage;
end;

function TPEAnalyst.GetPEHeaderPtr: Pointer;
begin
  result := PEHeader.DosHeader;
end;

function TPEAnalyst.GetSectionHeaders(Index: Cardinal): PImageSectionHeader;
begin
  result := PEHeader.Sections[Index];
end;

function TPEAnalyst.GetSectionCount: Cardinal;
begin
  result := FPEHeader.SectionCount;
end;

function TPEAnalyst.OffsetInSection(Offset: Cardinal): Cardinal;
begin
  result := FPEHeader.OffsetInSection(Offset);
end;

function TPEAnalyst.OffsettoRVA(Offset: Cardinal): Cardinal;
begin
  result := FPEHeader.OffsettoRVA(Offset);
end;

function TPEAnalyst.RVAInSection(RVA: Cardinal): Cardinal;
begin
  result := FPEHeader.RVAInSection(RVA);
end;

function TPEAnalyst.RVAtoOffset(RVA: Cardinal): Cardinal;
begin
  result := FPEHeader.RVAtoOffset(RVA);
end;

function TPEAnalyst.RVAtoPtr(RVA: Cardinal): Pointer;
begin
  result := FPEHeader.RVAtoPtr(RVA);
end;

procedure TPEAnalyst.SetEntryPointRVA(const Value: Cardinal);
begin
  FPEHeader.OptionalHeader32.AddressOfEntryPoint := Value;
end;

procedure TPEAnalyst.SetImageBase(const Value: Cardinal);
begin
  FPEHeader.OptionalHeader32.ImageBase := Value;
end;

procedure TPEAnalyst.UpdateImageSize;
begin
  FPEHeader.UpdateImageSize;
end;

procedure TPEAnalyst.DeleteSection(Index: Cardinal);
var
  i: Cardinal;
begin
  for i := 0 to DataDirectoryCount - 1 do
    if (DataDirectorys[i]^.VirtualAddress > SectionHeaders[Index]^.VirtualAddress) and
       (DataDirectorys[i]^.VirtualAddress + DataDirectorys[i]^.Size >
        SectionHeaders[Index]^.VirtualAddress + SectionHeaders[Index]^.Misc.VirtualSize) then
    begin
      DataDirectorys[i]^.VirtualAddress := 0;
      DataDirectorys[i]^.Size := 0;
    end;
  FPEHeader.WipeSectionHeader(Index);
end;

function TPEAnalyst.GetDataDirectoryCount: Cardinal;
begin
  result := FPEHeader.DirectoryCount;
end;

function TPEAnalyst.LastRawDataOffset: Cardinal;
var
  i, j: Cardinal;
begin
  result := 0;
  for i := 0 to SectionCount - 1 do
  begin
    j := SectionHeaders[i]^.PointerToRawData + SectionHeaders[i]^.SizeOfRawData;
    if result < j then
      result := j;
  end;
end;

function TPEAnalyst.HasDllFlag: Bool;
begin                                       
  result := FPEHeader.FileHeader.Characteristics and $2000 = $2000;
end;



 type
  PImpDir = ^TImpDir;              //壳中保存的导入表数据的结构  pimpdir->指针类型
  TImpDir = packed record    //T型定类义符
    ThunkRVA: DWORD;
    ImpFuncCount: DWORD;
    Name: Array [0..0] of Char;
    //导入的函数名或序号,pchar格式,第1个为导入dll的文件名。
    //如导入的是序号,则去掉二进制最高位的1(通过and $0FFFFFFF)
  end;
  PPkSectionDir = ^TPkSectionDir;  //壳中保存的Section数据的信息
  TPkSectionDir = packed record
    Offset: Cardinal;
    Length: Cardinal;
    RVA: Cardinal;
    VLength: Cardinal;
    Prop: Byte;
  end;
  PPkDataHeader = ^TPkDataHeader;  //壳中保存的压缩后数据的位置信息
  TPkDataHeader = packed record
    PkSectionDirCount: Cardinal;   //原始Section的个数
    PkSectionDirOffset: Cardinal;  //PkSectionDir数据相对PkDataHeader的偏移
    PkImpDirOffset: Cardinal;      //ImpDir数据相对PkDataHeader的偏移
    ImpSize: Cardinal;
    EPRVA: Cardinal;
    ResRVA: Cardinal;
    ResSize: Cardinal;
    DelayImpRVA: Cardinal;
    DelayImpSize: Cardinal;
    ExpRVA: Cardinal;
    ExpSize: Cardinal;
  end;     
  type
    PRegs = ^TRegs;
    TRegs = record
      Edi: Cardinal;
      Esi: Cardinal;
      Ebp: Cardinal;
      Esp: Cardinal;
      Ebx: Cardinal;
      Edx: Cardinal;
      Ecx: Cardinal;
      Eax: Cardinal;
  end;

var
  SrcPE: TMemoryStream;
  PkDataQueue: TPkDataQueue;  
  PEAnalyst: TPEAnalyst;
  pPackerSection: PImageSectionHeader;
  SectionDataSize: Cardinal = 0;  
  PkImportDirLength: Cardinal;

//===========SHELLCODE==============
  
procedure StartHere;
asm
end;

function LocalVar: PDWORD;     //一些数据,保存在壳中
asm
  call @j
  dd 0              //PkDataHeaderRVA

  dd $12345678      //'GetModuleHandleA' Thunk
  dd $12345678      //'LoadLibrary' Thunk
  dd $12345678      //'GetProcAddress' Thunk
  dd $feeeeeef      //'VirtualAlloc' Thunk
  dd $feeeeeef      //'VirtualFree' Thunk
  dd $feeeeeef      //'VirtualProtect' Thunk
  dd 0              //Null
@j:
  pop result
end;

{$INCLUDE 'DePack.pas'}

procedure NewEnteryPoint;        //壳的EP
asm

  push ebp
  mov ebp,esp
  push -1
  push ebx
  push esi
  push edi
  pop eax
  pop eax
  pop ebx
  pop eax
  pop ebp
  pushad
  call NewEP
end;

procedure EndHere;
asm
end;
//===========SHELLCODE==============

procedure AssembleImpTab;
//组装壳的导入表
const
  DllName: PChar = 'kernel32.dll';
  FuncName: Array [1..6] of PChar = ('GetModuleHandleA', 'LoadLibraryA',
    'GetProcAddress', 'VirtualAlloc', 'VirtualFree', 'VirtualProtect');
  //壳需要导入的函数
var
  PEImpPtr: Pointer;
  PkData: PPkData;

  PEImpPtrLen: Cardinal;
  PEImpDir: PImageImportDecriptor;
  pFuncName: PImageImportByName;
  pDllName: PChar;

  lImpDir, lDllName, lFuncName: Cardinal;
  pThunk: PDWORD;

  i, FuncCount, l, l2: Cardinal;
begin
  lImpDir := SizeOf(TImageImportDecriptor) * 2;      
  lDllName := Length(DllName) + 1;
  lFuncName := 0;
  FuncCount := High(FuncName) - Low(FuncName) + 1;
  for i := Low(FuncName) to High(FuncName) do
    Inc(lFuncName, Length(FuncName[i]) + 1);
  PEImpPtrLen := lImpDir + lDllName + lFuncName +
                 (SizeOf(WORD))* FuncCount +
                 SizeOf(DWORD) * (FuncCount + 1);

  PEImpPtr := AllocMem(PEImpPtrLen);

  PEImpDir := PEImpPtr;
  PEImpDir^.Union.OriginalFirstThunk := 0;
  PEImpDir^.TimeDateStamp := $FFFFFFFF;
  PEImpDir^.ForwarderChain := $FFFFFFFF;
  PEImpDir^.Name := lImpDir + SizeOf(DWORD) * (FuncCount + 1);
  PEImpDir^.FirstThunk := lImpDir;
  //Name, FirstThunk的值是Offset,不是RVA!

  pDllName := PtrAdd(PEImpDir, PEImpDir^.Name);
  CopyMemory(pDllName, DllName, lDllName);

  pThunk := PtrAdd(PEImpDir, PEImpDir^.FirstThunk);
  pFuncName := PtrAdd(pDllName, lDllName);
  l := lImpDir + SizeOf(DWORD) * (FuncCount + 1) + lDllName;
  for i := Low(FuncName) to High(FuncName) do
  begin
    pThunk^ := l;
    //pThunk的值是Offset,不是RVA!
    Inc(pThunk);
    pFuncName^.Hint := 0;
    CopyMemory(@pFuncName^.Name[0], FuncName[i], Length(FuncName[i]));
    l2 := Length(FuncName[i]) + SizeOf(TImageImportByName) - 1;
    pFuncName := PtrAdd(pFuncName, l2);
    Inc(l, l2);
  end;

  PkData := PkDataQueue.Get('ImpTab');  //存入列表
  PkData^.Ptr := PEImpPtr;
  PkData^.Len := PEImpPtrLen;
end;

procedure FixImpRVA(pImpDir: PImageImportDecriptor; BaseRVA: Cardinal);
//将Name, FirstThunk, pThunk值修正为RVA!
//BaseRVA: 导入表的RVA
//pImpDir: 指向导入表的指针
var
  pThunk: PDWORD;
begin
  Inc(pImpDir^.Name, BaseRVA);
  Inc(pImpDir^.FirstThunk, BaseRVA);
  pThunk := PtrAdd(pImpDir, SizeOf(TImageImportDecriptor) * 2 );
  while pThunk^ <> 0 do
  begin
    Inc(pThunk^, BaseRVA);
    Inc(pThunk);
  end;
end;

procedure FixImpThunk(pImpDir: PImageImportDecriptor; NewThunk: Cardinal);
//将导入表的FirstThunk指向LocalVar相应变量在加壳后程序中的RVA
//NewThunk: LocalVar第一个变量的RVA
//pImpDir: 指向导入表的指针
var

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -