有些病毒经常搞的机器无法关机到底是什么原因呢?其实就是HOOK 了ExitWindowsEx这个API函数,以下代码简要实现
{主程序}
//--------------------------------------------------
// 程序作者:zorro MYBlog:http://blog.youkuaiyun.com/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.