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

📄 reentry.pas

📁 破解“国际领先的Nprotect键盘加密技术”
💻 PAS
字号:
unit ReEntry;

interface

uses Windows;

  // 修改模块引入表
type
  TReEntry = class(TObject)
  public
    constructor Create(CallerModName, CalleeModName, FuncName: PChar; HookProc: FarProc);
    destructor Destroy(); override;
    function OriginProc(): FarProc; // 返回原始地址
  private
    m_CallerModName: PChar;   // 调用者模块名
    m_hCallerModule: HModule; // 调用者模块句柄
    m_CalleeModName: PChar;   // 被调者模块名
    m_HookProc,               // 新老函数地址
    m_OrigProc: FarProc;
    m_funcName: PChar;
    procedure ReplaceIATEntry(CurProc, NewProc: FarProc);
  end;

implementation

uses Messages, ImageHlp;

type
  // DLL数组结构
  TImageImportDescriptor = record
    OriginalFirstThunk: DWord; // 保存函数信息的TImageThunkData数组的RVA
    TimeDateStamp, ForwarderChain: DWord;
    Name: DWord;               // DLL名称字符串的RVA
    FirstThunk: DWord;         // 另一份TImageThunkData数组的拷贝的RVA,装载后,
  end;                         // 该TImageThunkData数组被修改为各函数入口地址
  PImageImportDescriptor = ^TImageImportDescriptor;

  // 函数名称信息
  TImageImportByName = packed record
    Hint: Word; // 如果非0, 表示函数的参考序号
    Name: array [0..0] of Char; // 函数名字符串
  end;
  PImageImportByName = ^TImageImportByName;

  // 函数数组结构
  TImageThunkData = record
    case Integer of               // 最高位不是1, 则为TImageImportByName的RVA,
      0: (ForwarderString: PByte);// 否则, 低31位代表引入的函数的序号, 另外,
      1: (Function_: PDWORD);     // 装载后, 此数组的一份拷贝变为各函数入口地址
      2: (Ordinal: ULONG);
      3: (AddressOfData: PImageImportByName);
  end;
  PImageThunkData = ^TImageThunkData;

constructor TReEntry.Create(
  CallerModName,    // 调用者模块名
  CalleeModName,    // 被调者模块名
  FuncName: PChar;  // 被调用函数名
  HookProc: FarProc); // 替换地址
begin
  m_CallerModName := CallerModName;
  m_hCallerModule := GetModuleHandle(CallerModName);
  if (m_hCallerModule = 0) then Exit;

  m_CalleeModName := CalleeModName;
  m_HookProc := HookProc;
  m_funcName := FuncName;
  m_OrigProc := GetProcAddress(GetModuleHandle(CalleeModName), FuncName);
  if (m_OrigProc = nil) then Exit;
  ReplaceIATEntry(m_OrigProc, m_HookProc);
end;

destructor TReEntry.Destroy();
begin
  if (m_hCallerModule <> 0) and (m_OrigProc <> nil) and
     (GetModuleHandle(m_CallerModName) = m_hCallerModule)
  then
    ReplaceIATEntry(m_HookProc, m_OrigProc);
end;

function TReEntry.OriginProc(): FarProc;
begin
  Result := m_OrigProc;
end;

procedure TReEntry.ReplaceIATEntry(CurProc, NewProc: FarProc);
var
  pImportDesc: PImageImportDescriptor;
  pThunk: PImageThunkData;
  CurModName: PChar;
  dwSize, dwProtect, dwTemp: DWord;
begin
  if (m_hCallerModule >= $80000000) then Exit;

  // 定位至函数引入表
  pImportDesc := ImageDirectoryEntryToData(Pointer(m_hCallerModule), True, IMAGE_DIRECTORY_ENTRY_IMPORT, dwSize);
  if (pImportDesc = nil) then Exit;

  // 遍历TImageImportDescriptor数组, 寻找名称匹配的DLL
  while (pImportDesc.Name <> 0) do
  begin
    CurModName := PChar(m_hCallerModule + pImportDesc.Name);
    if (lStrCmpI(CurModName, m_CalleeModName) = 0) then // DLL名字匹配
    begin
      // 定位至函数地址表
      pThunk := PImageThunkData(m_hCallerModule + pImportDesc.FirstThunk);

      // 遍历TImageThunkData数组 (寻找地址匹配的函数)
      while (pThunk.Function_ <> nil) do
      begin
        // 找到则改写Function_
        if (pThunk.Function_ = CurProc) then
        begin
          //MessageBox(0,m_funcName,CurModName,MB_OK);
          VirtualProtect(@pThunk.Function_, SizeOf(FarProc), PAGE_EXECUTE_WRITECOPY, @dwProtect);
          WriteProcessMemory(GetCurrentProcess(), @pThunk.Function_, @NewProc, SizeOf(FarProc), dwTemp);
          VirtualProtect(@pThunk.Function_, SizeOf(FarProc), dwProtect, @dwTemp);
          Break;
        end;

        // 下一个TImageThunkData
        Inc(pThunk);
      end; // while (pThunk.Function_ <> nil) do ..
    end;

    // 下一个TImageImportDescriptor
    Inc(pImportDesc);
  end; // while (pImportDesc.Name <> 0) do ..
end;

end.

⌨️ 快捷键说明

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