Общесистемное подключение API - PullRequest
2 голосов
/ 04 января 2011

Я должен разработать программу, которая может подключать некоторые функции в kernel32.dll, Advapi32.dll. например, я должен изменить функциональность некоторых функций, таких как RegOpenKey (). Из-за того, что я не могу ввести какой-либо код в целевой процесс, потому что, когда целевая программа запускается, сначала она вызывает эту функцию Также я вынужден не вводить какой-либо код в целевой процесс. Кроме того, я должен изменить эту функцию для каждого текущего запущенного процесса и приложения (32-разрядная, консольное приложение, приложение Win), и они будут запущены в будущем. Я прочитал много статей о внедрении DLL, перехвате DLL, но я не знаю, как это преодолеть. Поэтому, пожалуйста, помогите мне и поделитесь своими знаниями.

Ответы [ 5 ]

2 голосов
/ 04 января 2011

Единственный вариант перехвата без внедрения кода - драйвер режима ядра.Драйверы реестра легко внедрить в Vista +, но вам нужно будет перехватить реестр SSDT.SSDT не работает с одним и тем же кодом в XP и Vista / W7 и вообще не работает в среде x64 (методы перехвата не допускаются).Поэтому вам нужно сделать SSDT реестра для драйвера фильтра режима ядра для XP и CmRegisterCallback для Vista и W7 ( больше информации ).

1 голос
/ 04 января 2011

Может быть, вы можете посмотреть на Microsoft Detours .

0 голосов
/ 30 августа 2015

Как я понял из вашего описания, вы хотите изменить поведение определенного API.Однако вы не указали, хотите ли вы изменить данные, передаваемые в такой API, или просто проигнорировали запрос.В любом случае, для такого требования самое простое и простое решение - написать драйвер ядра мини-фильтра.При таком подходе вы будете использовать CmRegisterCallbackEx, а не CmRegisterCallback (так как этот устарел) для регистрации обратного вызова для фильтрации событий реестра.И тогда вы можете написать свои собственные функции обратного вызова, которые заботятся о каждом событии реестра, которое вы хотите изменить.Вот простой фрагмент о том, как написать такой драйвер ядра для мини-фильтра.Помните, что вам все еще необходимо написать логику для изменения API, просто отклоняя запрос или изменяя его содержимое.

#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>

LARGE_INTEGER g_Cookie = { 0 };

NTSTATUS DriverRegistryCallback(
    _In_ PVOID CallbackContext, 
    _In_ PVOID Argument1, 
    _In_ PVOID Argument2
    ) {
    UNREFERENCED_PARAMETER(CallbackContext);

    PREG_POST_OPERATION_INFORMATION PreInfo;
    PREG_OPEN_KEY_INFORMATION_V1 OpenKey;
    PREG_CREATE_KEY_INFORMATION_V1 CreateKey;

    REG_NOTIFY_CLASS RegOp = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1;
    switch (RegOp) {
        case RegNtPreCreateKeyEx:
            PreInfo = (PREG_POST_OPERATION_INFORMATION)Argument2;
            CreateKey = (PREG_CREATE_KEY_INFORMATION_V1)PreInfo->PreInformation;
            if (PreInfo->Status == STATUS_SUCCESS) {
                // do something here
            }
            break;

        case RegNtPreOpenKeyEx:
            PreInfo = (PREG_POST_OPERATION_INFORMATION)Argument2;
            OpenKey = (PREG_OPEN_KEY_INFORMATION_V1)PreInfo->PreInformation;
            if (PreInfo->Status == STATUS_SUCCESS) {
                // do something here
            }
            break;

        default:
            break;
    }

    return STATUS_SUCCESS;
}

VOID 
DriverUnload(
    _In_ PDRIVER_OBJECT pDriverObject
    ) {
    UNREFERENCED_PARAMETER(pDriverObject);

    PAGED_CODE();

    NTSTATUS status = CmUnRegisterCallback(g_Cookie);
    if (!NT_SUCCESS(status)) {
        DbgPrint("[RegistryFilter] Failed to unregister callback\n");
    }

    DbgPrint("[RegistryFilter] Driver unloaded successfully\n");
}

NTSTATUS 
DriverEntry(
    _In_ PDRIVER_OBJECT pDriverObject, 
    _In_ PUNICODE_STRING pRegistryPath
    ) {
    UNREFERENCED_PARAMETER(pRegistryPath);

    pDriverObject->DriverUnload = DriverUnload;

    UNICODE_STRING AltitudeString = RTL_CONSTANT_STRING(L"360000");
    NTSTATUS status = CmRegisterCallbackEx(DriverRegistryCallback, &AltitudeString, pDriverObject, NULL, &g_Cookie, NULL);
    if (!NT_SUCCESS(status)) {
        DbgPrint("[RegistryFilter] Failed to register callback\n");

        return status;
    }

    DbgPrint("[RegistryFilter] Driver loaded successfully\n");

    return status;
}

Помните, что это не ваше окончательное решение.Вы должны написать свою собственную логику, как я упоминал ранее, либо для отказа в доступе к определенному вызову, сравнивая данные, возвращенные к вашим собственным статическим данным, а затем возвращая STATUS_ACCESS_DENIED, либо изменяя структуру данных, содержащую значения, и затем передавая ее обратно.Вы должны знать, что если вы хотите изменить какое-либо событие Open*, вам нужно сначала обработать событие Create*.Поскольку любому событию Open* должен предшествовать, а первым должно быть событие Create*.

Кстати, SSDT не является предпочтительным решением, поскольку индексы изменяются с версии Windows на другую и с одного пакета обновления надругой.Это ненадежно, в общем и не рекомендуется, по крайней мере, для этой простой задачи.Не говоря уже о том, что у вас могут возникнуть проблемы с его настройкой для архитектуры x64.

РЕДАКТИРОВАТЬ: я забыл упомянуть, что это будет работать только начиная с Vista +, поэтому для работы в Windows XP необходимо внести определенные изменения, какизменятся имена структуры реестра и имена событий реестра.

Вот несколько ссылок, с которых можно начать:
- CmRegisterCallbackEx (https://msdn.microsoft.com/en-us/library/windows/hardware/ff541921(v=vs.85).aspx)
- пример кода Windows WDK CmRegisterCallbackEx(https://github.com/Microsoft/Windows-driver-samples/tree/master/general/registry)

0 голосов
/ 04 января 2011

Для этого вам лучше всего выбрать Hot-Patching, это то, что MS использует самостоятельно, чтобы применить обходы всей системы, когда функции были исправлены через их систему обновления.

0 голосов
/ 04 января 2011

Для ваших нужд вы должны написать драйвер ядра, который может перехватывать требуемые вызовы, для которых вы хотите изменить (или предоставить) дополнительную функциональность. Например, если вы перехватываете вызов write, все программы, запущенные на вашем компьютере (за редким исключением, которое, я думаю, вам не стоит беспокоиться), когда когда-либо вызывает операцию write, будут вызывать вашу перехваченную функцию с соответствующей информацией о процессе вызова и некоторой другой информацией (обычно называемой данными обратного вызова). Затем вы можете делать / добавлять то, о чем вы думаете, из своей подключенной функции.

Если вы используете Windows XP SP3 и выше, вы можете использовать драйвер фильтра, поскольку его легко изучить и реализовать по сравнению с устаревшим драйвером Windows. Хотя драйверы фильтров имеют ограничения, но по вашему требованию они идеально подойдут.

...