过一般保护(6)

2020-04-14 00:29

strcpy(KrnlInfo->HalName,AnsiString.Buffer);

KrnlInfo->ModuleBase[1]=(DWORD)DataTableEntry->DllBase; if ( NT_SUCCESS(Status) ) {

RtlFreeAnsiString(&AnsiString); //释放空间 }

count++; if(count==2) {

return TRUE; } }

NextEntry = NextEntry->Flink; }

return FALSE;

}

2,在内核驱动中把MS未导出的函数定义成函数指针,然后用户层通过解析PDB文件得到真正的函数地址传进内核驱动,定义如下:

NTSTATUS (WINAPI *PsResumeThread)(IN PETHREAD Thread,OUT PULONG PreviousSuspendCount OPTIONAL);

NTSTATUS (WINAPI *PsTerminateProcess)(IN PEPROCESS Process,IN NTSTATUS Status);

PEPROCESS (WINAPI *PsGetNextProcess) (IN PEPROCESS Process);

PETHREAD (WINAPI *PsGetNextProcessThread) (IN PEPROCESS Process,IN PETHREAD Thread);

VOID (WINAPI *PsQuitNextProcessThread) (IN PETHREAD Thread);

VOID (WINAPI *PsCallImageNotifyRoutines)(IN PUNICODE_STRING FullImageName,IN HANDLE ProcessId, IN PIMAGE_INFO ImageInfo );

NTSTATUS (WINAPI *PsSuspendThread) (IN PETHREAD Thread,OUT PULONG PreviousSuspendCount );

NTSTATUS (WINAPI *MmGetFileNameForAddress) (IN PVOID ProcessVa,OUT PUNICODE_STRING FileName);

NTSTATUS (WINAPI *MmGetFileNameForSection) (IN PVOID SectionObject,OUT POBJECT_NAME_INFORMATION *FileNameInfo);

NTSTATUS (WINAPI * MmCopyVirtualMemory)(IN PEPROCESS FromProcess,IN CONST VOID *FromAddress,IN PEPROCESS ToProcess,OUT PVOID ToAddress,IN SIZE_T BufferSize,IN KPROCESSOR_MODE PreviousMode,OUT PSIZE_T NumberOfBytesCopied);

NTSTATUS (WINAPI *ObDuplicateObject) (IN PEPROCESS SourceProcess,IN HANDLE SourceHandle,IN PEPROCESS TargetProcess OPTIONAL,OUT PHANDLE TargetHandle OPTIONAL,IN ACCESS_MASK DesiredAccess,IN ULONG HandleAttributes,IN ULONG Options,IN KPROCESSOR_MODE PreviousMode );

20

VOID (WINAPI *KeFreezeAllThreads) (VOID); VOID (WINAPI *KeThawAllThreads) (VOID);

VOID (FASTCALL *KiReadyThread)(IN PKTHREAD Thread); VOID (WINAPI * KiSetSwapEvent)();

BOOLEAN (WINAPI *KiSwapProcess) (IN PKPROCESS NewProcess,IN PKPROCESS OldProcess);

int (FASTCALL *KiSwapThread) ();

NTSTATUS (FASTCALL *MiMakeProtectionMask)(unsigned int a1);

NTSTATUS (WINAPI*MiProtectVirtualMemory) (IN PEPROCESS Process,IN PVOID *BaseAddress,IN PULONG RegionSize,IN ULONG NewProtectWin32,IN PULONG LastProtect);

NTSTATUS (WINAPI *PspCreateThread)(OUT PHANDLE ThreadHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLE ProcessHandle,IN PEPROCESS ProcessPointer,OUT PCLIENT_ID ClientId OPTIONAL,IN PCONTEXT ThreadContext OPTIONAL,IN PINITIAL_TEB InitialTeb OPTIONAL,IN BOOLEAN CreateSuspended,IN PKSTART_ROUTINE StartRoutine OPTIONAL,IN PVOID StartContext);

void (WINAPI *IopDeallocateApc)(PVOID P, int a2, int a3, int a4, int a5);

NTSTATUS (WINAPI *LpcRequestWaitReplyPortEx) (IN PVOID PortAddress,IN PPORT_MESSAGE RequestMessage,OUT PPORT_MESSAGE ReplyMessage); VOID (FASTCALL *HalRequestSoftwareInterrupt) (KIRQL RequestIrql); VOID (FASTCALL *KiUnlockDispatcherDatabase)(KIRQL irql); VOID (WINAPI *KeContextFromKframes)(IN PKTRAP_FRAME TrapFrame,PKEXCEPTION_FRAME ExceptionFrame,PCONTEXT ContextFrame); VOID (WINAPI *KeContextToKframes) ( PKTRAP_FRAME TrapFrame,PKEXCEPTION_FRAME ExceptionFrame,IN PCONTEXT ContextFrame,IN ULONG ContextFlags,IN KPROCESSOR_MODE PreviousMode); BOOLEAN (WINAPI *KiCheckForAtlThunk) (IN PEXCEPTION_RECORD ExceptionRecord,IN PCONTEXT Context);

BOOLEAN (WINAPI *RtlDispatchException) (IN PEXCEPTION_RECORD ExceptionRecord,IN PCONTEXT ContextRecord);

