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

📄 wdmfixer.dpr

📁 delphi源代码分析源码
💻 DPR
字号:
program WDMFixer;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils, Classes;

const
  FT_ANY = 0;
  FT_DLL = IMAGE_FILE_DLL;
  FT_ROM = IMAGE_ROM_OPTIONAL_HDR_MAGIC;
  FT_EXE = IMAGE_FILE_EXECUTABLE_IMAGE;


{ type defined in Jedi Api Project, JwaWinNT.pas }
type
  TIIDUnion = record
    case Integer of
      0: (Characteristics: DWORD);         // 0 for terminating null import descriptor
      1: (OriginalFirstThunk: DWORD);      // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
  end;

  PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
  {$EXTERNALSYM PIMAGE_IMPORT_DESCRIPTOR}
  _IMAGE_IMPORT_DESCRIPTOR = record
    Union: TIIDUnion;
    TimeDateStamp: DWORD;                  // 0 if not bound,
                                           // -1 if bound, and real date\time stamp
                                           //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                           // O.W. date/time stamp of DLL bound to (Old BIND)

    ForwarderChain: DWORD;                 // -1 if no forwarders
    Name: DWORD;
    FirstThunk: DWORD;                     // RVA to IAT (if bound this IAT has actual addresses)
  end;
  {$EXTERNALSYM _IMAGE_IMPORT_DESCRIPTOR}
  IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
  {$EXTERNALSYM IMAGE_IMPORT_DESCRIPTOR}
  TImageImportDecriptor = IMAGE_IMPORT_DESCRIPTOR;
  PImageImportDecriptor = PIMAGE_IMPORT_DESCRIPTOR;


type
  TCheckCallback = procedure (FN : String);

function isPE(F:TStream; FType:WORD) : Boolean;
var
  Size : DWORD;
  Tag : WORD;
  NTHead : DWORD;
begin
  Result := False;
  Size := F.Size;
  if Size <= SizeOf(TImageDosHeader) + 4 + SizeOf(TImageFileHeader) then
    Exit;

  F.Seek(0,soFromBeginning);
  F.Read(Tag, 2);
  F.Seek(2, soFromCurrent);
  if Tag <> IMAGE_DOS_SIGNATURE then
    Exit;

  F.Seek(SizeOf(TImageDosHeader)-8, soFromCurrent);
  F.Read(NTHead, 4); // _lfanew
  if Size <= NTHead + 4 + SizeOf(TImageFileHeader) then
    Exit;

  F.Seek(NTHead, soFromBeginning);
  F.Read(NTHead, 4);
  Result := NTHead = IMAGE_NT_SIGNATURE;
end;

const
  IMAGE_SIZEOF_OPTIONAL_HEADER_NONEDIRECTOR = 96;

function PosToTableEntry(F: TStream; Section: SmallInt; out VABase, VASize, RawAddr: DWORD): Boolean;
var
  tempPos : Int64;
  tempSize : DWORD;
  NumberOfRvaAndSizes : DWORD;
  i : Integer;
  SectionHeader : TImageSectionHeader;
  SizeOfOptionalHeader : DWORD;
begin
  Result := False;
  if (F.Position <> 0) or isPE(F, FT_ANY) then
  begin
    tempSize := 0;
    F.Seek(2, soFromCurrent);      // 跳2个字节: TImageFileHeader.Machine
    F.Read(tempSize, 2);           // 取TImageFileHeader.NumberOfSections
    F.Seek(SizeOf(TImageFileHeader) - 4 - 4 , soFromCurrent);   // 定位到TImageFileHeader.SizeOfOptionalHeader
    F.Read(SizeOfOptionalHeader, 4);
    SizeOfOptionalHeader := SizeOfOptionalHeader and $0000FFFF; // 去除掉高位的TImageFileHeader.Characteristics
    tempPos := F.Position;         // 可选头部
    F.Seek(IMAGE_SIZEOF_OPTIONAL_HEADER_NONEDIRECTOR-4, soFromCurrent);  //定位到NumberOfRvaAndSizes
    F.Read(NumberOfRvaAndSizes, 4);

    // 定位到DataDirectory[]
    F.Seek(SizeOf(TImageDataDirectory)*Section, soFromCurrent);  // 跳过目录;
    F.Read(VABase, 4);                                           // 读指定目录的VABase
    F.Read(VASize, 4);                                           // 读指定目录的VASize

    if VABase <> 0 then
    begin
      // 定位到节表
      inc(tempPos, SizeOfOptionalHeader);
      F.Seek(tempPos, soFromBeginning);

      // 取RawAddr
      for i := 0 to tempSize - 1 do
      begin
        F.Read(SectionHeader, SizeOf(TImageSectionHeader));
        with SectionHeader do
          // 如果虚地址相等或者VABase落在节的内部
          if (VABase = VirtualAddress) or
             ((VABase > VirtualAddress) and (VABase < VirtualAddress + Misc.VirtualSize)) then
          begin
            RawAddr := PointerToRawData + (VABase - VirtualAddress);
            F.Seek(RawAddr, soFromBeginning);
            Result := True;
            Exit;
          end;
      end;
    end;

    // 如果返回False, 则定位到PE头
    F.Position := tempPos - SizeOf(TImageFileHeader);
  end;
end;

procedure DoFix(callback:TCheckCallback; Dir : String = ''; FN : String = '*.*');
var
  Sr : TSearchRec;
begin
  if FindFirst(Dir+FN, faAnyFile-faVolumeID, Sr) = 0 then
    repeat
      if (Sr.Attr and faDirectory)=0 then //is File
        callback(Dir+Sr.Name)
      else //is Directory
        if Sr.Name[1] <> '.' then
          DoFix(callback, Dir+Sr.name+'\', FN);
    until FindNext(Sr) <> 0;
end;

procedure FixImport(FN : String);
var
  VABase, VASize, RawAddr: DWORD;
  F : TMemoryStream;

  ImportItem : TImageImportDecriptor;
begin
  try
    F := TMemoryStream.Create();
    F.LoadFromFile(FN);
  except
    exit;
  end;

  if PosToTableEntry(F, IMAGE_DIRECTORY_ENTRY_IMPORT, VABase, VASize, RawAddr) then
  begin
    while true do
    begin
      F.Read(ImportItem, SizeOf(TImageImportDecriptor));
      if ImportItem.name = 0 then
        Break;

      // 修正WDM文件导入表的中的 OriginalFirstThunk 值
      ImportItem.Union.OriginalFirstThunk := ImportItem.FirstThunk;

      F.Seek(-SizeOf(TImageImportDecriptor), soFromCurrent);
      F.Write(ImportItem, SizeOf(TImageImportDecriptor));
    end;
  end;

  F.SaveToFile(FN);
  F.Free;
end;

const SoftWareName = 'WDM Fixer for Delphi Apps. Ver1.0,';
      CompanyName  = 'copyright(c) 1999,2004 aurora software';
      Width        = 80 - Length(SoftWareName);
begin
  if ParamCount > 0 then
    DoFix(FixImport, '', ParamStr(1))
  else
  begin
    Write(SoftWareName,CompanyName:Width);
    Writeln('By Mr. Aimingoo.'); Writeln;
    writeln('Usage : WDMFixer FileName');
  end;
end.

⌨️ 快捷键说明

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