Example #1
0
StoreManager::StoreManager(
)
/*++

Routine Description:

    Description.

Arguments:

    -

Return Value:

    None.

--*/
{
    m_SmLogCtxOffset = GetFieldOffset("nt!_SM_GLOBALS", "StoreMgr.Log");
    m_SmcCacheMgrOffset = GetFieldOffset("nt!_SM_GLOBALS", "CacheMgr");

    if (!m_SmLogCtxOffset || !m_SmcCacheMgrOffset)
    {
        g_Ext->Dml("Error: Can't retrieve Store and Cache offsets.\n");
    }

    m_SmGlobalsAddress = 0;

    if (g_Ext->m_Control->IsPointer64Bit() == S_OK)
    {
        m_SmpLogBufferSize = sizeof(SMP_LOG_BUFFER64);
        m_SmLogEntrySize = sizeof(SM_LOG_ENTRY64);
    }
    else
    {
        m_SmpLogBufferSize = sizeof(SMP_LOG_BUFFER32);
        m_SmLogEntrySize = sizeof(SM_LOG_ENTRY32);
    }

    g_Ext->m_Symbols->GetOffsetByName("nt!SmGlobals", &m_SmGlobalsAddress);
}
Example #2
0
void WDbgArk::InitCallbackCommands() {
    uint32_t timer_routine_offset = 0;

    if ( GetFieldOffset("nt!_IO_TIMER", "TimerRoutine", reinterpret_cast<PULONG>(&timer_routine_offset)) != 0 )
        warn << wa::showqmark << __FUNCTION__ << ": GetFieldOffset failed with nt!_IO_TIMER.TimerRoutine" << endlwarn;

    uint32_t le_size = GetTypeSize("nt!_LIST_ENTRY");

    m_system_cb_commands = { {
        { "image", { "nt!PspLoadImageNotifyRoutineCount", "nt!PspLoadImageNotifyRoutine", 0, 0, 0 } },
        { "process", { "nt!PspCreateProcessNotifyRoutineCount", "nt!PspCreateProcessNotifyRoutine", 0, 0, 0 } },
        { "thread", { "nt!PspCreateThreadNotifyRoutineCount", "nt!PspCreateThreadNotifyRoutine", 0, 0, 0 } },
        { "registry", { "nt!CmpCallBackCount", "nt!CmpCallBackVector", GetCmCallbackItemFunctionOffset(), 0, 0 } },
        { "bugcheck", { "", "nt!KeBugCheckCallbackListHead", le_size, 0, 0 } },
        { "bugcheckreason", { "", "nt!KeBugCheckReasonCallbackListHead", le_size, 0, 0 } },
        { "bugcheckaddpages", { "", "nt!KeBugCheckAddPagesCallbackListHead", le_size, 0, 0 } },
        { "bugcheckaddremovepages", { "", "nt!KeBugCheckAddRemovePagesCallbackListHead", le_size, 0, 0 } },
        { "powersetting", { "", "nt!PopRegisteredPowerSettingCallbacks", GetPowerCallbackItemFunctionOffset(), 0, 0 } },
        { "kdppower", { "", "nt!KdpPowerListHead", le_size, 0, 0 } },
        { "callbackdir", {} },
        { "shutdown", { "", "nt!IopNotifyShutdownQueueHead", 0, 0, 0 } },
        { "shutdownlast", { "", "nt!IopNotifyLastChanceShutdownQueueHead", 0, 0, 0 } },
        { "drvreinit", { "", "nt!IopDriverReinitializeQueueHead", le_size + m_PtrSize, 0, 0 } },
        { "bootdrvreinit", { "", "nt!IopBootDriverReinitializeQueueHead", le_size + m_PtrSize, 0, 0 } },
        { "fschange", { "", "nt!IopFsNotifyChangeQueueHead", le_size + m_PtrSize, 0, 0 } },
        { "nmi", { "", "nt!KiNmiCallbackListHead", m_PtrSize, 0, 0 } },
        { "logonsessionroutine", { "", "nt!SeFileSystemNotifyRoutinesHead", m_PtrSize, 0, 0 } },
        { "prioritycallback", { "nt!IopUpdatePriorityCallbackRoutineCount", "nt!IopUpdatePriorityCallbackRoutine", 0,
          0, 0 } },
        { "pnp", {} },
        { "lego", { "", "nt!PspLegoNotifyRoutine", 0, 0, 0 } },
        { "debugprint", { "", "nt!RtlpDebugPrintCallbackList", le_size, 0, 0 } },
        { "alpcplog", { "", "nt!AlpcpLogCallbackListHead", le_size, 0, 0 } },
        { "empcb", { "", "nt!EmpCallbackListHead", GetTypeSize("nt!_GUID"), 0, 0 } },
        { "ioperf", { "", "nt!IopPerfIoTrackingListHead", le_size, 0, 0 } },
        { "dbgklkmd", { "", "nt!DbgkLkmdCallbackArray", 0, 0, 0 } },
        { "ioptimer", { "", "nt!IopTimerQueueHead", timer_routine_offset, 0, 0 } } } };

    for ( auto &cb_pair : m_system_cb_commands ) {
        uint64_t offset_count = 0ULL;
        uint64_t offset_head = 0ULL;

        if ( !cb_pair.second.list_count_name.empty() ) {
            if ( m_sym_cache->GetSymbolOffset(cb_pair.second.list_count_name, true, &offset_count) )
                cb_pair.second.list_count_address = offset_count;
        }

        if ( !cb_pair.second.list_head_name.empty() ) {
            if ( m_sym_cache->GetSymbolOffset(cb_pair.second.list_head_name, true, &offset_head) )
                cb_pair.second.list_head_address = offset_head;
        }
    }
}
Example #3
0
std::vector<ModuleInfo> GetLoadedModules()
{
	std::vector<ModuleInfo> info;
	ULONG cb;
	ULONG64 pebAddress = GetPebAddress();
	if (IsTarget64())
	{
		ULONG64 ldr;
		if (GetFieldValue(pebAddress, "ntdll!_PEB", "Ldr", ldr) != 0)
		{
			dprintf("read Ldr failed\n");
			goto ERROR_EXIT;
		}

		ULONG offset;
		if (GetFieldOffset("ntdll!_PEB_LDR_DATA", "InMemoryOrderModuleList", &offset) != 0)
		{
			dprintf("GetFieldOffset(_PEB_LDR_DATA::InMemoryOrderModuleList) failed\n");
			goto ERROR_EXIT;
		}
		ULONG64 headAddress = ldr + offset;
		LIST_ENTRY64 inMemoryOrderModuleList;
		if (GetFieldValue(ldr, "ntdll!_PEB_LDR_DATA", "InMemoryOrderModuleList", inMemoryOrderModuleList) != 0)
		{
			dprintf("read InMemoryOrderModuleList failed\n");
			goto ERROR_EXIT;
		}

		LIST_ENTRY64 entry = inMemoryOrderModuleList;
		while (entry.Flink != headAddress)
		{
			ModuleInfo moduleInfo;
			ULONG64 address = entry.Flink;
			if (!READMEMORY(address, entry))
			{
				dprintf("read entry at %p failed\n", address);
				goto ERROR_EXIT;
			}

			// LDR_DATA_TABLE_ENTRY at address - sizeof(entry)
			ULONG64 dllBase, sizeOfImage;
			if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "DllBase", dllBase) != 0)
			{
				dprintf("read DllBase around %p failed\n", address - sizeof(entry));
				goto ERROR_EXIT;
			}
			moduleInfo.DllBase = dllBase;
			if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "SizeOfImage", sizeOfImage) != 0)
			{
				dprintf("read SizeOfImage around %p failed\n", address - sizeof(entry));
				goto ERROR_EXIT;
			}
			moduleInfo.SizeOfImage = sizeOfImage;

			// UNICODE_STRING
			struct
			{
				USHORT Length;
				USHORT MaximumLength;
				ULONG64 Buffer;
			} fullDllName;
			if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "FullDllName", fullDllName) != 0)
			{
				dprintf("read FullDllName around %p failed\n", address - sizeof(entry));
				goto ERROR_EXIT;
			}
			std::vector<wchar_t> unicode;
			unicode.resize(fullDllName.Length / sizeof(wchar_t));
			if (!ReadMemory(fullDllName.Buffer, &unicode[0], fullDllName.Length, &cb) || cb != fullDllName.Length)
			{
				dprintf("read unicode at %p %d failed\n", fullDllName.Buffer, (int)fullDllName.Length);
				goto ERROR_EXIT;
			}
		
			int written = WideCharToMultiByte(CP_ACP, 0, &unicode[0], fullDllName.Length / sizeof(wchar_t),
				moduleInfo.FullDllName, sizeof(moduleInfo.FullDllName), NULL, NULL);
			if (written < 0 || written >= sizeof(moduleInfo.FullDllName))
			{
				dprintf("WideCharToMultiByte returns %d\n", written);
				goto ERROR_EXIT;
			}
			moduleInfo.FullDllName[written] = '\0';
			info.push_back(moduleInfo);
		}
		return info;
	}
	else
	{
		ULONG32 ldr;
		if (!READMEMORY(pebAddress + 0xc, ldr))
		{
			dprintf("read Ldr failed\n");
			goto ERROR_EXIT;
		}

		ULONG64 headAddress = ldr + 0x14;
		LIST_ENTRY32 inMemoryOrderModuleList;
		if (!READMEMORY(headAddress, inMemoryOrderModuleList))
		{
			dprintf("read InMemoryOrderModuleList failed\n");
			goto ERROR_EXIT;
		}

		LIST_ENTRY32 entry = inMemoryOrderModuleList;
		while (entry.Flink != headAddress)
		{
			ModuleInfo moduleInfo;
			ULONG64 address = entry.Flink;
			if (!READMEMORY(address, entry))
			{
				dprintf("read entry at %p failed\n", address);
				goto ERROR_EXIT;
			}

			// LDR_DATA_TABLE_ENTRY at address - sizeof(entry)
			ULONG32 dllBase, sizeOfImage;
			if (!READMEMORY(address - sizeof(entry) + 0x18, dllBase))
			{
				dprintf("read DllBase at %p failed\n", address - sizeof(entry) + 0x18);
				goto ERROR_EXIT;
			}
			moduleInfo.DllBase = dllBase;
			if (!READMEMORY(address - sizeof(entry) + 0x20, sizeOfImage))
			{
				dprintf("read SizeOfImage at %p failed\n", address - sizeof(entry) + 0x20);
				goto ERROR_EXIT;
			}
			moduleInfo.SizeOfImage = sizeOfImage;

			// UNICODE_STRING
			struct
			{
				USHORT Length;
				USHORT MaximumLength;
				ULONG32 Buffer;
			} fullDllName;
			if (!READMEMORY(address - sizeof(entry) + 0x24, fullDllName))
			{
				dprintf("read FullDllName at %p failed\n", address - sizeof(entry) + 0x24);
				goto ERROR_EXIT;
			}
			std::vector<wchar_t> unicode;
			unicode.resize(fullDllName.Length / sizeof(wchar_t));
			if (!ReadMemory(fullDllName.Buffer, &unicode[0], fullDllName.Length, &cb) || cb != fullDllName.Length)
			{
				dprintf("read unicode at %p %d failed\n", (ULONG64)fullDllName.Buffer, (int)fullDllName.Length);
				goto ERROR_EXIT;
			}
		
			int written = WideCharToMultiByte(CP_ACP, 0, &unicode[0], fullDllName.Length / sizeof(wchar_t),
				moduleInfo.FullDllName, sizeof(moduleInfo.FullDllName), NULL, NULL);
			if (written < 0 || written >= sizeof(moduleInfo.FullDllName))
			{
				dprintf("WideCharToMultiByte returns %d\n", written);
				goto ERROR_EXIT;
			}
			moduleInfo.FullDllName[written] = '\0';
			info.push_back(moduleInfo);
		}
		return info;
	}

