Exemple #1
0
std::pair<HRESULT, std::string> UnicodeStringStructToString(const ExtRemoteTyped &unicode_string) {
    std::string output_string = "";

    try {
        ExtRemoteTyped loc_unicode_string = unicode_string;
        ExtRemoteTyped buffer = *loc_unicode_string.Field("Buffer");
        uint16_t len = loc_unicode_string.Field("Length").GetUshort();
        uint16_t maxlen = loc_unicode_string.Field("MaximumLength").GetUshort();

        if ( len == 0 && maxlen == 1 ) {
            return std::make_pair(S_OK, output_string);
        }

        if ( maxlen >= sizeof(wchar_t) && (maxlen % sizeof(wchar_t) == 0) ) {
            uint16_t max_len_wide = maxlen / sizeof(wchar_t) + 1;

            std::unique_ptr<wchar_t[]> test_name(new wchar_t[max_len_wide]);
            std::memset(test_name.get(), 0, max_len_wide * sizeof(wchar_t));

            uint32_t read = buffer.ReadBuffer(test_name.get(), maxlen, true);

            if ( read == maxlen )
                output_string = wstring_to_string(test_name.get());

            return std::make_pair(S_OK, output_string);
        }
    } catch ( const ExtRemoteException &Ex ) {
        std::stringstream locerr;

        locerr << wa::showminus << __FUNCTION__ << ": " << Ex.GetMessage() << wa::endlerr;
        return std::make_pair(Ex.GetStatus(), output_string);
    }

    return std::make_pair(E_INVALIDARG, output_string);
}
Exemple #2
0
vector<HANDLE_OBJECT>
ObOpenObjectDirectory(
    _In_ ULONG64 InputObject
)
/*++

Routine Description:

    Description.

Arguments:

    InputObject - 

Return Value:

    vector<HANDLE_OBJECT>.

--*/
{
    vector<HANDLE_OBJECT> Handles;
    HANDLE_OBJECT Handle = { 0 };
    ExtRemoteTyped Directory;

    ULONG64 ObjectDir = InputObject;

    if (!ObjectDir)
    {
        ReadPointer(GetExpression("nt!ObpRootDirectoryObject"), &ObjectDir);
    }

    Directory = ExtRemoteTyped("(nt!_OBJECT_DIRECTORY *)@$extin", ObjectDir);

    ObReadObject(ObjectDir, &Handle);

    for (UINT i = 0; i < 37; i += 1)
    {
        ULONG64 Entry = Directory.Field("HashBuckets").ArrayElement(i).GetPointerTo().GetPtr();
        if (!Entry) continue;

        //
        // ExtRemoteTypedList requires a POINTER to the first entry. Not the offset of the first entry.
        //
        ExtRemoteTypedList EntryList(Entry, "nt!_OBJECT_DIRECTORY_ENTRY", "ChainLink");

        for (EntryList.StartHead(); EntryList.HasNode(); EntryList.Next())
        {
            HANDLE_OBJECT Handle = {0};

            ULONG64 Object = EntryList.GetTypedNode().Field("Object").GetPtr();
            ObReadObject(Object, &Handle);

            Handles.push_back(Handle);
        }
    }

    return Handles;
}
Exemple #3
0
void WDbgArk::WalkDirectoryObject(const uint64_t directory_address,
                                  void* context,
                                  RemoteTypedCallback callback) {
    if ( !directory_address ) {
        err << wa::showminus << __FUNCTION__ << ": invalid directory address" << endlerr;
        return;
    }

    if ( !callback ) {
        err << wa::showminus << __FUNCTION__ << ": invalid callback address" << endlerr;
        return;
    }

    try {
        ExtRemoteTyped directory_object("nt!_OBJECT_DIRECTORY", directory_address, false, NULL, NULL);
        ExtRemoteTyped buckets = directory_object.Field("HashBuckets");

        int64_t num_buckets = buckets.GetTypeSize() / m_PtrSize;

        for ( int64_t i = 0; i < num_buckets; i++ ) {
            for ( ExtRemoteTyped directory_entry = *buckets[i];
                  directory_entry.m_Offset;
                  directory_entry = *directory_entry.Field("ChainLink") ) {
                ExtRemoteTyped object = *directory_entry.Field("Object");

                if ( !SUCCEEDED(callback(this, object, context)) ) {
                    err << wa::showminus << __FUNCTION__ << ": error while invoking callback" << endlerr;
                    return;
                }
            }
        }
    }
    catch ( const ExtRemoteException &Ex ) {
        err << wa::showminus << __FUNCTION__ << ": " << Ex.GetMessage() << endlerr;
    }
}
Exemple #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;
}
Exemple #5
0
BOOLEAN
PEFile::InitImage(
)
/*++

Routine Description:

    Description.

Arguments:

    - 

Return Value:

    BOOLEAN.

--*/
{
    PIMAGE_DOS_HEADER Header = NULL;
    PVOID Image = NULL;
    ULONG BytesRead = 0;
    ULONG64 BaseImageAddress = m_ImageBase;

    PIMAGE_NT_HEADERS32 NtHeader32 = NULL;
    PIMAGE_NT_HEADERS64 NtHeader64 = NULL;

    PIMAGE_DATA_DIRECTORY DataDirectory = NULL;
    ExtRemoteTyped BaseImage;

    BOOLEAN Result = FALSE;
    ULONG64 ProcessDataOffset = 0ULL;

    if (m_Image.Initialized)
    {
        // g_Ext->Dml("b_Initialized already set to TRUE\n");
        Result = TRUE;
        goto CleanUp;
    }

    if (!m_ImageSize)
    {
        Header = (PIMAGE_DOS_HEADER)malloc(PAGE_SIZE);
        if (Header == NULL) goto CleanUp;
        RtlZeroMemory(Header, PAGE_SIZE);

        if (g_Ext->m_Data->ReadVirtual(BaseImageAddress, Header, PAGE_SIZE, &BytesRead) != S_OK)
        {
#if VERBOSE_MODE
            g_Ext->Dml("Error: Can't read 0x%I64x bytes at %I64x.\n", PAGE_SIZE, BaseImageAddress);
#endif
            goto CleanUp;
        }

        BaseImage = ExtRemoteTyped("(nt!_IMAGE_DOS_HEADER *)@$extin", BaseImageAddress);
        if (BaseImage.Field("e_magic").GetUshort() != IMAGE_DOS_SIGNATURE) goto CleanUp;

        NtHeader32 = (PIMAGE_NT_HEADERS32)((PUCHAR)Header + BaseImage.Field("e_lfanew").GetUlong());

        if (NtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
        {
            m_ImageSize = NtHeader32->OptionalHeader.SizeOfImage;
        }
        else if (NtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
        {
            NtHeader64 = (PIMAGE_NT_HEADERS64)NtHeader32;
            NtHeader32 = NULL;
            m_ImageSize = NtHeader64->OptionalHeader.SizeOfImage;;
        }
        else
        {
#if VERBOSE_MODE
            g_Ext->Dml("Error: Invalid signature.\n");
#endif
            goto CleanUp;
        }
    }

    Image = malloc(m_ImageSize);
    if (Image == NULL) goto CleanUp;
    RtlZeroMemory(Image, (ULONG)m_ImageSize);

    if (ExtRemoteTypedEx::ReadVirtual(BaseImageAddress, Image, (ULONG)m_ImageSize, &BytesRead) != S_OK)
    {
#if VERBOSE_MODE
        g_Ext->Dml("Error: Can't read 0x%I64x bytes at %I64x.\n", m_ImageSize, BaseImageAddress);
#endif
        goto CleanUp;
    }

    m_Image.Image = (PIMAGE_DOS_HEADER)Image;
    REF_POINTER(m_Image.Image);

    m_Image.NtHeader32 = (PIMAGE_NT_HEADERS32)((PUCHAR)Image + m_Image.Image->e_lfanew);
    NtHeader32 = m_Image.NtHeader32;

    if (NtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
    {
        m_Image.NtHeader32 = NULL;
        m_Image.NtHeader64 = (PIMAGE_NT_HEADERS64)((PUCHAR)Image + m_Image.Image->e_lfanew);
        m_Image.DataDirectory = (PIMAGE_DATA_DIRECTORY)m_Image.NtHeader64->OptionalHeader.DataDirectory;
        m_Image.Sections = (PIMAGE_SECTION_HEADER)(m_Image.NtHeader64 + 1);

        m_Image.NumberOfSections = m_Image.NtHeader64->FileHeader.NumberOfSections;
    }
    else if (NtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
    {
        m_Image.NtHeader64 = NULL;
        m_Image.DataDirectory = (PIMAGE_DATA_DIRECTORY)m_Image.NtHeader32->OptionalHeader.DataDirectory;
        m_Image.Sections = (PIMAGE_SECTION_HEADER)(m_Image.NtHeader32 + 1);
        m_Image.NumberOfSections = m_Image.NtHeader32->FileHeader.NumberOfSections;
    }
    else
    {
        goto CleanUp;
    }

#if VERBOSE_MODE
    g_Ext->Dml("m_Image = %p\n"
        "m_NtHeader32 = %p\n"
        "m_DataDirectory = %p\n"
        "m_Sections = %p\n", m_Image.Image, m_Image.NtHeader32, m_Image.DataDirectory, m_Image.Sections);

    g_Ext->Dml("m_NumberOfSections = %x\n", m_Image.NumberOfSections);
#endif

    Result = TRUE;

CleanUp:
    if (Header) free(Header);

    m_Image.Initialized = Result;

    return Result;
}
Exemple #6
0
ExtRemoteTyped
GetKeyNode(
    _In_ PWSTR FullKeyPath
    )
{
    ULONG64 CmpMasterHive;
    ULONG64 CmpRegistryRootObject;
    ExtRemoteTyped KeyNode;

    try {

        ReadPointer(CmpMasterHiveAddress, &CmpMasterHive);
        ReadPointer(CmpRegistryRootObjectAddress, &CmpRegistryRootObject);

        ExtRemoteTyped KeyHive("(nt!_HHIVE *)@$extin", CmpMasterHive);
        ExtRemoteTyped KeyBody("(nt!_CM_KEY_BODY *)@$extin", CmpRegistryRootObject);
        ExtRemoteTyped KeyControlBlock("(nt!_CM_KEY_CONTROL_BLOCK *)@$extin", KeyBody.Field("KeyControlBlock").GetPtr());

        ULONG KeyCell = KeyControlBlock.Field("KeyCell").GetUlong();

        KeyNode = ExtRemoteTyped("(nt!_CM_KEY_NODE *)@$extin", RegGetCellPaged(KeyHive, KeyCell));

        vector<KEY_NAME> KeysNames = GetKeysNames(FullKeyPath);

        for (size_t i = 1; i < KeysNames.size(); i++) {

            BOOL IsFound = FALSE;

            vector<KEY_NODE> SubKeys = GetSubKeys(KeyHive, KeyNode);

            for (size_t j = 0; j < SubKeys.size(); j++) {

                if (0 == _wcsicmp(KeysNames[i].Name, SubKeys[j].Name)) {

                    KeyNode = SubKeys[j].KeyNode;

                    if (KeyNode.Field("Signature").GetUshort() == CM_LINK_NODE_SIGNATURE) {

                        KeyHive = ExtRemoteTyped("(nt!_HHIVE *)@$extin", KeyNode.Field("ChildHiveReference.KeyHive").GetPtr());
                        KeyCell = KeyNode.Field("ChildHiveReference.KeyCell").GetUlong();
                        KeyNode = ExtRemoteTyped("(nt!_CM_KEY_NODE *)@$extin", RegGetCellPaged(KeyHive, KeyCell));
                    }

                    IsFound = TRUE;
                    break;
                }
            }

            if (!IsFound) {

                KeyNode = ExtRemoteTyped("(nt!_CM_KEY_NODE *)@$extin", NULL);
                break;
            }
        }
    }
    catch (...) {

    }

    return KeyNode;
}
Exemple #7
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);
        }