能力值:
( LV2,RANK:10 )
2 楼
顶一下 没有指令可调试 #pragma INITCODE 移出内存?
能力值:
( LV12,RANK:300 )
3 楼
先明确一下你要断的是“丢弃映像文件中可丢弃的区块的操作”还是“修改内存操作”。
实际上你要的是看它什么时候被覆盖掉了,被改变了,如果是这样,那么只要对相应地址下硬件写断点就行了。
而如果你非要知道系统什么时候把.INIT区块的内容丢弃的,那么你应该调试一下系统加载驱动的过程。
能力值:
( LV2,RANK:10 )
4 楼
难的有人回复啊
开始使用的是BA指令 但是不知道是我使用错误还是其他原因 并无显示
关于
“先明确一下你要断的是“丢弃映像文件中可丢弃的区块的操作”还是“修改内存操作”。
”
现在已基本确认 字符串内存变动就是由于它处于映像文件可丢弃区域并且被丢弃
我是想确认下何时丢弃
也就是关注INIT区域内的 字符串 假设BUFFER指针地址是865029e8 指针指向的地址是f7a0a160
我可以使用什么指令关注这两个地址何时改变以及移出内存?(BA指令无用)
“而如果你非要知道系统什么时候把.INIT区块的内容丢弃的,那么你应该调试一下系统加载驱动的过程。 ”
现在便是疑惑如何调试?求教下使用什么指令
在ENTRY函数RETURN之前字符串还是正常
一旦离开ENTRY我要UNLOAD才能重新进入调试 此时字符串已经读写错误了
能力值:
( LV12,RANK:300 )
5 楼
WINDBG下,你在ENTRY函数的RET指令处单步一下,不就可以回到IopLoadDriver函数的领空了吗,然后继续调下去就会找到对MmFreeDriverInitialization的调用。
好吧,我上面其实已经告诉你答案了,丢弃可丢弃的区块就是在IopLoadDriver调用完驱动入口函数之后,再调用MmFreeDriverInitialization实现的。
IopLoadDriver部分代码(引自wrk):
...... // // Now invoke the driver's initialization routine to initialize itself. // status = driverObject->DriverInit( driverObject, ®istryPath->Name ); *DriverEntryStatus = status; if (!NT_SUCCESS(status)) { status = STATUS_FAILED_DRIVER_ENTRY; } ...... if (NT_SUCCESS(status) && !IopIsLegacyDriver(driverObject)) { status = IopPnpDriverStarted(driverObject, KeyHandle, &serviceName); if (!NT_SUCCESS(status)) { if (driverObject->DriverUnload) { driverObject->Flags |= DRVO_UNLOAD_INVOKED; driverObject->DriverUnload(driverObject); IopBootLog(&baseName, FALSE); } else { #if DBG DbgPrint("IopLoadDriver: A PnP driver %wZ does not support DriverUnload routine.\n", &driverName); #endif } } } if (!NT_SUCCESS( status )) { ObMakeTemporaryObject( driverObject ); ObDereferenceObject( driverObject ); } else { // // Free the memory occupied by the driver's initialization routines. // IopBootLog(&baseName, TRUE); MmFreeDriverInitialization( driverObject->DriverSection ); IopReadyDeviceObjects( driverObject ); }
MmFreeDriverInitialization的内容(同样引自wrk):
MmFreeDriverInitialization ( IN PVOID ImageHandle ) /*++ Routine Description: This routine removes the pages that relocate and debug information from the address space of the driver. NOTE: This routine looks at the last sections defined in the image header and if that section is marked as DISCARDABLE in the characteristics, it is removed from the image. This means that all discardable sections at the end of the driver are deleted. Arguments: SectionObject - Supplies the section object for the image. Return Value: None. --*/ { PKLDR_DATA_TABLE_ENTRY DataTableEntry; PMMPTE PointerPte; PMMPTE LastPte; PFN_NUMBER NumberOfPtes; PVOID Base; PVOID StartVa; ULONG i; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER NtSection; PIMAGE_SECTION_HEADER FoundSection; PFN_NUMBER PagesDeleted; DataTableEntry = (PKLDR_DATA_TABLE_ENTRY)ImageHandle; Base = DataTableEntry->DllBase; ASSERT (MI_IS_SESSION_ADDRESS (Base) == FALSE); NumberOfPtes = DataTableEntry->SizeOfImage >> PAGE_SHIFT; LastPte = MiGetPteAddress (Base) + NumberOfPtes; NtHeaders = (PIMAGE_NT_HEADERS) RtlImageNtHeader (Base); if (NtHeaders == NULL) { return; } NtSection = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeaders + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + NtHeaders->FileHeader.SizeOfOptionalHeader ); NtSection += NtHeaders->FileHeader.NumberOfSections; FoundSection = NULL; for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i += 1) { NtSection -= 1; if ((NtSection->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0) { FoundSection = NtSection; } else { // // There was a non discardable section between this // section and the last non discardable section, don't // discard this section and don't look any more. // break; } } if (FoundSection != NULL) { StartVa = (PVOID) (ROUND_TO_PAGES ( (PCHAR)Base + FoundSection->VirtualAddress)); PointerPte = MiGetPteAddress (StartVa); NumberOfPtes = (PFN_NUMBER)(LastPte - PointerPte); if (NumberOfPtes != 0) { if (MI_IS_PHYSICAL_ADDRESS (StartVa)) { // // Don't free the INIT code for a driver mapped by large pages // because if it unloads later, we'd have to deal with // discontiguous ranges of pages to free. // return; } else { PagesDeleted = MiDeleteSystemPageableVm (PointerPte, NumberOfPtes, MI_DELETE_FLUSH_TB, NULL); } MI_INCREMENT_RESIDENT_AVAILABLE (PagesDeleted, MM_RESAVAIL_FREE_DRIVER_INITIALIZATION); MiReturnCommitment (PagesDeleted); MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_DRIVER_INIT_CODE, PagesDeleted); InterlockedExchangeAdd ((PLONG)&MmDriverCommit, (LONG) (0 - PagesDeleted)); } } return; }
简单地来说,原理似乎就是从驱动映像文件的PE结构中找到后面的连续的可丢弃的区块中的第一个区块,然后得到相应的PTE地址,直接在页表中把它给抹了。
综上,你可以调试IopLoadDriver,在其调用完驱动入口点再调用MmFreeDriverInitialization后再查看.INIT区块原来位置上的内容。
能力值:
( LV2,RANK:10 )
6 楼
了解 非常感谢你的回复