这篇文章给大家分享的是有关如何利用IDA Python来枚举Windows的系统调用表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
创新互联建站主要从事网站制作、成都网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务平原,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
Windows系统中所有发生的系统调用都会被分配一个ID,这个ID是一个唯一值,用于标识一个系统调用在执行时具体使用的是哪一个函数。在不同的Windows版本中,这些ID的变化可能会非常大,对于Windows 10来说,每一个发行版本中的这些ID都不同。但是对于普通应用程序而言,由于使用的是用户模式下的代码库,因此ID不会变化。
在解析系统调用表时我们还有三个重要的符号需要识别:表的基址、表的大小和参数在栈中所占的字节大小。对于ntoskrnl.exe来说,这三个参数的名称分别为:KiServiceTable、KiServiceLimit和KiArgumentTable。对于win32k.sys来说,这三个参数就变成了W32pServiceTable、W32pServiceLimit和W32pArgumentTable。在32位系统架构中,这些符号名称中都会包含下划线。
比如说,我们来看一看Windows 7 64位版本中ntoskrnl.exe(版本6.1.7601.24117)的信息。KiServiceLimit数据如图1所示:
根据这些信息,我们可以看到这里有401个系统调用(0x191)。KiServiceTable数据如图2所示:
根据图2的数据,我们就可以将函数和它们的ID手动映射出来了。其中,NtMapUserPhysicalPagesScatter对应的ID为0x0000,NtWaitForSingleObject对应的ID为0x0001,NtCallbackReturn对应的ID为0x0002,后面的依此类推。
这里有两种特殊情况需要专门处理。如果我们分析的是win32k.sys,在枚举函数ID时需要在表地址上加0x1000。同样的,对于64位Windows10(build 1607)我们也需要进行不同的处理。在这个版本的系统中,系统调用表包含了四个字节的函数偏移量。
下面给出的是版本号为10.0.17134.48的ntoskrnl.exe信息。KiServiceTable数据如图3所示:
这也就意味着,我们需要每次读取四个字节的值,然后将它们与基地址相加。
首先我们来看一看需要调用的IDA函数:
1. idaapi.get_imagebase:这个函数将会在我们所查看的模块中返回基地址。
2. idc.GetInputFile:该函数可以返回IDB加载的文件名称。
3. idc.BADADDR:这是一个值为-1(无符号整形)的常量,我们还可以用它来判断当前系统为32位还是64位模式。
4. idc.Name:该函数可以返回给定地址的名称。
5. idc.LocByName:它的功能跟idc.Name正好相反,它用于返回给定名称的地址。
6. idc.Dword:该函数能返回给定地址的四字节值。
7. idc.Qword:该函数可返回给定地址的八字节值。
8. idautils.DataRefsFrom:该函数可根据任意数据引用枚举给定地址。
首先,我们需要确定正在分析的对象是ntoskrnl.exe还是win32k.sys:
接下来,我们需要判断使用哪一个符号名称,并判断是否需要在变量中添加下划线:
如果表不存在,LocByName将返回BADADDR,所以我们就可以利用这一点来测试符号名称是否存在或是否需要添加下划线。
得到了正确的符号名称之后,我们需要获取表的实际大小:
首先获取LocByName的地址,然后利用Dword获取地址值。下面给出的是64位Windows 10的处理方法:
DataRefsFrom将会利用数据引用来遍历表的基地址,但如果目标是新版本的Windows 10系统,我们就需要在基地址上加上相应的值。接下来需要做的就是从表的基地址开始读取连续的值。我们可以使用Qword函数处理64位版本,用Dword处理32位版本。下面给出的是输出结果样本:
感谢各位的阅读!关于“如何利用IDA Python来枚举Windows的系统调用表”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!