ERROR_EXIT:
	info.clear();
	return info;
}
Example #4
0
BOOLEAN
ObReadObject(
    _In_ ULONG64 Object,
    _Out_ PHANDLE_OBJECT HandleObj
)
/*++

Routine Description:

    Description.

Arguments:

    Object - 
    HandleObj - 

Return Value:

    BOOLEAN.

--*/
{
    BOOLEAN Result = FALSE;
    LPWSTR ObjName = NULL;

    ULONG BodyOffset = 0;
    GetFieldOffset("nt!_OBJECT_HEADER", "Body", &BodyOffset);

    WCHAR TypeStr[64] = { 0 };

    if ((!Object) || (!IsValid(Object))) return FALSE;

    if (!ObTypeInit)
    {
        ObjTypeTable = ExtRemoteTyped("(nt!_OBJECT_TYPE **)@$extin", GetExpression("nt!ObTypeIndexTable"));
        ObTypeInit = TRUE;
    }

    ULONG64 ObjHeaderAddr = Object - BodyOffset;

    if (!IsValid(ObjHeaderAddr)) return FALSE;

    ExtRemoteTyped ObjHeader("(nt!_OBJECT_HEADER *)@$extin", ObjHeaderAddr);
    HandleObj->ObjectPtr = Object; // ObjHeader.Field("Body").GetPointerTo().GetPtr();

    if (ObjHeader.HasField("TypeIndex"))
    {
        HandleObj->ObjectTypeIndex = ObjHeader.Field("TypeIndex").GetChar();
        if ((HandleObj->ObjectTypeIndex <= 1) || (HandleObj->ObjectTypeIndex >= 45)) return FALSE;

        ExtRemoteTypedEx::GetUnicodeString(ObjTypeTable.ArrayElement(HandleObj->ObjectTypeIndex).Field("Name"), TypeStr, sizeof(TypeStr));
        wcscpy_s(HandleObj->Type, TypeStr);
    }
    else
    {
        if (!IsValid(ObjHeader.Field("Type").GetPtr())) goto CleanUp;

        ExtRemoteTypedEx::GetUnicodeString(ObjHeader.Field("Type").Field("Name"), TypeStr, sizeof(TypeStr));
        wcscpy_s(HandleObj->Type, TypeStr);
    }

    if (_wcsicmp(TypeStr, L"File") == 0)
    {
        ExtRemoteTyped FileObject("(nt!_FILE_OBJECT *)@$extin", HandleObj->ObjectPtr);
        ObjName = ExtRemoteTypedEx::GetUnicodeString2(FileObject.Field("FileName"));
    }
    else if (_wcsicmp(TypeStr, L"Driver") == 0)
    {
        ExtRemoteTyped DrvObject("(nt!_DRIVER_OBJECT *)@$extin", HandleObj->ObjectPtr);
        ObjName = ExtRemoteTypedEx::GetUnicodeString2(DrvObject.Field("DriverName"));
    }
    else if (_wcsicmp(TypeStr, L"Process") == 0)
    {
        ExtRemoteTyped ProcessObj("(nt!_EPROCESS *)@$extin", HandleObj->ObjectPtr);
        ObjName = ExtRemoteTypedEx::GetUnicodeString2(ProcessObj.Field("ImageFileName"));
    }
    else if (_wcsicmp(TypeStr, L"ALPC Port") == 0)
    {
        // dt nt!_ALPC_PORT
    }
    else if (_wcsicmp(TypeStr, L"EtwRegistration") == 0)
    {
        // dt nt!_ETW_?
    }
    else if (_wcsicmp(TypeStr, L"Thread") == 0)
    {
        // dt nt!_ETHREAD
    }
    else if (_wcsicmp(TypeStr, L"Event") == 0)
    {
        // dt nt!_KTHREAD
    }
    else if (_wcsicmp(TypeStr, L"Key") == 0)
    {
        ExtRemoteTyped KeyObject("(nt!_CM_KEY_BODY *)@$extin", HandleObj->ObjectPtr);
        HandleObj->ObjectKcb = KeyObject.Field("KeyControlBlock").GetPtr();
        ObjName = RegGetKeyName(KeyObject.Field("KeyControlBlock"));
        // dt nt!_CM_KEY_BODY -> nt!_CM_KEY_CONTROL_BLOCK
    }
    else
    {
        ULONG Offset = 0;
        UCHAR InfoMask = 0;

        if (ObjHeader.HasField("InfoMask"))
        {
            InfoMask = ObjHeader.Field("InfoMask").GetUchar();

            if (InfoMask & OBP_NAME_INFO_BIT)
            {
                if (InfoMask & OBP_CREATOR_INFO_BIT) Offset += GetTypeSize("nt!_OBJECT_HEADER_CREATOR_INFO");
                Offset += GetTypeSize("nt!_OBJECT_HEADER_NAME_INFO");
            }
        }
        else
        {
            Offset = ObjHeader.Field("NameInfoOffset").GetUchar();
        }

        if (Offset)
        {
            ExtRemoteTyped ObjNameInfo("(nt!_OBJECT_HEADER_NAME_INFO *)@$extin", ObjHeaderAddr - Offset);
            ObjName = ExtRemoteTypedEx::GetUnicodeString2(ObjNameInfo.Field("Name"));
        }
    }

    if (ObjName)
    {
        wcscpy_s(HandleObj->Name, ObjName);
        free(ObjName);
        ObjName = NULL;
    }

    Result = TRUE;
CleanUp:
    return Result;
}
			size_t GetFieldRuntimeOffset() const	{ return GetFieldOffset() - m_state.fields_debug_bytes; }
