R3下 API 挂钩监视右键管理员权限启动

1. 基本原理

以前的操作系统上,挂钩 CreateProcessInternel 即可监视进程创建,在 以管理员身份启动的时候,情况发生了变化,我们的 explorer 不再调用原来的路径,而是使用一个未被导出的函数 AicFindLaunchAdminProcess。

AicFindLaunchAdminProcess 函数定义为:

ULONG_PTR WINAPI AicFindLaunchAdminProcess(
    LPWSTR             lpApplicationName,
    LPWSTR             lpParameters,
    DWORD              UacRequestFlag,
    DWORD              dwCreationFlags,
    LPWSTR             lpCurrentDirectory,
    HWND               hWnd,
    PVOID              StartupInfo,
    PVOID              ProcessInfo,
    ELEVATION_REASON*  ElevationReason
);

我们只需要根据特征码定位该函数的入口点,并挂钩该函数,即可监视资源管理器中,那些以管理员身份启动的程序。

2.定位函数的代码

这里给出截止 Win 10,该函数的入口点定位代码:

//#include "FindLaunchAdminFunc.h"
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

//#pragma once


//disable nonmeaningful warnings.
#pragma warning(push)
//#pragma warning(disable: 4005) // macro redefinition
//#pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s
//#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
//#pragma comment(lib, "ntdll.lib")
#pragma warning(disable: 4005) // macro redefinition
#pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union

#include <windows.h>
#include <ntstatus.h>
#include <bcrypt.h>
//typedef PIMAGE_NT_HEADERS(NTAPI* RTLIMAGENTHEADER)(PVOID);
//HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
//RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader");
//
//typedef NTSTATUS(NTAPI* RTLGETVERSION)(PRTL_OSVERSIONINFOW);
//RTLGETVERSION RtlGetVersion = (RTLGETVERSION)GetProcAddress(hNtdll, "RtlGetVersion");


#define _NTDEF_
//#include <ntsecapi.h>
#undef _NTDEF_

#ifndef PAGE_SIZE
#define PAGE_SIZE 0x1000ull
#endif

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)


typedef ULONG ELEVATION_REASON;

#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1))

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
ULONG_PTR AicFindLaunchAdminProcess(
	_Out_ PNTSTATUS StatusCode);

#define SUCCESS                     0L
#define FAILURE_NULL_ARGUMENT       1L
#define FAILURE_API_CALL            2L
#define FAILURE_INSUFFICIENT_BUFFER 3L
#define MAX_PATH_LEN 260
#define MAX_ARGS_LEN 32768
#define UNICODE

// 下面是 FindLaunchAdminFunc.cpp


#define SHELL32_DLL                 L"shell32.dll"
#define WINDOWS_STORAGE_DLL         L"windows.storage.dll"
HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");

