我们知道在win32中可以用ZwQuerySystemInformation获得SystemHandleInformation(16)的信息,然后遍历_SYSTEM_HANDLE_INFORMATION结构,对比pid,找到自己进程的pid然后对比handle,找到自己进程openprocess的handle那个的object就是本进程EPROCESS的地址,下面这个链接有代码
http://www.xfocus.net/articles/200406/706.html
---------------------------------------------------
这些东西在win32上都能运行,没有问题,但是在wow64下面运行就不行了。
尽管本进程已经OpenProcess打开了自己,但是在遍历数据的时候却没有找到自己的OpenProcess句柄,进而找不到本进程的EPROCESS地址。。。。
代码如下
#include <stdio.h>
#include <windows.h>
#define alloc(a) VirtualAlloc(0,a,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE)
#define freea(a) VirtualFree(a,0,MEM_RELEASE)
typedef struct {
PVOID Unknown1;
PVOID Unknown2;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _SYSTEM_HANDLE
{
DWORD ProcessId;
// USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount; /* Or NumberOfHandles if you prefer. */
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemModuleInformation = 11,
SystemHandleInformation = 16
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS(WINAPI *_NtQuerySystemInformation)(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
void main()
{
_NtQuerySystemInformation NtQuerySystemInformation=(_NtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"),"NtQuerySystemInformation");
PSYSTEM_MODULE_INFORMATION pmodinf;
PSYSTEM_HANDLE_INFORMATION phaninf;
ULONG len = 0;
char kname[260] = { 0 };
PVOID kbase = NULL;
DWORD cpid = GetCurrentProcessId();
HANDLE self = OpenProcess(PROCESS_QUERY_INFORMATION, NULL, cpid);
HANDLE self2 = NULL;
DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &self2, NULL, NULL, NULL);
NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len);
pmodinf = (PSYSTEM_MODULE_INFORMATION)alloc(len);
RtlSecureZeroMemory(pmodinf, len);
NtQuerySystemInformation(SystemModuleInformation, pmodinf, len, &len);
lstrcpyA(kname, pmodinf->Module[0].ImageName);
kbase = pmodinf->Module[0].Base;
printf("kbase:%x\tkname:%s\n", kbase, kname);
HANDLE hntos = LoadLibraryA(kname);
len = 4096 * 16 * 16;
// NtQuerySystemInformation(SystemHandleInformation, NULL, 0, &len);
phaninf = (PSYSTEM_HANDLE_INFORMATION)alloc(len);
RtlSecureZeroMemory(phaninf, len);
NtQuerySystemInformation(SystemHandleInformation, phaninf, len, &len);
for (UINT i = 0; i < phaninf->HandleCount; i++)
{
if (phaninf->Handles[i].ProcessId==cpid)
{
printf("ObjectType:%d\n", phaninf->Handles[i].ObjectTypeNumber);
printf("Handle:%x,OpenProcessHandle:%x,DuplicateHandle:%x\n", phaninf->Handles[i].Handle, self,self2);
puts("");
if (phaninf->Handles[i].Handle==(USHORT)self)
{
puts("=============================");
printf("OpenProcessHandle\tEProcess Found!0x%x\n", phaninf->Handles[i].Object);
puts("=============================");
}
if (phaninf->Handles[i].Handle == (USHORT)self2)
{
puts("=============================");
printf("DuplicateHandle\tEProcess Found!0x%x\n", phaninf->Handles[i].Object);
puts("=============================");
}
}
}
freea(phaninf);
freea(pmodinf);
}
这个在wow64上就不能获得正确的地址。。
那么问题来了,有没有类似的方法在wow64上获得自己进程的EPROCSS地址呢?
小菜第一次发帖,求各位表哥解答
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)