问题是,当调用StartHook后,控制台程序就可以成功注入!则包含界面的有些程序就不可以注入,有些却又可以注入!
主要原因好像是因为我在里面加了一句:WaitForSingleObject(htd,INFINITE );
不加这句则不会出现这个问题,但是执行太快的程序则注入不到!
请高手解答:
在百度问根本就没有回答,晕,还是得靠CSDN的大侠们呐!
请将这main复制到Dlldll里,把unithook加到main这个Dll Project里!然后用程序调用StartHookk;
就会出现上面的问题!期待高手解答:main.dll代码:library main;
uses
  sysutils,
  Windows,
  Classes,
  Dialogs,
  Forms,
  tlhelp32,
  unitHook in 'unitHook.pas';{$R *.res}var
  hhk:HHOOK;
  Hook: array[0..1] of TNtHookClass;
  vspas:Bool;
  Curfile:String[255];
  htd:Cardinal;
  DllInstall:Bool;
{--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--}
procedure GetMyProcessID(const AFilename: string; const PathMatch: Boolean; var ProcessID: DWORD);
var
  lppe: TProcessEntry32;
  SsHandle: Thandle;
  FoundAProc, FoundOK: boolean;
begin
  ProcessID :=0;
  { 创建系统快照 }
  SsHandle := CreateToolHelp32SnapShot(TH32CS_SnapProcess, 0);  { 取得快照中的第一个进程 }
  { 一定要设置结构的大小,否则将返回False }
  lppe.dwSize := sizeof(TProcessEntry32);
  FoundAProc := Process32First(Sshandle, lppe);
  while FoundAProc do
  begin
    { 进行匹配 }
    if PathMatch then
      FoundOK := AnsiStricomp(lppe.szExefile, PChar(AFilename)) = 0
    else
      FoundOK := AnsiStricomp(PChar(ExtractFilename(lppe.szExefile)), PChar(ExtractFilename(AFilename))) = 0;
    if FoundOK then
    begin
      ProcessID := lppe.th32ProcessID;
      break;
    end;
    { 未找到,继续下一个进程 }
    FoundAProc := Process32Next(SsHandle, lppe);
  end;
  CloseHandle(SsHandle);
end;
{ 设置权限 }
function EnabledDebugPrivilege(const Enabled : Boolean) : Boolean;
var
  hTk : THandle; { 打开令牌句柄 }
  rtnTemp : Dword; { 调整权限时返回的值 }
  TokenPri : TOKEN_PRIVILEGES;
const
  SE_DEBUG = 'SeDebugPrivilege'; { 查询值 }
begin
  Result := False;
  { 获取进程令牌句柄,设置权限 }
  if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,hTk)) then
  begin
    TokenPri.PrivilegeCount := 1;
    { 获取Luid值 }
    LookupPrivilegeValue(nil,SE_DEBUG,TokenPri.Privileges[0].Luid);    if Enabled then
      TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
      TokenPri.Privileges[0].Attributes := 0;    rtnTemp := 0;
    { 设置新的权限 }
    AdjustTokenPrivileges(hTk,False,TokenPri,sizeof(TokenPri),nil,rtnTemp);    Result := GetLastError = ERROR_SUCCESS;
    CloseHandle(hTk);  end;
end;{ 注入远程进程 }
function InjectTo(const Host, Guest: string; const PID: DWORD = 0): DWORD;
var
  { 被注入的进程句柄,进程ID}
  hRemoteProcess: THandle;
  dwRemoteProcessId: DWORD;  { 写入远程进程的内容大小 }
  memSize: DWORD;  { 写入到远程进程后的地址 }
  pszLibFileRemote: Pointer;  iReturnCode: Boolean;
  TempVar: DWORD;  { 指向函数LoadLibraryW的地址 }
  pfnStartAddr: TFNThreadStartRoutine;  { dll全路径,需要写到远程进程的内存中去 }
  pszLibAFilename: PwideChar;
begin
  Result := 0;
  { 设置权限 }
  EnabledDebugPrivilege(True);  { 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 }
  Getmem(pszLibAFilename, Length(Guest) * 2 + 1);
  StringToWideChar(Guest, pszLibAFilename, Length(Guest) * 2 + 1);  { 获取进程ID }
  if PID > 0 then
     dwRemoteProcessID := PID
  else
     GetMyProcessID(Host, False, dwRemoteProcessID);  { 取得远程进程句柄,具有写入权限}
  hRemoteProcess := OpenProcess(PROCESS_CREATE_THREAD + {允许远程创建线程}
      PROCESS_VM_OPERATION + {允许远程VM操作}
      PROCESS_VM_WRITE, {允许远程VM写}
      FALSE, dwRemoteProcessId);  { 用函数VirtualAllocex在远程进程分配空间,并用WriteProcessMemory中写入dll路径 }
  memSize := (1 + lstrlenW(pszLibAFilename)) * sizeof(WCHAR);
  pszLibFileRemote := PWIDESTRING(VirtualAllocEx(hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE));
  TempVar := 0;
  iReturnCode := WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, memSize, TempVar);  if iReturnCode then
  begin
    pfnStartAddr := GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW');
    TempVar := 0;
    { 在远程进程中启动dll }
    Result := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, TempVar);
  end;  { 释放内存空间 }
  Freemem(pszLibAFilename);
