枚举进程中的所有内核对象

xiaoxingchi 2010-03-31 05:42:17
谁可以帮忙帮翻译一下,这个是C的可能不全,谁可以帮忙搞个全一点的。


=======================================

HANDLE GetProcessKernelObject(DWORD ProcessId)
{

HMODULE hNtDll = NULL;
ZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;
NTQUERYOBJECT pfnNtQueryObject = NULL;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = NULL;
POBJECT_ALL_INFORMATION pAllInfo =NULL;
POBJECT_NAME_INFORMATION pNameInfo = NULL;


ULONG nNumberHandle =0;
NTSTATUS ntStatus = 0;
ULONG ulSize,ulCount;
char cBuffer[0x80000],cInfoBuffer[0x10000];

hNtDll = GetModuleHandle(TEXT("ntdll.dll"));
pfnZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,"ZwQuerySystemInformation");
pfnNtQueryObject = (NTQUERYOBJECT)GetProcAddress(hNtDll,"NtQueryObject");

ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation,cBuffer,0x80000,&ulSize);

if(NT_SUCCESS(ntStatus))
{
DWORD n = ulSize/sizeof(SYSTEM_HANDLE_INFORMATION);
nNumberHandle = *(PULONG)cBuffer;
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(cBuffer +4);
ulCount = 0;

for(ULONG i=0;i!=nNumberHandle;++i)
{

if(pSysHandleInfo[i].ProcessId != ProcessId)
continue;


ntStatus = pfnNtQueryObject((HANDLE)pSysHandleInfo[i].Handle,ObjectAllInformation,cInfoBuffer,0x10000,&ulSize);
ntStatus = pfnNtQueryObject((HANDLE)pSysHandleInfo[i].Handle,ObjectNameInformation,cInfoBuffer,0x10000,&ulSize);
if(NT_SUCCESS(ntStatus))
{
pAllInfo = (POBJECT_ALL_INFORMATION)cInfoBuffer;
pNameInfo = (POBJECT_NAME_INFORMATION)cInfoBuffer;
if(_tcsstr(pNameInfo->NameBuffer,TEXT("QQGame_Mutex")) !=NULL)
{
return (HWND)pSysHandleInfo[i].Handle;
}
}
}
}
return NULL;
}


hMuTex = GetProcessKernelObject(GetCurrentProcessId());
CloseHandle(hMuTex);

原理,因为许多限制多开的软件都是利用命名内核对象来实现的,如果Create* 创建内核对象 返回 “以存在”那么就退出。
所以,先枚举进程中的所有内核对象,然后关闭他就好了~ 在R3下实现,用此方法可以多开大多数程序包括将来的~
...全文
1502 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
iori8421 2010-07-24
  • 打赏
  • 举报
回复
代码复制下了全乱了
Reverse.King 2010-04-01
  • 打赏
  • 举报
回复

procedure EumKnlObjectName(var sList:TStrings);
type
PObjectTypeInformation = ^TObjectTypeInformation;
TObjectTypeInformation = packed record
Name: UNICODE_STRING;
ObjectCount, HandleCount: Cardinal;
Reserved1: array[0..3] of Cardinal;
PeakObjectCount, PeakHandleCount: Cardinal;
Reserved2: array[0..3] of Cardinal;
InvalidAttributes: Cardinal;
GenericMapping: TGenericMapping;
ValidAccess: Cardinal;
Unknown: UCHAR;
MaintainHandleDatabase: Boolean;
Reserved3: array[0..1] of UCHAR;
PoolType: Cardinal;
PagedPoolUsage, NonPagedPoolUsage: Cardinal;
end;

POBJECT_ALL_TYPES_INFORMATION = ^TOBJECT_ALL_TYPES_INFORMATION;
TOBJECT_ALL_TYPES_INFORMATION = record // Information Class 3
NumberOfTypes: DWORD;
TypeInformation: TObjectTypeInformation;
end;

TOBJECT_INFORMATION_CLASS = (
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllTypesInformation,
ObjectHandleInformation);

