(70)内核重载 xp sp3 x86 单核
一、项目说明
这次项目是这样设计的,首先 inline hook NtTerminateProcess 函数,使其他进程不能关闭受保护的进程,这里选择记事本。
然后编写一个普通的程序,调用 TerminateProcess 函数关闭记事本,如无意外是关不掉的。
然后编写驱动,从文件系统中加载一份新内核到内存,拉伸PE,修复重定位表,IAT表,SSDT表;HOOK KiFastCallEntry 函数,让我们的程序系统调用走新内核,这样就可以关掉记事本了。
二、前置任务
首先把保护记事本和关闭记事本的程序给出,这两个没什么难度,不想解释。
效果就是加载保护驱动后,无法 TerminateProcess 关闭记事本。
调用 TerminateProcess 关闭记事本的程序
// KillNotepad.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>// 提权函数:提升为DEBUG权限
BOOL EnableDebugPrivilege()
{HANDLE hToken;BOOL fOk=FALSE;if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){TOKEN_PRIVILEGES tp;tp.PrivilegeCount=1;LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);fOk=(GetLastError()==ERROR_SUCCESS);CloseHandle(hToken);}return fOk;
}int _tmain(int argc, _TCHAR* argv[])
{EnableDebugPrivilege();HWND hWnd = FindWindowA(NULL, "无标题 - 记事本");DWORD dwPid = -1;GetWindowThreadProcessId(hWnd, &dwPid);HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);TerminateProcess(hProcess,0);return 0;
}
保护记事本的驱动
//#include <ntddk.h>
#include <ntifs.h>
#include <ntimage.h>//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------typedef struct _LDR_DATA_TABLE_ENTRY
{LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;UINT16 LoadCount;UINT16 TlsIndex;LIST_ENTRY HashLinks;PVOID SectionPointer;ULONG CheckSum;ULONG TimeDateStamp;PVOID LoadedImports;PVOID EntryPointActivationContext;PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;typedef NTSTATUS (*NTTERMINATEPROCESS) (HANDLE ProcessHandle, NTSTATUS ExitStatus);// 系统服务表
typedef struct _KSYSTEM_SERVICE_TABLE
{PULONG ServiceTableBase; // 函数地址表PULONG ServiceCounterTableBase; // SSDT 函数被调用的次数ULONG NumberOfService; // 函数个数PULONG ParamTableBase; // 函数参数表
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;// SSDT表
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{KSYSTEM_SERVICE_TABLE ntoskrnl; // 内核函数KSYSTEM_SERVICE_TABLE win32k; // win32k.sys 函数KSYSTEM_SERVICE_TABLE unUsed1;KSYSTEM_SERVICE_TABLE unUsed2;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path);
VOID DriverUnload(PDRIVER_OBJECT driver);
VOID PageProtectOff();
VOID PageProtectOn();
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize);
PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress);
VOID HookNtTerminateProcess();
VOID UnhookNtTerminateProcess();
VOID HbgNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus);//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------PDRIVER_OBJECT g_Driver;
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; // 内核导出的全局变量PVOID pNtTerminateProcess;
PVOID pNtTerminateProcessHookRet;// NtTerminateProcess 系统调用号
#define NTTERMINATEPROCESS_INDEX 0x101//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{ g_Driver = driver;driver->DriverUnload = DriverUnload;HookNtTerminateProcess();return STATUS_SUCCESS;
}// 卸载驱动
VOID DriverUnload(PDRIVER_OBJECT driver)
{UnhookNtTerminateProcess();DbgPrint("Kernel Unload Successfully.\n");
}// 关闭页保护
VOID PageProtectOff()
{__asm{cli; // 关闭中断mov eax, cr0;and eax, not 0x10000; // WP位置0mov cr0, eax;}
}// 开启页保护
VOID PageProtectOn()
{__asm{mov eax, cr0;or eax, 0x10000; // WP位置1mov cr0, eax;sti; // 恢复中断}
}// 获取内核基址,大小
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize)
{PLDR_DATA_TABLE_ENTRY pLdteHead; // 内核模块链表头PLDR_DATA_TABLE_ENTRY pLdteCur; // 遍历指针UNICODE_STRING usKrnlBaseDllName; // 内核模块名RtlInitUnicodeString(&usKrnlBaseDllName,L"ntoskrnl.exe");pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;pLdteCur = pLdteHead;do {PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);//DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ\n", pLdteCur->DllBase, pLdteCur->SizeOfImage, &(pLdteCur->FullDllName));if (RtlCompareUnicodeString(&pLdteCur->BaseDllName, &usKrnlBaseDllName, TRUE) == 0){*pKrnlBase = pLdteCur->DllBase;*uKrnlImageSize = pLdteCur->SizeOfImage;return;}pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdteCur->InLoadOrderLinks.Flink;} while (pLdteHead != pLdteCur);return;
}// 特征码搜索
PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress)
{PVOID pCur = pBeginAddress;while (pCur != pEndAddress){if (RtlCompareMemory(bytecode,pCur,bytecodeLen) == bytecodeLen){return pCur;}((ULONG)pCur)++;}return 0;
}// hook NtTerminateProcess
VOID HookNtTerminateProcess()
{ pNtTerminateProcess = (PVOID)KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[NTTERMINATEPROCESS_INDEX];PageProtectOff();// hook NtTerminateProcess ,采取短跳+长跳的方式*(PUCHAR)((ULONG)pNtTerminateProcess - 5) = 0xE9;*(PULONG)((ULONG)pNtTerminateProcess - 4) = (ULONG)HbgNtTerminateProcess - (ULONG)pNtTerminateProcess;*(PUSHORT)pNtTerminateProcess = (USHORT)0xF9EB;PageProtectOn();
}// unhook NtTerminateProcess
VOID UnhookNtTerminateProcess()
{*(PUSHORT)pNtTerminateProcess = (USHORT)0xFF8B;*(PUCHAR)((ULONG)pNtTerminateProcess - 5) = 0xCC;*(PULONG)((ULONG)pNtTerminateProcess - 4) = 0xCCCCCCCC;
}// 被修改的 NtTerminateProcess 函数,简单打印参数
__declspec(naked) VOID HbgNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{PEPROCESS pEprocess;NTSTATUS status;PCHAR ImageFileName;__asm{mov edi,edi;push ebp;mov ebp,esp;pushad;pushfd;sub esp,0x20;}status = ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,*PsProcessType,KernelMode,&pEprocess,NULL);if (!NT_SUCCESS(status)){goto ReturnToNtTerminateProcess;}// 根据镜像文件名判断是不是要保护的进程,字符串最大长度是16,超过就会截断,所以不用担心越界ImageFileName = (PCHAR)pEprocess + 0x174;if (strcmp(ImageFileName, "notepad.exe") == 0){if (ProcessHandle == (HANDLE)0xFFFFFFFF){// 通过关闭按钮关闭goto ReturnToNtTerminateProcess; }else{// 通过任务管理器或其他进程调用TerminateProcess关闭//DbgPrint("Terminate denied. %s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);goto ReturnAccessDenied;}}
ReturnToNtTerminateProcess:pNtTerminateProcessHookRet = (PVOID)((ULONG)pNtTerminateProcess + 5);__asm{add esp,0x20;popfd;popad;jmp pNtTerminateProcessHookRet;}
ReturnAccessDenied:__asm{ add esp,0x20;popfd;popad;leave;mov eax,0xC0000022; // STATUS_ACCESS_DENIEDretn 0x08;}
}
三、内核重载
写不出来,一是能力不足,二是动机不足。
动机方面,后面会学自建调用框架,完美替代内核重载。
能力方面,目前主要存在以下疑问:
- MDL 是什么,不清楚,ExAllocatePool 申请出来的内存似乎还不能执行?
- 修复 IAT 的方式?是否从当前内核内存镜像中复制过来?
- 修复重定位的方式?用老办法修复,还是从当前内核镜像中拷贝?是否必须共用一份全局变量?
- 修复SSDT表,是否是拷贝现有的SSDT表,然后减去新旧内核镜像的地址差?
下面给出目前唯一的成果,0环读写文件的API。
// 读取文件到内存中,返回读取的字节数;读取失败返回0
ULONG FileToMemory(LPCWSTR lpszFile, PVOID *pFileBuffer)
{OBJECT_ATTRIBUTES objectAttributes;IO_STATUS_BLOCK iostatus;HANDLE hfile;UNICODE_STRING KernelFileUnicodeString;NTSTATUS ntStatus;FILE_STANDARD_INFORMATION fsi;PUCHAR pBuffer;//初始化UNICODE_STRING字符串//RtlInitUnicodeString( &KernelFileUnicodeString, L"\\??\\C:\\Windows\\System32\\ntkrnlpa.exe");RtlInitUnicodeString( &KernelFileUnicodeString, lpszFile);//初始化objectAttributesInitializeObjectAttributes(&objectAttributes, &KernelFileUnicodeString,OBJ_CASE_INSENSITIVE, NULL, NULL );//创建文件ntStatus = ZwOpenFile( &hfile, GENERIC_ALL,&objectAttributes, &iostatus, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT);if (!NT_SUCCESS(ntStatus)){KdPrint(("The file is not exist!\n"));return 0;}//读取文件长度ntStatus = ZwQueryInformationFile(hfile,&iostatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);//KdPrint(("The program want to read %d bytes\n",fsi.EndOfFile.QuadPart));//为读取的文件分配缓冲区pBuffer = (PUCHAR)ExAllocatePool(PagedPool,(LONG)fsi.EndOfFile.QuadPart);//读取文件ZwReadFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,(LONG)fsi.EndOfFile.QuadPart,NULL,NULL);//KdPrint(("The program really read %d bytes\n",iostatus.Information));//释放缓冲区//ExFreePool(pBuffer);*pFileBuffer = pBuffer;//关闭文件句柄ZwClose(hfile);return (ULONG)fsi.EndOfFile.QuadPart;
}// 内存数据写入文件
VOID MemoryToFile(PVOID pMemBuffer, ULONG ulSize, LPCWSTR lpszFile)
{OBJECT_ATTRIBUTES objectAttributes;IO_STATUS_BLOCK iostatus;HANDLE hfile;UNICODE_STRING logFileUnicodeString;NTSTATUS ntStatus;//初始化UNICODE_STRING字符串RtlInitUnicodeString( &logFileUnicodeString, lpszFile);//初始化objectAttributesInitializeObjectAttributes(&objectAttributes,&logFileUnicodeString,OBJ_CASE_INSENSITIVE,//对大小写敏感 NULL, NULL );//创建文件ntStatus = ZwCreateFile( &hfile, GENERIC_WRITE,&objectAttributes, &iostatus, NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE,FILE_OPEN_IF,//即使存在该文件,也创建 FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pMemBuffer,ulSize,NULL,NULL);KdPrint(("The program really wrote %d bytes\n",iostatus.Information));//关闭文件句柄ZwClose(hfile);}
(70)内核重载 xp sp3 x86 单核相关推荐
- Windows XP SP3细节官方详解
Windows XP SP3预计本周即将正式发布.上周末,微软在官方网站上放出了名为"Overview of Windows XP Service Pack 3"的细节预览白皮书, ...
- xp sp3安装.Net 4.0提示严重错误,0x80070643,解决办法2017版
客户电脑上要装金税开票软件,需要.net 4.0.30319.1,电脑环境是xp sp3,已经安装了.net 2, .net 3.5sp1,安装.net 4.0的时候提示错误0x80070643 因为 ...
- Windows驱动开发学习笔记(七)—— 多核同步内核重载
Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...
- 微软推出Windows XP SP3中文版
网易科技讯 4月29日消息,在昨日推出Windows XP Service Pack 3英文版后,微软Windows Update网站今日又推出了其中文版的下载. Windows XP SP3包括了自 ...
- 关于Windows XP SP3 的 FAQ
根据 Microsoft 的消息,将在 2008 年第二季度发布的"Windows XP Service Pack 3"将是 Windows XP 的最后一个服务包了.并且 Win ...
- Microsoft Windows XP SP3安装测试手记
作为一名Microsoft TechNet Observer,我近期收到了ITProCity方面关于Windows vista Service Pack 3和Windows XP Service Pa ...
- 一个XP SP3调用0地址蓝屏BUG
0x00 蓝屏的堆栈 在XP SP3上跑POC之后,一段时间之后会出现蓝屏,蓝屏的堆栈如下,可以看出是ACKData里面CALL了一个0指针导致的蓝屏 0x01 蓝屏原因 1 ETW(Event Tr ...
- 关于Windows XP SP2 x86上不支持的两个C++11
这个年代了还有人用Windows XP SP2 x86,我也是醉了... 这个bug估计很少有人遇到吧. std::mutex和std::thread不支持在Windows XP SP2 x86上运行 ...
- 官方原版Windows XP SP3(VOL)中文简体版ISO下载
今天,向各位朋友推荐今年五月,由MSDN官方集成的XP With SP3专业VOL版. 文 件:Windows XP Professional with Service Pack 3 (x86) ...
最新文章
- 我花了三个小时写了一道题的六千字题解....(POJ 2888 Magic Bracelet)
- vs怎么编译php文件,vscode怎么初始编译
- 攻防世界-web-unfinish-从0到1的解题历程writeup
- Metro UI 菜单(Winform)
- Linux5观察doc目录并截屏,linux截屏命令
- 响应式布局之网站头部导航
- 轩辕实验室 |自动驾驶系统安全隐患分析
- 东芝Toshiba DP-2210 打印机驱动
- 第08章 Tableau在线服务器
- 企鹅龙(DRBL)无盘启动+再生龙(clonezilla)网络备份与还原系统
- 红尘梦落,卧醉千年,当所有的繁华散尽
- 专家访谈:Flex技术对web开发的影响
- 学习算法第一天:算法初步
- 李炎恢-在线商城第三季总结
- pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
- html网页全选效果,为什么我用js写的全选/反选/全不选页面,没有效果?
- 原生Servlet的编写
- CodeForces_29B
- opencv opencv contrib
- 北京内推 | 清华大学周伯文老师课题组招聘助理教授/博士后/工程师/访问学生...
热门文章
- python socket发送组播数据_Python socket 如何实现广播单播切换
- 线上redis一般安在linux_redis的zset有多牛?请把耳朵递过来
- android的文件操作,Android文件操作概要1.ppt
- 成功解决ValueError: DataFrame.dtypes for data must be int, float or bool.Did not expect the data types
- TF之DNN:TF利用简单7个神经元的三层全连接神经网络【2-3-2】实现降低损失到0.000以下
- Dataset之Boston:Boston波士顿房价数据集的简介、下载、使用方法之详细攻略
- ML之DT(树模型):DT(树模型算法)算法的简介、代码定义、案例应用之详细攻略
- 微信小程序背景图虚化
- Apache部署网页-Ubuntu16.04
- 数据结构实验之链表一:顺序建立链表(SDUT 2116)