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

📄 magicapihook.pas

📁 how you can hook functions by small size of codes
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit MagicApiHook;
(*
==============================================
Magic Api Hook Engine v1.0 - Date: 2006.04.24
this is a simple all around process api hooker
UserMode(Ring3) just for WinNT family
By: Magic_h2001 - magic_h2001@yahoo.com
Home: http://magic.shabgard.org
==============================================
*)
interface

uses Windows;

function LowCaseStr(S:string):string;
function UpCaseStr(S:string):string;
function StrCmp(String1,String2:string):Boolean;
function Trim(S:string):string;
function StrToInt(S:string):Integer;
function StrToInt64(S:string):Int64;
function IntToStr(i:Int64):string;
function IntToHex(i:Int64; P:Int64=0):string;
function HexToInt(S:string):Integer;
function HexToInt64(S:string):Int64;
function WideToStr(const WS:WideString):string;
function StrToWide(const S:AnsiString):WideString;
function GetWin:string;
function GetSys:string;
function GetTmp:string;
function IsWinNT:Boolean;
function IsWin9x:Boolean;
function IsAdmin:Boolean;
function GetPath(Path:string):string;
function GetFile(Path:string):string;
function GetFileInfo(Filename,BlockKey:string):string;
function IsFileExist(FileName:string):Boolean;
function IsFileInUse(FileName:string):Boolean;
function DebugPrivilege(ToEnable:Boolean):Boolean;
function GetExplorerPid:DWORD;
function PHandleToPID(dwProcessHandle:DWord):DWord;
function CalcJump(Src,Dest:DWORD):DWORD;
function InjectDll(DllPath:string; PID_or_PHD:DWORD):Boolean;
function UnInjectDll(DllName:string; PID_or_PHD:DWORD):Boolean;
function ApiHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;
function ApiUnHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;
function InjectAllProc(DllPath:string):Integer;
function UnInjectAllProc(DllPath:string):Integer;
function IsHeuristicScan:Boolean;
function OpCodeLength(Address:DWORD):DWORD; cdecl;

implementation

const
  TH32CS_SNAPPROCESS=$00000002;

type
  tagPROCESSENTRY32=packed record
    dwSize: DWORD;
    cntUsage: DWORD;
    th32ProcessID: DWORD;
    th32DefaultHeapID: DWORD;
    th32ModuleID: DWORD;
    cntThreads: DWORD;
    th32ParentProcessID: DWORD;
    pcPriClassBase: Longint;
    dwFlags: DWORD;
    szExeFile: array[0..MAX_PATH-1] of Char;
  end;
  PROCESSENTRY32=tagPROCESSENTRY32;
  TProcessEntry32=tagPROCESSENTRY32;

var LoadOpCodes: array[0..23] of Byte=($68,0,0,0,0,$E8,0,0,0,0,$B8,$FF,$FF,$FF,$FF,$50,$E8,0,0,0,0,$EB,$F3,$C3);
    FreeOpCodes: array[0..32] of Byte=($68,0,0,0,0,$E8,0,0,0,0,$B9,$FF,$FF,0,0,$50,$51,$50,$E8,0,0,0,0,$59,$83,$F8,$00,$58,$74,$02,$E2,$EF,$C3);

 CreateToolhelp32Snapshot: function(dwFlags, th32ProcessID: DWORD): THandle; stdcall;
 Process32First: function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall;
 Process32Next: function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall;
 OpenProcess: function(dwDesiredAccess:DWORD; bInheritHandle:BOOL; dwProcessId:DWORD):THandle; stdcall;
 VirtualAllocEx: function(hProcess:THandle; lpAddress:Pointer; dwSize,flAllocationType:DWORD; flProtect:DWORD):Pointer; stdcall;
 WriteProcessMemory: function(hProcess:THandle; const lpBaseAddress:Pointer; lpBuffer:Pointer; nSize:DWORD; var lpNumberOfBytesWritten:DWORD):BOOL; stdcall;
 CreateRemoteThread: function(hProcess:THandle; lpThreadAttributes:Pointer; dwStackSize:DWORD; lpStartAddress:TFNThreadStartRoutine; lpParameter:Pointer; dwCreationFlags:DWORD; var lpThreadId:DWORD):THandle; stdcall;

