Получение пути к файлу с помощью ntquery, но не получение полного пути - PullRequest
0 голосов
/ 03 июля 2019

Я создал этот ужасный кусок кода, чтобы узнать путь воспроизведения песен в Windows.Предполагалось, что это обычный программный продукт, поэтому я хотел, чтобы он работал с несколькими программами.Сначала я использовал handle.exe для запроса дескрипторов, открытых, скажем, foobar2000 или vlc или itunes, что бы ни проигрывало аудиофайл на самом деле.Здорово, что это сработало бы, выглядело бы что-то вроде этого:

\Device\HarddiskVolume2\Music\Mamorukun Curse OST\Mamoru-kun has been Cursed Meikai Katsugeki Arrange\02 Blossom Shower [MEIKAI ARRANGE VERSION].flac

Но в тот момент, когда я проигрывал песню с Unicode, все это ломалось и не работало.Поэтому я создал этот фрагмент кода, откуда бы ни добавлялся код, написанный кем-то еще давным-давно.Он запустился, и я получил его, чтобы выплевывать тот же тип вывода, но теперь он делает то же самое с символами Юникода.

Не совсем уверен, как бы я поделился этим в маленьких фрагментах, поэтому я собираюсьсвалить весь проект.Пожалуйста, помните, что этот код действительно плох и смущает, не будучи экспертом в C ++ или Windows API и тому подобном.

#include "Main.h"
#include <Windows.h>
#include <fstream>

PVOID GetLibraryProcAddress(LPCWSTR LibraryName, LPCSTR ProcName)
{

    return GetProcAddress(LoadLibrary(LibraryName), ProcName);
}

std::string getFileType(PWSTR buffer, USHORT length) {
    char* temp = new char[length];

    for (int i = 0; i < length; i++) {
        temp[i] = (char)buffer[i];
    }
    return temp;
}

int main(int argc, WCHAR *argv[])
{
    std::wofstream file("example.txt");

    _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
        GetLibraryProcAddress(L"ntdll.dll", "NtQuerySystemInformation");
    _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)
        GetLibraryProcAddress(L"ntdll.dll", "NtDuplicateObject");
    _NtQueryObject NtQueryObject = (_NtQueryObject)
        GetLibraryProcAddress(L"ntdll.dll", "NtQueryObject");

    NTSTATUS status;
    PSYSTEM_HANDLE_INFORMATION handleInfo;
    ULONG handleInfoSize = 0x10000;
    ULONG pid;
    HANDLE processHandle;
    ULONG i;

        // I'm entering the pid of foobar here.
    pid = 17304;

    if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
    {
        printf("Could not open PID %d! (Don't try to open a system process.)\n", pid);
        return 1;
    }

    handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

    while ((status = NtQuerySystemInformation(
        SystemHandleInformation,
        handleInfo,
        handleInfoSize,
        NULL
    )) == STATUS_INFO_LENGTH_MISMATCH)
        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

    if (!NT_SUCCESS(status))
        return 1;

    for (i = 0; i < handleInfo->HandleCount; i++)
    {
        SYSTEM_HANDLE handle = handleInfo->Handles[i];
        HANDLE dupHandle = NULL;
        POBJECT_TYPE_INFORMATION objectTypeInfo;
        PVOID objectNameInfo;
        UNICODE_STRING objectName;
        ULONG returnLength;

        if (handle.ProcessId != pid)
            continue;

        if (!NT_SUCCESS(NtDuplicateObject(
            processHandle,
            handle.Handle,
            GetCurrentProcess(),
            &dupHandle,
            0,
            0,
            0
        )))
        {
            continue;
        }

        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectTypeInformation,
            objectTypeInfo,
            0x1000,
            NULL
        )))
        {
            CloseHandle(dupHandle);
            continue;
        }

        /* Query the object name (unless it has an access of
           0x0012019f, on which NtQueryObject could hang. 
        if (handle.GrantedAccess == 0x0012019f)
        {
            free(objectTypeInfo);
            CloseHandle(dupHandle);
            continue;
        }

        */

        objectNameInfo = malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectNameInformation,
            objectNameInfo,
            0x1000,
            &returnLength
        )))
        {
            /* Reallocate the buffer and try again. 
            objectNameInfo = realloc(objectNameInfo, returnLength);
            if (!NT_SUCCESS(NtQueryObject(
                dupHandle,
                ObjectNameInformation,
                objectNameInfo,
                returnLength,
                NULL
            )))
            {
                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
                continue;
            }*/
        }

Большая часть того, что я пытаюсь сделать, содержится здесь внизу и имеет делос objectname.Buffer, но я ожидаю, что проблема будет исходить из приведенного выше кода, который в значительной степени волшебен для меня.

        /* Cast our buffer into an UNICODE_STRING. */
        objectName = *(PUNICODE_STRING)objectNameInfo;

        /* Print the information! */

        // looking for audio files.
        std::string format[4] = { ".flac",".mp3",".ogg",".wav"};

        if (objectName.Length)
        {
            //get handle type. looking for 'File'
            std::string type = getFileType(objectTypeInfo->Name.Buffer, objectTypeInfo->Name.Length / 2);

            // Check to see if this Handle is a file type.
            if (!type.find("File")) {

                int count;

                // loop through format array.
                for (const std::string & word : format) {

                    // loop through format word one letter at a time.
                    count = 0;
                    for (int i = 0; i < word.length(); i++) {

                        char bChar = objectName.Buffer[(objectName.Length / 2)-word.length()+i];
                        // if format word char matches bChar count++ until count == word.length;
                        if (word.at(i) == bChar) {
                            count++;
                        }
                        else {
                            break;
                        }
                    }
                    // Write the matching word to file.
                    if (count == word.length()) {
                        printf("\nFile Pulled, %ls\n\n", objectName.Buffer);
                        file << objectName.Buffer;
                        break;
                    }       
                }
            }   
        }
        free(objectTypeInfo);
        free(objectNameInfo);
        CloseHandle(dupHandle);
    }

    free(handleInfo);
    CloseHandle(processHandle);
    file.close();
    return 0;
}

Я заставил его выплюнуть

\Device\HarddiskVolume2\Music\Yonder Voice\Wonderful View Epilogue\04. ΓRⁿ[Γ∩ΓhΓXΓΦⁿ[Γpⁿ[.flac 

, которыйЭто своего рода сюрприз, но в большинстве случаев он выплевывает что-то вроде

\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice -

Как будто он мгновенно попадает в символ Unicode, он обрезает все перед ним.

Ожидаетсявывод будет выглядеть так:

\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice - 秘封活動記録 -月- ORIGINAL SOUNDTRACK\01. 決別の旅(TV-Size).mp3

Сейчас ожидаемый вывод выглядит как

\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice -

Хотя информация все еще должна быть в буфере, потому что она читает .mp3 для печатичтобы я смог увидеть.

Надеюсь, я достаточно хорошо объяснил свою проблему, она стала довольно нишевой в некоторых отношениях, никогда не ожидал, что что-то настолько простое, чтобы идти по этому пути головных болейи растерянность.

...