end;
//拦截 CreateProcessW
function NewCreateProcessW(lpApplicationName: PChar; lpCommandLine: PChar;
      lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
      bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
      lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
      var lpProcessInformation: TProcessInformation): BOOL; stdcall;
type
  TNewCreateProcessW=function (lpApplicationName: PChar; lpCommandLine: PChar;
      lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
      bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
      lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
      var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  ShowMessage(Application.ExeName+'   open    '+AnsiString(lpApplicationName));
  Hook[0].UnHook;
  Curfile:=AnsiString(lpApplicationName);
  vspas:=True;
  Result := TNewCreateProcessW(Hook[0].BaseAddr)(lpApplicationName,lpCommandLine,
  lpProcessAttributes, lpThreadAttributes, bInheritHandles,dwCreationFlags,lpEnvironment,
  lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
  Hook[0].Hook;
end;
function NewNtResumeThread(hThread:Cardinal;PreviousSuspendCount:PULONG):Cardinal;stdcall;
type
  TNewNtResumeThread=function (hThread:Cardinal;PreviousSuspendCount:PULONG):Cardinal;stdcall;
begin
if vspas then
  begin
  vspas:=False;
  Hook[1].UnHook;
  htd:=InjectTo(String(Curfile),'c:\main.dll');
  curfile:='';
  WaitForSingleObject(htd,INFINITE );
  end;
  Hook[1].UnHook;
  Result:=TNewNtResumeThread(Hook[1].BaseAddr)(hThread,PreviousSuspendCount);
  Hook[1].Hook;
end;
{--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--}
//删除API Hook
procedure UninitHook;
var
  I: Integer;
begin
  for I := 0 to High(Hook) do
  begin
    FreeAndNil(Hook[I]);
  end;
end;
//安装API Hook
procedure InitHook;
begin
  dllinstall:=True;
  Hook[0] := TNtHookClass.Create('kernel32.dll', 'CreateProcessW', @NewCreateProcessW);
  Hook[1] := TNTHookClass.Create('ntdll.dll','NtResumeThread',@NewNtResumeThread);
end;
{--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--}//传递消息
function HookProc(nCode, wParam, lParam: Integer): Integer; stdcall;
begin
  Result := CallNextHookEx(hhk, nCode, wParam, lParam);
end;//开始HOOK
procedure StartHook; stdcall;
begin
  hhk:= SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);
end;
//结束HOOK
procedure EndHook; stdcall;
begin
  if hhk <> 0 then
    UnhookWindowsHookEx(hhk);
end;//环境处理
procedure DllEntry(dwResaon: DWORD);
begin
  case dwResaon of
    DLL_PROCESS_ATTACH: InitHook;   //DLL载入
    DLL_PROCESS_DETACH: UninitHook; //DLL删除
  end;
end;exports
  StartHook,EndHook;begin
  if DllInstall then
  Exit;
  DllProc := @DllEntry;
  DllEntry(DLL_PROCESS_ATTACH);
end.
unit Hook代码:unit unitHook;interfaceuses
  Windows, Messages, Classes, SysUtils;type  //NtHook类相关类型
  TNtJmpCode=packed record  //8字节
    MovEax:Byte;
    Addr:DWORD;
    JmpCode:Word;
    dwReserved:Byte;
  end;  TNtHookClass=class(TObject)
  private
    hProcess:THandle;
    NewAddr:TNtJmpCode;
    OldAddr:array[0..7] of Byte;
    ReadOK:Boolean;
  public
    BaseAddr:Pointer;
    constructor Create(DllName,FuncName:string;NewFunc:Pointer);
    destructor Destroy; override;
    procedure Hook;
    procedure UnHook;
  end;implementation//==================================================
//NtHOOK 类开始
//==================================================
constructor TNtHookClass.Create(DllName: string; FuncName: string;NewFunc:Pointer);
var
  DllModule:HMODULE;
  dwReserved:DWORD;
begin
  //获取模块句柄
  DllModule:=GetModuleHandle(PChar(DllName));
  //如果得不到说明未被加载
  if DllModule=0 then DllModule:=LoadLibrary(PChar(DllName));
  //得到模块入口地址(基址)
  BaseAddr:=Pointer(GetProcAddress(DllModule,PChar(FuncName)));
  //获取当前进程句柄
  hProcess:=GetCurrentProcess;
  //指向新地址的指针
  NewAddr.MovEax:=$B8;
  NewAddr.Addr:=DWORD(NewFunc);
  NewAddr.JmpCode:=$E0FF;
  //保存原始地址
  ReadOK:=ReadProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved);
  //开始拦截
  Hook;
end;//释放对象
destructor TNtHookClass.Destroy;
begin
  UnHook;
  CloseHandle(hProcess);  inherited;
end;//开始拦截
procedure TNtHookClass.Hook;
var
  dwReserved:DWORD;
begin
  if (ReadOK=False) then Exit;
  //写入新的地址
  WriteProcessMemory(hProcess,BaseAddr,@NewAddr,8,dwReserved);
end;//恢复拦截
procedure TNtHookClass.UnHook;
var
  dwReserved:DWORD;
begin
  if (ReadOK=False) then Exit;
  //恢复地址
  WriteProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved);
end;end.