Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Last active May 17, 2018 13:27
Show Gist options
  • Save HoShiMin/9cafccafcf4b6b179b06 to your computer and use it in GitHub Desktop.
Save HoShiMin/9cafccafcf4b6b179b06 to your computer and use it in GitHub Desktop.
Многофункциональный API для работы с процессами
unit ProcessAPI;
interface
//{$DEFINE DEBUG_PRIVILEGE}
uses
Windows, TlHelp32, CodepageAPI;
// Результат функции GetProcessList - массив процессов:
type
// Информация о процессе (TlHelp32):
PROCESSENTRY32A = record
Size : DWORD;
Usage : DWORD;
ProcessID : DWORD;
DefaultHeapID : ULONG_PTR;
ModuleID : DWORD;
ThreadsCount : DWORD;
ParentProcessID : DWORD;
Priority : Longint;
Flags : DWORD;
ExeFile : array [0 .. MAX_PATH - 1] of AnsiChar;
end;
TProcessEntry32A = PROCESSENTRY32A;
// Информация о потоке (TlHelp32):
THREADENTRY32 = record
Size : DWORD;
Usage : DWORD;
ThreadID : DWORD;
OwnerProcessID : DWORD;
Priority : Longint;
DeltaPriority : Longint;
Flags : DWORD;
end;
TThreadEntry32 = THREADENTRY32;
TProcessInfo = TProcessEntry32A;
TProcessList = array of TProcessInfo;
// Информация о загруженноых модулях:
TModuleInfo = record
FullPath : AnsiString; // Полный путь к модулю
ModuleName : AnsiString; // Имя модуля
BaseAddress : UInt64; // Базовый адрес загрузки (начало распакованного файла в ОЗУ)
EntryAddress : UInt64; // Точка входа
SizeOfImage : Cardinal; // Размер образа в байтах
end;
// Базовая информация о процессе:
TProcessBasicInfo = record
ExitStatus : LongWord;
AffinityMask : UInt64;
BasePriority : LongWord;
UniqueProcessId : UInt64;
InheritedFromUniqueProcessId : UInt64;
end;
TModulesList = record
Length: Cardinal; // Всего загруженных модулей
Modules: array of TModuleInfo; // Массив из информации о каждом модуле
end;
// Структура результата функции GetProcessInfo:
PROCESS_INFO = record
// Идентификаторы:
Handle : LongWord; // Хэндл процесса при получении информации
ID : UInt64; // Идентификатор процесса
InheritedFromID : UInt64; // Идентификатор процесса-родителя
SessionID : LongWord; // Идентификатор сессии
// Свойства процесса:
Priority : UInt64; // Приоритет процесса
AffinityMask : UInt64; // Маска соответствия процесса ядрам (число надо перевести в двоичный вид)
// Разное:
IsDebugged : Boolean; // Отлаживается ли процесс
ExitStatus : LongWord; // Код выхода
ThreadsCount : LongWord; // Количество потоков
HandlesCount : LongWord; // Количество открытых хэндлов
ReservedMemory : LongWord; // Зарезервированная память в байтах
// Адреса:
ImageBaseAddress : UInt64; // Адрес загрузки образа в оперативной памяти
LdrAddress : UInt64; // Адрес загрузочной информации
PEBAddress : UInt64; // Адрес блока окружения процесса (структура PEB)
// Хэндлы ввода-вывода:
ConsoleHandle : UInt64; // Хэндл консоли
StdInputHandle : UInt64; // Стандартный хэндл ввода
StdOutputHandle : UInt64; // Стандартный хэндл вывода
StdErrorHandle : UInt64; // Стандартный хэндл вывода ошибок
// Строковые параметры:
ProcessName : AnsiString; // Имя процесса
CurrentDirectoryPath : AnsiString; // Текущая папка
ImagePathName : AnsiString; // Имя образа процесса
CommandLine : AnsiString; // Командная строка
// Список загруженных модулей:
ModulesList: TModulesList;
// Глобальные системные свойства:
Is64BitProcess: BOOL; // 64х-битный ли процесс
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Преобразование ProcessID в Handle:
function ProcessIDToHandle(ProcessID: LongWord; AccessRights: LongWord = PROCESS_VM_READ or PROCESS_QUERY_INFORMATION): THandle;
// Преобразование Handle в ProcessID:
function HandleToProcessID(ProcessHandle: THandle): LongWord;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 64х-битная ли ОС:
function Is64BitWindows: BOOL;
// Получение подробной информации о процессе по его ID:
function GetProcessInfo(ProcessID: LongWord; out ProcessInfo: PROCESS_INFO; Process32_64CompatibleMode: Boolean = false): Boolean;
// Получение базовой информации о процессе по его ID:
function GetProcessBasicInfo(ProcessID: LongWord; out ProcessBasicInfo: TProcessBasicInfo): Boolean;
// 64х-битный ли процесс:
function Is64BitProcess(ProcessID: LongWord): LongBool;
// Запущен ли процесс (по имени процесса):
function IsProcessLaunched(ProcessName: AnsiString): Boolean; overload;
// Запущен ли процесс (по ID процесса):
function IsProcessLaunched(ProcessID: LongWord): Boolean; overload;
// Есть ли библиотека в процессе:
function IsLibInProcess(LibName: AnsiString; ProcessID: LongWord): Boolean;
// Получить список запущенных процессов с краткой информацией:
procedure GetProcessList(out ProcessList: TProcessList);
// Получить информацию из TlHelp32 по ID процесса:
function GetTlHelp32ProcessInfo(ProcessID: LongWord): TProcessInfo; overload;
// Получить информацию из TlHelp32 по имени процесса:
function GetTlHelp32ProcessInfo(ProcessName: AnsiString): TProcessInfo; overload;
// Запуск процесса:
procedure StartProcess(const CommandLine: string; out ProcessHandle: THandle; out ProcessID: LongWord);
// Ожидание завершения процесса:
procedure WaitProcess(ProcessID: LongWord);
// Убить процесс по ID:
procedure KillProcess(ProcessID: LongWord); overload;
// Убить процесс по имени:
procedure KillProcess(ProcessName: AnsiString; CanKillSelf: Boolean = False); overload;
// Получить загрузку ЦП данным процессом (Delay ставить в пределах от 25 до 500, меньше - неточно, больше - ни к чему):
function GetProcessCPULoading(ProcessID: LongWord; Delay: Cardinal): Single;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
type
Pointer64 = UInt64;
Pointer32 = UInt;
// Структура для получения данных о процессе под Win32
PROCESS_BASIC_INFORMATION = record
ExitStatus: LongWord;
PebBaseAddress: Pointer;
AffinityMask: Cardinal;
BasePriority: Integer;
UniqueProcessId: LongWord;
InheritedFromUniqueProcessId: LongWord;
end;
PROCESS_BASIC_INFORMATION64 = record
ExitStatus: LongWord;
Reserved0: LongWord;
PebBaseAddress: UInt64;
AffinityMask: UInt64;
BasePriority: LongWord;
Reserved1: LongWord;
UniqueProcessId: UInt64;
InheritedFromUniqueProcessId: UInt64;
end;
PROCESS_BASIC_INFORMATION_WOW64 = record
Wow64PebAddress: UInt64;
end;
UCHAR = AnsiChar;
// Юникодная строка в Win32
UNICODE_STRING = record
Length: Word;
MaximumLength: Word;
Buffer: Pointer;
end;
UNICODE_STRING_WOW64 = record
Length: Word;
MaximumLength: Word;
Buffer: Pointer32;
end;
UNICODE_STRING64 = record
Length: Word;
MaximumLength: Word;
Fill: LongWord;
Buffer: UInt64;
end;
PLDR_MODULE = Pointer;
TModuleListEntry = record
ForwardLDRModule: PLDR_MODULE;
BackwardLDRModule: PLDR_MODULE;
end;
LDR_MODULE = record
InLoadModuleOrderList: TModuleListEntry;
InMemoryModuleOrderList: TModuleListEntry;
InInitializationModuleOrderList: TModuleListEntry;
BaseAddress: Pointer;
EntryPoint: Pointer;
SizeOfImage: UInt;
FullDLLName: UNICODE_STRING;
BaseDLLName: UNICODE_STRING;
Flags: ULONG;
LoadCount: Short;
TlsIndex: Short;
TimeDateStamp: ULONG;
end;
PEB_LDR_DATA = record
Size: ULong;
Initialized: Boolean;
SsHandle: Pointer;
InLoadModuleOrderList: TModuleListEntry;
InMemoryModuleOrderList: TModuleListEntry;
InInitializationModuleOrderList: TModuleListEntry;
end;
PPEB_LDR_DATA = ^PEB_LDR_DATA;
// LDR WOW64:
PLDR_MODULE_WOW64 = Pointer32;
TModuleListEntryWow64 = record
ForwardLDRModule: PLDR_MODULE_WOW64;
BackwardLDRModule: PLDR_MODULE_WOW64;
end;
LDR_MODULE_WOW64 = record
InLoadModuleOrderList: TModuleListEntryWow64;
InMemoryModuleOrderList: TModuleListEntryWow64;
InInitializationModuleOrderList: TModuleListEntryWow64;
BaseAddress: Pointer32;
EntryPoint: Pointer32;
SizeOfImage: UInt;
FullDLLName: UNICODE_STRING_WOW64;
BaseDLLName: UNICODE_STRING_WOW64;
Flags: ULONG;
LoadCount: Short;
TlsIndex: Short;
TimeDateStamp: ULONG;
end;
PEB_LDR_DATA_WOW64 = record
Size: ULong;
Initialized: Boolean;
SsHandle: Pointer32;
InLoadModuleOrderList: TModuleListEntryWow64;
InMemoryModuleOrderList: TModuleListEntryWow64;
InInitializationModuleOrderList: TModuleListEntryWow64;
end;
PPEB_LDR_DATA_WOW64 = Pointer32;
// LDR x64:
PLDR_MODULE64 = UInt64;
TModuleListEntry64 = record
ForwardLDRModule: PLDR_MODULE64;
BackwardLDRModule: PLDR_MODULE64;
end;
LDR_MODULE64 = record
InLoadModuleOrderList: TModuleListEntry64;
InMemoryModuleOrderList: TModuleListEntry64;
InInitializationModuleOrderList: TModuleListEntry64;
BaseAddress: Pointer64;
EntryPoint: Pointer64;
SizeOfImage: ULong;
FullDLLName: UNICODE_STRING64;
BaseDLLName: UNICODE_STRING64;
Flags: ULONG;
LoadCount: Short;
TlsIndex: Short;
TimeDateStamp: ULONG;
end;
PEB_LDR_DATA64 = record
Size: UInt;
Initialized: Boolean;
SsHandle: UInt64;
InLoadModuleOrderList: TModuleListEntry64;
InMemoryModuleOrderList: TModuleListEntry64;
InInitializationModuleOrderList: TModuleListEntry64;
end;
PEB = record
InheritedAddressSpace: UCHAR;
ReadImageFileExecOptions: UCHAR;
BeingDebugged: Boolean;
BitField: UChar;
Mutant: Pointer;
ImageBaseAddress: Pointer;
Ldr: PPEB_LDR_DATA;
ProcessParameters: Pointer;
Reserved0: array [0..103] of Byte;
Reserved1: array [0..51] of Pointer;
PostProcessInitRoutine: Pointer;
Reserved2: array [0..127] of Byte;
Reserved3: Pointer;
SessionID: LongWord;
end;
PEB_WOW64 = record
InheritedAddressSpace: UCHAR;
ReadImageFileExecOptions: UCHAR;
BeingDebugged: Boolean;
BitField: UChar;
Mutant: Pointer32;
ImageBaseAddress: Pointer32;
Ldr: PPEB_LDR_DATA_WOW64;
ProcessParameters: Pointer32;
Reserved0: array [0..103] of Byte;
Reserved1: array [0..51] of Pointer32;
PostProcessInitRoutine: Pointer32;
Reserved2: array [0..127] of Byte;
Reserved3: Pointer32;
SessionID: LongWord;
end;
PEB64 = record
InheritedAddressSpace: Byte;
ReadImageFileExecOptions: Byte;
BeingDebugged: Boolean;
BitField: Byte;
Reserved0: LongWord;
Mutant: UInt64;
ImageBaseAddress: UInt64;
Ldr: UInt64;
ProcessParameters: UInt64;
Reserved1: array [0..519] of Byte;
PostProcessInitRoutine: UInt64;
Reserved2: array [0..135] of Byte;
SessionID: LongWord;
end;
// Структура RTL_USER_PROCESS_PARAMETERS под Win32
RTL_USER_PROCESS_PARAMETERS = record
MaximumLength: LongWord;
Length: LongWord;
Flags: LongWord;
DebugFlags: LongWord;
ConsoleHandle: THandle;
ConsoleFlags: LongWord;
StdInputHandle: THandle;
StdOutputHandle: THandle;
StdErrorHandle: THandle;
CurrentDirectoryPath: UNICODE_STRING;
CurrentDirectoryHandle: THandle;
DllPath: UNICODE_STRING;
ImagePathName: UNICODE_STRING;
CommandLine: UNICODE_STRING;
end;
RTL_USER_PROCESS_PARAMETERS_WOW64 = record
MaximumLength: LongWord;
Length: LongWord;
Flags: LongWord;
DebugFlags: LongWord;
ConsoleHandle: LongWord;
ConsoleFlags: LongWord;
StdInputHandle: LongWord;
StdOutputHandle: LongWord;
StdErrorHandle: LongWord;
CurrentDirectoryPath: UNICODE_STRING_WOW64;
CurrentDirectoryHandle: LongWord;
DllPath: UNICODE_STRING_WOW64;
ImagePathName: UNICODE_STRING_WOW64;
CommandLine: UNICODE_STRING_WOW64;
end;
RTL_USER_PROCESS_PARAMETERS64 = record
MaximumLength: LongWord;
Length: LongWord;
Flags: LongWord;
DebugFlags: LongWord;
ConsoleHandle: UInt64;
ConsoleFlags: LongWord;
Reserved: LongWord;
StdInputHandle: UInt64;
StdOutputHandle: UInt64;
StdErrorHandle: UInt64;
CurrentDirectoryPath: UNICODE_STRING64;
CurrentDirectoryHandle: UInt64;
DllPath: UNICODE_STRING64;
ImagePathName: UNICODE_STRING64;
CommandLine: UNICODE_STRING64;
end;
VM_COUNTERS = record
PeakVirtualSize: LongWord;
VirtualSize: LongWord;
PageFaultCount: LongWord;
PeakWorkingSetSize: LongWord;
WorkingSetSize: LongWord;
QuotaPeakPagedPoolUsage: LongWord;
QuotaPagedPoolUsage: LongWord;
QuotaPeakNonPagedPoolUsage: LongWord;
QuotaNonPagedPoolUsage: LongWord;
PagefileUsage: LongWord;
PeakPagefileUsage: LongWord;
end;
PROCESSINFOCLASS = (
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessTlsInformation,
ProcessCookie,
ProcessImageInformation,
ProcessCycleTime,
ProcessPagePriority,
ProcessInstrumentationCallback,
ProcessThreadStackAllocation,
ProcessWorkingSetWatchEx,
ProcessImageFileNameWin32,
ProcessImageFileMapping,
ProcessAffinityUpdateMode,
ProcessMemoryAllocationMode,
ProcessGroupInformation,
ProcessTokenVirtualizationEnabled,
ProcessOwnerInformation,
ProcessWindowInformation,
ProcessHandleInformation,
ProcessMitigationPolicy,
ProcessDynamicFunctionTableInformation,
ProcessHandleCheckingMode,
ProcessKeepAliveCount,
ProcessRevokeFileHandles,
ProcessWorkingSetControl,
ProcessHandleTable,
ProcessCheckStackExtentsMode,
ProcessCommandLineInformation,
ProcessProtectionInformation,
MaxProcessInfoClass
);
SYSTEMINFOCLASS = (
SystemBasicInformation,
Unknown,
SystemPerformanceInformation,
SystemInformationClassMax
);
NTStatus = LongWord;
SIZE_T = Cardinal;
_PROCESS_MEMORY_COUNTERS_EX = record
cb: LongWord;
PageFaultCount: LongWord;
PeakWorkingSetSize: SIZE_T;
WorkingSetSize: SIZE_T;
QuotaPeakPagedPoolUsage: SIZE_T;
QuotaPagedPoolUsage: SIZE_T;
QuotaPeakNonPagedPoolUsage: SIZE_T;
QuotaNonPagedPoolUsage: SIZE_T;
PagefileUsage: SIZE_T;
PeakPagefileUsage: SIZE_T;
PrivateUsage: SIZE_T;
end;
function NtQueryInformationProcess(
ProcessHandle: THandle;
ProcessInformationClass: PROCESSINFOCLASS;
ProcessInformation: Pointer;
ProcessInformationLength: LongWord;
out ReturnLength: LongWord
): NTStatus; stdcall; external 'ntdll.dll';
function NtReadVirtualMemory(
ProcessHandle: THandle;
BaseAddress: Pointer;
Buffer: Pointer;
BufferLength: LongWord;
out ReturnLength: LongWord
): BOOL; stdcall; external 'ntdll.dll';
function NtQuerySystemInformation(
SystemInformationClass: SYSTEMINFOCLASS;
SystemInformation: Pointer;
SystemInformationLength: ULONG;
ReturnLength: PDWORD
): NTStatus; stdcall; external 'ntdll.dll';
// 64х-битные аналоги:
var
NtWow64QueryInformationProcess64: function(
ProcessHandle: THandle;
ProcessInformationClass: PROCESSINFOCLASS;
ProcessInformation: Pointer;
ProcessInformationLength: LongWord;
out ReturnLength: UInt64
): NTStatus; stdcall;
NtWow64ReadVirtualMemory64: function(
ProcessHandle: THandle;
BaseAddress: UInt64;
Buffer: Pointer;
BufferLength: UInt64;
out ReturnLength: UInt64
): BOOL; stdcall;
IsWow64Process: function(ProcessHandle: THandle; out Wow64Process: BOOL): BOOL; stdcall;
procedure GetProcessMemoryInfo(ProcessHandle: THandle; out ProcessMemoryCounters: _PROCESS_MEMORY_COUNTERS_EX; ProcessMemoryCountersSize: LongWord); stdcall; external 'psapi.dll';
function GetProcessHandleCount(ProcessHandle: THandle; CounterPtr: Pointer): LongBool; stdcall; external 'kernel32.dll';
function GetProcessId(Handle: THandle): LongWord; stdcall; external 'kernel32.dll';
function Process32FirstA(hSnapshot: THandle; var lppe: TProcessEntry32A): BOOL; stdcall; external 'kernel32.dll' name 'Process32First';
function Process32NextA(hSnapshot: THandle; var lppe: TProcessEntry32A): BOOL; stdcall; external 'kernel32.dll' name 'Process32Next';
implementation
type
{$IFDEF CPUX64}
NativeUInt = UInt64;
{$ELSE}
NativeUInt = LongWord;
{$ENDIF}
var
_Is64BitWindows: BOOL = FALSE;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function ProcessIDToHandle(ProcessID: LongWord; AccessRights: LongWord): THandle;
begin
Result := OpenProcess(
AccessRights,
FALSE,
ProcessID
);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function HandleToProcessID(ProcessHandle: THandle): LongWord;
begin
Result := GetProcessID(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
{$IFDEF DEBUG_PRIVILEGE}
const
SE_DEBUG_NAME = 'SeDebugPrivilege';
// Установка привилегий
function NTSetPrivilege(sPrivilege: AnsiString; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
if LookupPrivilegeValueA(nil, PAnsiChar(sPrivilege), TokenPriv.Privileges[0].Luid) then
begin
TokenPriv.PrivilegeCount := 1;
case bEnabled of
True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
False: TokenPriv.Privileges[0].Attributes := 0;
end;
ReturnLength := 0;
PrevTokenPriv := TokenPriv;
AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
CloseHandle(hToken);
end;
Result := GetLastError = ERROR_SUCCESS;
end;
{$ENDIF}
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function Is64BitWindows: BOOL;
{$IFNDEF CPUX64}
var
Wow64Process: Bool;
{$ENDIF}
begin
IsWow64Process := GetProcAddress(GetModuleHandle(kernel32), 'IsWow64Process');
{$IFDEF CPUX64}
Result := True;
{$ELSE}
Wow64Process := false;
if Assigned(IsWow64Process) then Wow64Process := IsWow64Process(GetCurrentProcess, Wow64Process) and Wow64Process;
Result := Wow64Process;
{$ENDIF}
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
procedure _InitFunctions;
var
NtdllHandle: THandle;
begin
_Is64BitWindows := Is64BitWindows;
if _Is64BitWindows then
begin
// Ищем адреса 64х-битных функций:
NtdllHandle := GetModuleHandleA('ntdll.dll');
{$IFDEF CPUX64}
NtWow64QueryInformationProcess64 := GetProcAddress(NtdllHandle, 'NtQueryInformationProcess');
NtWow64ReadVirtualMemory64 := GetProcAddress(NtdllHandle, 'NtReadVirtualMemory');
{$ELSE}
NtWow64QueryInformationProcess64 := GetProcAddress(NtdllHandle, 'NtWow64QueryInformationProcess64');
NtWow64ReadVirtualMemory64 := GetProcAddress(NtdllHandle, 'NtWow64ReadVirtualMemory64');
{$ENDIF}
end
else
begin
_Is64BitWindows := false;
end;
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
procedure _GetModulesList32(ProcessHandle: THandle; LDRAddress: Pointer; out Modules: TModulesList);
var
LdrInfo: PEB_LDR_DATA;
ModuleInfo: LDR_MODULE;
StringBuffer: Pointer;
StringPointer: Pointer;
StringLength: Word;
BytesRead: LongWord;
begin
// Читаем PEB_LDR_DATA:
NtReadVirtualMemory(ProcessHandle, LDRAddress, @LdrInfo, SizeOf(LdrInfo), BytesRead);
// Читаем LDR_MODULE_INFO:
NtReadVirtualMemory(ProcessHandle, LdrInfo.InLoadModuleOrderList.ForwardLDRModule, @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
FillChar(Modules, SizeOf(Modules), #0);
while (LdrInfo.InLoadModuleOrderList.ForwardLDRModule <> nil) and (BytesRead <> 0) and (ModuleInfo.BaseAddress <> nil) do
begin
Inc(Modules.Length);
SetLength(Modules.Modules, Modules.Length);
// Получаем численную информацию:
with Modules do
begin
Modules[Length - 1].BaseAddress := UInt64(ModuleInfo.BaseAddress);
Modules[Length - 1].EntryAddress := UInt64(ModuleInfo.EntryPoint);
Modules[Length - 1].SizeOfImage := UInt64(ModuleInfo.SizeOfImage);
end;
// Читаем полный путь:
StringPointer := ModuleInfo.FullDLLName.Buffer;
StringLength := ModuleInfo.FullDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtReadVirtualMemory(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].FullPath := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем имя библиотеки:
StringPointer := ModuleInfo.BaseDLLName.Buffer;
StringLength := ModuleInfo.BaseDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtReadVirtualMemory(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].ModuleName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем следующий в списке LDR_MODULE_INFO:
NtReadVirtualMemory(ProcessHandle, ModuleInfo.InLoadModuleOrderList.ForwardLDRModule, @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure _GetProcessInfo32(ProcessID: LongWord; out ProcessInfo: PROCESS_INFO);
var
ProcessHandle: THandle;
ProcessBasicInfo: PROCESS_BASIC_INFORMATION;
PEBInfo: PEB;
UserParameters: RTL_USER_PROCESS_PARAMETERS;
BytesRead: UInt;
ReturnLength: UInt;
//ReturnStatus: LongWord;
_Is64BitProcess: BOOL;
CurrentDirectory: AnsiString;
ImageName: AnsiString;
CmdLine: AnsiString;
StringBuffer: Pointer;
StringPointer: Pointer;
StringLength: Word;
TlHelp32Info: TProcessInfo;
LocalHandlesCount: LongWord;
MemoryCounters: _PROCESS_MEMORY_COUNTERS_EX;
begin
FillChar(ProcessBasicInfo, SizeOf(ProcessBasicInfo), #0);
FillChar(PEBInfo, SizeOf(PEBInfo), #0);
FillChar(UserParameters, SizeOf(UserParameters), #0);
FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);
ProcessHandle := ProcessIDToHandle(ProcessID);
// Получаем разрядность процесса:
_Is64BitProcess := FALSE; // Процессы заведомо 32х-битные
// Заполняем PROCESS_BASIC_INFORMATION:
NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo, SizeOf(ProcessBasicInfo), ReturnLength);
// Читаем PEB:
NtReadVirtualMemory(ProcessHandle, ProcessBasicInfo.PebBaseAddress, @PEBInfo, SizeOf(PEBInfo), BytesRead);
// Читаем RTL_USER_PROCESS_PARAMETERS:
NtReadVirtualMemory(ProcessHandle, PEBInfo.ProcessParameters, @UserParameters, SizeOf(UserParameters), BytesRead);
// Получаем список загруженных модулей:
_GetModulesList32(ProcessHandle, PEBInfo.Ldr, ProcessInfo.ModulesList);
// Читаем строки:
// CommandLine:
StringPointer := UserParameters.CommandLine.Buffer;
StringLength := UserParameters.CommandLine.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtReadVirtualMemory(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CmdLine := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// ImageFilePath:
StringPointer := UserParameters.ImagePathName.Buffer;
StringLength := UserParameters.ImagePathName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtReadVirtualMemory(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
ImageName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
//CurrentDirectoryPath:
StringPointer := UserParameters.CurrentDirectoryPath.Buffer;
StringLength := UserParameters.CurrentDirectoryPath.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtReadVirtualMemory(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CurrentDirectory := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Получаем информацию о памяти процесса:
FillChar(MemoryCounters, SizeOf(MemoryCounters), #0);
GetProcessMemoryInfo(ProcessHandle, MemoryCounters, SizeOf(MemoryCounters));
// Получаем информацию из TlHelp32:
FillChar(TlHelp32Info, SizeOf(TlHelp32Info), #0);
TlHelp32Info := GetTlHelp32ProcessInfo(ProcessID);
// Получаем количество открытых хэндлов:
GetProcessHandleCount(ProcessHandle, @LocalHandlesCount);
// Возвращаем результат:
with ProcessInfo do
begin
Handle := ProcessHandle;
ID := ProcessBasicInfo.UniqueProcessId;
InheritedFromID := ProcessBasicInfo.InheritedFromUniqueProcessId;
SessionID := PEBInfo.SessionID;
Priority := ProcessBasicInfo.BasePriority;
AffinityMask := ProcessBasicInfo.AffinityMask;
IsDebugged := PEBInfo.BeingDebugged;
ExitStatus := ProcessBasicInfo.ExitStatus;
ThreadsCount := TlHelp32Info.ThreadsCount;
HandlesCount := LocalHandlesCount;
ReservedMemory := MemoryCounters.PrivateUsage;
ImageBaseAddress := UInt64(PEBInfo.ImageBaseAddress);
LdrAddress := UInt64(PEBInfo.Ldr);
PEBAddress := UInt64(ProcessBasicInfo.PebBaseAddress);
ConsoleHandle := UserParameters.ConsoleHandle;
StdInputHandle := UserParameters.StdInputHandle;
StdOutputHandle := UserParameters.StdOutputHandle;
StdErrorHandle := UserParameters.StdErrorHandle;
ProcessName := TlHelp32Info.ExeFile;
CurrentDirectoryPath := CurrentDirectory;
ImagePathName := ImageName;
CommandLine := CmdLine;
Is64BitProcess := _Is64BitProcess;
end;
CloseHandle(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
procedure _GetModulesList64(ProcessHandle: THandle; LDRAddress: UInt64; out Modules: TModulesList);
var
LdrInfo: PEB_LDR_DATA64;
ModuleInfo: LDR_MODULE64;
StringBuffer: Pointer;
StringPointer: UInt64;
StringLength: Word;
BytesRead: UInt64;
begin
// Читаем PEB_LDR_DATA:
NtWow64ReadVirtualMemory64(ProcessHandle, LDRAddress, @LdrInfo, SizeOf(LdrInfo), BytesRead);
// Читаем LDR_MODULE_INFO:
NtWow64ReadVirtualMemory64(ProcessHandle, UInt64(LdrInfo.InLoadModuleOrderList.ForwardLDRModule), @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
FillChar(Modules, SizeOf(Modules), #0);
while (LdrInfo.InLoadModuleOrderList.ForwardLDRModule <> 0) and (BytesRead <> 0) and (ModuleInfo.BaseAddress <> 0) do
begin
Inc(Modules.Length);
SetLength(Modules.Modules, Modules.Length);
// Получаем численную информацию:
with Modules do
begin
Modules[Length - 1].BaseAddress := ModuleInfo.BaseAddress;
Modules[Length - 1].EntryAddress := ModuleInfo.EntryPoint;
Modules[Length - 1].SizeOfImage := ModuleInfo.SizeOfImage;
end;
// Читаем полный путь:
StringPointer := ModuleInfo.FullDLLName.Buffer;
StringLength := ModuleInfo.FullDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].FullPath := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем имя библиотеки:
StringPointer := ModuleInfo.BaseDLLName.Buffer;
StringLength := ModuleInfo.BaseDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].ModuleName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем следующий в списке LDR_MODULE_INFO:
NtWow64ReadVirtualMemory64(ProcessHandle, ModuleInfo.InLoadModuleOrderList.ForwardLDRModule, @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure _GetProcessInfo64(ProcessID: LongWord; out ProcessInfo: PROCESS_INFO);
var
ProcessHandle: THandle;
ProcessBasicInfo: PROCESS_BASIC_INFORMATION64;
PEBInfo: PEB64;
UserParameters: RTL_USER_PROCESS_PARAMETERS64;
BytesRead: UInt64;
ReturnLength: UInt64;
//ReturnStatus: LongWord;
_Is64BitProcess: BOOL;
CurrentDirectory: AnsiString;
ImageName: AnsiString;
CmdLine: AnsiString;
StringBuffer: Pointer;
StringPointer: UInt64;
StringLength: Word;
TlHelp32Info: TProcessInfo;
LocalHandlesCount: LongWord;
MemoryCounters: _PROCESS_MEMORY_COUNTERS_EX;
begin
FillChar(ProcessBasicInfo, SizeOf(ProcessBasicInfo), #0);
FillChar(PEBInfo, SizeOf(PEBInfo), #0);
FillChar(UserParameters, SizeOf(UserParameters), #0);
FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);
ProcessHandle := ProcessIDToHandle(ProcessID);
// Получаем разрядность процесса:
IsWow64Process(ProcessHandle, _Is64BitProcess);
_Is64BitProcess := not _Is64BitProcess;
// Заполняем PROCESS_BASIC_INFORMATION:
NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo, SizeOf(ProcessBasicInfo), ReturnLength);
// Читаем PEB:
NtWow64ReadVirtualMemory64(ProcessHandle, ProcessBasicInfo.PebBaseAddress, @PEBInfo, SizeOf(PEBInfo), BytesRead);
// Читаем RTL_USER_PROCESS_PARAMETERS:
NtWow64ReadVirtualMemory64(ProcessHandle, PEBInfo.ProcessParameters, @UserParameters, SizeOf(UserParameters), BytesRead);
// Получаем список загруженных модулей:
_GetModulesList64(ProcessHandle, PEBInfo.Ldr, ProcessInfo.ModulesList);
// Читаем строки:
// CommandLine:
StringPointer := UserParameters.CommandLine.Buffer;
StringLength := UserParameters.CommandLine.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CmdLine := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// ImageFilePath:
StringPointer := UserParameters.ImagePathName.Buffer;
StringLength := UserParameters.ImagePathName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
ImageName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
//CurrentDirectoryPath:
StringPointer := UserParameters.CurrentDirectoryPath.Buffer;
StringLength := UserParameters.CurrentDirectoryPath.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CurrentDirectory := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Получаем информацию о памяти процесса:
FillChar(MemoryCounters, SizeOf(MemoryCounters), #0);
GetProcessMemoryInfo(ProcessHandle, MemoryCounters, SizeOf(MemoryCounters));
// Получаем информацию из TlHelp32:
FillChar(TlHelp32Info, SizeOf(TlHelp32Info), #0);
TlHelp32Info := GetTlHelp32ProcessInfo(ProcessID);
// Получаем количество открытых хэндлов:
GetProcessHandleCount(ProcessHandle, @LocalHandlesCount);
// Возвращаем результат:
with ProcessInfo do
begin
Handle := ProcessHandle;
ID := ProcessBasicInfo.UniqueProcessId;
InheritedFromID := ProcessBasicInfo.InheritedFromUniqueProcessId;
SessionID := PEBInfo.SessionID;
Priority := ProcessBasicInfo.BasePriority;
AffinityMask := ProcessBasicInfo.AffinityMask;
IsDebugged := PEBInfo.BeingDebugged;
ExitStatus := ProcessBasicInfo.ExitStatus;
ThreadsCount := TlHelp32Info.ThreadsCount;
handlesCount := LocalHandlesCount;
ReservedMemory := MemoryCounters.PrivateUsage;
ImageBaseAddress := PEBInfo.ImageBaseAddress;
LdrAddress := PEBInfo.Ldr;
PEBAddress := ProcessBasicInfo.PebBaseAddress;
ConsoleHandle := UserParameters.ConsoleHandle;
StdInputHandle := UserParameters.StdInputHandle;
StdOutputHandle := UserParameters.StdOutputHandle;
StdErrorHandle := UserParameters.StdErrorHandle;
ProcessName := TlHelp32Info.ExeFile;
CurrentDirectoryPath := CurrentDirectory;
ImagePathName := ImageName;
CommandLine := CmdLine;
Is64BitProcess := _Is64BitProcess;
end;
CloseHandle(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
procedure _GetModulesListWow64(ProcessHandle: THandle; LDRAddress: Pointer32; out Modules: TModulesList);
var
LdrInfo: PEB_LDR_DATA_WOW64;
ModuleInfo: LDR_MODULE_WOW64;
StringBuffer: Pointer;
StringPointer: UInt64;
StringLength: Word;
BytesRead: UInt64;
begin
// Читаем PEB_LDR_DATA:
NtWow64ReadVirtualMemory64(ProcessHandle, UInt64(LDRAddress), @LdrInfo, SizeOf(LdrInfo), BytesRead);
// Читаем LDR_MODULE_INFO:
NtWow64ReadVirtualMemory64(ProcessHandle, UInt64(LdrInfo.InLoadModuleOrderList.ForwardLDRModule), @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
FillChar(Modules, SizeOf(Modules), #0);
while (LdrInfo.InLoadModuleOrderList.ForwardLDRModule <> 0) and (BytesRead <> 0) and (ModuleInfo.BaseAddress <> 0) do
begin
Inc(Modules.Length);
SetLength(Modules.Modules, Modules.Length);
// Получаем численную информацию:
with Modules do
begin
Modules[Length - 1].BaseAddress := ModuleInfo.BaseAddress;
Modules[Length - 1].EntryAddress := ModuleInfo.EntryPoint;
Modules[Length - 1].SizeOfImage := ModuleInfo.SizeOfImage;
end;
// Читаем полный путь:
StringPointer := ModuleInfo.FullDLLName.Buffer;
StringLength := ModuleInfo.FullDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].FullPath := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем имя библиотеки:
StringPointer := ModuleInfo.BaseDLLName.Buffer;
StringLength := ModuleInfo.BaseDLLName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
Modules.Modules[Modules.Length - 1].ModuleName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Читаем следующий в списке LDR_MODULE_INFO:
NtWow64ReadVirtualMemory64(ProcessHandle, ModuleInfo.InLoadModuleOrderList.ForwardLDRModule, @ModuleInfo, SizeOf(ModuleInfo), BytesRead);
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure _GetProcessInfoWow64(ProcessID: LongWord; out ProcessInfo: PROCESS_INFO);
var
ProcessHandle: THandle;
ProcessBasicInfo: PROCESS_BASIC_INFORMATION64;
ProcessBasicInfoWow64: PROCESS_BASIC_INFORMATION_WOW64;
PEBInfo: PEB_WOW64;
UserParameters: RTL_USER_PROCESS_PARAMETERS_WOW64;
BytesRead: UInt64;
ReturnLength: UInt64;
//ReturnStatus: LongWord;
_Is64BitProcess: BOOL;
CurrentDirectory: AnsiString;
ImageName: AnsiString;
CmdLine: AnsiString;
StringBuffer: Pointer;
StringPointer: UInt64;
StringLength: Word;
TlHelp32Info: TProcessInfo;
LocalHandlesCount: LongWord;
MemoryCounters: _PROCESS_MEMORY_COUNTERS_EX;
begin
FillChar(ProcessBasicInfo, SizeOf(ProcessBasicInfo), #0);
FillChar(PEBInfo, SizeOf(PEBInfo), #0);
FillChar(UserParameters, SizeOf(UserParameters), #0);
FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);
ProcessHandle := ProcessIDToHandle(ProcessID);
// Получаем разрядность процесса:
IsWow64Process(ProcessHandle, _Is64BitProcess);
_Is64BitProcess := not _Is64BitProcess;
// Заполняем PROCESS_BASIC_INFORMATION:
NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo, SizeOf(ProcessBasicInfo), ReturnLength);
// Получаем адрес 32х-битного PEB:
NtWow64QueryInformationProcess64(ProcessHandle, ProcessWow64Information, @ProcessBasicInfoWow64, SizeOf(ProcessBasicInfoWow64), ReturnLength);
// Читаем PEB:
//NtWow64ReadVirtualMemory64(ProcessHandle, ProcessBasicInfo.PebBaseAddress, @PEBInfo, SizeOf(PEBInfo), BytesRead);
NtWow64ReadVirtualMemory64(ProcessHandle, ProcessBasicInfoWow64.Wow64PebAddress, @PEBInfo, SizeOf(PEBInfo), BytesRead);
// Читаем RTL_USER_PROCESS_PARAMETERS:
NtWow64ReadVirtualMemory64(ProcessHandle, UInt64(PEBInfo.ProcessParameters), @UserParameters, SizeOf(UserParameters), BytesRead);
// Получаем список загруженных модулей:
_GetModulesListWow64(ProcessHandle, UInt64(PEBInfo.Ldr), ProcessInfo.ModulesList);
// Читаем строки:
// CommandLine:
StringPointer := UserParameters.CommandLine.Buffer;
StringLength := UserParameters.CommandLine.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CmdLine := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// ImageFilePath:
StringPointer := UserParameters.ImagePathName.Buffer;
StringLength := UserParameters.ImagePathName.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
ImageName := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
//CurrentDirectoryPath:
StringPointer := UserParameters.CurrentDirectoryPath.Buffer;
StringLength := UserParameters.CurrentDirectoryPath.Length;
GetMem(StringBuffer, StringLength + 2);
FillChar(StringBuffer^, StringLength + 2, #0);
NtWow64ReadVirtualMemory64(ProcessHandle, StringPointer, StringBuffer, StringLength, BytesRead);
CurrentDirectory := WideToAnsi(PWideChar(StringBuffer));
FreeMem(StringBuffer);
// Получаем информацию о памяти процесса:
FillChar(MemoryCounters, SizeOf(MemoryCounters), #0);
GetProcessMemoryInfo(ProcessHandle, MemoryCounters, SizeOf(MemoryCounters));
// Получаем информацию из TlHelp32:
FillChar(TlHelp32Info, SizeOf(TlHelp32Info), #0);
TlHelp32Info := GetTlHelp32ProcessInfo(ProcessID);
// Получаем количество открытых хэндлов:
GetProcessHandleCount(ProcessHandle, @LocalHandlesCount);
// Возвращаем результат:
with ProcessInfo do
begin
Handle := ProcessHandle;
ID := ProcessBasicInfo.UniqueProcessId;
InheritedFromID := ProcessBasicInfo.InheritedFromUniqueProcessId;
SessionID := PEBInfo.SessionID;
Priority := ProcessBasicInfo.BasePriority;
AffinityMask := ProcessBasicInfo.AffinityMask;
IsDebugged := PEBInfo.BeingDebugged;
ExitStatus := ProcessBasicInfo.ExitStatus;
ThreadsCount := TlHelp32Info.ThreadsCount;
HandlesCount := LocalHandlesCount;
ReservedMemory := MemoryCounters.PrivateUsage;
ImageBaseAddress := UInt64(PEBInfo.ImageBaseAddress);
LdrAddress := UInt64(PEBInfo.Ldr);
PEBAddress := ProcessBasicInfo.PebBaseAddress;
ConsoleHandle := UserParameters.ConsoleHandle;
StdInputHandle := UserParameters.StdInputHandle;
StdOutputHandle := UserParameters.StdOutputHandle;
StdErrorHandle := UserParameters.StdErrorHandle;
ProcessName := TlHelp32Info.ExeFile;
CurrentDirectoryPath := CurrentDirectory;
ImagePathName := ImageName;
CommandLine := CmdLine;
Is64BitProcess := _Is64BitProcess;
end;
CloseHandle(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function GetProcessInfo(ProcessID: LongWord; out ProcessInfo: PROCESS_INFO; Process32_64CompatibleMode: Boolean = false): Boolean;
var
IsTarget64Bit: LongBool;
TargetHandle: THandle;
begin
FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);
TargetHandle := ProcessIDToHandle(ProcessID);
Result := (TargetHandle <> INVALID_HANDLE_VALUE) or (TargetHandle <> 0);
if not Result then Exit;
IsWow64Process(TargetHandle, IsTarget64Bit);
IsTarget64Bit := not IsTarget64Bit;
CloseHandle(TargetHandle);
{$IFDEF CPUX64}
if IsTarget64Bit then
_GetProcessInfo64(ProcessID, ProcessInfo)
else
if Process32_64CompatibleMode then
_GetProcessInfo64(ProcessID, ProcessInfo)
else
_GetProcessInfoWow64(ProcessID, ProcessInfo);
{$ELSE}
if _Is64BitWindows then
if IsTarget64Bit then
_GetProcessInfo64(ProcessID, ProcessInfo)
else
if Process32_64CompatibleMode then
_GetProcessInfo64(ProcessID, ProcessInfo)
else
_GetProcessInfo32(ProcessID, ProcessInfo)
else
_GetProcessInfo32(ProcessID, ProcessInfo);
{$ENDIF}
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetProcessBasicInfo(ProcessID: LongWord; out ProcessBasicInfo: TProcessBasicInfo): Boolean;
var
ProcessBasicInfo32: {$IFDEF CPUX64}PROCESS_BASIC_INFORMATION64{$ELSE}PROCESS_BASIC_INFORMATION{$ENDIF};
ProcessBasicInfo64: PROCESS_BASIC_INFORMATION64;
ProcessHandle: THandle;
ReturnLength32: LongWord;
ReturnLength64: UInt64;
begin
ProcessHandle := ProcessIDtoHandle(ProcessID);
Result := (ProcessHandle <> INVALID_HANDLE_VALUE) or (ProcessHandle <> 0);
if not Result then Exit;
if Is64BitProcess(ProcessID) then
begin
NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo64, SizeOf(ProcessBasicInfo64), ReturnLength64);
ProcessBasicInfo.ExitStatus := ProcessBasicInfo64.ExitStatus;
ProcessBasicInfo.AffinityMask := ProcessBasicInfo64.AffinityMask;
ProcessBasicInfo.BasePriority := ProcessBasicInfo64.BasePriority;
ProcessBasicInfo.UniqueProcessId := ProcessBasicInfo64.UniqueProcessId;
ProcessBasicInfo.InheritedFromUniqueProcessId := ProcessBasicInfo64.InheritedFromUniqueProcessId;
end
else
begin
NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo32, SizeOf(ProcessBasicInfo32), ReturnLength32);
ProcessBasicInfo.ExitStatus := ProcessBasicInfo32.ExitStatus;
ProcessBasicInfo.AffinityMask := ProcessBasicInfo32.AffinityMask;
ProcessBasicInfo.BasePriority := ProcessBasicInfo32.BasePriority;
ProcessBasicInfo.UniqueProcessId := ProcessBasicInfo32.UniqueProcessId;
ProcessBasicInfo.InheritedFromUniqueProcessId := ProcessBasicInfo32.InheritedFromUniqueProcessId;
end;
CloseHandle(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function Is64BitProcess(ProcessID: LongWord): LongBool;
var
ProcessHandle: NativeUInt;
begin
ProcessHandle := ProcessIDtoHandle(ProcessID);
if _Is64BitWindows then
begin
IsWow64Process(ProcessHandle, Result);
Result := not Result;
end
else
begin
Result := False;
end;
CloseHandle(ProcessHandle);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IsProcessLaunched(ProcessName: AnsiString): Boolean;
var
hSnapshot: THandle;
ProcessInfo: TProcessInfo;
begin
Result := false;
ProcessInfo.Size := SizeOf(ProcessInfo);
hSnapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32FirstA(hSnapshot, ProcessInfo) then
begin
if ProcessInfo.ExeFile = ProcessName then
begin
Result := true;
end
else
begin
while Process32NextA(hSnapshot, ProcessInfo) do
begin
if ProcessInfo.ExeFile = ProcessName then
begin
Result := true;
Break;
end;
end;
end;
end;
CloseHandle(hSnapshot);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IsProcessLaunched(ProcessID: LongWord): Boolean;
var
ProcessHandle: THandle;
begin
ProcessHandle := OpenProcess(PROCESS_VM_READ, FALSE, ProcessID);
Result := ProcessHandle <> 0;
if Result then CloseHandle(ProcessHandle);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IsLibInProcess(LibName: AnsiString; ProcessID: LongWord): Boolean;
var
ProcessInfo: PROCESS_INFO;
I: LongWord;
begin
Result := False;
GetProcessInfo(ProcessID, ProcessInfo);
if ProcessInfo.ModulesList.Length > 0 then
for I := 0 to ProcessInfo.ModulesList.Length - 1 do
if ProcessInfo.ModulesList.Modules[I].ModuleName = LibName then
begin
Result := True;
Exit;
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetProcessIdFromThreadID(ThreadID: LongWord): LongWord;
var
TlHelpHandle: LongWord;
ThreadEntry32: TThreadEntry32;
begin
Result := 0;
TlHelpHandle := CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if TlHelpHandle <> INVALID_HANDLE_VALUE then
begin
ThreadEntry32.Size := SizeOf(TThreadEntry32);
if Thread32First(TlHelpHandle, tagTHREADENTRY32(ThreadEntry32)) then
repeat
if ThreadEntry32.ThreadID = ThreadID then
Result := ThreadEntry32.OwnerProcessID;
until not Thread32Next(TlHelpHandle, tagTHREADENTRY32(ThreadEntry32));
CloseHandle(TlHelpHandle);
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure GetProcessList(out ProcessList: TProcessList);
var
hSnapshot: THandle;
ProcessInfo: TProcessInfo;
Size: LongWord;
begin
Size := 0;
SetLength(ProcessList, Size);
ProcessInfo.Size := SizeOf(ProcessInfo);
hSnapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32FirstA(hSnapshot, ProcessInfo) then
begin
Inc(Size);
SetLength(ProcessList, Size);
ProcessList[Size - 1] := ProcessInfo;
while Process32NextA(hSnapshot, ProcessInfo) do
begin
Inc(Size);
SetLength(ProcessList, Size);
ProcessList[Size - 1] := ProcessInfo;
end;
end;
CloseHandle(hSnapshot);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetTlHelp32ProcessInfo(ProcessID: LongWord): TProcessInfo; overload;
var
hSnapshot: THandle;
ProcessInfo: TProcessInfo;
begin
FillChar(Result, SizeOf(Result), #0);
ProcessInfo.Size := SizeOf(ProcessInfo);
hSnapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32FirstA(hSnapshot, ProcessInfo) then
begin
if ProcessInfo.ProcessID = ProcessID then
begin
Result := ProcessInfo;
end
else
begin
while Process32NextA(hSnapshot, ProcessInfo) do
begin
if ProcessInfo.ProcessID = ProcessID then
begin
Result := ProcessInfo;
Break;
end;
end;
end;
end;
CloseHandle(hSnapshot);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetTlHelp32ProcessInfo(ProcessName: AnsiString): TProcessInfo; overload;
var
hSnapshot: THandle;
ProcessInfo: TProcessInfo;
begin
FillChar(Result, SizeOf(Result), #0);
ProcessInfo.Size := SizeOf(ProcessInfo);
hSnapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32FirstA(hSnapshot, ProcessInfo) then
begin
if ProcessInfo.ExeFile = ProcessName then
begin
Result := ProcessInfo;
end
else
begin
while Process32NextA(hSnapshot, ProcessInfo) do
begin
if ProcessInfo.ExeFile = ProcessName then
begin
Result := ProcessInfo;
Break;
end;
end;
end;
end;
CloseHandle(hSnapshot);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure StartProcess(const CommandLine: string; out ProcessHandle: THandle; out ProcessID: LongWord);
var
ProcessInfo: _PROCESS_INFORMATION;
StartupInfo: _STARTUPINFO;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);
StartupInfo.wShowWindow := SW_SHOWNORMAL;
CreateProcess(
nil,
PChar(CommandLine),
nil,
nil,
FALSE,
0,
nil,
nil,
StartupInfo,
ProcessInfo
);
CloseHandle(ProcessInfo.hThread);
ProcessHandle := ProcessInfo.hProcess;
ProcessID := ProcessInfo.dwProcessId;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure WaitProcess(ProcessID: LongWord); inline;
var
ProcessHandle: THandle;
begin
ProcessHandle := OpenProcess(SYNCHRONIZE, FALSE, ProcessID);
if ProcessHandle = 0 then Exit;
WaitForSingleObject(ProcessHandle, INFINITE);
CloseHandle(ProcessHandle);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure KillProcess(ProcessID: LongWord); overload;
var
ProcessHandle: THandle;
begin
ProcessHandle := ProcessIDToHandle(ProcessID, PROCESS_TERMINATE);
TerminateProcess(ProcessHandle, 0);
CloseHandle(ProcessHandle);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure KillProcess(ProcessName: AnsiString; CanKillSelf: Boolean = False); overload;
var
ProcessList: TProcessList;
ProcessListCount: Integer;
I: Integer;
CurrentID: LongWord;
NeedToKillSelf: Boolean;
begin
GetProcessList(ProcessList);
CurrentID := GetCurrentProcessID;
ProcessListCount := Length(ProcessList);
if ProcessListCount = 0 then Exit;
NeedToKillSelf := False;
for I := 0 to ProcessListCount - 1 do
begin
if ProcessList[I].ExeFile = ProcessName then
if ProcessList[I].ProcessID = CurrentID then
NeedToKillSelf := True
else
KillProcess(ProcessList[I].ProcessID);
end;
if CanKillSelf and NeedToKillSelf then ExitProcess(0);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetProcessCPULoading(ProcessID: LongWord; Delay: Cardinal): Single;
var
SystemInfo: SYSTEM_INFO;
ProcessorsCount: Byte;
lpCreationTime, lpExitTime,
lpKernelTime, lpUserTime: TFileTime;
WorkingTime: Int64;
WorkingInterval, LifeInterval: Single;
FirstUpdateTime, SecondUpdateTime: Cardinal;
FirstWorkingTime: Int64;
ProcessHandle: THandle;
begin
ProcessHandle := ProcessIDtoHandle(ProcessID);
// Получаем количество ядер:
GetSystemInfo(SystemInfo);
ProcessorsCount := SystemInfo.dwNumberOfProcessors;
// Получаем времена процесса:
GetProcessTimes(ProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
FirstUpdateTime := GetTickCount;
// Рабочее время в начале интервала:
FirstWorkingTime := Int64(lpKernelTime) + Int64(lpUserTime);
Sleep(Delay);
// Получаем времена процесса через интервал:
GetProcessTimes(ProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
SecondUpdateTime := GetTickCount;
// Интервал, во время которого будем измерять нагрузку:
LifeInterval := SecondUpdateTime - FirstUpdateTime;
if LifeInterval <= 0 then LifeInterval := 0.01;
// Рабочее время в конце интервала:
WorkingTime := Int64(lpKernelTime) + Int64(lpUserTime);
// Разность между рабочими временами в конце и начале интервала:
WorkingInterval := WorkingTime - FirstWorkingTime;
// Выводим результат:
Result := WorkingInterval / (LifeInterval * 100 * ProcessorsCount);
CloseHandle(ProcessHandle);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
initialization
{$IFDEF DEBUG_PRIVILEGE}
NTSetPrivilege(SE_DEBUG_NAME, True);
{$ENDIF}
_InitFunctions;
end.
@Plasticable
Copy link

Ну и нахуя я это прочитал

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment