drv experiment : 从内核API代码定位函数地址或结构指针地址

来源:互联网 发布:如何防sql注入 编辑:程序博客网 时间:2024/05/19 16:35

用WinDbg看已经导出的内核API代码, 如果看到需要的未导出函数调用或想直接从汇编代码中定位那个API地址,

可以定位 CALL指令中未导出函数地址.


未导出函数地址 = 已经导出的内核API首地址 + 计算出的 硬编码偏移.


得到已经导出的内核API地址

PVOID GetKernelApiAddress(wchar_t * pcApiName){    UNICODE_STRING str;    if (NULL == pcApiName)        return NULL;    RtlInitUnicodeString(&str, pcApiName);    /// MmGetSystemRoutineAddress    /// If the function name can be resolved,     /// the routine returns a pointer to the function.     /// Otherwise, the routine returns NULL.    return MmGetSystemRoutineAddress(&str);}

用WinDbg反汇编已导出内核API, 手工计算出未导出API地址的相对偏移.

例如: 从 KeCapturePersistentThreadState 中得到 KdGetDataBlockAPI地址.

kd> uf 0x804f286ant!KeCapturePersistentThreadState:804f286a 8bff            mov     edi,edi804f286c 55              push    ebp804f286d 8bec            mov     ebp,esp804f286f 51              push    ecx804f2870 53              push    ebx804f2871 8b5d24          mov     ebx,dword ptr [ebp+24h]804f2874 56              push    esi804f2875 e814510000      call    nt!KdGetDataBlock (804f798e)804f287a 33f6            xor     esi,esi


uf nt!KdGetDataBlock

nt!KdGetDataBlock:804f798e b8e06a5480      mov     eax,offset nt!KdDebuggerDataBlock (80546ae0)804f7993 c3              ret

手工计算需要的未导出API的过程


addr_KeCapturePersistentThreadState = 0x804f286a

offset_call_KdGetDataBlock = 0x804f2875 - addr_KeCapturePersistentThreadState;

addr_call_KdGetDataBlock = addr_KeCapturePersistentThreadState + offset_call_KdGetDataBlock;

offset_KdGetDataBlock = (ULONG)(*(ULONG *)(addr_call_KdGetDataBlock + 1)); ///< Call命令为0xe8, 一个字节

len_call_KdGetDataBlock = 5; ///<  e814510000 一共5个字节

addr_KdGetDataBlock = addr_call_KdGetDataBlock  + len_call_KdGetDataBlock  + offset_KdGetDataBlock ;///< get it ~


如果在内核API反汇编代码中要得到数据结构指针地址, 同理.

只要有内核API用到了这个数据结构指针, 就能找到.

例如: nt!KdGetDataBlock API中的 数据结构指针 nt!KdDebuggerDataBlock


nt!KdDebuggerDataBlock 是未文档的数据结构 KD_DEBUGGER_DATA_BLOCK

如果该数据结构定义未知, 那就得在网上搜索前辈们逆向出来的数据结构资料了.

http://gr8lkd.googlecode.com/svn/trunk/sys/dumptypes.h

typedef struct _KD_DEBUGGER_DATA_BLOCK {ULONG  Unknown1[4];ULONG  ValidBlock; // 'GBDK'ULONG  Size; // 0x290PFUNC<PVOID>  _imp__VidInitialize;PFUNC<PVOID>  RtlpBreakWithStatusInstruction;ULONG  Unknown2[4];PFUNC<PVOID>  KiCallUserMode;ULONG  Unknown3[2];PFUNC<PVOID>  PsLoadedModuleList;PFUNC<PVOID>  PsActiveProcessHead;PFUNC<PVOID>  PspCidTable;PFUNC<PVOID>  ExpSystemResourcesList;PFUNC<PVOID>  ExpPagedPoolDescriptor;PFUNC<PVOID>  ExpNumberOfPagedPools;PFUNC<PVOID>  KeTimeIncrement;PFUNC<PVOID>  KeBugCheckCallbackListHead;PFUNC<PVOID>  KiBugCheckData;PFUNC<PVOID>  IopErrorLogListHead;PFUNC<PVOID>  ObpRootDirectoryObject;PFUNC<PVOID>  ObpTypeObjectType;PFUNC<PVOID>  MmSystemCacheStart;PFUNC<PVOID>  MmSystemCacheEnd;PFUNC<PVOID>  MmSystemCacheWs;PFUNC<PVOID>  MmPfnDatabase;PFUNC<PVOID>  MmSystemPtesStart;PFUNC<PVOID>  MmSystemPtesEnd;PFUNC<PVOID>  MmSubsectionBase;PFUNC<PVOID>  MmNumberOfPagingFiles;PFUNC<PVOID>  MmLowestPhysicalPage;PFUNC<PVOID>  MmHighestPhysicalPage;PFUNC<PVOID>  MmNumberOfPhysicalPages;PFUNC<PVOID>  MmMaximumNonPagedPoolInBytes;PFUNC<PVOID>  MmNonPagedSystemStart;PFUNC<PVOID>  MmNonPagedPoolStart;PFUNC<PVOID>  MmNonPagedPoolEnd;PFUNC<PVOID>  MmPagedPoolStart;PFUNC<PVOID>  MmPagedPoolEnd;PFUNC<PVOID>  MmPagedPoolInfo;PFUNC<PVOID>  Unknown4;PFUNC<PVOID>  MmSizeOfPagedPoolInBytes;PFUNC<PVOID>  MmTotalCommitLimit;PFUNC<PVOID>  MmTotalCommittedPages;PFUNC<PVOID>  MmSharedCommit;PFUNC<PVOID>  MmDriverCommit;PFUNC<PVOID>  MmProcessCommit;PFUNC<PVOID>  MmPagedPoolCommit;PFUNC<PVOID>  Unknown5;PFUNC<PVOID>  MmZeroedPageListHead;PFUNC<PVOID>  MmFreePageListHead;PFUNC<PVOID>  MmStandbyPageListHead;PFUNC<PVOID>  MmModifiedPageListHead;PFUNC<PVOID>  MmModifiedNoWritePageListHead;PFUNC<PVOID>  MmAvailablePages;PFUNC<PVOID>  MmResidentAvailablePages;PFUNC<PVOID>  PoolTrackTable;PFUNC<PVOID>  NonPagedPoolDescriptor;PFUNC<PVOID>  MmHighestUserAddress;PFUNC<PVOID>  MmSystemRangeStart;PFUNC<PVOID>  MmUserProbeAddress;PFUNC<PVOID>  KdPrintCircularBuffer;PFUNC<PVOID>  KdPrintWritePointer;PFUNC<PVOID>  KdPrintWritePointer2;PFUNC<PVOID>  KdPrintRolloverCount;PFUNC<PVOID>  MmLoadedUserImageList;PFUNC<PVOID>  NtBuildLab;PFUNC<PVOID>  Unknown6;PFUNC<PVOID>  KiProcessorBlock;PFUNC<PVOID>  MmUnloadedDrivers;PFUNC<PVOID>  MmLastUnloadedDriver;PFUNC<PVOID>  MmTriageActionTaken;PFUNC<PVOID>  MmSpecialPoolTag;PFUNC<PVOID>  KernelVerifier;PFUNC<PVOID>  MmVerifierData;PFUNC<PVOID>  MmAllocateNonPagedPool;PFUNC<PVOID>  MmPeakCommitment;PFUNC<PVOID>  MmTotalCommitLimitMaximum;PFUNC<PVOID>  CmNtCSDVersion;PFUNC<PVOID>  MmPhysicalMemoryBlock;PFUNC<PVOID>  MmSessionBase;PFUNC<PVOID>  MmSessionSize;PFUNC<PVOID>  Unknown7;} KD_DEBUGGER_DATA_BLOCK, *PKD_DEBUGGER_DATA_BLOCK;










原创粉丝点击