大概流程:
首先通過ZwQuerySystemInformation(SystemHandleInformation,*,*)獲取句柄信息,然後根據句柄調用ZwQueryObject(*,ObjectNameInformation,*)獲取對象名信息,最後匹配確定目標。示例是確定“\\Windows\\ApiPort"所屬的進程。
需要注意的是用有的句柄調用ZwQueryObject會返回STATUS_INVALID_HANDLE(0xc0000008)不知道爲什麼?(不應該失效吧?還是沒有權限?)
#define SystemHandleInformationClass 0x10
#define ObjectNameInformation 0x1
/*
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
*/
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
VOID GetFileImageNameOffsetInEPROCESS()
{
PEPROCESS CurrentP=NULL;
ULONG Offset=0,SearchRange=0x3000;
CurrentP=IoGetCurrentProcess();
if(CurrentP)
{
//DbgPrint("current process name is %s\n",(CHAR*)CurrentP+0x16c);
//內存匹配
do
{
if(_strnicmp((CHAR*)((ULONG)CurrentP+Offset),"System",6))
{
Offset++;
}
else
{
DbgPrint("ImageFileName is at 0x%x in EPROCESS\n",Offset);
ImageFileNameOffset=Offset;
break;
}
}while(Offset<SearchRange);
}
}
VOID FindCsrss()
{
NTSTATUS status=STATUS_SUCCESS;
ULONG BufferSize=0x4000,ReturnLength=0;
ULONG NumberTables=0,NumberIndex=0x000;
PVOID Buffer=NULL;
SYSTEM_HANDLE_TABLE_ENTRY_INFO* EntryInfo=NULL;
PEPROCESS Process=NULL;
KAPC_STATE ApcState;
//UNICODE_STRING Name;
WCHAR Name[0x800]={0};
RtlInitUnicodeString(&Name,L"123456");
Buffer=ExAllocatePoolWithTag(NonPagedPool,BufferSize,0x12345678);
if(Buffer==NULL)
{
DbgPrint("allocate buffer fails!\n");
return;
}
status=ZwQuerySystemInformation(SystemHandleInformationClass,Buffer,BufferSize,&ReturnLength);
if(status==STATUS_INFO_LENGTH_MISMATCH)
{
DbgPrint("more space is needed!\n");
ExFreePool(Buffer);
BufferSize=ReturnLength;
Buffer=ExAllocatePoolWithTag(NonPagedPool,ReturnLength,0x12345678);
status=ZwQuerySystemInformation(SystemHandleInformation,Buffer,BufferSize,&ReturnLength);
//WriteFile(FileNamex,Buffer,BufferSize);
if(status==STATUS_SUCCESS)
{
DbgPrint("handle information,there have %x handles!\n",*(ULONG*)Buffer);
NumberTables=*(ULONG*)Buffer;
do
{
EntryInfo=(PSYSTEM_HANDLE_TABLE_ENTRY_INFO)((CHAR*)Buffer+4+NumberIndex*sizeof
(SYSTEM_HANDLE_TABLE_ENTRY_INFO));
if(EntryInfo)
{
status=PsLookupProcessByProcessId(EntryInfo->UniqueProcessId,&Process);
if(status==STATUS_SUCCESS)
{
KeStackAttachProcess(Process,&ApcState);
status=ZwQueryObject((HANDLE)EntryInfo->HandleValue,
ObjectNameInformation,
Name,0x600,NULL);
KeUnstackDetachProcess(&ApcState);
}
if(status==STATUS_SUCCESS)
{
if(Name[0]==0x20)
{
if(0==_wcsnicmp(Name+4,L"\\Windows\\ApiPort",0x20))
{
DbgPrint("ProcessId:0x%x---ImageName:%s owns the goal!\n",\
EntryInfo->UniqueProcessId,\
(char*)Process+ImageFileNameOffset
);
break;
}
}
}
else if(NumberIndex<=0x10)//打印前16個
{
DbgPrint("status:0x%x,HandleValue:0x%x\n",status,\
EntryInfo->HandleValue);
}
}
NumberIndex++;
if(Process)
{
ObDereferenceObject(Process);
}
}while(NumberIndex<NumberTables);
}
}
if(Buffer)
{
ExFreePool(Buffer);
}
}