libpeconv icon indicating copy to clipboard operation
libpeconv copied to clipboard

[feature request] Add WinAPI/NTAPI wrapper

Open Kanerudaisuki opened this issue 5 months ago • 1 comments

Is it possible to create a wrapper for WinAPI/NTAPI and similar interfaces so that they can be replaced with custom implementations, such as using syscalls or extending support to kernel-mode drivers?

like:

    bool is_pointer_in_ntdll(LPVOID lpAddress)
    {
        HMODULE mod = peconv::get_module_via_peb(L"ntdll.dll");
        size_t module_size = peconv::get_module_size_via_peb(mod);
        if (peconv::validate_ptr(mod, module_size, lpAddress, sizeof(BYTE))) {
            return true; //this address lies within NTDLL
        }
        return false;
    }
    bool is_pointer_in_ntdll(LPVOID lpAddress)
    {
        HMODULE mod = peconv::get_module_via_peb(L"ntdll.dll");
        size_t module_size = peconv::get_module_size_via_peb(mod);
        if (peconv::validate_ptr(mod, module_size, lpAddress, sizeof(BYTE))) {
            return true; //this address lies within NTDLL
        }
        return false;
    }
    HMODULE get_ntdll_hndl()
    {
        if (g_ntdllHndl == nullptr) {
            g_ntdllHndl = LoadLibraryA("ntdll.dll");
        }
        return g_ntdllHndl;
    }
    SIZE_T _search_readable_size(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T minimal_size)
    {
        if (!buffer || buffer_size == 0) {
            return 0;
        }
        if ((buffer_size < minimal_size) || minimal_size == 0) {
            return 0;
        }
        SIZE_T last_failed_size = buffer_size;
        SIZE_T last_success_size = 0;

        SIZE_T test_read_size = 0;
        if (!ReadProcessMemory(processHandle, start_addr, buffer, minimal_size, &test_read_size)) {
            //cannot read even the minimal size, quit trying
            return test_read_size;
        }
        last_success_size = minimal_size;

        SIZE_T read_size = 0;
        SIZE_T to_read_size = buffer_size/2;

        while (to_read_size > minimal_size && to_read_size < buffer_size)
        {
            read_size = 0;
            if (ReadProcessMemory(processHandle, start_addr, buffer, to_read_size, &read_size)) {
                last_success_size = to_read_size;
            }
            else {
                last_failed_size = to_read_size;
            }
            const size_t delta = (last_failed_size - last_success_size) / 2;
            if (delta == 0) break;
            to_read_size = last_success_size + delta;
        }
        if (last_success_size) {
            read_size = 0;
            memset(buffer, 0, buffer_size);
            if (ReadProcessMemory(processHandle, start_addr, buffer, last_success_size, &read_size)) {
                return read_size;
            }
        }
        return 0;
    }

and VirtualProtectEx among others

All these codes are hardcoded, making it difficult to extend to kernel-mode drivers.

Thanks.

Kanerudaisuki avatar Jul 25 '25 19:07 Kanerudaisuki

Hi @Kanerudaisuki ! Yes, it is a good idea, I will add it in the future.

hasherezade avatar Jul 27 '25 20:07 hasherezade