typedef PIMAGE_NT_HEADERS(NTAPI* RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader");

typedef NTSTATUS(NTAPI* RTLGETVERSION)(PRTL_OSVERSIONINFOW);
RTLGETVERSION RtlGetVersion = (RTLGETVERSION)GetProcAddress(hNtdll, "RtlGetVersion");

//RTLIMAGENTHEADER RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader");
//
// AicLaunchAdminProcess prologue signature.
//

unsigned char LaunchAdminProcessSignature760x[] = {
	0xFF, 0xF3, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81,
	0xEC, 0x30, 0x04, 0x00, 0x00
};

unsigned char LaunchAdminProcessSignature9200[] = {
	0x44, 0x89, 0x44, 0x24, 0x18, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56,
	0x41, 0x57, 0x48, 0x81, 0xEC, 0xF0, 0x03, 0x00, 0x00
};

unsigned char LaunchAdminProcessSignature9600[] = {
	0x44, 0x89, 0x4C, 0x24, 0x20, 0x44, 0x89, 0x44, 0x24, 0x18, 0x53, 0x56, 0x57, 0x41,
	0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 0xEC, 0x00, 0x04, 0x00, 0x00
};

unsigned char LaunchAdminProcessSignature10240_10586[] = {
	0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81,
	0xEC, 0x30, 0x04, 0x00, 0x00
};

unsigned char LaunchAdminProcessSignature14393[] = {
	0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81,
	0xEC, 0x20, 0x04, 0x00, 0x00
};

unsigned char LaunchAdminProcessSignature_15063_18362[] = {
	0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81,
	0xEC, 0x20, 0x04, 0x00, 0x00
};
//40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC 30 04 00 00
unsigned char LaunchAdminProcessSignature_18363_xxxxx[] = {
	0x40, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81,
	0xEC, 0x30, 0x04, 0x00, 0x00
};


/*
* supFindPattern
*
* Purpose:
*
* Lookup pattern in buffer.
*
*/
PVOID supFindPattern(
	CONST PBYTE Buffer,
	SIZE_T BufferSize,
	CONST PBYTE Pattern,
	SIZE_T PatternSize
)
{
	PBYTE	p = Buffer;

	if (PatternSize == 0)
		return NULL;
	if (BufferSize < PatternSize)
		return NULL;
	BufferSize -= PatternSize;

	do {
		p = (PBYTE)memchr(p, Pattern[0], BufferSize - (p - Buffer));
		if (p == NULL)
			break;

		if (memcmp(p, Pattern, PatternSize) == 0)
			return p;

		p++;
	} while (BufferSize - (p - Buffer) > 0); //-V555

	return NULL;
}

/*
* AicFindLaunchAdminProcess
*
* Purpose:
*
* Locate unexported AppInfo routine in memory by signature.
*
*/
ULONG_PTR AicFindLaunchAdminProcess(
	_Out_ PNTSTATUS StatusCode)
{
	ULONG_PTR Address = 0;
	PBYTE Pattern = NULL, ScanBase = NULL;
	DWORD PatternSize = 0, ScanSize = 0;
	IMAGE_NT_HEADERS* NtHeaders;
	LPCWSTR ScanModule = NULL;// LPWSTR
	RTL_OSVERSIONINFOW g_ctx{};
	RtlSecureZeroMemory(&g_ctx, sizeof(g_ctx));
	g_ctx.dwOSVersionInfoSize = sizeof(g_ctx);
	RtlGetVersion((PRTL_OSVERSIONINFOW)&g_ctx);
	DWORD dwBuildNumber = g_ctx.dwBuildNumber;
	if (g_ctx.dwBuildNumber < 10240)
		ScanModule = SHELL32_DLL;
	else
		ScanModule = WINDOWS_STORAGE_DLL;

	switch (g_ctx.dwBuildNumber) {

	case 7600:
	case 7601:
		Pattern = LaunchAdminProcessSignature760x;
		PatternSize = sizeof(LaunchAdminProcessSignature760x);
		break;
	case 9200:
		Pattern = LaunchAdminProcessSignature9200;
		PatternSize = sizeof(LaunchAdminProcessSignature9200);
		break;
	case 9600:
		Pattern = LaunchAdminProcessSignature9600;
		PatternSize = sizeof(LaunchAdminProcessSignature9600);
		break;
	case 10240:
	case 10586:
		Pattern = LaunchAdminProcessSignature10240_10586;
		PatternSize = sizeof(LaunchAdminProcessSignature10240_10586);
		break;
	case 14393:
		Pattern = LaunchAdminProcessSignature14393;
		PatternSize = sizeof(LaunchAdminProcessSignature14393);
		break;
	case 15063:
	case 16299:
	case 17134:
	case 17763:
	case 18362:
		Pattern = LaunchAdminProcessSignature_15063_18362;
		PatternSize = sizeof(LaunchAdminProcessSignature_15063_18362);
		break;
	case 18363:
	default:
		Pattern = LaunchAdminProcessSignature_18363_xxxxx;
		PatternSize = sizeof(LaunchAdminProcessSignature_18363_xxxxx);
		break;
	}

	ScanBase = (PBYTE)GetModuleHandleW(ScanModule);
	if (ScanBase == NULL) {
		ScanBase = (PBYTE)LoadLibraryExW(ScanModule, NULL, 0); //is in \KnownDlls
	}

	if (ScanBase == NULL) {
		*StatusCode = STATUS_INTERNAL_ERROR;
		return 0;
	}

	NtHeaders = RtlImageNtHeader(ScanBase);
	if (NtHeaders->OptionalHeader.SizeOfImage <= PatternSize) {
		*StatusCode = STATUS_INTERNAL_ERROR;
		return 0;
	}

	ScanSize = NtHeaders->OptionalHeader.SizeOfImage - PatternSize;
	Address = (ULONG_PTR)supFindPattern(ScanBase, (SIZE_T)ScanSize, Pattern, (SIZE_T)PatternSize);
	if (Address == 0) {
		*StatusCode = STATUS_PROCEDURE_NOT_FOUND;
		return 0;
	}

	*StatusCode = STATUS_SUCCESS;

	return Address;
}

3. 挂钩和注入的例程

找到该函数的地址后,我们就可以使用 Detours 挂钩该函数了,我们的钩子函数如下:

ULONG_PTR WINAPI AicLaunchAdminProcessHook(
    LPWSTR lpApplicationName,
    LPWSTR lpParameters,
    DWORD UacRequestFlag,
    DWORD dwCreationFlags,
    LPWSTR lpCurrentDirectory,
    HWND hWnd,
    PVOID StartupInfo,
    PVOID ProcessInfo,
    ELEVATION_REASON* ElevationReason) {
    
    ULONG Str = { '\0' };
    //ULONG new_ElevationReason = 10;
    //DWORD NewUacRequestFlag = 17; //admin

    if (_wcsicmp(lpApplicationName, L"C:\\Windows\\System32\\cmd.exe") == 0) {
        WCHAR  text[128] = { 0 };
        wsprintf(text, L"进程已终止。位于: %s ", lpApplicationName);
        int RetSD = MessageBoxW(NULL, text, L"Hooking!CallMessage", MB_OK | MB_ICONERROR);
        return Str;
    }
    else {
        ULONG_PTR ret = TrueAicLaunchAdminProcess(lpApplicationName, lpParameters, UacRequestFlag, dwCreationFlags, lpCurrentDirectory, hWnd, StartupInfo, ProcessInfo, ElevationReason);
        return ret;
    }
}

完整注入代码如下:

#include <stdlib.h>
#include <iostream>
#include <detours.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Shellapi.h>
#include <fstream>
#include <algorithm>
#include <Shlwapi.h>
#include "FindLaunchAdminFunc.h"
#pragma comment(lib,"Shlwapi.lib")
#include <cassert>

#pragma warning(disable:4996)

HMODULE s_hDll;
//共享代码段
#pragma data_seg("SHARED")
HHOOK g_hCreateProcessHook = NULL;
BOOL g_bStopHook = FALSE;
BOOL g_bHookInstalled = FALSE;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")

//#define WM_SHOWTASK (WM_USER + 1309)// 专用消息

using namespace std;


#define MAKEINTRESOURCE  MAKEINTRESOURCEW

extern HINSTANCE hAppInstance;

ULONG_PTR(WINAPI* TrueAicLaunchAdminProcess)(
    LPWSTR lpApplicationName,
    LPWSTR lpParameters,
    DWORD UacRequestFlag,
    DWORD dwCreationFlags,
    LPWSTR lpCurrentDirectory,
    HWND hWnd,
    PVOID StartupInfo,
    PVOID ProcessInfo,
    ELEVATION_REASON* ElevationReason
    ) = NULL;


typedef ULONG_PTR(WINAPI* pfnAipFindLaunchAdminProcess)(
    LPWSTR lpApplicationName,
    LPWSTR lpParameters,
    DWORD UacRequestFlag,
    DWORD dwCreationFlags,
    LPWSTR lpCurrentDirectory,
    HWND hWnd,
    PVOID StartupInfo,
    PVOID ProcessInfo,
    ELEVATION_REASON* ElevationReason);


/**
* If lpApplicationName is powershell or cmd, append to lpParameters to run payload.
* Otherwise, copies payload to same name as app name from lpApplicationName and keeps
* original lpParameters to spoof path.
*/
ULONG_PTR WINAPI AicLaunchAdminProcessHook(
    LPWSTR lpApplicationName,
    LPWSTR lpParameters,
    DWORD UacRequestFlag,
    DWORD dwCreationFlags,
    LPWSTR lpCurrentDirectory,
    HWND hWnd,
    PVOID StartupInfo,
    PVOID ProcessInfo,
    ELEVATION_REASON* ElevationReason) {

    //ULONG new_ElevationReason = 10;
    ULONG Str = { '\0' };
    //DWORD NewUacRequestFlag = 17; //admin
    //
    if (_wcsicmp(lpApplicationName, L"C:\\Users\\Lenovo\\Desktop\\FindEXPpath.exe") == 0) {
        //wcscat_s(lpParameters, MAX_PATH_LEN, L"-c \"& C:\\Users\\Lenovo\\Desktop\\FindEXPpath.exe\"");
        WCHAR  text[128] = { 0 };
        wsprintf(text, L"进程已终止。位于: %s ", lpApplicationName);
        int RetSD = MessageBoxW(NULL, text, L"Hooking!CallMessage", MB_OK | MB_ICONERROR);
        return Str;
    }
    else {
        ULONG_PTR ret = TrueAicLaunchAdminProcess(lpApplicationName, lpParameters, UacRequestFlag, dwCreationFlags, lpCurrentDirectory, hWnd, StartupInfo, ProcessInfo, ElevationReason);
        return ret;
    }
    //return new_ElevationReason;
}


//查找函数地址
HMODULE WINAPI ModuleFromAddress(PVOID pv) {
    MEMORY_BASIC_INFORMATION mbi;
    if (::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
        return (HMODULE)mbi.AllocationBase;
    else
        return NULL;
}



BOOL APIENTRY SetHook() {
    // 如果已经安装就return
    if (g_bHookInstalled)
       return TRUE;
    NTSTATUS ErrorCode;
    LONG error;
    PVOID LaunchAdminProcessPtr = NULL;

    if (DetourIsHelperProcess()) {
        return TRUE;
    }

    DetourRestoreAfterWith();
    LaunchAdminProcessPtr = (PVOID)AicFindLaunchAdminProcess(&ErrorCode);
    TrueAicLaunchAdminProcess = (pfnAipFindLaunchAdminProcess)LaunchAdminProcessPtr;
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)TrueAicLaunchAdminProcess, AicLaunchAdminProcessHook);
    error = DetourTransactionCommit();

    g_bHookInstalled = TRUE;
    return TRUE;
}