PObjectNameInformation = ^TObjectNameInformation;
TObjectNameInformation = packed record
Name: UNICODE_STRING;
end;

PSystemHandleInformation = ^TSystemHandleInformation;
TSystemHandleInformation = packed record
ProcessId: DWORD;
ObjectTypeNumber: Byte;
Flags: Byte;
Handle: Word;
eObject: Pointer;
GrantedAccess: ACCESS_MASK;
end;

PSystemHandleInformation_Ex = ^TSystemHandleInformation_Ex;
TSystemHandleInformation_Ex = packed record
NumberOfHandles: DWORD;
Information: TSystemHandleInformation;
end;

PNtQuerySystemInformation = function(SystemInformationClass: DWORD; SystemInformation: Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): DWORD; stdcall;

PNtQueryObject = function(ObjectHandle: THANDLE;
ObjectInformationClass: TOBJECT_INFORMATION_CLASS;
ObjectInformation: Pointer;
ObjectInformationLength: DWORD;
ReturnLength: PDWORD): DWORD; stdcall;
var
_ModuleHandle, _Count, i: Dword;
_NtQueryObject: PNtQueryObject;
_ObjTypeInfo: POBJECT_ALL_TYPES_INFORMATION;
_P, _StrLen, _Size: DWORD;
_ObjName: string;
_NtQuerySystemInformation: PNtQuerySystemInformation;
pHandleInfor: PSystemHandleInformation_Ex;
_HandleInfor: PSystemHandleInformation;
_Name: PObjectNameInformation;
begin

_Count := 0;
_ModuleHandle := GetModuleHandle('ntdll.dll');
_NtQueryObject := GetProcAddress(_ModuleHandle, 'NtQueryObject');
_NtQuerySystemInformation := GetProcAddress(LoadLibrary('ntdll.dll'), 'NtQuerySystemInformation');
_Size := $1000;
GetMem(pHandleInfor, _Size);
while _NtQuerySystemInformation(16, pHandleInfor, _Size, nil) <> 0 do
begin
_Size := _Size + _Size;
ReallocMem(pHandleInfor, _Size);
end;
_Name := GetMemory($1000);
for I := 0 to pHandleInfor^.NumberOfHandles - 1 do
begin
_HandleInfor := PSystemHandleInformation(dword(pHandleInfor) + 4 + (i * SizeOf(TSystemHandleInformation)));
if (_HandleInfor^.ProcessId = GetCurrentProcessId) then
begin
if _NtQueryObject(_HandleInfor^.Handle, ObjectNameInformation, _Name, $1000, nil) = 0 then
begin
_ObjName := WideCharToString(_Name.Name.Buffer);

sList.Add(IntToHex(Dword(_HandleInfor^.Handle), 8) + '-' + IntToStr(_HandleInfor^.ObjectTypeNumber) + ':' + _ObjName);

end;
end;
end;
end;
gyk120 2010-04-01
  • 打赏
  • 举报
回复
Zw那些ntdll导出的东西,翻译起来很麻烦,毕竟是个体力活,想偷懒的话去找下jedi api库,那个有翻译好的native api函数,可以直接用
xiaoxingchi 2010-04-01
  • 打赏
  • 举报
回复
楼上的 现在能翻译了吗
SQLDebug_Fan 2010-04-01
  • 打赏
  • 举报
回复
如果定义找全了,翻译就很容易了。
xiaoxingchi 2010-04-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sqldebug_fan 的回复:]
代码挺简洁的,麻烦在需要把ZWQUERYSYSTEMINFORMATION这些定义找全。
[/Quote]

ZWQUERYSYSTEMINFORMATION的定义我找到这些,看对你有没有用处.
xiaoxingchi 2010-04-01
  • 打赏
  • 举报
