Мучаюсь целый день с одной ошибкой - в DriverEntry загрузил ядро с диска , настроил релоки(таблицу импорта не трогал). Нашел адрес функции atoi и вызвал ее. Запускаю - бсод, PAGE FAULT IN NOPAGED AREA. Подумал что накосячил с релоками - но релоки в юземоде работали. Все же закоментил вызов функции - бсода нет. Запускаю отладчик с версией которая дает бсод - все мои сообщения печатаються в дебаг и результат atoi дает правильный - но после выполнения DriverEntry я вылетаю..... Как такое может быть? неужели atoi могла создать какой-нибудь поток.....
Leksey Погоди, чот я не понял для чего ты загрузил второе ядро ??? ты поменял имя или оставил так же как и оригинала? во вторых. Ты прописал в двусвязном списке дров этот новый модуль ? Распиши для чего ты это делал и какой результат в конечном итоге хотел получить ? Ты случаем не для того его грузил чтобы к примеру скинуть хуки в ядре ? Если для этого, то при таком методе загрузке бсода тебе не миновать, там по другому грузить надо.
Второе ядро я загрузил затем что мне нужны копии кода некототорых функций из ntoskrnl.exe. Имя я не менял - гружу как файл ручками и настриваю секции, релоки, импорт сам... Скинуть хуки я не хотел... мне нужна копия кода ядра чтобы я мог вызывать некоторые функции через нее, например atoi . Показывать DriverEntry - проблематично, ибо там фактически вызов одной функции - довольно не маленькой... Вот собсно важный участок: Код (Text): typedef int (*customAtoi)(const char*); __try { res = GetNtoskrnlImageInfo(&ntoskrnlInfo); if (res == True) { res = CreateKrnlImageCopy(&ntoskrnlInfo, &modInfo); if (res == True) { customAtoi catoi; catoi = (customAtoi)GetProcedureAddress(modInfo.imageBase,"atoi"); catoi("1234");//Если закоментить то все окей FreeKrnlImageCopy(&modInfo); } else DbgPrint(("ThHide: CreateKrnlImageCopy Failed.")); } else DbgPrint(("ThHide: GetNtoskrnlImageInfo Failed.")); } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("ThHide: Exception code = %d \n", GetExceptionCode()); } Bool CreateKrnlImageCopy(KernelModuleInfo* ntoskrnlInfo, KernelModuleInfo* modInfo) { Bool result = False; byte* fbuffer = 0; NTSTATUS status; UNICODE_STRING fullFileName; HANDLE fileHandle; IO_STATUS_BLOCK iostatus; OBJECT_ATTRIBUTES oa; RtlInitUnicodeString( &fullFileName,L"\\??\\C:\\WINDOWS\\system32\\ntoskrnl.exe"); InitializeObjectAttributes( &oa,&fullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); status = ZwCreateFile (&fileHandle,GENERIC_READ | SYNCHRONIZE,&oa,&iostatus,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); if (NT_SUCCESS(status)) { FILE_STANDARD_INFORMATION fileInfo; status = ZwQueryInformationFile(fileHandle,&iostatus,&fileInfo,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation); if (NT_SUCCESS(status)) { fbuffer = (byte*)ExAllocatePool(NonPagedPool, fileInfo.EndOfFile.LowPart); if (fbuffer != 0) { status = ZwReadFile(fileHandle, 0, 0, 0,&iostatus, fbuffer, fileInfo.EndOfFile.LowPart, 0, 0); if (NT_SUCCESS(status)) { modInfo->size = ntoskrnlInfo->size; modInfo->imageBase = (byte*)ExAllocatePool(NonPagedPool, modInfo->size); if (modInfo->imageBase != 0) { result = LoadPEModule(fbuffer, modInfo->imageBase, StandartFixRelocations, 0,0); if (result == False) { ExFreePool(modInfo->imageBase); modInfo->imageBase = 0; } } } ExFreePool(fbuffer); } } ZwClose(fileHandle); } return result; } Bool FreeKrnlImageCopy(KernelModuleInfo* modInfo) { if (modInfo->imageBase != 0) ExFreePool(modInfo->imageBase); return True; } Функция LoadPeModule написана так что не содержит системных вызовов - и была хорошо протестена в юзермоде. это чуть ли не первый мой драйвер - так что я думаю что-то неправильно использую память, файлы....
Leksey Память для образа ядра выделяешь в non-paged pool? Если нет, то добавь блокировку образа в памяти через MmProbeAndLockPages
Я проверяю - там не ноль точно. Я в дебаг все вывожу. Это урезанная версия, результат правльный функция дает. Вылетает после DriverEntry. Crash-dump сча посмотрю...
скорее всего стек слетает. при попытке выхода из DriverEntry в стеке наверное некорректный адрес возврата. ты уверен, что правильно сделал конвенцию вызова? __stdcall надо оно слетает же уже после atoi() скорее всего он напутал конвецию вызова..
спасибо, Great, произвел изменения: Код (Text): typedef int (__stdcall *customAtoi)(const char*); NTSTATUS __stdcall DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) Это текущее описание этих функций. После замены запускаю- все как обычно - atoi выдает результат - DbgPrint прямо перед return STATUS_SUCCESS; выводит что надо. Теперь новый BSOD: SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common bugcheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: c0000005, The exception code that was not handled Arg2: 805a803b, The address that the exception occurred at Arg3: fa372bb8, Exception Record Address Arg4: fa3728b4, Context Record Address Debugging Details: ------------------ EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text> FAULTING_IP: nt!IopIsLegacyDriver+b 805a803b 83790400 cmp dword ptr [ecx+4],0 EXCEPTION_RECORD: fa372bb8 -- (.exr fffffffffa372bb8) ExceptionAddress: 805a803b (nt!IopIsLegacyDriver+0x0000000b) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 0a2e6c70 Attempt to read from address 0a2e6c70 CONTEXT: fa3728b4 -- (.cxr fffffffffa3728b4) eax=fa4096b8 ebx=e18a393e ecx=0a2e6c6c edx=8055a8c0 esi=81152220 edi=fa4096b8 eip=805a803b esp=fa372c80 ebp=fa372c80 iopl=0 nv up ei pl nz ac po cy cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010213 nt!IopIsLegacyDriver+0xb: 805a803b 83790400 cmp dword ptr [ecx+4],0 ds:0023:0a2e6c70=???????? Resetting default scope DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO PROCESS_NAME: System ERROR_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text> READ_ADDRESS: 0a2e6c70 BUGCHECK_STR: 0x7E LAST_CONTROL_TRANSFER: from 805a6a1c to 805a803b STACK_TEXT: fa372c80 805a6a1c fa4096b8 00000000 f83e2cf4 nt!IopIsLegacyDriver+0xb fa372d4c 805a6ca8 00000764 00000001 00000000 nt!IopLoadDriver+0x6b6 fa372d74 804e47fe 00000764 00000000 811b9748 nt!IopLoadUnloadDriver+0x45 fa372dac 8057dfed f83e2cf4 00000000 00000000 nt!ExpWorkerThread+0x100 fa372ddc 804fa477 804e4729 80000001 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 SYMBOL_NAME: ANALYSIS_INCONCLUSIVE FOLLOWUP_NAME: MachineOwner MODULE_NAME: Unknown_Module IMAGE_NAME: Unknown_Image DEBUG_FLR_IMAGE_TIMESTAMP: 0 STACK_COMMAND: .cxr 0xfffffffffa3728b4 ; kb FAILURE_BUCKET_ID: 0x7E_ANALYSIS_INCONCLUSIVE BUCKET_ID: 0x7E_ANALYSIS_INCONCLUSIVE Followup: MachineOwner
На то он и PageFault - появляеться внезапно и грубо и фиг каким try/except защитися. У меня заработало!!! По совету Great я перепроверил все конвенции функций.... Короче в чем-то PageFault прав - идиотская ошибка. PS извиняюся, постараюсь так больше не делать....
Подскажите решение моей задачи, задача такая: Есть некоторый драйвер N, обычный драйвер без хуков, не троян, не вирус. Задача: написать драйвер-враппер M который бы внутри себя (например в виде большого массива) содержал драйвер N и все что делал, это его запускал. Я так понимаю план действий должен быть таков: 1. Выделить память через ExAllocatePool 2. скопировать туда массив с драйвером 3. корректно подгрузить импорты драйвера N 4. поправить релокешены драйвера N 5. передать управление на точку входа DriverEntry 6. При выгрузке драйвера N осовободить память (опционально) Загвоздка у меня возникает с корректной загрузкой драйвера так, чтобы он был пригоден к передаче на него управления. Я искал информацию, как это сделать в юзермоде, но там используеться связка CreateProcess/WriteProcessMemory, тоетсь просто создается новый процесс средствами винды и содержимое его заменяется. В ядре такое не пройдет. 2 Leksey Я так понял ты решаешь сходную задачу по загрузке модуля в драйвере, не мог бы ты поделится опытом? Интересует, в частности функция LoadPEModule. Спасибо заранне за любые ответы!