BOOLEAN (WINAPI *KdIsThisAKdTrap) (IN PEXCEPTION_RECORD ExceptionRecord,IN PCONTEXT ContextRecord,IN KPROCESSOR_MODE PreviousMode);

VOID (WINAPI *KiSegSsToTrapFrame ) (IN PKTRAP_FRAME TrapFrame,IN ULONG SegSs);

VOID (WINAPI *KiEspToTrapFrame)(IN PKTRAP_FRAME TrapFrame,IN ULONG Esp); ULONG (WINAPI *KiCopyInformation) (IN OUT PEXCEPTION_RECORD

21

ExceptionRecord1,IN PEXCEPTION_RECORD ExceptionRecord2); BOOLEAN

(WINAPI *KiDebugRoutine) (

IN PKTRAP_FRAME TrapFrame,

IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord,

IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance );

3,Ring3层程序调用微软提供的SymLoadModule64()函数把这两个内核PDB文件加载到Od进程空间,具体代码如下: //装入PDB文件

DWORD64 HxLoadSym(const char* szSymPath,unsigned long ulBase) {

DWORD dwFileSize=0; HANDLE hFile = NULL;

DWORD64 dw64ModAddress = 0;

hFile = CreateFile(szSymPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );

if( INVALID_HANDLE_VALUE == hFile ) {

_tprintf(_T(\when open %s: %d\szSymPath, GetLastError()); return 0; }

if( INVALID_FILE_SIZE == ( dwFileSize = GetFileSize(hFile, NULL)) ) {

_tprintf(_T(\GetLastError()); return 0; }

CloseHandle(hFile);

dw64ModAddress = SymLoadModule64(GetCurrentProcess(),NULL,(PSTR)szSymPath,NULL,ulBase,dwFileSize);

if( dw64ModAddress == 0 ) {

_tprintf(_T(\when SymLoadModule64(): %d \\n\

22

GetLastError()); return 0; }

return dw64ModAddress; }

4,对hal.dll和ntoskrnl.exe分别调用SymEnumSymbols()函数得到内核未导出的函数的地址,SymEnumSymbols()要求一个回调函数,它的类型是BOOL CALLBACK SymEnumSymbolsProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext );我们可以根据pSymInfo->Name和我们要得到的未导出的函数的名字比较,如果相等,则返回函数地址。具体代码如下:

BOOL HxFindSymBols(DWORD64 pSym,PHX_DYNC_FUNCTION fnList,int nLen) {

g_Nlen=nLen; g_fnList=fnList;

if(!SymEnumSymbols( GetCurrentProcess(), pSym,

NULL, // Null point out that list all symbols SymEnumSymbolsProc, NULL)) {

_tprintf( _T(\when SymEnumSymbols(): %d \\n\GetLastError() ); }

return TRUE; } BOOL CALLBACK SymEnumSymbolsProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext ) {

DWORD i;

char a[200]={0};

char funcname[60]={0}; if( pSymInfo != 0 ) {

strcpy(funcname,pSymInfo->Name); for(i=0;i

if(strcmp(g_fnList[i].FunName,funcname)==0)//比较函数名字是否相等

{

g_fnList[i].FunAddr=(DWORD)pSymInfo->Address; break;

23

}

} } }

return TRUE;

5.4 向Windows系统内核中加入我们自己的系统服务表

Windows系统中有两个系统服务表,一个是KeServiceDescriptorTable,还有一个是KeServiceDescriptorTableShadow,它们的区别就是如果线程是GUI线程,则这个线程最后会从KeServiceDescriptorTableShadow服务表中找系统调用的地址然后去调用,当Ring3层的API调用最终调用sysenter指令进入Ring0时,这条指令会让CPU的指令指针寄存器(EIP)指向KiFastCallEntry(),然后CPU会运行KiFastCallEntry(),kiFastCallEntry()函数会根据系统调用ID从KeServiceDescriptorTable表或者从KeServiceDescriptorTableShadow表找取对应的系统调用函数然后去调用它。下面是用Windbg调试器看的我机器上这两种系统服务表的情况:

lkd> dd KeServiceDescriptorTable

8055d700 80505460 00000000 0000011c 805058d4 8055d710 00000000 00000000 00000000 00000000 8055d720 00000000 00000000 00000000 00000000 8055d730 00000000 00000000 00000000 00000000

lkd> dd KeServiceDescriptorTableShadow

8055d6c0 80505460 00000000 0000011c 805058d4 8055d6d0 bf99ce80 00000000 0000029b bf99db90 8055d6e0 00000000 00000000 00000000 00000000 8055d6f0 00000000 00000000 00000000 00000000

系统服务描述表结构定义如下

typedef struct _SERVICE_DESCRIPTOR_TABLE {

PVOID *ServiceTable; //指向真正的系统服务地址表

PULONG CounterTable;//系统调用的记录,调用了多少次,在Check版本才有效

ULONG TableSize;//表的大小,Windows总共提供了多少个系统调用

PUCHAR ArgumentTable;//参数大小表,每个系统调用要的参数大小,大小以字节为单位

} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

所以我们要做的是调用ExAllocatePool在Windows系统的非分页内存中分配空间,然后初始化它们。最后依次改变KeServiceDescriptorTable和KeServiceDescriptorTableShadow系统服务表的ServiceTable成员和

24


过一般保护(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:FreeBSD 使用手册-安装篇

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: