获取操作系统的内核基地址
操作系统的内核模块根据处理器的个数和是否⽀持PAE(PhysicalAddressExtension物理地址扩展)分为以下四种
---Uniprocessor单处理器,不⽀持PAE
---Uniprocessor单处理器,⽀持PAE
---Multiprocessor多处理器,不⽀持PAE
---Mulitiprocessor多处理器,⽀持PAE
操作系统实际上加载的内核模块只能是上述四种中其中的⼀种
本⽂介绍的⽅法⽐较通⽤,没有局限性,可以正确的获得系统内核的基地址,主要⽅法有以下⼏种:
通过中未归档化的ZwQuerySystemInformation的11号调⽤得到系统的所有加载模块,其中我们需要的操作系统内核模块就位于
第⼀个,此⽅法适⽤于ring0和ring3
通过KPCR结构中的KdVersionBlock成员结构得到KernelBa,此⽅法最为简单但只适⽤于ring0
通过DriverEntry函数中的第⼀个参数DriverObject结构中的DriverSection成员,实际上是⼀个指向LDR_DATA_TABLE_ENTRY的结
构指针,通过遍历该表得到内核的基地址,此⽅法同样只适⽤于ring0,不过需要知道内核模块的名称⽐如或者
不具有通⽤赚钱的网游 性,因此该⽅法下⾯就不讨论了
1)ZwQuerySystemInformation⽅法
该未归档化的系统调⽤在中,因此需要通过GetProcAddress来动态的获得函数地址
#defineNT_SUCCESS(Status)(((NTSTATUS)(Status))>=0)
typedefNTSTATUS(__stdcall*ZWQUERYSYSTEMINFORMATION)(
INULONGSystemInformationClass,//SYSTEM_INFORMATION_CLASS
INOUTPVOIDSystemInformation,
INULO柳永简介 NGSystemInformationLength,
OUTPULONGReturnLengthOPTIONAL
);
ZWQUERYSYSTEMINFORMATIONZwQuerySystemInformation;
HMODULEhNtDll=LoadLibraryA("");
if(!hNtDll)
{
printf("%s:LoadLibraryA紫质症 failed,error=%dn",__FUNCTION__,GetLastError());
return0;
}
ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,"ZwQuerySystemInformation");
if(!ZwQuerySystemInformation)
{
printf("%s:GetProcAddressfailed,error=%dn",__FUNCTION__,GetLastErr企业为什么要上市 or());
return0;
}
取得地址之后就可以通过11号调⽤来得到SYSTEM_MODULE_INFORMATION,结构如下所⽰
typedefstruct_SYSTEM_MODULE_INFORMATION{//InformationClass11
ULONGRerved[2];
PVOIDBa;
ULONGSize;
ULONGFlags;
USHORTIndex;
USHORTUnknown;
USHORTLoadCount;
USHORTModuleNameOfft;
CHARImageName[256];
}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
这⾥缓冲区⼤⼩的取值步骤分为两次,第⼀次传递进去的SystemInformation为NULL,SystemInformationLength为0,这样返回的
RenturnLength就是需要分配的缓冲区的⼤⼩,到时候malloc⼀下就可以了,然后再次调⽤ZwQuerySystemInformation即可
ULONGcbNeed;
ZwQuerySystemInformation(11,NULL,0,&cbNeed);
PSYSTEM_MODULE_INFORMATIONInfo=(PSYSTEM_MODULE_INFORMATION)malloc(cbNeed);
NTSTATUSstatus=ZwQuerySystemInformation(11,Info,cbNeed,&cbNeed);
if(!NT_SUCCESS(status))
{
printf("%s:ZwQuerySystemInformationfailed,error=0x%08xn",__FUNCTION__,status);
return0;
}
此时的Info的前四个字节是系统加载的所有模块的个数,后⾯才是SYSTEM_MODULE_INFORMATION结构数组,因此将缓冲区稍微调整⼀
下,然后内核基地址就是第⼀个SYSTEM_MODULE_INFORMATION结构中的Ba
//ULONGModuleCnt=*(PULONG)Info;
PSYSTEM_MODULE_INFORMATIONSystemModuleInfo=(PSYSTEM_MODULE_INFORMATION)((PULONG)Info+1);
printf("ImageName=%s,ImageBa=0x%08xn",SystemModuleInfo->ImageName,SystemModuleInfo->Ba);
free(Info);
2)KPCR⽅法
每个处理器核⼼都有⼀个KPCR结构(documented归档化),包含了该ProcessorCore的中断向量表IDT,任务状态段TSS,全局描述符表
GDT等信息,当然还有KdVersionBlock,⽤windbgdt_kpcr发现KdVersionBlock的类型是PVOID,其实KeVersionBlock指向的是
_DBGKD_GET_VERSION64结构体,这个结构体的⼤⼩只有0x28,这个结构信息还可以通过IG_GET_KERNEL_VERSION的IOCTL操作
来得到,紧跟在后⾯的是KDDEBUGGER_DATA64(不同版本的系统结构不⼀样,但是新加⼊的成员都是放在结构体的后⾯,所以前⾯的
变量位置并没有改变),系统中很多未导出的重要变量都在此结构体中⽐如
PsLoadedModuleList,PsActiveProcessHead,PspCidTable,ObpRootDirectoryObject,ObpTypeObjectType,KiProcessorBlock等,
这些结构体都是从%WDKPATH%incapiWDBGEXTS.H中获得的,可以通过GetDebuggerData来得到,这⾥列出这些结构体吧
typedefstruct_DBGKD_GET_VERSION64{
USHORTMajorVersion;
USHORTMinorVersion;
UCHARProtocolVersion;
UCHARKdSecondaryVersion;//Cannotbe'A'forcompatwithdumpheader
USHORTFlags;
USHORTMachineType;
//
//Protocolcommandsupportdescriptions.
//Theallowthedebuggertoautomatically
//adapttodifferentlevelsofcommandsupport
//indifferentkernels.
//
//Onebeyondhighestpackettypeunderstood,zerobad.
UCHARMaxPacketType;
//Onebeyondhigheststatechangeunderstood,zerobad.
UCHARMaxStateChange;
//Onebeyondhigheststatemanipulatemessageunderstood,zerobad.
UCHARMaxManipulate;
//Kindofexecutionenvironmentthekernelisrunningin,
//nback
//bythesimulationifoneexists.
UCHARSimulation;
USHORTUnud[1];
ULONG64KernBa;
ULONG64PsLoadedModuleList;
//
//Componentsmayregisteradebugdatablockforuby
//theaddressofthelisthead.
//
//Therewillalwaysbeanentryforthedebugger.
//
ULONG64DebuggerDataList;
}DBGKD_GET_VERSION团干部培训 64,*PDBGKD_GET_VERSION64;
typedefstruct_DBGKD_DEBUG_DATA_HEADER64{
//
//Linktootherblocks
//
LIST_ENTRY64List;
//
//Thisisauniquetagtoidentifytheowneroftheblock.
//Ifyourcomponentonlyusonepooltag,uitforthis,too.
//
ULONGOwnerTag;
//
//Thismustbeinitializedtothesizeofthedatablock,
//includingthisstructure.
//
ULONGSize;
}DBGKD_DEBUG_DATA_HEADER64,*PDBGKD_DEBUG_DATA_HEADER64;
typedefstruct_KDDEBUGGER_DATA64{
DBGKD_DEBUG_DATA_HEADER64Header;
//
//Baaddressofkernelimage
//
ULONG64KernBa;
//
//DbgBreakPointWithStatusisafunctionwhichtakesanargument
//eldcontainstheaddressofthe
//edebuggeresabreakpoint
//atthisaddress,itmayretrievetheargumentfromthefirst
//argumentregister,oronx86theeaxregister.
//
ULONG64BreakpointWithStatus;//addressofbreakpoint
//
//Addressofthesavedcontextrecordduringabugcheck
//
//anautomaticinKeBugcheckEx'sframe,and
//isonlyvalidafterabugcheck.
//
ULONG64SavedContext;
//
//helpforwalkingstackswithurcallbacks:
//
//
//Theaddressofthethreadstructureisprovidedinthe
//WAIT_STATE_theofftfromthebaof
//thethreadstructuretothepointertothekernelstackframe
//forthecurrentlyactiveurmodecallback.
//
USHORTT葱英语 hCallbackStack;//offtinthreaddata
//
//thevaluesareofftsintothatframe:
//
USHORTNextCallback;//savedpointertonextcallbackframe
USHORTFramePointer;//savedframepointer
//
//padtoaquadboundary
//
USHORTPaeEnabled:1;
//
//Addressofthekernelcalloutroutine.
//
ULONG64KiCallUrMode;//kernelroutine
//
//Addressoftheurmodeentrypointforcallbacks.
//
ULONG64KeUrCallbackDispatcher;//addressinntdll
//
//Addressofvariouskerneldatastructuresandlists
//thatareofinteresttothekerneldebugger.
//
ULONG64PsLoadedModuleList;
ULONG64PsActiveProcessHead;
ULONG64PspCidTable;
ULONG64ExpSystemResourcesList;
ULONG64ExpPagedPoolDescriptor;
ULONG64ExpNumberOfPagedPools;
ULONG64KeTimeIncrement;
ULONG64KeBugCheckCallbackListHead;
ULONG64KiBugcheckData;
ULONG64IopErrorLogListHead;
ULONG64ObpRootDirectoryObject;
ULONG64ObpTypeObjectType;
ULONG64MmSystemCacheStart;
ULONG64MmSystemCacheEnd;
ULONG64MmSystemCacheWs;
ULONG64MmPfnDataba;
ULONG64MmSystemPtesStart;
ULONG64MmSystemPtesEnd;
ULONG64MmSubctionBa;
ULONG64MmNumberOfPagingFiles;
ULONG64MmLowestPhysicalPage;
ULONG64MmHighestPhysicalPage;
ULONG64MmNumberOfPhysicalPages;
ULONG64MmMaximumNonPagedPoolInBytes;
ULONG64MmNonPagedSystemStart;
ULONG64MmNonPagedPoolStart;
ULONG64MmNonPagedPoolEnd;
ULONG64MmPagedPoolStart;
ULONG64MmPagedPoolEnd;
ULONG64MmPagedPoolInformation;
ULONG64MmPageSize;
ULONG64MmSizeOfPagedPoolInBytes;
ULONG64MmTotalCommitLimit;
ULONG64MmTotalCommittedPages;
ULONG64MmSharedCommit;
ULONG64MmDriverCommit;
ULONG64MmProcessCommit;
ULONG64MmPagedPoolCommit;
ULONG64MmExtendedCommit;
ULONG64MmZeroedPageListHead;
ULONG64MmFreePageListHead;
ULONG64MmStandbyPageListHead;
ULONG64MmModifiedPageListHead;
ULONG64MmModifiedNoWritePageListHead;
ULONG64MmAvailablePages;
ULONG64MmResidentAvailablePages;
ULONG64PoolTrackTable;
ULONG64NonPagedPoolDescriptor;
ULONG64MmHighestUrAddress;
ULONG64MmSystemRangeStart;
ULONG64MmUrProbeAddress;
ULONG64KdPrintCircularBuffer;
ULONG64KdPrintCircularBufferEnd;
ULONG64KdPrintWritePointer;
ULONG64KdPrintRolloverCount;
ULONG64MmLoadedUrImageList;
//NT5.1Addition
ULONG64NtBuildLab;
ULONG64KiNormalSystemCall;
//NT5.0hotfixaddition
ULONG64KiProcessorBlock;
ULONG64MmUnloadedDrivers;
ULONG64MmLastUnloadedDriver;
ULONG64MmTriageActionTaken;
ULONG64MmSpecialPoolTag;
ULONG64KernelVerifier;
ULONG64MmVerifierData;
ULONG64MmAllocatedNonPagedPool;
ULONG64MmPeakCommitment;
ULONG64MmTotalCommitLimitMaximum;
ULONG64CmNtCSDVersion;
//NT5.1Addition
ULONG64MmPhysicalMemoryBlock;
ULONG64MmSessionBa;
ULONG64MmSessionSize;
ULONG64MmSystemParentTablePage;
//Server2003addition
ULONG64MmVirtualTranslationBa;
USHORTOfftKThreadNextProcessor;
USHORTOfftKThreadTeb;
USHORTOfftKThreadKernelStack;
USHORTOfftKThreadInitialStack;
USHORTOfftKThreadApcProcess;
USHORTOfftKThreadState;
USHORTOfftKThreadBStore;
USHORTOfftKThreadBStoreLimit;
USHORTSizeEProcess;
USHORTOfftEprocessPeb;
USHORTOfftEprocessParentCID;
USHORTOfftEprocessDirectoryTableBa;
USHORTSizePrcb;
USHORTOfftPrcbDpcRoutine;
USHORTOfftPrcbCurrentThread;
USHORTOfftPrcbMhz;
USHORTOfftPrcbCpuType;
USHORTOfftPrcbVendorString;
USHORTOfftPrcbProcStateContext;
USHORTOfftPrcbNumber;
USHORTSizeEThread;
ULONG64KdPrintCircularBufferPtr;
ULONG64KdPrintBufferSize;
ULONG64KeLoaderBlock;
U祝贺升职的祝福语 SHORTSizePcr;
USHORTOfftPcrSelfPcr;
USHORTOfftPcrCurrentPrcb;
USHORTOfftPcrContainedPrcb;
USHORTOfftPcrInitialBStore;
USHORTOfftPcrBStoreLimit;
USHORTOfftPcrInitialStack;
USHORTOfftPcrStackLimit;
USHORTOfftPrcbPcrPage;
USHORTOfftPrcbProcStateSpecialReg;
USHORTGdtR0Code;
USHORTGdtR0Data;
USHORTGdtR0Pcr;
USHORTGdtR3Code;
USHORTGdtR3Data;
USHORTGdtR3Teb;
USHORTGdtLdt;
USHORTGdtTss;
USHORTGdt64R3CmCode;
USHORTGdt64R3CmTeb;
ULONG64IopNumTriageDumpDataBlocks;
ULONG64IopTriageDumpDataBlocks;
//Longhornaddition
ULONG64VfCrashDataBlock;
ULONG64MmBadPagesDetected;
ULONG64MmZeroedPageSingleBitErrorsDetected;
//Windows7addition
ULONG64EtwpDebuggerData;
USHORTOfftPrcbContext;
}KDDEBUGGER_DATA64,*PKDDEBUGGER_DATA64;
因此要获取的KernelBa只要通过KdVersionBlock->DBGKD_GET_VERSION64->KernBa或者KdVersionBlock-
>DBGKD_GET_VERSION64->KDDEBUGGER_DATA64->KernBa即可
在贴出代码之前有个需要注意的地⽅就是之前说过每个ProcessorCore都有⼀个KPCR结构,如果你的操作系统是多核的话你可以观察⼀
下,只有CPU0的KdVersionBlock才有值,其他的都是NULL
怎么查看呢,通过windbg扩展命令!pcr[CPUID],如果没有指定CPUID的话那么默认显⽰的是CPU0的KPCR,通过!pcr0和!pcr1……得到
KPCR地址,然后dt再查看
如果碰巧当前线程正运⾏在CPU0那么算你幸运,如果是在给长辈的生日祝福 别的核上运⾏的话会直接BSOD,那怎么办呢,可以通过
KeSetSystemAffinityThread来使该段代码运⾏在CPU0,该函数请查看MSDN
现在可以放代码了
//由于只⽤到了⼀个硬编码,在不同的系统上⾯都是⼀样的,所以可以在不同的环境中编译
DRIVER_INITIALIZEDriverEntry;
DRIVER_UNLOADDriverUnload;
NTSTATUSDriverEntry(PDRIVER_OBJECTDriverObject,PUNICODE_STRINGRegPath)
{
NTSTATUSstatus=STATUS_SUCCESS;
PVOIDKdVersionBlock;
PKDDEBUGGER_DATA64KdDebuggerData64;
DbgPrint("DriverEntry!n");
KeSetSystemAffinityThread(1);
__asm{
moveax,fs:[0x34]//KdVersionBlock’sofftinKPCRis0x34
movKdVersionBlock,eax
}
KdDebuggerData64=(PKDDEBUGGER_DATA64)((ULONG_PTR)KdVersionBlock+sizeof(DBGKD_GET_VERSION64));
//DbgPrint("KernelBa=0x%08xn",(PDBGKD_GET_VERSION64)KdVersionBlock->KernBa);
DbgPrint("KernelBa=0x%08xn",KdDebuggerData64->KernBa);
KeRevertToUrAffinityThread();
DriverObject->DriverUnload=DriverUnload;
returnstatus;
}
VOIDDriverUnload(PDRIVER_OBJECTDriverObject)
{
DbgPrint("DriverUnload!n");
}
通过KdVersionBlock->_DBGKD_GET_VERSION64->KDDEBUGGER_DATA64这条路径可以获得很多重要的没导出的系统变
量,KdVersionBlock真是个好东西,呵呵
BTW:fs寄存器在内核态的时候指向的是KPCR结构,⽤户态下指向的是当前线程的TEB(ThreadEnvironmentBlock线程环境块),因此
这种⽅法只适⽤于ring0层
本文发布于:2023-03-23 14:58:11,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1679554693357688.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:ntoskrnl.doc
本文 PDF 下载地址:ntoskrnl.pdf
留言与评论(共有 0 条评论) |