话说那NT也有历遍进程的函数,那就是PSAPI.函数为:
BOOL EnumProcesses(
DWORD *lpidProcess, // array of process identifiers
DWORD cb, // size of array
DWORD *cbNeeded // number of bytes returned
);
和
BOOL EnumProcessModules(
HANDLE hProcess, // handle to process
HMODULE *lphModule, // array of module handles
DWORD cb, // size of array
LPDWORD lpcbNeeded // number of bytes required
);
前一函数返回所有进程的ID.而后一函数根据进程句柄来获取该进程的模块句柄数组.这里介绍的乃是另外一种方法.该方法比上述方法速度快很多.就是运用NATIVE API.下面乃是公开的秘密.:)网络上已经有很多关于此函数的论述,该函数查询功能之大,超乎想象,几乎任何系统信息都可以查询,现在披露有关历遍进程的部分.:)
typedef struct ThreadSysInfo_t {
LARGE_INTEGER ThreadKernelTime;
LARGE_INTEGER ThreadUserTime;
LARGE_INTEGER ThreadCreateTime;
ULONG TickCount;
ULONG StartEIP;
CLIENT_ID ClientId;
ULONG DynamicPriority;
ULONG BasePriority;
ULONG nSwitches;
ULONG Unknown;
KWAIT_REASON WaitReason;
}THREADSYSINFO, *PTHREADSYSINFO;
typedef struct ProcessThreadSystemInfo {
ULONG RelativeOffset;
ULONG nThreads;
ULONG Unused1[6];
LARGE_INTEGER ProcessCreateTime;
LARGE_INTEGER ProcessUserTime;
LARGE_INTEGER ProcessKernelTime;
UNICODE_STRING ProcessName;
ULONG BasePriority;
ULONG ProcessId;
ULONG ParentProcessId;
ULONG HandleCount;
ULONG Unused2[2];
ULONG PeakVirtualSizeBytes;
ULONG TotalVirtualSizeBytes;
ULONG nPageFaults;
ULONG PeakWorkingSetSizeBytes;
ULONG TotalWorkingSetSizeBytes;
ULONG PeakPagedPoolUsagePages;
ULONG TotalPagedPoolUsagePages;
ULONG PeakNonPagedPoolUsagePages;
ULONG TotalNonPagedPoolUsagePages;
ULONG TotalPageFileUsageBytes;
ULONG PeakPageFileUsageBytes;
ULONG TotalPrivateBytes;
THREADSYSINFO ThreadSysInfo[1];
} PROCESSTHREADSYSTEMINFO, *PPROCESSTHREADSYSTEMINFO;
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
IN SYSTEMINFOCLASS SystemInfoClass, //Set to 5 for enumerate all process
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
当然,KMD也可以在PASSIVE LEVEL运用此函数的内核引出:
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEMINFOCLASS SystemInfoClass, //Set to 5 for enumerate all process
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
妙极否?:)由于查询功能太过强大,此函数必须有SE_TCB_NAME特权才能运作.大家感受到了SE_TCB_NAME特权的吸引人之处了吧!:DDD特权特权我所爱也.;)))
***********************************
用PSAPI,给你源码,有点乱,慢慢看吧。
//---------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
const
KILL_NOERR = 0;
KILL_NOTSUPPORTED = -1;
KILL_ERR_OPENPROCESS = -2;
KILL_ERR_TERMINATEPROCESS = -3;
ENUM_NOERR = 0;
ENUM_NOTSUPPORTED = -1;
ENUM_ERR_OPENPROCESSTOKEN = -2;
ENUM_ERR_LookupPrivilegeValue = -3;
ENUM_ERR_AdjustTokenPrivileges = -4;
SE_DEBUG_NAME = 'SeDebugPrivilege';
type
TForm1 = class(TForm)
Button1: TButton;
TreeView1: TTreeView;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure TreeView1DblClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ProcessNameList,ProcessIDList,FullNameList:TStrings;
implementation
{$R *.DFM}
function EnumProcesses(lpidProcess,cb,cbNeeded:dword):
integer;stdcall;external 'PSAPI.DLL';
function EnumProcessModules(hProcess:THandle;lphModule:HMODULE;cb,lpcbNeeded:Dword):
integer;stdcall;external 'PSAPI.DLL';
function GetModuleBaseNameA(hProcess:THandle;hModule:HMODULE;lpBaseName:pchar;nSize:DWord):
integer;stdcall;external 'PSAPI.DLL';
function GetModuleFileNameExA(hProcess:THandle;hModule:HMODULE;lpFilename:pchar;nSize:DWord):
integer;stdcall;external 'PSAPI.DLL';
procedure ErrorMessage;
var
MsgBuf:string;
begin
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER or
FORMAT_MESSAGE_FROM_SYSTEM or
FORMAT_MESSAGE_IGNORE_INSERTS,
nil,
GetLastError(),
LANG_NEUTRAL,//MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
@MsgBuf,
sizeof(MsgBuf),
nil
);
MessageBox(0,pchar(MsgBuf),'错误',MB_OK);
raise EAbort.Create ('') ;
end;
procedure GetTokenInfo(ProcessID:THandle);
var
InfoBuffer:TTokenPrivileges;
i:Integer;
ucPrivilegeName:pchar;
dwPrivilegeNameSize,dwInfoBufferSize:DWord;
PrivilegesList:TStrings;
hToken,hProcess : THANDLE;
s:string;
p:pchar;
begin
//get process handle from process id
hProcess := OpenProcess( PROCESS_ALL_ACCESS,
true, processID );
if hProcess=0 then
ErrorMessage;
//get token handle from process handle
if (OpenProcessToken(hProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_READ, hToken) = false) then
begin
ErrorMessage;
end;
dwInfoBufferSize:=0;
if GetTokenInformation(hToken,TokenPrivileges,@InfoBuffer,
sizeof(TTokenPrivileges),dwInfoBufferSize)=false then
begin
ErrorMessage;
end;
{
if PrivilegesList=nil then
PrivilegesList:=TStringList.Create
else
PrivilegesList.Clear;
}
ucPrivilegeName:=strAlloc(128);
exit;
s:='bbbb';
strPcopy(ucPrivilegeName,s);
//ucPrivilegeName:='aaa';
s:=strpas(ucPrivilegeName);
showmessage(s);
dwPrivilegeNameSize:=1000;
for i:=0 to InfoBuffer.PrivilegeCount-1 do
begin
if LookupPrivilegeName(nil,InfoBuffer.Privileges[i].Luid,
ucPrivilegeName,dwPrivilegeNameSize)=false then
begin
ErrorMessage;
end;
//PrivilegesList.Add (strpas(ucPrivilegeName));
//Form1.Memo1.Lines.Add(strpas(ucPrivilegeName));
//s:=strpas(ucPrivilegeName);
showmessage(s);
end;
strDispose(ucPrivilegeName);
//Form1.Memo1.Lines:=PrivilegesList;
CloseHandle( hProcess );
{
if PrivilegesList<>nil then
PrivilegesList.Free ;
}
end;
function EnableDebugPrivilegeNT : integer;
var
hToken : THANDLE;
DebugValue : TLargeInteger;
tkp : TTokenPrivileges ;
ReturnLength : DWORD;
PreviousState: TTokenPrivileges;
begin
if (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_READ, hToken) = false) then
result := ENUM_ERR_OPENPROCESSTOKEN
else
begin
if (LookupPrivilegeValue(nil, SE_DEBUG_NAME, DebugValue) = false) then
result := ENUM_ERR_LookupPrivilegeValue
else
begin
ReturnLength := 0;
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := DebugValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TTokenPrivileges),PreviousState , ReturnLength);
if (GetLastError <> ERROR_SUCCESS) then
result := ENUM_ERR_AdjustTokenPrivileges
else
result := ENUM_NOERR;
end;
end;
end;
function Kill_By_Pid(pid : longint) : integer;
var
hProcess : THANDLE;
TermSucc : BOOL;
begin
hProcess := OpenProcess(PROCESS_ALL_ACCESS, true, pid);
if (hProcess = 0) then // v 1.2 : was =-1
begin
result := KILL_ERR_OPENPROCESS;
end
else
begin
TermSucc := TerminateProcess(hProcess, 0);
if (TermSucc = false) then
result := KILL_ERR_TERMINATEPROCESS
else
result := KILL_NOERR;
end;
end;
procedure UpdateTreeView(Tree:TTreeView);
var
i:integer;
MyNode:TTreeNode;
begin
with Tree.Items do
begin
Clear;
if MyNode<>nil then
MyNode:=nil ;
for i:=0 to ProcessNameList.Count-1 do
begin
if (MyNode=nil)or(UpperCase(copy(processNameList[i],length(processNameList[i])-2,3))='EXE') then
MyNode:=add(nil,processNameList[i])
else
AddChild(MyNode,processNameList[i]);
end;
end;
end;
procedure PrintProcessNameAndID(processID: DWORD);
var
// szProcessName:ARRAY[0..1024] OF CHAR;
szFullName:ARRAY[0..1024] OF CHAR;
szModName :ARRAY[0..1024] OF CHAR;
hProcess : THandle;
hMods :array [0..1024] of dword;
cbNeeded,cMod : DWORD ;
i : Integer;
begin
// Get a handle to the process.
hProcess := OpenProcess( PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
szModName := 'unknown';
szFullName := 'unknown';
if ( hProcess<>0 ) then
begin
if EnumProcessModules( hProcess, dword(@hMods), sizeof(hMods),dword(@cbNeeded))<>0 then
begin
// GetModuleBaseNameA( hProcess, hMod, szProcessName,sizeof(szProcessName) );
// GetModuleFileNameExA(hProcess, hMod, szFullName,sizeof(szFullName));
cMod:=cbNeeded div sizeof(HMODULE);
for i := 0 to (cMod-1) do
begin
// Get the full path to the module's file.
GetModuleBaseNameA( hProcess, hMods[i], szModName,sizeof(szModName));
GetModuleFileNameExA( hProcess, hMods[i], szFullName,sizeof(szModName));
ProcessNameList.Add (StrPas(szModName));
FullNameList.Add (StrPas(szFullName));
end;
end;
end;
// Print the process name and identifier.
//Form1.Memo1.Lines.Add (StrPas(szProcessName));
// ProcessNameList.Add (StrPas(szProcessName));
// FullNameList.Add (StrPas(szFullName));
CloseHandle( hProcess );
end;
procedure TForm1.Button1Click(Sender: TObject);
var
cbNeeded, cProcesses:dword;
aProcesses: array [0..1024] of dword;
i:Cardinal;
begin
if EnumProcesses( Dword(@aProcesses), sizeof(aProcesses), Dword(@cbNeeded))<>0 then
begin
cProcesses := cbNeeded div sizeof(DWORD);
end
else
showmessage(inttostr(GetLastError));
if ProcessIDList<>nil then
processidlist.Clear
else
ProcessIDList:=TStringList.Create;
if ProcessNameList<>Nil then
ProcessNameList.Clear
else
ProcessNameList:=Tstringlist.Create;
if FullNameList<>Nil then
FullNameList.Clear
else
FullNameList:=TStringList.Create ;
for i:=0 to cprocesses-1 do
processidlist.Add(intToStr(aProcesses[i]));
for i:=0 to cProcesses-1 do
begin
PrintProcessNameAndID( strtoint(ProcessIDList[i]));
end;
// Memo1.lines:=ProcessNameList;
UpdateTreeView(Form1.TreeView1);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if ProcessIDList<>Nil then
ProcessIDList.Free;
if ProcessNameList<>nil then
ProcessNameList.Free ;
if FullNameList<>Nil then
FullNameList.Free ;
end;
procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
MyNode:TTreeNode;
begin
MyNode:=TreeView1.GetNodeAt(x,y);
if MyNode<>nil then
begin
MyNode.Selected :=true;
if MyNode.HasChildren then
begin
Caption:='['+ ProcessIDList[MyNode.index]+ ']'+FullNameList[MyNode.AbsoluteIndex];
GetTokenInfo(strToint(ProcessIDList[MyNode.Index]));
end
else
Caption:=FullNameList[MyNode.AbsoluteIndex];
end;
end;
procedure TForm1.TreeView1DblClick(Sender: TObject);
var
MyNode:TTreeNode;
begin
MyNode:= TreeView1.Selected;
if (MyNode<>Nil)and(MyNode.HasChildren) then
begin
showmessage(intTostr(Kill_By_Pid(strToInt(ProcessIDList[MyNode.Index]))));
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EnableDebugPrivilegeNT;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
s:string ;
p:Pchar;
begin
p:=strAlloc(128);
strcopy(p,'aa');
//p:='aaa';
s:=strpas(p);
showmessage(s);
strDispose(p);
end;
end.