回复
获取进程常用的方法是用ToolHelp库函数或者PsAPI库函数,这两个库函数最终都将调用Ntdll.dll中的ZwQuerySystemInformation函数来获取进程,既然如此,我们完全可以直接用ZwQuerySystemInformation来获取进程。ZwQuerySystemInformation是个未公开的函数,没有被导出,因此使用的时候需要用GetProcAddress获取其地址。ZwQuerySystemInformation函数原型如下:

NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass, // information classIN OUT PVOID SystemInformation, // information buffer
IN ULONG SystemInformationLength, // size of information buffer
OUT PULONG ReturnLength OPTIONAL // receives information length
);

SystemInformationClass 要获取什么信息,获取进程和线程信息时将此参数指定为5
SystemInformation 缓冲区指针,函数将把获取的信息保存到这里
SystemInformationLength 缓冲区长度
ReturnLength 函数将在这里返回实际获取的信息长度,注意这个参数是个指针

函数成功执行时返回0。函数返回到缓冲区里的信息是一系列的。SYSTEM_PROCESS_INFORMATION结构,其定义如下:


typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta; // offset to the next entry
ULONG ThreadCount; // number of threads
ULONG Reserved1[6]; // reserved

SYSTEM_PROCESS_INFORMATION结构,其定义如下:

typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta; // offset to the next entry
ULONG ThreadCount; // number of threads
ULONG Reserved1[6]; // reserved
LARGE_INTEGER CreateTime; // process creation time
LARGE_INTEGER UserTime; // time spent in user mode
LARGE_INTEGER KernelTime; // time spent in kernel mode
UNICODE_STRING ProcessName; // process name
KPRIORITY BasePriority; // base process priority
ULONG ProcessId; // process identifier
ULONG InheritedFromProcessId; // parent process identifier
ULONG HandleCount; // number of handles
ULONG Reserved2[2]; // reserved
VM_COUNTERS VmCounters; // virtual memory counters
#if _WIN32_WINNT >= 0x500
IO_COUNTERS IoCounters; // i/o counters
#endif
SYSTEM_THREAD_INFORMATION Threads[1]; // threads
} SYSTEM_PROCESS_INFORMATION, * SYSTEM_PROCESS_INFORMATION;


这里注意在Windows NT 4.0和Windows 2000里SYSTEM_PROCESS_INFORMATION结构的大小是不一样的,这也是使用未公开API的危险,因为难保将来Microsoft会修改或者删除这些API。从各个结构成员的名字很好理解其代表的意思,其中NextEntryDelta为下一个SYSTEM_PROCESS_INFORMATION结构的相对偏移;ProcessId就是进程ID了;ProcessName就是进程名,这是个UNICODE_STRING结构,如果你写过驱动的话应该对这个结构再熟悉不过了,这里就不帖出来了。最后一个结构成员Threads是一个SYSTEM_THREAD_INFORMATION结构,其定义如下:

typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime; // time spent in kernel mode
LARGE_INTEGER UserTime; // time spent in user mode
LARGE_INTEGER CreateTime; // thread creation time
ULONG WaitTime; // wait time
PVOID StartAddress; // start address
CLIENT_ID ClientId; // thread and process IDs
KPRIORITY Priority; // dynamic priority
KPRIORITY BasePriority; // base priority
ULONG ContextSwitchCount; // number of context switches
LONG State; // current state
LONG WaitReason; // wait reason
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;

xiaoxingchi 2010-03-31
  • 打赏
  • 举报
回复
分不够可以再开贴加分。有哪个愿意把这个C版 译成 D版的啊?
飞天赤狐 2010-03-31
  • 打赏
  • 举报
回复
那得进行进程注入吧,要不然恐怕也close不了
SQLDebug_Fan 2010-03-31
  • 打赏
  • 举报
回复
代码挺简洁的,麻烦在需要把ZWQUERYSYSTEMINFORMATION这些定义找全。
xiaoxingchi 2010-03-31
  • 打赏
  • 举报
回复
谁来翻译一下嘛
金卯刀 2010-03-31
  • 打赏
  • 举报
回复
是全的,翻譯GetProcessKernelObject就好了...

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