Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to hook undocumented function #109

Closed
IvanGazul opened this issue Jan 28, 2023 · 1 comment
Closed

Unable to hook undocumented function #109

IvanGazul opened this issue Jan 28, 2023 · 1 comment

Comments

@IvanGazul
Copy link

IvanGazul commented Jan 28, 2023

I dont want to sound malicious but firtstly i wanted to hook TerminateProcess,and i hooked it (because TerminateProcess is defined in Windows.h).Recently i wanted to see how i can hook NtTerminateProcess(Undocumented function) from ntdll and it doesnt hook that,and i decided to test with my own console programm that will use NtTerminateProcess(you enter the name of the process it kills it WITH NtTerminateProcess from ntdll) and it returns me MH_ERROR_NOT_CREATED.

My code:
[Lib.dll]

#include "pch.h"
#include <MinHook.h>
#include <Windows.h>
#include <ntstatus.h>
#include <bcrypt.h>
#include <cstdio>
#include <iostream>
#include <string.h>
#include <Tlhelp32.h>
#include <tchar.h>

#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x32.lib")
#endif

using namespace std;

typedef NTSTATUS(WINAPI* OldNtTP)(HANDLE, NTSTATUS);
//NtTerminateProcess before hooking (bh)
OldNtTP bhTerminateProcess = NULL;
//NtTerminateProcess after hooking (ah)
OldNtTP ahTerminateProcess = NULL;

//Funtion that needs to find process handle by its name
HANDLE GetProcessHandleByName(const wchar_t* processName) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return nullptr;
    }

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe)) {
        CloseHandle(hSnapshot);
        return nullptr;
    }

    do {
        if (!_wcsicmp(pe.szExeFile, processName)) {
            CloseHandle(hSnapshot);
            return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
        }
    } while (Process32Next(hSnapshot, &pe));

    CloseHandle(hSnapshot);
    return nullptr;
}

typedef BOOL(WINAPI* sCompareObjectHandles)(HANDLE, HANDLE);

//For some reason NtTerminateProcess and GetProcessHandleByName have different HANDLE's
//i found a fuction in KernelBase.dll that compares 2 HANDLE's and if they are 'attached'
//to the same object it returns TRUE,very useful.
sCompareObjectHandles MyCompareObjectHandles =
(sCompareObjectHandles)GetProcAddress(GetModuleHandleA("KernelBase.dll"), "CompareObjectHandles");

NTSTATUS WINAPI hTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
    //for debuging,in some cases it shows me that
    //MH_EnableHook failed but it hooks normally
    cout << "[+] Hooked worked for some reason..";

    HANDLE my = GetProcessHandleByName(L"notepad.exe");
    //Comparing if ntTerminateProcess want to terminate my process:
    if (MyCompareObjectHandles(my, ProcessHandle)) {
        MessageBoxW(NULL, L"Hooked!", L"MinHook", NULL);
        return STATUS_ACCESS_DENIED;
    }
    return bhTerminateProcess(ProcessHandle, ExitStatus);
}

int main();
void UnHook();

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        main();
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        UnHook();
        break;
    }
    return TRUE;
}

//I tried with LoadLibrary and GetProcAddress but that didnt work too..
//HMODULE ntdll = LoadLibraryA("ntdll.dll");
//OldNtTP origNtT = (OldNtTP)GetProcAddress(ntdll, "NtTerminateProcess");

void SetHook()
{
    if (MH_Initialize() == MB_OK)
    {
        MH_CreateHookApiEx(L"ntdll","NtTerminateProcess", &hTerminateProcess, reinterpret_cast<LPVOID*>(&bhTerminateProcess), reinterpret_cast<LPVOID*>(&ahTerminateProcess));
        if((MH_EnableHook(&ahTerminateProcess) != MH_OK))
            cout << "\nFailed to hook NtTerminateProcess..\n\n";
    }
}

void UnHook()
{
    if (MH_DisableHook(&ahTerminateProcess) == MB_OK)
    {
        MH_Uninitialize();
    }
}

int main() {
    //allocating console to see how programm works.
    AllocConsole();
    FILE* fp;
    freopen_s(&fp, "CONOUT$", "w", stdout);
    //Setting hook
    cout << "Injected!";

    SetHook();

    return 0;
}

My project: https://github.com/imtheinvoker/TryHookingNtTerminateProcess

@IvanGazul
Copy link
Author

Im so stupid..If you have similar problem.If you use MH_CreateHookApiEx() do [Correct: MH_EnableHook(fucn)] [Wrong: MH_EnableHook(&func)] without '&' because we already have a link of our function using CreateHookApiEx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant