0. Открываю файл \\SystemRoot\\system32\\ntdll.dll 1. Создаю секцию. 2. Мапирую ее . Далее изменяю память которую возвратила ZwMapViewOfSection . Могут ли эти изменения быть глобальными? В п.1 создается новая секция или мне возвращается HANDLE уже существующей секции ? Это все в ядре происходит.
Без флага PAGE_WRITECOPY не будет производится копирования страниц и соответственно изменения глобальны для всех отображений секции. функция ZwCreateSection создаёт новую секцию, уже существующую можно открыть с пом. ZwOpenSection
Такое ощущение что я порчу проекцию нтдлл... Code (Text): PVOID ViewBase; ULONG_PTR ViewSize; UNICODE_STRING uStr; USHORT IdZwSetContext; NTSTATUS nt; PVOID p; RtlInitUnicodeString(&uStr,L"\\SystemRoot\\system32\\ntdll.dll"); nt = MapPeFile(&uStr,&ViewBase,&ViewSize); if ( ! NT_SUCCESS(nt) ) return FALSE; ZwUnmapViewOfSection(ZwCurrentProcess(),ViewBase); Code (Text): NTSTATUS MapPeFile(PUNICODE_STRING uStr,OUT PVOID *pRet,ULONG_PTR *ViewSize) { OBJECT_ATTRIBUTES objAttr; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS nt; HANDLE hFile,hSection; InitializeObjectAttributes(&objAttr,uStr,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL); nt = ZwCreateFile(&hFile,GENERIC_READ,&objAttr,&IoStatusBlock,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN,0,NULL,0); if ( !NT_SUCCESS(nt) ) { return nt; } nt = ZwCreateSection(&hSection,SECTION_MAP_READ,NULL,NULL,PAGE_READONLY,SEC_IMAGE,hFile); if ( !NT_SUCCESS(nt) ) { ZwClose(hFile); return nt; } *pRet = 0; *ViewSize = 0; nt = ZwMapViewOfSection(hSection, PsGetCurrentProcessId(), pRet, 0, 0, NULL, ViewSize, ViewUnmap, 0, PAGE_READONLY ); // ZwClose(hFile); // ZwClose(hSection); if ( nt == STATUS_IMAGE_NOT_AT_BASE ) do{ PIMAGE_BASE_RELOCATION pImgBaseReloc; LONG_PTR SizeRelocDir; ULONG_PTR xDelta; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeaders; pDosHeader = (PIMAGE_DOS_HEADER)*pRet; if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ) break; pNtHeaders = (PIMAGE_NT_HEADERS) (pDosHeader->e_lfanew + (PCHAR)*pRet); if ( pNtHeaders->Signature != IMAGE_NT_SIGNATURE ) break; pImgBaseReloc = (PIMAGE_BASE_RELOCATION)(pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (PCHAR)*pRet); SizeRelocDir = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; xDelta = (ULONG_PTR)*pRet - pNtHeaders->OptionalHeader.ImageBase; __asm int 3; if ( xDelta ) while ( (pImgBaseReloc->SizeOfBlock > 0) & (SizeRelocDir>0)) { PMDL Mdl; PVOID VirtAddr; ULONG CountRel = (pImgBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD); PWORD AddrRel = (PWORD)( (PCHAR)pImgBaseReloc + sizeof(IMAGE_BASE_RELOCATION)); Mdl = IoAllocateMdl((PCHAR)*pRet + pImgBaseReloc->VirtualAddress,2*PAGE_SIZE,FALSE,FALSE,NULL ); if ( Mdl ) { MmBuildMdlForNonPagedPool(Mdl); if ( VirtAddr = MmMapLockedPagesSpecifyCache(Mdl,UserMode,MmNonCached,NULL,FALSE,NormalPagePriority)/*MmGetSystemAddressForMdlSafe(Mdl,NormalPagePriority)*/ ) { //MmProtectMdlSystemAddress(Mdl,PAGE_READWRITE); while ( CountRel--) { if ( (*AddrRel >> 12) == IMAGE_REL_BASED_HIGHLOW) { ULONG TargetVA; PULONG Pach; PIMAGE_SECTION_HEADER psec ; TargetVA = /*pImgBaseReloc->VirtualAddress +*/ (*AddrRel & 0x0FFF); Pach = (PULONG)((PCHAR)VirtAddr + TargetVA); TargetVA = *(ULONG*)((PCHAR)*pRet + pImgBaseReloc->VirtualAddress + TargetVA); *Pach += xDelta; } ++AddrRel; } MmUnmapLockedPages(VirtAddr,Mdl); } IoFreeMdl(Mdl); } SizeRelocDir -= pImgBaseReloc->SizeOfBlock; pImgBaseReloc = (PIMAGE_BASE_RELOCATION)((PCHAR)pImgBaseReloc + pImgBaseReloc->SizeOfBlock ); }; nt = 0; }while(0); if (! NT_SUCCESS(nt) ) { return nt; }; return nt; }
Эммммм, может быть ZwUnmapViewOfSection нужно вызывать внутри функции MapPeFile (после обработки данных или в случае неудачи)? Где гарантия, что твой hSection будет равен ZwCurrentProcess()?
Ты о ZwUnmapViewOfSection(ZwCurrentProcess(),ViewBase); ? Так туда надо как раз хендл процесса. Данные отлично обрабатываются а вот csrss падает после обработки иногда не доходя до ZwUnmapViewOfSection . Щас покажу лог виндбг...
XshStasX Во-первых, флаг PAGE_WRITECOPY тебе не нужен, т.к. секция у тебя своя. Вот если бы ты лазил в уже существующую проекцию образа в каком-либо процессе, то твои изменения произошли бы и в других процессах, куда эта же секция была спроецирована. Во-вторых, функция MmBuildMdlForNonPagedPool() может быть использована только для невыгружаемого пула, в твоём случае следует использовать MmProbeAndLockPages() в try/except-блоке. Дальше код не смотрел и вообще непонятно, что это и зачем. А, и ещё замечание по поводу MmProtectMdlSystemAddress() - её нельзя использовать для изменения защиты страниц системного пула (не твой случай, конечно, но это так, мало ли). Запусти свой драйвер под Verifier-ом, вполне возможно, что он сходу укажет где на самом деле косяк.
Загружает РЕ файл и настраивает релоки. Зачем? Чтоб получить Id не которых сервисов. Verifier - пока не помог. Windbg: Terminating critical process csrss. И предлагает брякнуться к него.
x64 Этих апи обычно не достаточно. Простейшая казалось бы задача - запретить запись в файловую проекцию. Оказывается средствами ядра это сделать невозможно, без ручной правки VAD. Аверы вообще с памятью работать не умеют, вывод сделан на основе ресерча всех фаеров. XshStasX Не могут.
В общем после выполнения RtlZeroMemory(VirtAddr,PAGE_SIZE); идет перезапись ntdll других процессов ( а именно csrss, мой процесс System). Code (Text): if ( Mdl ) { __asm int 3; __try { MmProbeAndLockPages(Mdl,KernelMode,IoReadAccess); }__except( EXCEPTION_EXECUTE_HANDLER ) { __asm int 3; ZwUnmapViewOfSection(ZwCurrentProcess(),*pRet); return GetExceptionCode(); } if ( VirtAddr = MmGetSystemAddressForMdlSafe(Mdl,NormalPagePriority) ) { MmProtectMdlSystemAddress(Mdl,PAGE_READWRITE); __asm int 3; RtlZeroMemory(VirtAddr,PAGE_SIZE); MmUnmapLockedPages(VirtAddr,Mdl); } MmUnlockPages(Mdl); IoFreeMdl(Mdl); }
Malfoy Ну конечно Вот код с первого поста Code (Text): InitializeObjectAttributes(&objAttr,uStr,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL); nt = ZwCreateFile(&hFile,GENERIC_READ,&objAttr,&IoStatusBlock,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN,0,NULL,0); if ( !NT_SUCCESS(nt) ) { return nt; } nt = ZwCreateSection(&hSection,SECTION_MAP_READ,NULL,NULL,PAGE_READONLY,SEC_IMAGE,hFile); if ( !NT_SUCCESS(nt) ) { ZwClose(hFile); return nt; } *pRet = 0; *ViewSize = 0; nt = ZwMapViewOfSection(hSection, PsGetCurrentProcessId(), pRet, 0, 0, NULL, ViewSize, ViewUnmap, 0, PAGE_READONLY );
Вот и верь мне после этого) Если передан файловый хендл, то ZwCreateSection берёт SECTION_OBJECT оттуда (FileObject->SectionObjectPointer->ImageSectionObject), если он там есть. Т.е. сам по себе объект секции будет новый, вызов ObCreateObject будет безусловно, но для разных секций созданных с одного файла будут использованы одни и те же физические страницы памяти. Если я опять наврал - я не виноват ))))
XshStasX Убедись что реально была создана новая проекция , так как похоже ты открыл уже существующию ... (ZwMapViewOfSection для ntdll выполняется с Read\Write и похоже вы её заюзали) Malfoy Address descritpro пилятся антируткитами, ав кажится раньше не пилили.
Вобще мапить секцию READONLY, а потом через MDL получать те же физические страницы, но с другими правами - это "грязный хак" и так лучше не делать. Нужные права надо получать на этапе маппинга. Понятно, что если секция без права write, то мапнуть страницы с write неполучится. Тут можно попробовать PAGE_WRITECOPY...
Malfoy VAD - virtual address descritptor не?:читаёте посты рание . это про людей из АВ и выпили руткитов.