DllHijacker For Delphi

{*******************************************************}
{                                                       }
{    DllHijacker                                        }
{                                                       }
{    版权所有 (C) 2008 pathletboy                       }
{                                                       }
{*******************************************************}

unit Common;

interface

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

type
   TBuildDprStatus = (SUCCESS, FILE_NOT_FOUND, FILE_READ_ERROR, FILE_NOT_PE,
FILE_NOT_DLL, FILE_NOT_HAVE_EXPORTTABLE, SAVEFILE_ERROR, UNKNOW_ERROR);

function BuildDpr(const FileName: string): TBuildDprStatus;
implementation

function BuildDpr(const FileName: string): TBuildDprStatus;

   function RvaToRaw(const ImageSectionHeader: PImageSectionHeader; Rva:
Cardinal): Cardinal;
   var
Temp: PImageSectionHeader;
   begin
Temp := ImageSectionHeader;
while Temp.VirtualAddress <> 0 do
begin
   if (Rva >= Temp.VirtualAddress) and (Rva < (Temp.VirtualAddress
       + Temp.Misc.VirtualSize)) then
   begin
       Result := Temp.PointerToRawData + Rva - Temp.VirtualAddress;
       Break;
   end;
   inc(Temp);
end;
   end;

var
   TargetFile: TMemoryStream;
   DosHead: TImageDosHeader;
   NtHead: TImageNtHeaders;
   ExportTable: TImageExportDirectory;
   ExportTableAddress: Cardinal;
   //ExportTableSize: Cardinal;
   ExportFunctionNameAddress: Cardinal;
   ArrayFunctionNames: array of string;
   i: Integer;
   OneChar: Char;
   DprFileName: string;
   DprSourceFile: TStringList;
   PSectionHeader: PImageSectionHeader;
begin
   Result := UNKNOW_ERROR;

   if not FileExists(FileName) then
   begin
Result := FILE_NOT_FOUND;
Exit;
   end;

   TargetFile := TMemoryStream.Create;
   try

try
   TargetFile.LoadFromFile(FileName);
   TargetFile.Read(DosHead, SizeOf(DosHead));
   if DosHead.e_magic <> IMAGE_DOS_SIGNATURE then
   begin
       Result := FILE_NOT_PE;
       Exit;
   end;

   TargetFile.Seek(DosHead._lfanew, soFromBeginning);
   TargetFile.Read(NtHead, SizeOf(NtHead));
   if NtHead.Signature <> IMAGE_NT_SIGNATURE then
   begin
       Result := FILE_NOT_PE;
       Exit;
   end;

   if NtHead.FileHeader.Characteristics and IMAGE_FILE_DLL = 0 then
   begin
       Result := FILE_NOT_DLL;
       Exit;
   end;

   if NtHead.OptionalHeader.DataDirectory[0].Size = 0 then //ExportTable
   begin
       Result := FILE_NOT_HAVE_EXPORTTABLE;
       Exit;
   end;
   PSectionHeader := Pointer(DWORD(TargetFile.Memory) + DosHead._lfanew +
       SizeOf(NtHead));

   ExportTableAddress := RvaToRaw(PSectionHeader,
       NtHead.OptionalHeader.DataDirectory[0].VirtualAddress);

   //ExportTableSize := NtHead.OptionalHeader.DataDirectory[0].Size;
   TargetFile.Seek(ExportTableAddress, soFromBeginning);
   TargetFile.Read(ExportTable, SizeOf(ExportTable));
   TargetFile.Seek(RvaToRaw(PSectionHeader,
       DWORD(ExportTable.AddressOfNames)),
       soFromBeginning);
   TargetFile.Read(ExportFunctionNameAddress,
       SizeOf(ExportFunctionNameAddress));
   TargetFile.Seek(RvaToRaw(PSectionHeader, ExportFunctionNameAddress),
       soFromBeginning);
   SetLength(ArrayFunctionNames, ExportTable.NumberOfNames);
   for i := 0 to ExportTable.NumberOfNames - 1 do
   begin
       TargetFile.Read(OneChar, SizeOf(OneChar));
       while OneChar <> #0 do
       begin
      ArrayFunctionNames[i] := ArrayFunctionNames[i] + OneChar;
      TargetFile.Read(OneChar, SizeOf(OneChar));
       end;
       OutputDebugString(PChar(Format('函数名序号:%d 函数名:%s', [i,
      ArrayFunctionNames[i]])));
   end;

   DprFileName := StringReplace(ExtractFileName(FileName),
       ExtractFileExt(FileName), '', [rfReplaceAll]);
   DprSourceFile := TStringList.Create;
   try
       try
      DprSourceFile.Add(Format('library %s;', [DprFileName]));
      DprSourceFile.Add('');
      DprSourceFile.Add('//==============================================================================');
      DprSourceFile.Add('// DllHijacker By pathletboy');
      DprSourceFile.Add('//==============================================================================');
      DprSourceFile.Add('');
      DprSourceFile.Add('uses');
      DprSourceFile.Add(' Windows;');

      DprSourceFile.Add('');
      DprSourceFile.Add('{$R *.res}');
      DprSourceFile.Add('');
      DprSourceFile.Add('var');
      DprSourceFile.Add(' ModHandle: Cardinal;');
      for i := 0 to ExportTable.NumberOfNames - 1 do
      begin
         DprSourceFile.Add(' POld' + ArrayFunctionNames[i] + ': Pointer;');
      end;
      DprSourceFile.Add('');

      for i := 0 to ExportTable.NumberOfNames - 1 do
      begin
         DprSourceFile.Add('procedure ' + ArrayFunctionNames[i] +
             '; asm jmp POld' + ArrayFunctionNames[i] + ' end;');
      end;
      DprSourceFile.Add('');

      DprSourceFile.Add('exports');
      for i := 0 to ExportTable.NumberOfNames - 1 do
      begin
         if i <> ExportTable.NumberOfNames - 1 then
             DprSourceFile.Add(' ' + ArrayFunctionNames[i] + ',')
         else
             DprSourceFile.Add(' ' + ArrayFunctionNames[i] + ';');
      end;
      DprSourceFile.Add('');

      DprSourceFile.Add('begin');
      DprSourceFile.Add(' ModHandle:= LoadLibrary(''' + FileName + ''');');
      DprSourceFile.Add(' if ModHandle > 0 then');
      DprSourceFile.Add(' begin');
      for i := 0 to ExportTable.NumberOfNames - 1 do
      begin
         DprSourceFile.Add(' POld' + ArrayFunctionNames[i] +
             ':= GetProcAddress(ModHandle, ''' + ArrayFunctionNames[i] +
             ''');');
      end;
      DprSourceFile.Add(' end;');
      DprSourceFile.Add('end.');

      DprSourceFile.SaveToFile(ExtractFilePath(Application.ExeName) +
         DprFileName + '.dpr');
      OutputDebugString(PChar(DprFileName + '.dpr Saved!'));
       except
      Result := SAVEFILE_ERROR;
      Exit;
       end;
   finally
       DprSourceFile.Free;
   end;

   OutputDebugString(PChar(DprFileName));
   Result := SUCCESS;
except
   Result := FILE_READ_ERROR;
   Exit;
end;
   finally
TargetFile.Free;
   end;

end;

end.