我正在尝试使用mhook在CreateProcess(),CreateProcessEx()或ZwCreateSection()上创建全局钩子,以便可以阻止某些应用程序启动。我遵循了https://www.apriorit.com/dev-blog/160-apihooks中提供的步骤。但这似乎不起作用。甚至有可能,如果可以,请提供任何建议。 我尝试使用以下代码记录使用CreateProcess()进行的每个流程创建。
#include "stdafx.h"
#include<fstream>
#include "mhook/mhook-lib/mhook.h"
typedef BOOL (WINAPI *_CreateProcess)(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
_CreateProcess TrueCreateProcess =
(_CreateProcess)::GetProcAddress(::GetModuleHandle(L"kernel32"),"CreateProcess");
BOOL WINAPI HookCreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
)
{
std::wofstream out;
out.open("D:\\Log.txt",std::ios_base::app);
if(out!=NULL)
{
out<<"Process Created\n";
}
return TrueCreateProcess(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
BOOL WINAPI DllMain(
__in HINSTANCE hInstance,
__in DWORD Reason,
__in LPVOID Reserved
)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&TrueCreateProcess, HookCreateProcess);
break;
case DLL_PROCESS_DETACH:
Mhook_Unhook((PVOID*)&TrueCreateProcess);
break;
}
return TRUE;
}
答案 0 :(得分:1)
继续使用原始帖子评论中的注释:
调试另一个进程(例如explorer.exe),并在回调指向断点的同时注入DLL。然后运行任何非高架程序,看看是否有断点命中。由于以下两个原因之一,它不会命中:钩子例程未被调用;或挂钩从未设置。
您还应该首先在本地过程中测试这些内容,就像注释中提到的@RbMm一样。采纳他的建议,您的生活将会更加幸福。
首先,请不要在Win32 API的API挂钩方面碰到它,除非您想要最有缺陷的设计实现,任何人都可以理解。
以上两种想法都比依靠Win32 API来完成您要执行的操作要好,但是它们仍然是非常糟糕的想法。我会解释一些原因。
对于Windows Vista和Windows 7,您可以将代码注入csrss.exe,然后修补CsrCreateProcess(由csrss.exe所依赖的模块导出)。这比将代码注入到多个流程中更为可靠(并且还将用于监视提升流程中的流程创建),但是就稳定性和安全性而言,这仍然不是一个好主意。您需要启用SeDebugPrivilege才能触摸crsss.exe进行记录。
对于csrss.exe是受保护进程的Windows的较新版本,您可以在lsass.exe之类的进程中修补NtOpenProcess(NTDLL)。但是,对于稳定性和安全性又一次提出了不好的主意-更不用说不能保证这将一直是100%可靠的事实。这仅是您可以尝试进行教育实验的估计值。您还需要考虑lsass.exe是受保护进程的可能性(可以通过修改注册表来启用它-并且出于安全原因,每个人都应该这样做)。
以上两种想法由于其自身的原因也是不好的。
有Windows Management Instrumentation(WMI),可用于接收有关创建新进程的通知,但不会表现为“拦截”。它的行为类似于创建后的通知。但是,如果您需要做的只是日志进程创建,那么它大概就是您可以在用户模式下做的最好的事情,而不会弄乱未记录的行为,并且从关注安全性,稳定性和效率的角度来看
上述想法是一个好的例子,应该是安全,有效,稳定和有据可查的。
从内核模式开始的另一种方法是通过PsSetLoadImageNotifyRoutine / Ex(然后过滤NTDLL.DLL)或通过PsSetCreateThreadNotifyRoutine(并保留自己的带有线程ID的进程监视日志,以确定线程创建是否是第一个用于线程创建的方法)。处理)。
现在,关于DLL注入,请勿使用AppInit_DLL。这是完成原始帖子中尝试执行的操作时最有缺陷的机制之一。即使我不同意您的设计,也最好解释一下为什么它是一个有缺陷的设计。
AppInit_DLLs仅会影响已加载User32.dll的程序,这意味着您的监视将受到严格限制/不可靠。您将无法跨非GUI程序监视进程创建(这些程序很少导入User32.dll,例如Windows Service,甚至是不依赖于User32相关内容的控制台进程,例如消息框等)。>
更好的RCE方法将有一个特权进程(因此,获取进程句柄的限制更少)依赖于远程线程创建/异步过程调用来触发执行简单且格式正确的shell代码(它将在该阶段之前写入进程的虚拟内存)以调用LdrLoadDll(NTDLL)。只要注入的DLL也是本机的,这还将允许注入到本机进程(不依赖任何Win32 API模块的进程)中。
总的来说,作为一般性评论,您确实不想继续尝试寻求帮助(挂钩Win32 API),并提到了我提到的用于完成过程创建监视的其他挂钩方法。仅出于理论目的,并非旨在实际建议您采用这些方法。我不能太强调重点放在文档和稳定性上是很重要的,因为尽管您现在可能不相信它,但是尝试做一些像您当前正在尝试的设计那样的事情,却很容易使您陷入困境。彻底破坏。我一点也不夸张。
请记住,执行远程代码执行通常是一个坏主意,请仅在没有其他方法的情况下执行此操作。一个可能真正需要时的示例是AV供应商试图开发一个Behavior Blocker / HIPS,但是没有内核模式回调来过滤他们试图过滤的内容(并且他们可能没有通过Intel的虚拟化支持) VT-x或AMD SVM来控制x64上的内核而不会导致错误检查)。一个糟糕的理由是,目的只是简单地“记录”流程创建,尤其是当有诸如WMI之类的可用选项具有此功能时。
请不要采取这种错误的方式,但是我从经验中学到,API挂钩确实不是一直存在的答案,通常需要考虑一种更好的设计。有时您可能确实必须依赖它,但是基于我所看到的,大多数询问它的人甚至根本不需要依赖它。
如果这不仅是实验,而且是针对生产级别的,请采用WMI或内核模式设备驱动程序方法。如果您采用内核模式设备驱动程序方法,请在内核模式下尽可能少地做,并在用户模式服务进程中处理过滤。
祝你好运。