过一般保护(4)

2019-03-23 11:57

5系统详细设计

5.1 HOOK ntdll.dll的KiFastSystemCall()函数

下面这是用Windbg看的KiFastSystemCall函数,如下,它只有四个字节,一般的HOOK至少要5个字节以上。所以我们要采用另一种方式HOOK,在ntdll.dll里找到一片没有用的内存,正好KiFastSystemCall上面10个字节就没有用到。所以我们可以在这10个字节里填入我们最终要跳转到的地址,然后从KiFastSystemCall函数开头处改写代码使其跳到KiFastSystemCall-10字节处就行了,具体的HOOK代码和UnHook代码如下: 0:001> u KiFastSystemCall ntdll!KiFastSystemCall:

7c92e4f0 8bd4 mov edx,esp 7c92e4f2 0f34 sysenter

BOOL HOOK() {

PCHAR fun;

UCHAR HookCode[5]={0}; UCHAR Hook[2]={0}; fun = (PCHAR)GetProcAddress(GetModuleHandle(\;//得到KiFastSystemCall函数映射的地址 if (fun!= NULL) {

DWORD lOldProtect; DWORD oldprotect; fun-=10;

if(VirtualProtect((PVOID)((DWORD)fun),14,PAGE_EXECUTE_READWRITE,&lOldProtect))//改写代码段内存为可读写和执行的权限,方便我们能改写代码段 {

fun[0]=0xE9;

*((DWORD*)(fun+1))=((DWORD)HxKiFastSystemCall - (DWORD)fun-5);

fun+=10; fun[0]=0xEB; fun[1]=0xF4;

15

VirtualProtect((PVOID)((DWORD)fun-10),14,lOldProtect,&oldprotect); hookFunctionAddr=fun; return TRUE; } }

return FALSE; }

BOOL UNHOOK() {

if (hookFunctionAddr!= NULL) {

DWORD lOldProtect;

PCHAR fun = hookFunctionAddr;

if(VirtualProtect((PVOID)((DWORD)fun),4,PAGE_EXECUTE_READWRITE,&lOldProtect)) {

fun[0]=0x8b; fun[1]=0xd4;

VirtualProtect((PVOID)((DWORD)fun),4,lOldProtect,NULL); } }

return TRUE; }

5.2 实现HOOK的HxKiFastSystemCall(),改变系统调用的流程

当OD调试器调用一般的API时比如OpenProcess(),ReadVirtualMemory(),WriteVirtualMemory()函数时,最终会进入KiFastSystemCall()这个函数,从而进入我们自己实现的HxKiFastSystemCall()函数,在进入HxKiFastSystemCall函数的环境下,eax指向调用此API对应的系统调用ID,esp指向堆栈,里面放着用户层传来的参数。在这里我们把此函数定义成__declspec( naked ),这么定义是为了防止编译器额外的加上优化和自动保护堆栈代码。在此之前我们先要把esp压栈,保存上下文。然后传进系统调用ID,然后调用FilterServiceFun()函数对我们感兴趣的服务ID进行过滤改变,然后eax返回的是我们改写过的系统调用ID,之后再次调用sysenter真正的进行系统调用,实现Ring3进入Ring0层,这里没用sysenter指令,因为vc 6.0编译器不识别它,我用的是二进制代码,具体实现代码如下:

__declspec( naked ) HxKiFastSystemCall() { __asm {

push esp; //保存堆栈

16

push eax; //服务Id call FilterServiceFun; pop esp; mov edx,esp

__asm _emit 0x0F //sysenter指令进入ring0 __asm _emit 0x34 } }

extern DWORD MyServiceStartID;

int WINAPI FilterServiceFun(DWORD ServiceId) {

DWORD MyServicId; switch(ServiceId) {

case 122: //

MyServicId=MyServiceStartID; //OutputDebugStringA(\层调用了NtOpenProcess()\ break; case 128:

MyServicId=MyServiceStartID+1;

// OutputDebugStringA(\层调用了NtOpenThread()\ break; case 125:

MyServicId=MyServiceStartID+2;

// OutputDebugStringA(\层调用了NtOpenSection()\ break; case 53:

MyServicId=MyServiceStartID+3;

// OutputDebugStringA(\层调用了NtCreateThread()\ break; case 180:

MyServicId=MyServiceStartID+4;

// OutputDebugStringA(\层调用了NtQueueApcThread()\ break; case 186:

MyServicId=MyServiceStartID+5;

// OutputDebugStringA(\层调用了NtReadVirtualMemory()\ break; case 277:

MyServicId=MyServiceStartID+6;

// OutputDebugStringA(\层调用了NtWriteVirtualMemory()\ break; case 137:

17

MyServicId=MyServiceStartID+7;

//OutputDebugStringA(\层调用了NtProtectVirtualMemory()\ break; case 33:

MyServicId=MyServiceStartID+8;

// OutputDebugStringA(\层调用了NtCreateDebugObject()\ break; case 57:

MyServicId=MyServiceStartID+9;

// OutputDebugStringA(\层调用了NtDebugActiveProcess()\ break; case 58:

MyServicId=MyServiceStartID+10;

// OutputDebugStringA(\层调用了NtDebugContinue()\ break; case 269:

MyServicId=MyServiceStartID+11;

// OutputDebugStringA(\层调用了NtWaitForDebugEvent()\ break; case 223:

MyServicId=MyServiceStartID+12; // OutputDebugStringA(\层调用了NtSetInformationDebugObject()\ break; default:

MyServicId = ServiceId; }

return MyServicId; }

5.3 解析微软提供的PDB文件得到未导出的内核函数地址

1,Ring0层内核驱动先通过遍历当前Windows系统的内核模块链表得到hal.dll和ntoskrnl.exe内核模块的装载地址,然后传给Ring3层程序。具体代码如下:

BOOL HxGetKenelNameAndLoadAddr(HX_OSKRNL_INFO *KrnlInfo) {

NTSTATUS Status;

PLDR_DATA_TABLE_ENTRY DataTableEntry; ANSI_STRING AnsiString; PLIST_ENTRY NextEntry;

UNICODE_STRING KernelString; UNICODE_STRING HalString; int count=0;

18

ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);

KernelString.Buffer = (const PUSHORT) KERNEL_NAME;

KernelString.Length = sizeof (KERNEL_NAME) - sizeof (WCHAR); KernelString.MaximumLength = sizeof KERNEL_NAME;

HalString.Buffer = (const PUSHORT) HAL_NAME;

HalString.Length = sizeof (HAL_NAME) - sizeof (WCHAR); HalString.MaximumLength = sizeof HAL_NAME;

NextEntry = PsLoadedModuleList->Flink; while (NextEntry != PsLoadedModuleList) {

DataTableEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

//第一次得到内核的名字和装载基址

if (RtlEqualUnicodeString (&KernelString, &DataTableEntry->BaseDllName, TRUE)) {

DbgPrint(%ullDllName);

Status=RtlUnicodeStringToAnsiString(&AnsiString,&DataTableEntry->FullDllName,TRUE);

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

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

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

count++; }

//比较得到Hal.dll内核的装载基址

if (RtlEqualUnicodeString (&HalString, &DataTableEntry->BaseDllName, TRUE)) {

Status=RtlUnicodeStringToAnsiString(&AnsiString,&DataTableEntry->FullDllName,TRUE);

19


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

下一篇:部编新人教版七年级历史下册知识点复习提纲(改版) - 图文

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

马上注册会员

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