- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试编写一个 APC dll 注入(inject)驱动程序,我找到了 this示例并考虑根据我的需要对其进行修改。
我使用 PcreateProcessNotifyRoutineEx获取我针对的特定应用程序的 ProcessId,在本例中为“iexplore.exe”,然后使用 PloadImageNotifyRoutine检查 ntdll.dll 是否已经加载和初始化(来自 this recommendation ),如果 ntdll.dll 已加载,我调用“我的”InjectDLL 函数。
这是调用 InjectDll 的 PloadImageNotifyRoutine 函数:
VOID PloadImageNotifyRoutine(
_In_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo
)
{
PEPROCESS Process = NULL;
PETHREAD Thread = NULL;
PCHAR pTeb = nullptr;
DWORD ArbitraryUserPointer = 0;
PCHAR pszProcessNameA = nullptr;
pTeb = (PCHAR)__readfsdword(0x18);
ArbitraryUserPointer = *(DWORD*)(pTeb + 0x014);
// If ArbitraryUserPointer points to kernel32.dll it means ntdll.dll is done loading.
if (FALSE == IsStringEndWith((wchar_t*)ArbitraryUserPointer, L"\\kernel32.dll"))
{
return;
}
if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
{
return;
}
pszProcessNameA = (PCHAR)PsGetProcessImageFileName(Process);
if (FALSE == StringNCompare(pszProcessNameA, "iexplore.exe", GetStringLength("iexplore.exe")))
{
return;
}
Thread = KeGetCurrentThread();
InjectDll(MODULE_PATH, Process, Thread);
ObDereferenceObject(Process);
}
这是 InjectDll 函数:
BOOLEAN InjectDll(PWCHAR pModulePath, PEPROCESS Process, PETHREAD Thread)
{
PKINJECT mem;
ULONG size;
mem = NULL;
size = 4096;
if (!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
{
return FALSE;
}
//more code ...
}
我在这里删除了一些检查,这样会更清楚。
我试着调试了一下,但它看起来像ZwAllocateVirtualMemory正在尝试分配内存,在某个时候失败并终止线程。
调用 ExAllocatePoolWithTag 后,它开始释放内存、取消映射部分并终止线程(<=我在调试时在堆栈中看到的调用 - 并没有真正跟踪每个调用,但在一般 View 中查看了它)。
线程终止前的堆栈:
nt!ExAllocatePoolWithTag+0x195
nt!NtAllocateVirtualMemory+0x1066
nt!KiSystemServicePostCall
nt!ZwAllocateVirtualMemory+0x11
kernel_apc_dll_injector!InjectDll+0x54
kernel_apc_dll_injector!PloadImageNotifyRoutine+0x2b0
nt!PsCallImageNotifyRoutines+0x62
该进程仍然可以从任务管理器中看到,但它的内存为 92k 且没有 CPU 使用率,可能是因为它没有正确“清理”。
不知道我的分析对不对,也许对于这个问题来说是没有必要的。
最佳答案
首先注意 - 不要从图像通知例程调用 PsLookupProcessByProcessId
。这根本就不需要。检查 ProcessId == PsGetCurrentProcessId()
。如果是 - 使用当前进程指针(正如您在调用 ZwAllocateVirtualMemory
- NtCurrentProcess()
中使用的那样)否则就存在。
现在关于 main - “ZwAllocateVirtualMemory 导致线程终止” - 当然不是。线程不终止。它挂起。首先,如果线程终止——因为这是在这个阶段进程中的单线程——所有进程都终止。但是您自己说该过程仍然可以从任务管理器中看到。您还如何查看已终止线程的调用堆栈?这也说明线程没有终止但在 ExAllocatePoolWithTag
回调在某些临界区中执行的问题,您可以在此例程中执行的操作受到限制(操作系统在临界区内的 PASSIVE_LEVEL 调用驱动程序的 process-notify 例程,正常内核 APC 已禁用)。限制之一是调用 ZwAllocateVirtualMemory
- 它卡在回调中,您可以看到。
所以你不能调用 ZwAllocateVirtualMemory
并直接从回调中进行注入(inject)。但解决方案存在。将普通内核 apc 插入当前线程。它将不会就地执行,因为 - 在回调中禁用了正常的内核 APC。但是就在您退出回调并且 apc 将被启用之后 - 您的 apc 被执行。在这里(在正常例程中)您已经可以调用 ZwAllocateVirtualMemory
并执行 dll 注入(inject)
关于c - Windows 内核驱动程序 : ZwAllocateVirtualMemory causing thread to terminate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50610741/
在C中分配内存时, char * undecoded_query_array = (char*) malloc(100); 我收到以下错误: 警告:对于堆 006D0000(基数 006D2000,大
有人知道 linux 中 ZwAllocateVirtualMemory 的等效项吗?我想要一个 linux 设备驱动程序在进程中分配虚拟地址空间。 最佳答案 较新内核版本的 do_mmap 和 vm
我正在尝试编写一个 APC dll 注入(inject)驱动程序,我找到了 this示例并考虑根据我的需要对其进行修改。 我使用 PcreateProcessNotifyRoutineEx获取我针对的
我是一名优秀的程序员,十分优秀!