BOOL APIENTRY DropHook() {
    //如果已经卸载就return
    if (!g_bHookInstalled)return TRUE;

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    // Detach functions found from the export table.
    if (TrueAicLaunchAdminProcess != NULL) {
        DetourDetach(&(PVOID&)TrueAicLaunchAdminProcess, AicLaunchAdminProcessHook);
    }

    LONG ret = DetourTransactionCommit();
    fflush(stdout);

    g_bHookInstalled = FALSE;
    return ret == NO_ERROR;
}



static LRESULT CALLBACK CreateProcessHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;

    //wchar_t Dir[_MAX_DIR];
    wchar_t FullPath[MAX_PATH]; // [sp+200h] [bp-614h]@1
    //wchar_t Ext[_MAX_EXT];
    //wchar_t Filename[_MAX_FNAME];
    //wchar_t Drive[_MAX_DRIVE];
    GetModuleFileNameW(0, FullPath, MAX_PATH);
    //_wsplitpath_s(FullPath, Drive, _MAX_DRIVE, Dir, _MAX_DIR, Filename, _MAX_FNAME, Ext, _MAX_EXT);

    //wstring tar = Filename;

    //transform(tar.begin(), tar.end(), tar.begin(), towlower);

    //C:\Windows\explorer.exe
    //C:\Windows\System32\Taskmgr.exe
    //if ((_wcsicmp(Filename, L"explorer") == 0)) {
    // 忽略字符串大小写查找
    if (StrStrIW(FullPath, L"explorer.exe")) {

        if (!g_bStopHook)
        {
            SetHook();
        }
        else
            DropHook();
    }
    return CallNextHookEx(g_hCreateProcessHook, nCode, wParam, lParam);
}


// 导出函数 加载全局钩子
extern "C" __declspec(dllexport) BOOL SetGlobalHook() {
    g_bStopHook = FALSE;

    g_hCreateProcessHook = SetWindowsHookExW(WH_GETMESSAGE,
        CreateProcessHookProc,
        ModuleFromAddress(CreateProcessHookProc), 0);

    if (g_hCreateProcessHook == NULL) {
        wchar_t text[30];
        wsprintf(text, L"HOOK失败!error : %d.\n", GetLastError());
        MessageBox(0, text, TEXT("错误"), MB_OK);
        return false;
    }
    return TRUE;
}

// 导出函数 卸载全局钩子
extern "C" __declspec(dllexport) BOOL DropGlobalHook() {
    //DropHook();
    g_bStopHook = TRUE;
    Sleep(3000);
    UnhookWindowsHookEx(g_hCreateProcessHook);
    
    return TRUE;
}


BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        s_hDll = hModule;
        DisableThreadLibraryCalls(hModule);
        //DropGlobalHook();
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        //DropGlobalHook();
        
        break;
    }
    return TRUE;
}

4. 运行效果截图


更新于:2023.10.24

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涟幽516

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值