HookAPI 之 ExitWindowsEX

來源:互聯網
上載者:User

 

 

有些病毒經常搞的機器無法關機到底是什麼原因呢?其實就是HOOK 了ExitWindowsEx這個API函數,以下代碼簡要實現

{主程式}

//--------------------------------------------------
// 程式作者:zorro MYBlog:http://blog.csdn.net/zorro0920/
// QQ:15124763      All rights reserved!!
// 轉載請保留此資訊
//--------------------------------------------------
unit Main;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private

  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  h_Hook:HHook;
implementation

{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
  //結束
  if  h_Hook<>0 then
    UnhookWindowsHookEx(h_Hook);
  Application.Terminate;
end;
//------------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
  hHookDll,htaskmar,ThreadID:thandle;
  pHookFunction:Pointer;
begin
     hHookDll:= LoadLibrary('Hook.dll');
     if hHookDll<>0 then
     begin
       ShowMessage('hHookDll<>0');
       pHookFunction:=GetProcAddress(hHookDll,'HookFunction');
       if  pHookFunction<>nil then
       begin
           h_Hook:=SetWindowsHookEx(3,pHookFunction,hHookDll,0);
          
       end;
     end
     else
       ShowMessage('hHookDll=0');
end;

end.

 

{HOOK.DLL}

 

library Hook;

uses
  SysUtils,
  Classes,
  HookApi in 'HookApi.pas';

{$R *.res}
exports
  HookFunction;
 
begin
 
end.
 

{主要單元檔案}

unit HookAPI;

interface
uses
Windows, Classes,dialogs,SysUtils,Messages;
type
  PImage_Import_Entry = ^Image_Import_Entry;
  Image_Import_Entry = record
    OriginalFirstThunk : DWORD;
    TimeDateStamp : DWORD;
    forwarderChain:DWORD;
    Name : DWORD;
    LookupTable : DWORD;
  end;

  PImageThunkData = ^TImageThunkData;
  TImageThunkData = record
  case integer of
    1:( ForwarderString : DWord; );
    2:( Function_       : DWord; );
    3:( Ordinal         : DWord; );
    4:( AddressOfData   : DWord; );
  end;
 
  Function TrueFunctionAddress(Code: Pointer): Pointer;
  Function WriteFunction(OldFunc, NewFunc: Pointer):Integer;
  function HookFunction(nCode:Integer;WParam:WPARAM;LParam:LPARAM):LRESULT;stdcall;
var
 h_hook:HHook;
 hmod:Dword;
 //flag:Boolean = True;
implementation

type
TImportCode = packed record
JumpInstruction: Word;
AddressOfPointerToFunction: ^Pointer;
end;
PImportCode = ^TImportCode;
//-----------------------------------------------------------------------------
function TrueFunctionAddress(Code: Pointer): Pointer;
var
  func: PImportCode;
begin
  Result := Code;
  if Code = nil then exit;
  try
  func := code;
  if (func.JumpInstruction=$25FF) then begin
    Result := func.AddressOfPointerToFunction^;
  end;
  except
    Result := nil;
  end;
end;
//------------------------------------------------------------------------------
Function WriteFunction(OldFunc, NewFunc: Pointer):Integer;
var
  BeenDone: TList;

  Function WriteAddrInModule(hModule: THandle; OldFunc,NewFunc: Pointer): Integer;
  var
    Dos : PImageDosHeader;
    NT : PImageNTHeaders;
    ImportDesc : PImage_Import_Entry;
    RVA : DWORD;
    Func : ^Pointer;
    DLL : String;
    //f : Pointer;
    written : DWORD;
  begin
  Result := 0;
  Dos := Pointer(hModule);
  if BeenDone.IndexOf(Dos) >= 0 then exit;
  BeenDone.Add(Dos);
  //OldFunc := TrueFunctionAddress(OldFunc);//函數的實際地址
  if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;

  if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;  //IMAGE_DOS_SIGNATURE='MZ'
  {定位至NT Header}
  NT := Pointer(Integer(Dos) + dos._lfanew);
  {定位至引入函數表}
  RVA := NT^.OptionalHeader.DataDirectory
  [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  if RVA = 0 then exit;  //如果引入函數表為空白,則退出
  ImportDesc := pointer(integer(Dos)+RVA);

  While(ImportDesc^.Name<>0) do
  begin
    DLL := PChar(Integer(Dos) + ImportDesc^.Name);
    WriteAddrInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);
    //定位至被引入的下級DLL模組的函數表
    Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
    While Func^ <> nil do
    begin
      //f := TrueFunctionAddress(Func^);
      if Func^ = OldFunc then //如果函數實際地址就是所要找的地址
      begin
        //showmessage('準備覆蓋函數');
        WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written);//把新函數地址覆蓋它
        If Written > 0 then Inc(Result);
      end;
      Inc(Func); //如果函數實際地址就是所要找的地址
   end;
  Inc(ImportDesc); //下一個被引入的下級DLL模組
  end;
 end;

begin
  BeenDone := TList.Create;
  try
  Result := WriteAddrInModule(GetModuleHandle(nil),OldFunc,NewFunc);
  finally
    BeenDone.Free;
  end;
end;

//------------------------------------------------------------------------------

Function My_Process(uFlags:UINT;dwReserved:DWORD):Boolean;
begin
  Result:=True;
end;
//------------------------------------------------------------------------------

Function HookFunction(nCode:Integer;WParam:WPARAM;LParam:LPARAM):LRESULT;stdcall;export;
var
  OldFunction:Pointer;
begin
  //ShowMessage('HookFunction');
  OldFunction:=GetProcAddress(GetModuleHandle('User32.DLL'),'ExitWindowsEx');
  WriteFunction(OldFunction,@My_Process);
  Result:=CallNextHookEx(h_hook, ncode, wParam, lParam);
end;
end.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.