无法将 C# 字符串从用户空间传递到内核模式 C 并使用它来查找特定 LDR_DATA_TABLE_ENTRY
Trouble passing a C# string from userland to kernelmode C and using it to find specific LDR_DATA_TABLE_ENTRY
我无法比较从用户模式类型 LPWSTR 传递到 LDR table 条目类型的字符串 UNICODE_STRING
内核 C:
struct {
int pid;
int user_pid;
int size;
int protection_mode;
int allocation_type;
void* address;
void* write_buffer;
LPWSTR module_name;
}
userland_operation;
这个结构通过 deviceiocontrol 传递给内核。对应的userland结构如下:
public struct MemOperation
{
public int Pid;
public int UserPid;
public int Size;
public int protection_mode;
public int allocation_type;
public IntPtr Addr;
public IntPtr WriteBuffer;
[MarshalAs(UnmanagedType.LPWStr)] public String ModuleName;
}
其中字符串 ModuleName
被编组为 LPWStr。
ModuleName
是进程中加载模块的所需搜索词。现在,事情变得棘手了。我可以通过 _LDR_DATA_TABLE_ENTRY
访问的字符串是 UNICODE_STRING
。我想将此 UNICODE_STRING 与我的 LPWSTR 进行比较。
我试过以下方法,但没有用:
{
UNICODE_STRING str;
RtlInitUnicodeString(&str, module_name) // module name is the userland passed string LPWSTR
if (RtlCompareUnicodeString(&str, &module_ldr->BaseDllName, TRUE) {
}
}
我也试过 wcscmp 和其他一些东西。我不确定如何正确比较这两者。我在函数中添加了一些次要的伪代码,以提供有关我要执行的操作的额外上下文。
NTSTATUS GetModuleList(HANDLE PID, PVOID UserBuffer, LPWSTR module_name) {
KAPC_STATE APC;
__try {
PEPROCESS TargetProcess;
PsLookupProcessByProcessId(PID, &TargetProcess);
PPEB Peb = PsGetProcessPeb(TargetProcess);
if (!Peb)
return STATUS_INVALID_PARAMETER;
KeStackAttachProcess(TargetProcess, &APC);
UINT64 Ldr = (UINT64)Peb + PEBLDR_OFFSET;
ProbeForRead((CONST PVOID)Ldr, 8, 8);
PLIST_ENTRY ModListHead = (PLIST_ENTRY)(*(PULONG64)Ldr + PEBLDR_MEMORYLOADED_OFFSET);
ProbeForRead((CONST PVOID)ModListHead, 8, 8);
PLIST_ENTRY Module = ModListHead->Flink;
while (ModListHead != Module) {
LDR_DATA_TABLE_ENTRY* Module_Ldr = (LDR_DATA_TABLE_ENTRY*)(Module);
//psuedo if (module_name is in Module_Ldr->BaseDllName) // the comparison, where BaseDllName is type UNICODE_STRING
Module = Module->Flink;
}
KeUnstackDetachProcess(&APC);
ObDereferenceObject(TargetProcess);
return STATUS_SUCCESS;
在下面的调用中:
if (RtlCompareUnicodeString(&str, &module_ldr->BaseDllName) {
此函数接受一个您没有传递的附加参数。
请参考https://docs.microsoft.com/en-us/windows/win32/devnotes/rtlcompareunicodestring
我想我会回答这个问题,因为我几年前就问过这个问题,现在不再有这个问题了。
我在调用 KeStackAttachProcess
之前从用户区创建的字符串在调用后无效。我不太确定这是否就是堆栈附加到进程的工作方式,但不管修复是什么非常微不足道的事情,例如(这是伪造的):
RtlInitUnicodeString(&str, module_name)
UNICODE_STRING example;
KeStachAttachProcess()
example = &module_ldr->BaseDllName;
KeStackDetachProcess()
RtlCompareUnicodeString(&example, &module_name)
比较是在附加之外进行的。
我无法比较从用户模式类型 LPWSTR 传递到 LDR table 条目类型的字符串 UNICODE_STRING
内核 C:
struct {
int pid;
int user_pid;
int size;
int protection_mode;
int allocation_type;
void* address;
void* write_buffer;
LPWSTR module_name;
}
userland_operation;
这个结构通过 deviceiocontrol 传递给内核。对应的userland结构如下:
public struct MemOperation
{
public int Pid;
public int UserPid;
public int Size;
public int protection_mode;
public int allocation_type;
public IntPtr Addr;
public IntPtr WriteBuffer;
[MarshalAs(UnmanagedType.LPWStr)] public String ModuleName;
}
其中字符串 ModuleName
被编组为 LPWStr。
ModuleName
是进程中加载模块的所需搜索词。现在,事情变得棘手了。我可以通过 _LDR_DATA_TABLE_ENTRY
访问的字符串是 UNICODE_STRING
。我想将此 UNICODE_STRING 与我的 LPWSTR 进行比较。
我试过以下方法,但没有用:
{
UNICODE_STRING str;
RtlInitUnicodeString(&str, module_name) // module name is the userland passed string LPWSTR
if (RtlCompareUnicodeString(&str, &module_ldr->BaseDllName, TRUE) {
}
}
我也试过 wcscmp 和其他一些东西。我不确定如何正确比较这两者。我在函数中添加了一些次要的伪代码,以提供有关我要执行的操作的额外上下文。
NTSTATUS GetModuleList(HANDLE PID, PVOID UserBuffer, LPWSTR module_name) {
KAPC_STATE APC;
__try {
PEPROCESS TargetProcess;
PsLookupProcessByProcessId(PID, &TargetProcess);
PPEB Peb = PsGetProcessPeb(TargetProcess);
if (!Peb)
return STATUS_INVALID_PARAMETER;
KeStackAttachProcess(TargetProcess, &APC);
UINT64 Ldr = (UINT64)Peb + PEBLDR_OFFSET;
ProbeForRead((CONST PVOID)Ldr, 8, 8);
PLIST_ENTRY ModListHead = (PLIST_ENTRY)(*(PULONG64)Ldr + PEBLDR_MEMORYLOADED_OFFSET);
ProbeForRead((CONST PVOID)ModListHead, 8, 8);
PLIST_ENTRY Module = ModListHead->Flink;
while (ModListHead != Module) {
LDR_DATA_TABLE_ENTRY* Module_Ldr = (LDR_DATA_TABLE_ENTRY*)(Module);
//psuedo if (module_name is in Module_Ldr->BaseDllName) // the comparison, where BaseDllName is type UNICODE_STRING
Module = Module->Flink;
}
KeUnstackDetachProcess(&APC);
ObDereferenceObject(TargetProcess);
return STATUS_SUCCESS;
在下面的调用中:
if (RtlCompareUnicodeString(&str, &module_ldr->BaseDllName) {
此函数接受一个您没有传递的附加参数。 请参考https://docs.microsoft.com/en-us/windows/win32/devnotes/rtlcompareunicodestring
我想我会回答这个问题,因为我几年前就问过这个问题,现在不再有这个问题了。
我在调用 KeStackAttachProcess
之前从用户区创建的字符串在调用后无效。我不太确定这是否就是堆栈附加到进程的工作方式,但不管修复是什么非常微不足道的事情,例如(这是伪造的):
RtlInitUnicodeString(&str, module_name)
UNICODE_STRING example;
KeStachAttachProcess()
example = &module_ldr->BaseDllName;
KeStackDetachProcess()
RtlCompareUnicodeString(&example, &module_name)
比较是在附加之外进行的。