#c #c #winapi #driver #winappdriver
Вопрос:
Я пытаюсь напечатать следующее имя процесса после моего процесса в LIST_ENTRY
списке. Но я всегда получаю BSOD.
#include <Ntifs.h>
#include <ntddk.h>
#include <WinDef.h>
void SampleUnload(_In_ PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
DbgPrint("Sample driver Unload calledn");
}
extern "C"
NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = SampleUnload;
DbgPrint("Sample driver Load calledn");
PEPROCESS EP;
if (::PsLookupProcessByProcessId(::PsGetCurrentProcessId(), amp;EP) == STATUS_INVALID_PARAMETER) {
DbgPrint("Can't get EPROCESS");
return STATUS_INVALID_PARAMETER;
}
LIST_ENTRY list_entry = *((LIST_ENTRY*)(LPBYTE)EP 0x448);
UCHAR* fileName;
fileName = ((UCHAR*)(LPBYTE)list_entry.Flink - 0x448 0x5a8);
for (int i = 0; i < 15; i )
DbgPrint("%u" , fileName[i]);
DbgPrint("Finish");
return STATUS_SUCCESS;
}
В EPROCESS
структуре есть LIST_ENTRY
объект в 0x448
смещении.
Поэтому я создал LIST_ENTRY
объект и назначил ему адрес EPROCESS 0x448
, а затем добавил 0x5a8-0x448
к LIST_ENTRY.FLINK
нему .
Это предполагает попадание в ImageFileName
массив в 0x5a8
смещении.
Но по какой-то причине это не работает.
Комментарии:
1. Какая строка кода запускает BSOD?
2. Я не знаю, я очень хорошо разбираюсь в мире водителей. Как я могу проверить?
3. Используйте отладчик ядра — docs.microsoft.com/en-us/windows-hardware/drivers/debugger/…
4.
*((LIST_ENTRY*)(LPBYTE)EP 0x448);
Вы можете попытаться добавить несколько скобок вокруг(LPBYTE)EP 0x448
, чтобы убедиться, что арифметика указателей выполнена до приведения кLIST_ENTRY*
5. Теперь я получаю защищенную систему в ascii. как я могу преобразовать это в строку?
Ответ №1:
У вас есть несколько бессмысленных приведений в коде:
*((LIST_ENTRY*)(LPBYTE)EP 0x448);
и
((UCHAR*)(LPBYTE)list_entry.Flink - 0x448 0x5a8);
Это означает, например, преобразование EP
(а не его адрес) в байтовый указатель, а затем (поскольку приведения имеют ассоциативность справа налево) немедленно забудьте о преобразовании в байтовый указатель и вместо этого преобразуйте в a LIST_ENTRY*
. Затем, когда вы закончите колебаться, какой тип использовать, выполните арифметику указателей на LIST_ENTRY
объекты. Это 0x448 * sizeof(LIST_ENTRY)
байты.
Я думаю, ты действительно хотел это сделать:
LPBYTE lpb = (LPBYTE)amp;EP 0x448;
LIST_ENTRY list_entry = *(LIST_ENTRY*)lpb;
Хотя, возможно, это ошибка с нарушением строгого сглаживания. Или ошибка выравнивания.
Комментарии:
1. только
(LPBYTE)EP 0x448
безamp;
. это, конечно, не имеет никакого отношения к «строгому нарушению псевдонимов», но весь рассматриваемый код бессмыслен и полон ошибок2.@тантан 1
PsLookupProcessByProcessId(::PsGetCurrentProcessId())
— бессмысленно. используйтеPsGetCurrentProcess
2 проверка ошибок на наличиеPsLookupProcessByProcessId
ошибок 3ObfDereferenceObject(EP)
не вызывается 4 используйте жестко закодированные смещения всегда неправильно3. Эй, @RbMm , как я могу избежать использования жестко закодированных смещений?