Всем, добрый день. Прохожу по всем структурам, получаю дамп, ниже исходник. Всё делаю по мануалу 3A (http://download.intel.com/design/processor/manuals/253668.pdf). Цитатка из мана я предположил, то знаковое расширение получается так: Если старший бит itmpPXE =0, то это расширение нулевое, иначе забивается FFFF. Но это неверно, потому что есть адреса ffff000000008ff8 Не могу разобраться, как с генерировать биты адреса с 63-48. Подскажите, пожалуйста. Код (Text): __int64 itmpPXE = 0; __int64 itmpPPE = 0; __int64 itmpPDE = 0; __int64 itmpPTE = 0; PVOID copypage = ExAllocatePool ( NonPagedPool , _2M ); for (ULONG i = 0 ; i < PXE_PER_PAGE ; i++ ) { if (X64_PXE_ARRAY[i].pnpe.P) { itmpPXE = static_cast<__int64>(i)<<PXI_SHIFT; if (itmpPXE >= 0x0000800000000000 ) { itmpPXE = 0xFFFF000000000000 + itmpPXE; } //DbgLogMsg(StructSystem, "%.16I64X\r\n" , itmpPXE ); for (ULONG ii = 0 ; ii < PPE_PER_PAGE ; ii++ ) { if (X64_PPE_ARRAY[ii].pnpe.P) { itmpPPE = ii<<PPI_SHIFT; //DbgLogMsg(StructSystem,"\t%.16I64X\r\n" , itmpPPE ); for (ULONG iii = 0 ; iii < PDE_PER_PAGE ; iii++ ) { if (X64_PDE_ARRAY[iii].pnpe.P) { itmpPDE = iii << PDI_SHIFT; ULONG ps = X64_PDE_ARRAY[iii].pnpe.PS; if ( ps == 0) /* 4Kb */ { for (ULONG iiii = 0 ; iiii < PTE_PER_PAGE ; iiii++ ) { if (X64_PTE_ARRAY[iiii].pnpe.P) { itmpPTE = iiii << PTI_SHIFT; if (safecopy(copypage,(PVOID)(itmpPXE + itmpPPE + itmpPDE + itmpPTE),_4K)) { DbgLogMsg(StructSystem,"\t\t\t%.16I64X-%.16I64X(4kb)\r\n" , itmpPXE + itmpPPE + itmpPDE + itmpPTE , itmpPXE + itmpPPE + itmpPDE + itmpPTE + _4K ); DbgLogMsgSaveBuf(DataSystem,copypage,_4K); } } } } else /* 2Mb */ { if (safecopy(copypage,(PVOID)(itmpPXE + itmpPPE + itmpPDE),_2M)) { DbgLogMsg(StructSystem,"\t\t%.16I64X-%.16I64X(2mb)\r\n" , itmpPXE + itmpPPE + itmpPDE, itmpPXE + itmpPPE + itmpPDE + _2M); DbgLogMsgSaveBuf(DataSystem,copypage,_2M); } } } } } } } } ExFreePool(copypage); return;
rpy3uH пробовал,выходит 300 килобайт но есть адреса, где в 63-48 выставлены FFFF их получается не копирую З.Ы. для 32 битной винды дамп контекста 4Гб составляет ~150 Мб, львиная доля это ядро.
Сначала опишу задачу: необходимо дампить полность память выбранного контекста используя страничную адресацию (PTE etc) Для 32 всё работает. При переводе на 64 устройство памяти другое, не понятно как получать первые 63-48 биты в адресе, все остальные биты находятся путём сдвига соответствующих индексов в таблицf[. А про 63-48 биты ничего путного не сказано, забивать их нулями - не дело, потому что часть памяти не дампиться. Проблема: как выбрать значения для 63-48 битов в адресе.
биты 63-48 виртуального адреса вообще не учавствуют в формировании физического адреса, поэтому вроде как, по барабану что в этих битах.
если я не ошибаюсь в Win64 если отбросить старшие 16 бит адреса, то всё равно user-mode и kernel-mode адреса не пересекутся. user-mode : 0 - 0x0000080000000000 kernel-mode : 0xFFFF080000000000 - 0xFFFFFFFFFFFFFFFF т.е. адреса 0xFFFF060000001234 просто не существует.
Ev0lwavesrpy3uH Правильно, ли я понимаю 0x0000000000000000 .. (0x0000080000000000-1) - user memory 0xFFFF080000000000 .. 0xFFFFFFFFFFFFFFFFF -kernel memory asmfan, спасибо за совет. Цитатка из Amd Что Amd имели ввиду, что такое canonical-address forms?
вот из этого следует что user-mode 0 - 080000000000 kernel-mode 080000000000 - FFFFFFFFFFFF просто отбрасываем старше 16 бит и всё
asmfan спасибо за ссылку, user memory копируется хорошо. Но на ядерной памяти падает, прям начале, может кто подробнее посмотрит, вроде всё так.
Доработал, теперь нормально дампит, выпадает подсамый конец ядра) Отлаживаю на VirtualBox c XPx64, он падает в guru meditation. До падения размер дамп выходит разный: 300-600 Мб. Падает после 0xFFFFFFFFFFD00000. Код (Text): void print_pte_x64(ULONG StartOffset, ULONG FinishOffset) { unsigned __int64 pPXE = PXE_BASE; unsigned __int64 pPPE = PPE_BASE; unsigned __int64 pPDE = PDE_BASE; unsigned __int64 pPTE = PTE_BASE; unsigned __int64 i = 0; unsigned __int64 ii = 0; unsigned __int64 iii = 0; unsigned __int64 iiii = 0; unsigned __int64 SizeofFile = 0; unsigned __int64 Address = 0; PVOID copypage = ExAllocatePool ( NonPagedPool , _2M ); PTable_4K_2M ptable_4K_2M = (PTable_4K_2M) ExAllocatePool( NonPagedPool, TABLE_4K_2M ); memset( ptable_4K_2M, 0, TABLE_4K_2M ); // HANDLE handleStructFile = CreateFileAU(/*L"\\??\\C:\\Struct.txt"*/StructSystem); // HANDLE handleDatatFile = CreateFileAU(/*L"\\??\\C:\\Data.txt"*/DataSystem); for ( i = 0 ; i < 512 ; i++ ) { if ( PX64_PE(pPXE + i*8)->pnpe.P ) { for ( ii = 0 ; ii < 512 ; ii++ ) { if ( PX64_PE(pPPE + i*8*512 + ii*8)->pnpe.P ) { for ( iii = 0 ; iii < 512 ; iii++ ) { if (PX64_PE(pPDE + i*8*512*512 + ii*8*512 + iii*8)->pnpe.P) if (PX64_PE(pPDE + i*8*512*512 + ii*8*512 + iii*8)->pnpe.PS==0) { for ( iiii = 0 ; iiii < 512 ; iiii++ ) { if (PX64_PE(pPTE + i*8*512*512*512 + ii*8*512*512 + iii*8*512 + iiii*8)->pnpe.P) { Address = static_cast<__int64>(i)<<PXI_SHIFT ; if (Address >= 0x0000800000000000 ) Address += 0xFFFF000000000000; Address += ii<<PPI_SHIFT; Address += iii<<PDI_SHIFT; Address += iiii<<PTI_SHIFT ; if (safecopy(copypage,(PVOID)Address,_4K)) { KdPrint(("%.16I64X-%.16I64X(4 Kbyte) %x %x %x %x \r\n" , Address , Address + _4K, i, ii , iii , iiii)); DbgLogMsgSaveBuf( DataSystem, copypage, _4K ); //if (NT_SUCCESS(saveAU( handleDatatFile,copypage,_4K ))) { ptable_4K_2M->fileoffset = SizeofFile; ptable_4K_2M->StartVirtAddr = Address; ptable_4K_2M->FinishVirtAddr= Address+_4K; //if (NT_SUCCESS(saveAU( handleStructFile, ptable_4K_2M, TABLE_4K_2M ))){;} SizeofFile += _4K; DbgLogMsgSaveBuf(StructSystem,ptable_4K_2M,TABLE_4K_2M); DbgLogMsg(Trace,"%.16I64X-%.16I64X(4 Kbyte) %x %x %x %x \r\n" , Address , Address + _4K, i, ii , iii , iiii); } } } } } else { Address = static_cast<__int64>(i)<<PXI_SHIFT ; if (Address >= 0x0000800000000000 ) Address += 0xFFFF000000000000; Address += ii<<PPI_SHIFT; Address += iii<<PDI_SHIFT; if (safecopy(copypage,(PVOID)Address,_2M)) { DbgLogMsgSaveBuf(DataSystem,copypage,_2M); KdPrint(("%.16I64X-%.16I64X(2 Mbyte) %x %x %x \r\n", Address , Address + _2M, i, ii , iii )); //if (NT_SUCCESS(saveAU( handleDatatFile, copypage, _2M ))) { ptable_4K_2M->fileoffset = SizeofFile; ptable_4K_2M->StartVirtAddr = Address; ptable_4K_2M->FinishVirtAddr= Address+_2M; DbgLogMsgSaveBuf( StructSystem, ptable_4K_2M, TABLE_4K_2M ); //if (NT_SUCCESS(saveAU( handleStructFile, ptable_4K_2M, TABLE_4K_2M ))){;} SizeofFile += _2M; DbgLogMsg(Trace,"%.16I64X-%.16I64X(2 Mbyte) %x %x %x \r\n", Address , Address + _2M, i, ii , iii ); } } } } } } } } if (copypage) ExFreePool(copypage); if (ptable_4K_2M) ExFreePool(ptable_4K_2M); // ZwClose(handleDatatFile); // ZwClose(handleStructFile); }