far*_*jad 9 c++ hook driver wdk
我正在为我的应用程序编写一个简单的内核驱动程序(想想一个非常简单的反恶意软件应用程序.)
我已经迷上了ZwOpenFile()
并且习惯于PsGetCurrentProcess()
获得调用者进程的句柄.
它返回一个PEPROCESS结构:
PEPROCESS proc = PsGetCurrentProcess();
Run Code Online (Sandbox Code Playgroud)
我使用ZwQueryInformationProcess()
来获取PID
和ImageFileName
:
DbgPrint("ZwOpenFile Called...\n");
DbgPrint("PID: %d\n", PsGetProcessId(proc));
DbgPrint("ImageFileName: %.16s\n", PsGetProcessImageFileName(proc));
Run Code Online (Sandbox Code Playgroud)
并尝试以FullPath
这种方式获得过程(但我得到了BSOD):
WCHAR strBuffer[260];
UNICODE_STRING str;
//initialize
str.Buffer = strBuffer;
str.Length = 0x0;
str.MaximumLength = sizeof(strBuffer);
//note that the seconds arg (27) is ProcessImageFileName
ZwQueryInformationProcess(proc, 27, &str, sizeof(str), NULL);
DbgPrint("FullPath: %wZ\n", str.Buffer);
Run Code Online (Sandbox Code Playgroud)
如你所见,str.Buffer
是空的或充满垃圾.填充str
通道时缓冲区溢出可能ZwQueryInformationProcess()
会触发BSOD.
任何帮助,将不胜感激.
此API的MSDN文档表明了这一点
当ProcessInformationClass参数为ProcessImageFileName时,ProcessInformation参数指向的缓冲区应足够大,以容纳UNICODE_STRING结构以及字符串本身.存储在Buffer成员中的字符串是图像file.file的名称.
考虑到这一点,我建议你尝试修改你的缓冲区结构,如下所示:
WCHAR strBuffer[(sizeof(UNICODE_STRING) / sizeof(WCHAR)) + 260];
UNICODE_STRING str;
str = (UNICODE_STRING*)&strBuffer;
//initialize
str.Buffer = &strBuffer[sizeof(UNICODE_STRING) / sizeof(WCHAR)];
str.Length = 0x0;
str.MaximumLength = 260 * sizeof(WCHAR);
//note that the seconds arg (27) is ProcessImageFileName
ZwQueryInformationProcess(proc, 27, &strBuffer, sizeof(strBuffer), NULL);
Run Code Online (Sandbox Code Playgroud)
此外,您的代码需要检查并处理此处文档中描述的错误情况.这可能是您错过了BSOD触发器案例的原因.
如果缓冲区太小,则函数将失败并显示STATUS_INFO_LENGTH_MISMATCH错误代码,并且ReturnLength参数将设置为所需的缓冲区大小.
小智 5
//如果可用的话,在函数定义之前在头文件中声明这段代码。
typedef NTSTATUS (*QUERY_INFO_PROCESS) (
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
QUERY_INFO_PROCESS ZwQueryInformationProcess;
Run Code Online (Sandbox Code Playgroud)
//函数定义
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName)
{
NTSTATUS status;
ULONG returnedLength;
ULONG bufferLength;
HANDLE hProcess;
PVOID buffer;
PEPROCESS eProcess;
PUNICODE_STRING imageName;
PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process
status = PsLookupProcessByProcessId(processId, &eProcess);
if(NT_SUCCESS(status))
{
status = ObOpenObjectByPointer(eProcess,0, NULL, 0,0,KernelMode,&hProcess);
if(NT_SUCCESS(status))
{
} else {
DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
}
ObDereferenceObject(eProcess);
} else {
DbgPrint("PsLookupProcessByProcessId Failed: %08x\n", status);
}
if (NULL == ZwQueryInformationProcess) {
UNICODE_STRING routineName;
RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
ZwQueryInformationProcess =
(QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);
if (NULL == ZwQueryInformationProcess) {
DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
}
}
/* Query the actual size of the process path */
status = ZwQueryInformationProcess( hProcess,
ProcessImageFileName,
NULL, // buffer
0, // buffer size
&returnedLength);
if (STATUS_INFO_LENGTH_MISMATCH != status) {
return status;
}
/* Check there is enough space to store the actual process
path when it is found. If not return an error with the
required size */
bufferLength = returnedLength - sizeof(UNICODE_STRING);
if (ProcessImageName->MaximumLength < bufferLength)
{
ProcessImageName->MaximumLength = (USHORT) bufferLength;
return STATUS_BUFFER_OVERFLOW;
}
/* Allocate a temporary buffer to store the path name */
buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, 'uLT1');
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Retrieve the process path from the handle to the process */
status = ZwQueryInformationProcess( hProcess,
ProcessImageFileName,
buffer,
returnedLength,
&returnedLength);
if (NT_SUCCESS(status))
{
/* Copy the path name */
imageName = (PUNICODE_STRING) buffer;
RtlCopyUnicodeString(ProcessImageName, imageName);
}
/* Free the temp buffer which stored the path */
ExFreePoolWithTag(buffer, 'uLT1');
return status;
}
Run Code Online (Sandbox Code Playgroud)
//Function Call..在PreOperation Call back中写入这段代码并且IRQ应该是PASSIVE_LEVEL
PEPROCESS objCurProcess=NULL;
HANDLE hProcess;
UNICODE_STRING fullPath;
objCurProcess=IoThreadToProcess(Data->Thread);//Note: Date is type of FLT_CALLBACK_DATA which is in PreOperation Callback as argument
hProcess=PsGetProcessID(objCurProcess);
fullPath.Length=0;
fullPath.MaximumLength=520;
fullPath.Buffer=(PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,'uUT1');
GetProcessImageName(hProcess,&fullPath);
Run Code Online (Sandbox Code Playgroud)
在fullPath变量中有进程的完整路径..就像如果进程是explorer.exe那么路径将如下所示:-
\Device\HarddiskVolume3\Windows\explorer.exe
Run Code Online (Sandbox Code Playgroud)
注意:- \Device\HarddiskVolume3 路径可能会因机器和硬盘中的不同卷而更改,这是我的例子。
归档时间: |
|
查看次数: |
11578 次 |
最近记录: |