发明名称 一种Linux系统物理内存镜像文件分析方法
摘要 本发明的Linux系统物理内存镜像文件分析方法,包括a).操作系统版本判断以及页目录地址的获取;b).地址转换;c).数据库中已存系统内核符号表的恢复;c-1).获取内核符号的数目;c-2).获取内核符号的类型和名称;c-3).获取内核符号的虚拟地址;d).数据库中未存系统内核符号的恢复;e).获取系统关键信息;e-1).获取进程信息和文件信息;e-2).获取已加载模块信息;e-3).获取网络、CPU、日志和调试信息;f).获取模块导出符号表。本发明的分析方法具有普遍适用性,打破了以往必须知道内系统版本信息和附加内核符号表文件的局限性,为Linux系统内存分析提供了更为通用的分析方法,有益效果显著。
申请公布号 CN105160001A 申请公布日期 2015.12.16
申请号 CN201510571067.5 申请日期 2015.09.09
申请人 山东省计算中心(国家超级计算济南中心) 发明人 张淑慧;王连海;徐丽娟;杨淑棉;刘广起
分类号 G06F17/30(2006.01)I 主分类号 G06F17/30(2006.01)I
代理机构 济南泉城专利商标事务所 37218 代理人 褚庆森
主权项 一种Linux系统物理内存镜像文件分析方法,其特征在于,通过以下步骤来实现:a).操作系统版本判断以及页目录地址的获取,在对Linux系统初始化时,通过调用初始化函数crash_save_vmcoreinfo_int函数,将vmcoreinfo_data的内容进行初始化;从获取的vmcoreinfo_data数据中提取操作系统版本信息以及内核符号_stext、swapper_pg_dir的值;如果操作系统版本信息中含有i686字符或者获取到的swapper_pg_dir的值为八位16进制表示的地址,则判断出该Linux系统为32位操作系统;如果操作系统版本信息中含有x86_64字符或者获取到的swapper_pg_dir的值为十六位16进制表示的地址,则此系统为64位操作系统;获取到的swapper_pg_dir的值为页目录虚拟地址,如果操作系统为32位,则将其减去0xc0000000即为页目录的物理地址;如果操作系统为64位,则将其减去0xffffffff8000000,即可获取页目录的物理地址;b).地址转换,32位操作系统地址分为开启PAE模式和未开启PAE模式,这两种模式下又分为大页模式和小页模式,利用页目录的物理地址,便可实现虚拟地址向物理地址的地址转换;64位操作系统地址分为小页模式和大页模式,利用步骤a)中获取的页目录的物理地址,亦可实现虚拟地址向物理地址的转换;c).数据库中已存系统内核符号表的恢复,判断在物理内存镜像文件的内核变量数据库中是否能查询到操作系统版本信息,如果能查询到操作系统的版本信息,则获取kallsyms_addresses、kallsyms_num_syms、kallsyms_names、kallsyms_markers、kallsyms_token_table以及kallsyms_token_index内核变量的值,再通过步骤c‑1)至c‑3)恢复系统的内核符号表;如果不能查询到操作系统的版本信息,则执行步骤d);c‑1).获取内核符号的数目,将获取的kallsyms_num_syms变量虚拟地址利用步骤b)中的地址转换方法,转换为对应的物理地址,并获取此物理地址对应的物理内存信息为/proc/kallsyms中系统内核符号的个数;c‑2).获取内核符号的类型和名称,kallsyms_names对应经过排序的内核符号的类型和名称组成的字符串,首先将kallsyms_names变量虚拟地址按照步骤b)中的方法转化为物理地址,利用此物理地址在内存镜像文件中获取字符串,每个字符串的格式为字符串长度和压缩串;然后再利用内核变量kallsyms_token_table和kallsyms_token_index将字符串解析出来,以获取内核符号的类型、名称;c‑3).获取内核符号的虚拟地址,kallsyms_addresses变量对应经过排序的所有内核符号的虚拟地址,对于经步骤c‑2)获取的内核符号,按照其在kallsyms_names变量中的次序,从kallsyms_addresses变量所对应的物理地址中获取内核符号表的虚拟地址;通过步骤c‑2)和步骤c‑3)即可获取系统数据库中所有内核符号表的类型、名称和虚拟地址信息;d).数据库中未存系统内核符号的恢复,如果在内核变量数据库中没能查询到目标操作系统版本,则根据步骤a)中获取的内核变量_stext的值在内存中进行搜索,在搜索到的地址处往前追溯寻找内核变量_text的值,内核变量_text的值为_stext去掉后十六位的偏移;获取到的_text的值为kallsyms_addresses的地址或其地址的近似值;将获取到的kallsyms_addresses地址或其地址的近似值转换为虚拟地址,在内存镜像文件中进行搜索,查找出函数update_iter在内存中的数据;反编译update_iter函数在内存中数据,即可获取kallsyms_addresses、kallsyms_num_syms、kallsyms_names、kallsyms_markers、kallsyms_token_table以及kallsyms_token_index五个内核变量的值;获取到该五个内核变量后,按照与步骤c)中相同的方法,即可获取系统数据库中所有内核符号表的类型、名称和虚拟地址信息;e).获取系统关键信息,获取到系统内核变量值后,按照如下步骤从中抽取对获取系统关键信息较为重要的内核变量;e‑1).获取进程信息和文件信息,根据步骤d)或e)中获取的内核符号表信息中的init_task内核变量,获取swapper进程对应的task_struck结构体,根据task_struck结构体形成的双向链表获取所有正在运行的进程;根据结构体task_struck中的struct mm_struct*mm、struct fs_struct*fs、struct files_struct*files、struct thread_struct thread变量,获取与进程相关的文件信息;e‑2).获取已加载模块信息,根据步骤d)或e)中获取的内核符号表信息中的modules内核变量,内核变量modules指向一个已加载模块结构体module地址,通过所有已加载模块及其module形成的双向链表,获取所有已加载模块信息;e‑3).获取网络、CPU、日志和调试信息,根据步骤d)或e)中获取的内核符号表信息中的rt_hash_mask、rt_hash_table、net_namespace_list内核变量值获取网络配置及链接信息,根据boot_cpu_data内核变量获取目标计算机CPU信息,根据log_buf内核变量获取目标计算机系统日志和调试信息,根据iomem_resource内核变量获取系统物理内存分段信息,根据file_systems内核变量获取系统文件系统信息;f).获取模块导出符号表,从步骤e)中的module结构体中获取Elf_Sym*symtab、unsigned int num_symtab、char*strtab内核变量,num_symtab指向模块导出符号个数,symtab指向所有符号地址,strtab指向所有符号名字,根据这三个变量获取模块导出符号,这些符号在进行内存分析时起着重要作用。
地址 250014 山东省济南市历下区科院路19号山东省计算中心