(******************************************************************************)
function LowCaseStr(S:string):string;
var i: Integer;
begin
 Result:=S;
 if S='' then Exit;
 for i:=1 to Length(S) do if Result[i] in ['A'..'Z'] then Inc(Result[i],32);
end;
(******************************************************************************)
function UpCaseStr(S:string):string;
var i: Integer;
begin
 Result:=S;
 if S='' then Exit;
 for i:=1 to Length(S) do Result[i]:=UpCase(Result[i]);
end;
(******************************************************************************)
function StrCmp(String1,String2:string):Boolean;
begin
 Result:=lstrcmpi(Pchar(String1),Pchar(String2))=0;
end;
(******************************************************************************)
function Trim(S:string):string;
begin
 Result:='';
 if S='' then Exit;
 while S[1]=' ' do begin
  Delete(S,1,1);
  if S='' then Exit;
 end;
 while S[Length(S)]=' ' do begin
  Delete(S,Length(S),1);
  if S='' then Exit;
 end;
 Result:=S;
end;
(******************************************************************************)
function IntToStr(i:Int64):string;
begin
 try
  Str(i,Result);
 except
  Result:='';
 end;
end;
(******************************************************************************)
function StrToInt(S:string):Integer;
var
 Code:Integer;
begin
 Val(S, Result, Code);
 if Code<>0 then Result:=0;
end;
(******************************************************************************)
function StrToInt64(S:string):Int64;
var
 Code:Integer;
begin
 Val(S, Result, Code);
 if Code<>0 then Result:=0;
end;
(******************************************************************************)
function HexToInt(S:string):Integer;
var Tmp:string;
begin
 Result:=0;
 Tmp:='';
 if S='' then Exit;
 if (S[1]='-') or (S[1]='+') then begin
   Tmp:=S[1];
   Delete(S,1,1);
  end;
 S:=Tmp+'$'+S;
 Result:=StrToInt(S);
end;
(******************************************************************************)
function HexToInt64(S:string):Int64;
var Tmp:string;
begin
 Result:=0;
 Tmp:='';
 if S='' then Exit;
 if (S[1]='-') or (S[1]='+') then begin
   Tmp:=S[1];
   Delete(S,1,1);
  end;
 S:=Tmp+'$'+S;
 Result:=StrToInt64(S);
end;
(******************************************************************************)
function IntToHex(i:Int64; P:Int64=0):string;
const
  Hexa:array[0..$F] of char='0123456789ABCDEF';
begin
 if (P=0) and (i=0) then begin
  Result:='0';
  Exit;
 end;
 Result:='';
 while (P>0)or(i>0) do begin
  dec(p,1);
  Result:=hexa[i and $F]+Result;
  i:=i shr 4;
 end;
end;
(******************************************************************************)
function WideToStr(const WS:WideString):string;
var l:Integer;
begin
 Result:='';
 if WS='' then Exit;
 l:=WideCharToMultiByte(CP_ACP,0,@WS[1],-1,nil,0,nil,nil);
 SetLength(Result,l-1);
 if l>1 then WideCharToMultiByte(CP_ACP,0,@WS[1],-1,@Result[1],l-1,nil,nil);
end;
(******************************************************************************)
function StrToWide(const S:AnsiString):WideString;
var l:Integer;
begin
 Result:='';
 if S='' then Exit;
 l:=MultiByteToWideChar(CP_ACP,0, Pchar(@S[1]),-1,nil,0);
 SetLength(Result,l-1);
 if l>1 then MultiByteToWideChar(CP_ACP,0,Pchar(@S[1]),-1,PWideChar(@Result[1]),l-1);
end;
(******************************************************************************)
function GetWin:string;
var
  Gwin : array[0..MAX_PATH] of Char;
begin
  GetWindowsDirectory(Gwin,MAX_PATH);
  Result:=Gwin;
  if Length(Result)>0 then
  if Result[Length(Result)]<>'\' then Result:=Result+'\';
