Resume InlineHookSSDT
在InlineHook中修改了zwOpenProcess函数的中的指令
与Resume HookSSDT同理 找出一个正确的值覆盖上去就行、
突发奇想 有没有可能上去一个驱动或者程序 直接卸载掉InlineHook 岂不是很爽
直接映射WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
BOOLEAN
MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize)
{
UNICODE_STRING uniFileFullPath;
OBJECT_ATTRIBUTES oa;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb; HANDLE hFile = NULL;
HANDLE hSection = NULL; if (!wzFileFullPath || !MappingBaseAddress){
return FALSE;
} RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath);
InitializeObjectAttributes(&oa,
&uniFileFullPath,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
); //获得文件句柄
Status = IoCreateFile(&hFile,
GENERIC_READ | SYNCHRONIZE,
&oa, //文件绝对路径
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING
);
if (!NT_SUCCESS(Status))
{ return FALSE;
} oa.ObjectName = NULL;
Status = ZwCreateSection(&hSection,
SECTION_QUERY | SECTION_MAP_READ,
&oa,
NULL,
PAGE_WRITECOPY,
SEC_IMAGE, //?? 指示内存对齐
hFile
);
ZwClose(hFile);
if (!NT_SUCCESS(Status))
{ return FALSE;
}
Status = ZwMapViewOfSection(hSection,
NtCurrentProcess(), //映射到当前进程的内存空间中
MappingBaseAddress,
,
,
,
MappingViewSize,
ViewUnmap,
,
PAGE_WRITECOPY
);
ZwClose(hSection);
if (!NT_SUCCESS(Status))
{
return FALSE;
} return TRUE;
}
映射到ring0层
首先 先获取到ntoskrnl模块信息
BOOLEAN GetSystemMoudleInformationBySystemModuleNameInWin7_X64(char* szFindSystemModuleName,ULONG64* ulMoudleBaseAddress,ULONG32* ulModuleSize)
{
int i = ;
NTSTATUS Status = STATUS_SUCCESS;
PVOID Information = NULL;
ULONG ulNeeds = ; Status = ZwQuerySystemInformation(SystemModuleInformation,NULL,,&ulNeeds); if (Status!=STATUS_INFO_LENGTH_MISMATCH)
{
return FALSE;
}
Information = ExAllocatePool(PagedPool,ulNeeds); //PagedPool(数据段 置换到磁盘) NonPagedPool(代码段 不置换到磁盘) if (Information==NULL)
{
return FALSE;
}
Status = ZwQuerySystemInformation(SystemModuleInformation,Information,ulNeeds,&ulNeeds); if (!NT_SUCCESS(Status))
{
ExFreePool(Information);
return FALSE;
} for (i=;i<((PSYSTEM_MODULE_INFORMATION)Information)->NumberOfModules;i++)
{ if (strstr(((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].ImageName,
szFindSystemModuleName)!=NULL) //Ntoskernel.exe
{
*ulMoudleBaseAddress = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Base;
*ulModuleSize = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Size; if (Information!=NULL)
{
ExFreePool(Information);
Information = NULL;
}
return TRUE; } } if (Information!=NULL)
{
ExFreePool(Information);
Information = NULL;
} return FALSE;
}
win7
BOOLEAN GetSystemMoudleInformationBySystemModuleNameInWinXP_X86(char* szFindSystemModuleName,ULONG32* ulMoudleBaseAddress,ULONG32* ulModuleSize)
{
int i = ;
NTSTATUS Status = STATUS_SUCCESS;
PVOID Information = NULL;
ULONG ulNeeds = ; Status = ZwQuerySystemInformation(SystemModuleInformation,NULL,,&ulNeeds); if (Status!=STATUS_INFO_LENGTH_MISMATCH)
{
return FALSE;
}
Information = ExAllocatePool(PagedPool,ulNeeds); //PagedPool(数据段 置换到磁盘) NonPagedPool(代码段 不置换到磁盘) if (Information==NULL)
{
return FALSE;
}
Status = ZwQuerySystemInformation(SystemModuleInformation,Information,ulNeeds,&ulNeeds); if (!NT_SUCCESS(Status))
{
ExFreePool(Information);
return FALSE;
} for (i=;i<((PSYSTEM_MODULE_INFORMATION)Information)->NumberOfModules;i++)
{ if (strstr(((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].ImageName,
szFindSystemModuleName)!=NULL) //Ntoskernel.exe
{
*ulMoudleBaseAddress = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Base;
*ulModuleSize = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Size; if (Information!=NULL)
{
ExFreePool(Information);
Information = NULL;
}
return TRUE; } } if (Information!=NULL)
{
ExFreePool(Information);
Information = NULL;
} return FALSE;
}
winxp
获取到SSDTAddress
BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
{ PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); //fffff800`03ecf640
PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
PUCHAR i = NULL;
UCHAR v1=,v2=,v3=;
INT64 iOffset = ; //002320c7
ULONG64 VariableAddress = ;
*SSDTAddress = NULL;
for(i=StartSearchAddress;i<EndSearchAddress;i++)
{
if( MmIsAddressValid(i) && MmIsAddressValid(i+) && MmIsAddressValid(i+) )
{
v1=*i;
v2=*(i+);
v3=*(i+);
if(v1==0x4c && v2==0x8d && v3==0x15 )
{
memcpy(&iOffset,i+,);
*SSDTAddress = iOffset + (ULONG64)i + ; break;
}
}
} if (*SSDTAddress==NULL)
{
return FALSE;
}
return TRUE;
}
win7
BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
{
//从NtosKernel.exe 模块中的导出表获得该导出变量 KeServiceDescriptorTable /*
kd> dd KeServiceDescriptorTable
80563520 804e58a0 00000000 0000011c 805120bc
*/
*SSDTAddress = NULL;
*SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable"); if (*SSDTAddress!=NULL)
{
return TRUE;
} return FALSE;
} PVOID
GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
{
UNICODE_STRING uniVariableName;
PVOID VariableAddress = NULL; if (wzVariableName && wcslen(wzVariableName) > )
{
RtlInitUnicodeString(&uniVariableName, wzVariableName); //从Ntos模块的导出表中获得一个导出变量的地址
VariableAddress = MmGetSystemRoutineAddress(&uniVariableName);
} return VariableAddress;
}
WinXP
在通过函数名获取到函数索引
BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,
ULONG32* SSDTFunctionIndex)
{ ULONG32 ulOffset_SSDTFunctionIndex = ; //从Ntdll模块的导出表中获得7c92d5e0
//使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
ULONG i;
BOOLEAN bOk = FALSE;
WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
SIZE_T MappingViewSize = ;
PVOID MappingBaseAddress = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
ULONG32* AddressOfFunctions = NULL;
ULONG32* AddressOfNames = NULL;
USHORT* AddressOfNameOrdinals = NULL;
CHAR* szFunctionName = NULL;
ULONG32 ulFunctionOrdinal = ;
ULONG32 ulFunctionAddress = ; *SSDTFunctionIndex = -; //将Ntdll.dll 当前的空间中
bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
if (bOk==FALSE)
{
return FALSE;
}
else
{
__try{
NtHeader = RtlImageNtHeader(MappingBaseAddress);
if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
for(i = ; i < ExportDirectory->NumberOfNames; i++)
{
szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
if (_stricmp(szFunctionName, szFindFunctionName) == )
{
ulFunctionOrdinal = AddressOfNameOrdinals[i];
ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]); *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
break;
}
}
}
}__except(EXCEPTION_EXECUTE_HANDLER)
{
;
}
} ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); if (*SSDTFunctionIndex==-)
{
return FALSE;
} return TRUE;
}
WinXP
BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
{ ULONG32 ulOffset_SSDTFunctionIndex = ; ULONG i;
BOOLEAN bOk = FALSE;
WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
SIZE_T MappingViewSize = ;
PVOID MappingBaseAddress = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
ULONG32* AddressOfFunctions = NULL;
ULONG32* AddressOfNames = NULL;
USHORT* AddressOfNameOrdinals = NULL;
CHAR* szFunctionName = NULL;
ULONG32 ulFunctionOrdinal = ;
ULONG64 ulFunctionAddress = ; *SSDTFunctionIndex = -; //将Ntdll.dll 当前的空间中
bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
if (bOk==FALSE)
{
return FALSE;
}
else
{
__try{
NtHeader = RtlImageNtHeader(MappingBaseAddress);
if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
for(i = ; i < ExportDirectory->NumberOfNames; i++)
{
szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
if (_stricmp(szFunctionName, szFindFunctionName) == )
{
ulFunctionOrdinal = AddressOfNameOrdinals[i];
ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]); *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
break;
}
}
}
}__except(EXCEPTION_EXECUTE_HANDLER)
{
;
}
} ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); if (*SSDTFunctionIndex==-)
{
return FALSE;
} return TRUE;
}
win7
得到索引后 就能得到函数的地址
找到函数的地址 然后在映射的内存中取出争取的地址 回复回去
http://www.cnblogs.com/yifi/p/4968944.html
Resume InlineHookSSDT的更多相关文章
- Pause/Resume Instance 操作详解 - 每天5分钟玩转 OpenStack(34)
本节通过日志详细分析 Nova Pause/Resume 操作. 有时需要短时间暂停 instance,可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中.当需要恢复的时候,执 ...
- ZeroMQ接口函数之 :zmq_proxy_steerable – 以STOP/RESUME/TERMINATE控制方式开启内置的ZMQ代理
ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ——————————————————————————————————— ...
- Win10开机提示Resume from Hibernation该怎么办?
Windows10系统的电脑开机提示:Resume from Hibernation(从休眠恢复),这是电脑没有真正关机,而是上次关机时进入了[休眠状态],所以开机时提示:从休眠恢复.如何解决Wind ...
- Delphi线程简介---Create及其参数、Resume、Suspend
TThread在Classes单元里的声明如下 type TThread = class private FHandle: THandle; FThreadID: THandle; FTerminat ...
- 转,CV和resume的区别
一直以来,BBS上的信息资料都传达给我一个网上“主流”的关于CV和resume的看法: CV约等于Resume,前者略倾向于学术,后者略倾向于工作经验,字数控制在1-2页内 说实话,一直以来我也就这么 ...
- 被废弃的 Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit
最近学习多线程的知识,看到API里说这些方法被废弃了,就查了一下原因 Thread.stop 这个方法会解除被加锁的对象的锁,因而可能造成这些对象处于不一致的状态,而且这个方法造成的ThreadDea ...
- Don’t use Suspend and Resume, but don’t poll either.
http://www.paradicesoftware.com/blog/2014/02/dont-use-suspend-and-resume-but-dont-poll-either/ Don’t ...
- Android中Linux suspend/resume流程
Android中Linux suspend/resume流程首先我们从linux kernel 的suspend说起,不管你是使用echo mem > /sys/power/state 或者使用 ...
- Delphi 线程resume 不能调用Execute
如果Resume不能唤起线程,请试试如下的函数,试试. GetExitCodeThread(ThreadHandle,ExitCode)来取得ExitCode,如果ExitCode=STILL_ACT ...
随机推荐
- django的安装和搭建
一.先下载pyton,配置下python的环境变量,这个很重要,然后下载django,解压到与python同一个根目录底下,进入django目录,运行python setup.py install安装 ...
- .net连接access操作类
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- HTML5 学习笔记--------》HTML5概要与新增标签!
一.HTML5概要 1.1.为什么需要HTML5 HTML4陈旧不能满足日益发展的互联网需要,特别是移动互联网.为了增强浏览器功能Flash被广泛使用,但安全与稳定堪忧,不适合在移动端使用(耗电. ...
- 分享几个Javascript 封装方法
基本封装方法 请看下面的例子: var Person = function(name,age){ this.name = name; this.age = age || "未填写" ...
- [css]【转载】CSS样式分离之再分离
原文链接:http://www.zhangxinxu.com/wordpress/2010/07/css%E6%A0%B7%E5%BC%8F%E5%88%86%E7%A6%BB%E4%B9%8B%E5 ...
- TCP/IP 小知识
子网掩码有数百种,这里只介绍最常用的两种子网掩码,它们分别是“255.255.255.0”和“255.255.0.0”. 1.子网掩码是“255.255.255.0”的网络:最后面一个数字可以在0~2 ...
- 转:桥接模式(Bridge)
转自:http://www.cnblogs.com/rush/archive/2011/06/29/2093743.html 分析十分透彻明了 可以再结合另外一篇文章中的示例理解(http://b ...
- 转!!Java垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- js获取时间格式化
http://www.cnblogs.com/zhangpengshou/archive/2012/07/19/2599053.html
- DedeCMSV57数据库结构文档
表名:dede_addonarticle(ENGINE=MyISAM/CHARSET=gbk) 说明:Top 字段名 说明描述 具体参数 aid 文章ID mediumint(8) unsig ...