如何获取ssdt函数索引
cuckoo源码分析
MapNtdllIntoMemory()主要作用在内存中加载一份ntdll.dll,然后获取导出目录表地址。
PVOID MapNtdllIntoMemory()
{NTSTATUS status;HANDLE hSection;OBJECT_ATTRIBUTES objAttr;UNICODE_STRING pathFile;USHORT NumberOfSections;SECTION_IMAGE_INFORMATION sii = {0};PVOID pSection = NULL;PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNtHeader = NULL;PIMAGE_NT_HEADERS64 pNtHeader64 = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = NULL;DWORD dwExportRVA, dwExportSize;RtlInitUnicodeString(&pathFile, L"\\KnownDlls\\ntdll.dll");InitializeObjectAttributes(&objAttr, &pathFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);if(NT_SUCCESS(status = ZwOpenSection(&hSection, SECTION_MAP_READ, &objAttr))){ZwQuerySection(hSection, 1, &sii, sizeof(sii), 0);Dbg("ntdll entry point : %llx\n", sii.EntryPoint);Ntdll_ImageBase = sii.EntryPoint;pDosHeader = (PIMAGE_DOS_HEADER)Ntdll_ImageBase;#ifdef _M_X64pNtHeader64 = (PIMAGE_NT_HEADERS64)((unsigned char*)Ntdll_ImageBase+pDosHeader->e_lfanew); pSectionHeader = (PIMAGE_SECTION_HEADER)((unsigned char*)pNtHeader64+sizeof(IMAGE_NT_HEADERS64)); dwExportRVA = pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;dwExportSize = pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;#endifpNtHeader = (PIMAGE_NT_HEADERS)((unsigned char*)Ntdll_ImageBase+pDosHeader->e_lfanew); pSectionHeader = (PIMAGE_SECTION_HEADER)((unsigned char*)pNtHeader+sizeof(IMAGE_NT_HEADERS)); dwExportRVA = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;dwExportSize = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;Dbg("Export table address : 0x%08x\n", dwExportRVA);Dbg("Export table size : 0x%08x\n", dwExportSize);Dbg("EAT : 0x%08X\n", (PIMAGE_EXPORT_DIRECTORY)((unsigned char*)Ntdll_ImageBase+dwExportRVA));pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((unsigned char*)Ntdll_ImageBase+dwExportRVA);Dbg("number of exported functions : 0x%08x\n", pImageExportDirectory->NumberOfFunctions);}ZwClose(hSection);return pImageExportDirectory;
}
GetSyscallNumber()通过导出目录表的地址,获取要hook的函数地址,得到函数体,在通过硬编码来获取操作系统索引id的数字编码,然后取得到系统服务号(syscall)。
ULONG GetSyscallNumber(__in PIMAGE_EXPORT_DIRECTORY pImageExportDirectory, __in PUCHAR funcName, __in ULONG offsetSyscall)
{PULONG addrName = NULL, addrFunc = NULL;PWORD addrOrdinal = NULL;ULONG i = 0;PCHAR name = NULL;SIZE_T n;if(pImageExportDirectory && funcName){addrName = (PULONG)((unsigned char*)Ntdll_ImageBase + pImageExportDirectory->AddressOfNames);addrFunc = (PULONG)((unsigned char*)Ntdll_ImageBase + pImageExportDirectory->AddressOfFunctions);addrOrdinal = (PWORD)((unsigned char*)Ntdll_ImageBase + pImageExportDirectory->AddressOfNameOrdinals);for(i=0; i < pImageExportDirectory->NumberOfNames; ++i){name = ((unsigned char*)Ntdll_ImageBase + addrName[i]);__try{ProbeForRead(name, 0, 1);RtlStringCchLengthA(funcName, NTSTRSAFE_MAX_CCH, &n);if(RtlEqualMemory(funcName, name, n)){Dbg("[+] FOUND : %s\n", name);Dbg("addr : 0x%08x\n", ((unsigned char*)Ntdll_ImageBase + addrFunc[addrOrdinal[i]]));Dbg("syscall : %x\n", *(PULONG)((PUCHAR)((unsigned char*)Ntdll_ImageBase + addrFunc[addrOrdinal[i]]+offsetSyscall)));return *(PULONG)((PUCHAR)((unsigned char*)Ntdll_ImageBase + addrFunc[addrOrdinal[i]]+offsetSyscall));}}__except(EXCEPTION_EXECUTE_HANDLER){Dbg("Exception : %x\n", GetExceptionCode());}}}return 0;
}
以下是每个NT函数的汇编代码,函数地址+1的位置就是系统服务号,通过系统服务号(syscall)就可以从ssdt表中找到对应的函数
Install_Hook()
针对win32的ssdt_hook
因为在windows 7 32位的操作系统中ssdt表是导出的,所以可以直接import获取到这个结构体的地址
__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;
源码中定义一个宏
#define SYSTEMSERVICE(_syscall)
KeServiceDescriptorTable.ServiceTableBase[_syscall]
核心代码
OrigFunc是原函数地址,hookedFunc是新函数地址
*origFunc = (PVOID)SYSTEMSERVICE(syscall);
(PVOID)SYSTEMSERVICE(syscall) = hookedFunc;
如何获取ssdt函数索引相关推荐
- ssdt函数索引号_【NT】一行代码获取SSDT服务索引号
注:本文是以32位的windows7为实例. 今天在研究SSDT的过程中看到了一个大神写的教程,其中还附了一些代码,代码主要讲解的是SSDT hook过程,我在他的代码中没有看到任何有关服务函数的索引 ...
- win10 64位SSDT函数索引动态查找
在win10 64位下SSDT是不导出的.同时如果你要hook某个函数时你要知道他的索引,以前都是调试或者网上找然后硬编码进去.这里动态找. 原理是上层调用的所有函数都经过ntdll 然后进入0环,进 ...
- 使用WinDbg获取SSDT 系统服务描述表的函数服务号(索引)
今天研究了一下午SSDT的东东,最尴尬的是起初我不知道如何获取到SSDT的函数服务号,而这个玩意儿在不同版本的windows是不一样的,后面经过研究还是找到了正确的方法.这里简单的分享一下. · ...
- php 函数索引 中文索引
PHP 函数索引 (共有 967 个函数) Abs: 取得绝对值. Acos: 取得反余弦值. ada_afetch: 取得数据库的返回列. ada_autocommit: 开关自动改动功能. ada ...
- 通过名字获得ssdt函数的序号
假设现在我们已经能够获得ssdt表的位置,能够实现对ssdt函数地址替换,那么现在又一个问题就是找到想要hook的ssdt函数. 由于不同版本的操作系统下对应的函数调用号是不同的,所以这里可以通过nt ...
- wpf 窗口的返回值_如何:获取页函数的返回值
如何:获取页函数的返回值How to: Get the Return Value of a Page Function 03/30/2017 本文内容 本示例显示如何获取页函数的返回值.This ex ...
- pandas获取dataframe中索引值最大值所在的数据行(get dataframe row of max index value)
pandas获取dataframe中索引值最大值所在的数据行(get dataframe row of max index value) 目录 pandas获取dataframe中索引值最大值所在的数 ...
- python使用np.argsort对一维numpy概率值数据排序获取倒序索引、获取的top索引(例如top2、top5、top10)索引二维numpy数组中对应的原始数据:原始数据概率最大的头部数据
python使用np.argsort对一维numpy概率值数据排序获取倒序索引.获取的top索引(例如top2.top5.top10)索引二维numpy数组中对应的原始数据:原始数据概率最大的头部数据 ...
- python使用np.argsort对一维numpy概率值数据排序获取升序索引、获取的top索引(例如top2、top5、top10)索引二维numpy数组中对应的原始数据:原始数据概率最小的头部数据
python使用np.argsort对一维numpy概率值数据排序获取升序索引.获取的top索引(例如top2.top5.top10)索引二维numpy数组中对应的原始数据:原始数据概率最小的头部数据 ...
最新文章
- 制作OS X El CAPITAN安装U盘
- python requests 接口测试_python+requests接口测试基础
- python 文件命令
- 重装php后网站无法,1、解决重装php后变量在下一个页面无法取到的问题:
- Web内容管理系统 Magnolia 启程-挖掘优良的架构(3)
- Android 升级到android studio 2.2项目死活run不起来
- php 解析xml 的四种方法(转)
- jzoj6276-[Noip提高组模拟1]树【线段树,扫描线,倍增】
- python读取大文件内容_python读取大文件
- css文本行高是哪个属性_CSS字体属性和文本属性总结
- python如果选择不在列表里_使用python中的in ,not in来检查元素是不是在列表中的方法...
- Static 静态内部类
- 安装ubuntu出现BUG soft lockup的解决方法(16.04 14.04)
- jQuery1.9.1源码分析--Animation模块
- Java之美[从蛮荒到撬动地球]之设计模式二
- 谈谈网络协议,常见的网络协议有那些?
- JDK1.6安装_BouncyCastle JCE扩展加密算法解决JDK1.6 sftp连接openssh8.6Algorithm negotiation fail问题
- 美团 2021 届秋季校园招聘—小团的 AB 队(排序)
- 洛谷P8255 解法 2020328
- Spark 基础教程