end;
(******************************************************************************)
function GetSys:string;
var
  Gsys : array[0..MAX_PATH] of Char;
begin
  GetSystemDirectory(Gsys,MAX_PATH);
  Result:=Gsys;
  if Length(Result)>0 then
  if Result[Length(Result)]<>'\' then Result:=Result+'\';
end;
(******************************************************************************)
function GetTmp:string;
var
  Gtmp : array[0..MAX_PATH] of Char;
begin
  GetTempPath(MAX_PATH,Gtmp);
  Result:=Gtmp;
  if Length(Result)>0 then
  if Result[Length(Result)]<>'\' then Result:=Result+'\';
end;
(******************************************************************************)
function IsWinNT:Boolean;
var osVerInfo: TOSVersionInfo;
begin
 Result:=false;
 osVerInfo.dwOSVersionInfoSize:=SizeOf(TOSVersionInfo);
 if GetVersionEx(osVerInfo) then
   if osVerInfo.dwPlatformId=VER_PLATFORM_WIN32_NT then Result:=True
end;
(******************************************************************************)
function IsWin9x:Boolean;
asm
 MOV     EAX, FS:[030H]
 TEST    EAX, EAX
 SETS    AL
end;
(******************************************************************************)
function IsAdmin:Boolean;
const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0,0,0,0,0,5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  DOMAIN_ALIAS_RID_ADMINS     = $00000220;
var
  IsUserAnAdmin: function(): BOOL; stdcall;
  hAccessToken: THandle;
  ptgGroups: PTokenGroups;
  dwInfoBufferSize: DWORD;
  psidAdministrators: PSID;
  xi: Integer;
  bSuccess: BOOL;
  hMod: Thandle;
begin
 Result:=False;
 if IsWin9x then begin
   Result:=True;
   Exit;
 end;
 hMod:=GetModuleHandle('shell32.dll');
 if hMod=0 then hMod:=LoadLibrary('shell32.dll');
 IsUserAnAdmin:=GetProcAddress(hMod,'IsUserAnAdmin');
 if not Assigned(IsUserAnAdmin) then begin
  bSuccess:=OpenThreadToken(GetCurrentThread,TOKEN_QUERY,True,hAccessToken);
  if not bSuccess then if GetLastError=ERROR_NO_TOKEN then
   bSuccess:=OpenProcessToken(GetCurrentProcess,TOKEN_QUERY,hAccessToken);
  if bSuccess then begin
    GetMem(ptgGroups,1024);
    bSuccess:=GetTokenInformation(hAccessToken,TokenGroups,ptgGroups,1024,dwInfoBufferSize);
    CloseHandle(hAccessToken);
    if bSuccess then begin
      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,psidAdministrators);
      if ptgGroups.GroupCount>0 then
        for xi:=0 to ptgGroups.GroupCount-1 do
         if EqualSid(psidAdministrators,ptgGroups.Groups[xi].Sid) then begin
          Result:=True;
          Break;
         end;
      FreeSid(psidAdministrators);
    end;
    FreeMem(ptgGroups);
  end;
 end
 else Result:=IsUserAnAdmin();
