Credit
다양한 Windows 버전에서 Undocumented Struct인 EPROCESS의 오프셋을 구하는 코드입니다.
프로젝트 설정에서 경고를 오류로 처리
를 꺼야 합니다.
#pragma warning(disable: 4047 4024 4189 4133 4152 6506 6387)
/* You probly not want to import this */
typedef NTSTATUS(*NtQueryInformationProcess_t)(
_In_ HANDLE ProcessHandle,
_Out_ PROCESSINFOCLASS ProcessInformationClass,
_In_ PVOID ProcessInformation,
_Out_ ULONG ProcessInformationLength,
_Out_ PULONG ReturnLength
);
/**/
typedef struct _IMPORT_OFFSET
{
int UniqueProcessid_off;
int ActiveProcessLinks_off;
int ImageFileName_off;
int PEB_off;
}IMPORT_OFFSET;
IMPORT_OFFSET iOffset;
const char szSystem[] = "System";
const wchar_t szNtQueryInformationProcess[] = L"NtQueryInformationProcess";
BOOLEAN GetPebOffset()
{
int LinkOffset = iOffset.ActiveProcessLinks_off;
int ProcName = iOffset.ImageFileName_off;
BOOLEAN success = FALSE;
PEPROCESS Process = PsGetCurrentProcess();
UNICODE_STRING routineName = { 0, };
RtlInitUnicodeString(&routineName, szNtQueryInformationProcess);
NtQueryInformationProcess_t NtQueryInformationProcess = MmGetSystemRoutineAddress(&routineName);
for (int i = 0; i < 0x10; i++)
{
PROCESS_BASIC_INFORMATION ProcessInformation = { 0, };
PLIST_ENTRY ListEntry = (PVOID*)((PCHAR)Process + LinkOffset);
Process = ((PCHAR)ListEntry->Flink - LinkOffset);
HANDLE Key = NULL;
if (ObOpenObjectByPointer(Process, NULL, NULL, NULL, *PsProcessType, KernelMode, &Key) == STATUS_SUCCESS)
{
PULONG Ret = NULL;
NtQueryInformationProcess(Key, ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), Ret);
ZwClose(Key);
}
if (ProcessInformation.PebBaseAddress)
{
for (int j = iOffset.ActiveProcessLinks_off; j < PAGE_SIZE - 0x10; j += 4)
{
if (*(PHANDLE)((PCHAR)Process + j) == ProcessInformation.PebBaseAddress)
{
iOffset.PEB_off = j;
success = TRUE;
return success;
}
}
}
}
return success;
}
BOOLEAN GetOffset()
{
BOOLEAN success = FALSE;
PEPROCESS Process = PsGetCurrentProcess();
HANDLE PID = PsGetCurrentProcessId();
PLIST_ENTRY ListEntry = { 0, };
PLIST_ENTRY NextEntry = { 0, };
for (int i = 0x80; i < PAGE_SIZE - 0x10; i += 4)
{
if (*(PHANDLE)((PCHAR)Process + i) == PID)
{
ListEntry = (PVOID*)((PCHAR)Process + i + 0x8);
if (MmIsAddressValid(ListEntry) && MmIsAddressValid(ListEntry->Flink))
{
NextEntry = ListEntry->Flink;
if (ListEntry == NextEntry->Blink)
{
iOffset.UniqueProcessid_off = i;
iOffset.ActiveProcessLinks_off = i + 8;
success = TRUE;
break;
}
}
}
}
if (!success)
{
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[!] Not Found Offset... Sorry :(\\n");
return success;
}
// ImageFileName Offset
success = FALSE;
for (int i = iOffset.ActiveProcessLinks_off; i < PAGE_SIZE; i++)
{
if (!strncmp((PCHAR)Process + i, szSystem, 6))
{
iOffset.ImageFileName_off = i;
success = TRUE;
break;
}
}
if (!success)
{
return success;
}
if (!GetPebOffset())
{
return success;
}
return success;
}