Example #6
0
BOOLEAN
ObReadObject(
    _In_ ULONG64 Object,
    _Out_ PHANDLE_OBJECT HandleObj
)
/*++

Routine Description:

    Description.

Arguments:

    Object - 
    HandleObj - 

Return Value:

    BOOLEAN.

--*/
{
    BOOLEAN Result = FALSE;
    PWSTR ObjectName = NULL;
    WCHAR TypeStr[64] = {0};
    ULONG BodyOffset = 0;

    GetFieldOffset("nt!_OBJECT_HEADER", "Body", &BodyOffset);

    try {

        ZeroMemory(HandleObj, sizeof(HANDLE_OBJECT));

        if ((!Object) || (!IsValid(Object))) return FALSE;

        if (!ObTypeInit)
        {
            ObjTypeTable = ExtRemoteTyped("(nt!_OBJECT_TYPE **)@$extin", ObTypeIndexTableAddress);
            ObTypeInit = TRUE;
        }

        ULONG64 ObjHeaderAddr = Object - BodyOffset;

        if (!IsValid(ObjHeaderAddr)) return FALSE;

        ExtRemoteTyped ObjHeader("(nt!_OBJECT_HEADER *)@$extin", ObjHeaderAddr);
        HandleObj->ObjectPtr = Object; // ObjHeader.Field("Body").GetPointerTo().GetPtr();

        if (ObjHeader.HasField("TypeIndex"))
        {
            BYTE HeaderCookie;

            HandleObj->ObjectTypeIndex = ObjHeader.Field("TypeIndex").GetUchar();

            if (g_Ext->m_Data->ReadVirtual(ObHeaderCookieAddress, &HeaderCookie, sizeof(HeaderCookie), NULL) == S_OK) {

                HandleObj->ObjectTypeIndex = (((ObjHeaderAddr >> 8) & 0xff) ^ HandleObj->ObjectTypeIndex) ^ HeaderCookie;
            }

            ExtRemoteTypedEx::GetUnicodeString(ObjTypeTable.ArrayElement(HandleObj->ObjectTypeIndex).Field("Name"), TypeStr, sizeof(TypeStr));

            StringCchCopyW(HandleObj->Type, _countof(HandleObj->Type), TypeStr);
        }