end;
(******************************************************************************)
function GetPath(Path:string):string;
begin
 Result:='';
 if Path='' then Exit;
 if Pos('\',Path)<>0 then begin
   while Path[Length(Path)]<>'\' do Delete(Path,Length(Path),1);
   Result:=Path;
   Exit;
 end;
 if Pos('/',Path)<>0 then begin
   while Path[Length(Path)]<>'/' do Delete(Path,Length(Path),1);
   Result:=Path;
   Exit;
 end;
end;
(******************************************************************************)
function GetFile(Path:string):string;
begin
 while Pos(':',Path)<>0 do Delete(Path,1,Pos(':',Path));
 while Pos('\',Path)<>0 do Delete(Path,1,Pos('\',Path));
 while Pos('/',Path)<>0 do Delete(Path,1,Pos('/',Path));
 Result:=Path;
end;
(******************************************************************************)
function GetFileInfo(Filename,BlockKey:string):string;
var Size,VSize,Dummy: Longword;
    Pbuff,Plang: Pointer;
    Pvalue: Pchar;
    Qroot: string;
begin
 Result:='';
 Size:=GetFileVersionInfoSize(Pchar(Filename),Dummy);
 if Size=0 then Exit;
 GetMem(Pbuff,Size);
 try
 if GetFileVersionInfo(Pchar(Filename),0,Size,Pbuff) then begin
   Result:='';
   Qroot:='\StringFileInfo\040904E4\';
   if not VerQueryValue(Pbuff,Pchar(Qroot+BlockKey),Pointer(Pvalue),VSize) then begin
     if VerQueryValue(Pbuff,Pchar('\VarFileInfo\Translation'),Plang,VSize) then begin
       Qroot:=IntToHex(Integer(Plang^),8);
       Qroot:=Copy(Qroot,5,4)+Copy(Qroot,1,4);
       Qroot:='\StringFileInfo\'+Qroot+'\';
       if not VerQueryValue(Pbuff,Pchar(Qroot+BlockKey),Pointer(Pvalue),VSize) then Exit;
     end else Exit;
   end;
   Result:=Pvalue;
 end;
 finally
   FreeMem(Pbuff);
 end;
end;
(******************************************************************************)
function IsFileExist(FileName:string):Boolean;
var
 cHandle:THandle;
 FindData:TWin32FindData;
begin
 cHandle:=FindFirstFileA(Pchar(FileName),FindData);
 Result:=cHandle<>INVALID_HANDLE_VALUE;
 if Result then FindClose(cHandle);
end;
(******************************************************************************)
function IsFileInUse(FileName:string):Boolean;
var
 HFileRes: HFile;
begin
 Result:=False;
 if IsFileExist(FileName) then begin
  HFileRes := CreateFile(Pchar(FileName),GENERIC_READ or GENERIC_WRITE,
              FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
  Result:=(HFileRes=INVALID_HANDLE_VALUE);
  if Result=False then CloseHandle(HFileRes);
 end;
end;
(******************************************************************************)
function DebugPrivilege(ToEnable:Boolean):Boolean;
var
 OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
 ReturnLength: DWORD;
 hToken: THandle;
 Luid: Int64;
begin
 Result:=True;
 if IsWin9x then Exit;
 Result:=False;
 if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,hToken) then Exit;
 try
  if not LookupPrivilegeValue(nil,'SeDebugPrivilege',Luid) then Exit;
  TokenPrivileges.Privileges[0].luid:=Luid;
  TokenPrivileges.PrivilegeCount:=1;
  TokenPrivileges.Privileges[0].Attributes:=0;
  AdjustTokenPrivileges(hToken,False,TokenPrivileges,SizeOf(TTokenPrivileges),OldTokenPrivileges,ReturnLength);
  OldTokenPrivileges.Privileges[0].luid:=Luid;
  OldTokenPrivileges.PrivilegeCount:=1;
  if ToEnable then OldTokenPrivileges.Privileges[0].Attributes:=TokenPrivileges.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED
  else OldTokenPrivileges.Privileges[0].Attributes:=TokenPrivileges.Privileges[0].Attributes and (not SE_PRIVILEGE_ENABLED);
  Result:=AdjustTokenPrivileges(hToken,False,OldTokenPrivileges,ReturnLength,PTokenPrivileges(nil)^,ReturnLength);
 finally
  CloseHandle(hToken);
 end;
end;
(******************************************************************************)
function GetExplorerPid:DWORD;
begin
 GetWindowThreadProcessID(FindWindow('Shell_TrayWnd',nil), @Result );
end;
(******************************************************************************)
function PHandleToPID(dwProcessHandle:DWord):DWord;
type
 TPI=packed record
       Reserved1      : Pointer;
       PebBaseAddress : Pointer;
       Reserved2      : array[0..1] of Pointer;
       UniqueProcessId: DWord;
       Reserved3      : Pointer;
     end;
 PPI=^TPI;
var
 NtQueryInformationProcess: function(dwHandle: DWord; dwInfo: DWord; pbi: PPI; dwSize: DWord; pData: Pointer): DWord; stdcall;

⌨️ 快捷键说明

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