CN114327467A - 一种获取系统函数信息的方法以及相关设备 - Google Patents
一种获取系统函数信息的方法以及相关设备 Download PDFInfo
- Publication number
- CN114327467A CN114327467A CN202011052935.6A CN202011052935A CN114327467A CN 114327467 A CN114327467 A CN 114327467A CN 202011052935 A CN202011052935 A CN 202011052935A CN 114327467 A CN114327467 A CN 114327467A
- Authority
- CN
- China
- Prior art keywords
- function
- module
- global
- system function
- target
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000000034 method Methods 0.000 title claims abstract description 52
- 230000006870 function Effects 0.000 claims abstract description 495
- 238000009795 derivation Methods 0.000 claims abstract description 33
- 238000004806 packaging method and process Methods 0.000 abstract 1
- 238000004590 computer program Methods 0.000 description 16
- 238000010586 diagram Methods 0.000 description 13
- 238000012545 processing Methods 0.000 description 9
- 230000008878 coupling Effects 0.000 description 3
- 238000010168 coupling process Methods 0.000 description 3
- 238000005859 coupling reaction Methods 0.000 description 3
- 238000013461 design Methods 0.000 description 3
- 230000003287 optical effect Effects 0.000 description 3
- 238000007792 addition Methods 0.000 description 2
- 238000004891 communication Methods 0.000 description 2
- 238000012986 modification Methods 0.000 description 2
- 230000004048 modification Effects 0.000 description 2
- GCKMFJBGXUYNAG-HLXURNFRSA-N Methyltestosterone Chemical compound C1CC2=CC(=O)CC[C@]2(C)[C@@H]2[C@@H]1[C@@H]1CC[C@](C)(O)[C@@]1(C)CC2 GCKMFJBGXUYNAG-HLXURNFRSA-N 0.000 description 1
- 238000006243 chemical reaction Methods 0.000 description 1
- 238000013500 data storage Methods 0.000 description 1
- 238000012217 deletion Methods 0.000 description 1
- 230000037430 deletion Effects 0.000 description 1
- 238000005516 engineering process Methods 0.000 description 1
- 239000000835 fiber Substances 0.000 description 1
- 238000001914 filtration Methods 0.000 description 1
- 230000010365 information processing Effects 0.000 description 1
- 238000004519 manufacturing process Methods 0.000 description 1
- 238000012544 monitoring process Methods 0.000 description 1
- 239000004065 semiconductor Substances 0.000 description 1
- 239000007787 solid Substances 0.000 description 1
- 238000007619 statistical method Methods 0.000 description 1
- 238000006467 substitution reaction Methods 0.000 description 1
Images
Landscapes
- Stored Programmes (AREA)
Abstract
本申请实施例提供了一种获取系统函数信息的方法及相关设备,用于提高hook系统函数的效率。该方法包括:编写全局函数并设置全局函数的功能,以使得通过全局函数来确定系统函数的信息;设置全局变量;将全局函数和全局变量封装在初始模块中,并设置初始模块的导出函数,初始模块的导出函数用于外部模块获取系统函数的内存地址和系统函数对应的模块,初始模块为系统中最先加载且最后释放的模块;当需要hook目标系统函数时,执行初始模块,并通过初始模块的全局函数确定目标系统函数的内存地址和目标系统函数对应的模块,以使得外部模块通过导出函数获得目标系统函数的内存地址和目标系统函数对应的模块。
Description
技术领域
本申请涉及信息处理技术领域,尤其涉及一种获取系统函数信息的方法以及相关设备。
背景技术
在使用某些功能时,我们需要hook系统函数,例如检测内存泄露需要hook系统的open函数和write函数。而实际应用中,这些系统函数在不同的系统上所属于的模块不一样,比如write函数在android 7.x系统上是在libc.so模块中,因此在hook时需要对libc.so的write函数进行hook。而在android8-9系统上,write函数在libart.so模块中;在android10系统上,write函数又在libartbase.so模块中,因此需要事先在各个系统上进行查找每个系统函数所属于的模块然后对该模块进行hook。
那么现有技术中,一旦发布了新的系统且系统函数所属的模块发生变化,在hook时又需要去修改代码来兼容新的系统,对系统的自适应能力较差。因此如何在hook时能兼容各个系统甚至未发布的系统,是当前亟需解决的问题。
发明内容
本申请实施例提供了一种获取系统函数信息的方法及相关设备,可以提高hook系统函数的效率。
本申请实施例的第一方面提供了一种获取系统函数信息的方法,包括:编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
可选地,所述编写全局函数并设置所述全局函数的功能包括:设计所述全局函数Bool getSystemFunction(){},其中,所述getSystemFunction(){}用于表示所述全局函数,所述Bool用于表示所述全局函数的类型;通过以下步骤实现所述全局函数的功能:获取当前进程加载的所有目标so文件,并确定所述各目标so文件的导出表,所述目标so文件为系统模块;确定所述各导出表的初始导出函数地址和末尾导出函数地址;从第一导出表的初始导出函数地址遍历至所述第一导出表的末尾导出函数地址,并按特定规则确定是否存在待查找系统函数的名称,所述第一导出表为所述各导出表中的任一导出表;若存在,则所述第一导出表对应的目标so文件为所述待查找系统函数对应的系统模块。
可选地,所述获取当前进程加载的所有目标so文件,并确定所述各目标so文件的导出表包括:通过函数snprintf(data,sizeof(data),"/proc/%d/maps",getpid())将系统的"/proc/%d/maps"文件拷贝至data中,所述sizeof(data)用于表示所述data的字节大小,所述getpid()用于表示所述当前进程的标识信息;通过函数fopen打开所述data,并通过while循环读取所述data中的每一行信息;在所述每一行信息中,确定/system/lib/目录下的所有so文件为所述目标so文件;通过函数ElfW(Half)dlpi_phnum=so->info_.dlpi_phnum读取所述各目标so文件的头部信息来获取所述各目标so文件中的表格,所述dlpi_phnum用于表示表格的数目;通过for函数遍历所述各目标so文件中的表格,将匹配PT_DYNAMIC类型的表确定为所述各目标so文件的导出表。
可选地,所述确定所述各导出表的初始导出函数地址和末尾导出函数地址包括:通过以下函数确定所述各导出表的初始导出函数地址和末尾导出函数地址:*dyn=dlpi_addr+dlpi_phdr[i].p_vaddr;*dyn_end=dyn+(dlpi_phdr[i].p_memsz/sizeof(Dyn));其中所述dyn用于表示所述初始导出函数地址,所述dlpi_addr用于表示so文件的内存加载地址,所述dlpi_phdr[i].p_vaddr用于表示导出表的内存相对于所述so文件的起始地址偏移;所述dyn_end用于表示末尾导出函数地址,所述sizeof(Dyn)用于表示每一个导出项的大小,所述dlpi_phdr[i].p_memsz用于表示整个导出表所占用的大小。
可选地,所述按特定规则确定是否存在待查找系统函数的名称包括:确定所述待查找系统函数的匹配函数,所述匹配函数为当模块中有所述待查找系统函数时一定会存在的函数,所述匹配函数包括同类型函数;判断所述第一导出表中是否存在所述待查找系统函数和所述系统函数的匹配函数;若都存在,则确定存在所述待查找系统函数的名称。
可选的,所述设置所述初始模块的导出函数包括:设计数据结构以记录所述系统函数的信息,所述系统函数的信息包括所述系统函数的内存地址,所述系统函数的名称,所述系统函数对应的模块的名称;通过动态链表存储多个所述数据结构,得到数据链表;将所述数据链表中的各数据结构依次转换为设定格式的字节信息,以得到一维数组;将所述一维数组导出给所述外部模块使用。
可选的,所述将所述数据链表中的各数据结构依次转换为设定格式的字节信息,以得到一维数组包括:分别将第一数据结构中的系统函数的内存地址转化为a个字节的地址信息,系统函数的名称转化为b个字节的函数名称信息,系统函数对应的模块的名称转化为c个字节的模块名称信息,所述第一数据结构为所述数据链表中的第一个数据结构;依次对所述数据链表中的数据结构进行格式转化直至所述数据链表中的最后一个数据结构,以得到所述一维数组。
本申请实施例第二方面提供了一种获取装置,包括:编写单元,用于编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;设置单元,用于设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;所述设置单元还用于将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;执行单元,用于当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
综上所述,可以看出,本申请提供的实施例中,编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。通过本申请实施例,可以获取到系统函数的内存地址和系统函数对应的模块名称,从而就可以适应各种系统,提高了系统函数hook的效率。
附图说明
图1为本申请实施例提供的一种可能的获取系统函数信息的方法的流程示意图;
图2为本申请实施例提供的一种可能的获取装置的实施例示意图;
图3为本申请实施例提供的一种可能的获取装置的硬件结构示意图;
图4为本申请实施例提供的一种可能的电子设备的实施例示意图;
图5为本申请实施例提供的一种可能的计算机可读存储介质的实施例示意图。
具体实施方式
本申请实施例提供了一种获取系统函数信息的方法及相关设备,可以提高hook系统函数的效率。
本申请的说明书和权利要求书及上述附图中的术语“第一”、“第二”、“第三”、“第四”等(如果存在)是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的实施例能够以除了在这里图示或描述的内容以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。
请参阅图1,为本申请实施例提供的一种可能的获取系统函数信息的方法的流程图,具体包括:
当需要hook系统函数时,需要事先在各个系统上进行查找每个系统函数所属于的模块,然后对该模块进行hook。而不同的Android系统,相同系统函数所属于的模块可能会有所区别,为了能兼容多个系统甚至未发布的系统,需要在程序最早的时候就能够执行对系统模块的查找,从而尽早的保障其他模块对系统函数的hook。可以知道的是,一个系统是由多个模块组成的,例如可能会有网络模块、获取系统内存模块、监控系统内存模块,统计分析系统内存模块,hook系统函数模块等,随着功能的迭代还会增加很多其他模块。
为了保障能够在各个模块运行之前就能获取到所有的系统函数,本申请则设计了一个独立的模块,为便于描述,本申请中称该模块为初始模块。该初始模块用于获取系统函数的内存地址来进行后续的hook功能,为保障在各个模块需要使用系统函数之前就已经获取到,在整个系统中,需要最先加载初始模块,且最后释放初始模块,从而使得其他模块在获取其中的系统函数时不会出现获取不到的情况。
本申请实施例中,将对如何设计该初始模块进行详细说明:
101、编写全局函数,以使得通过全局函数来确定系统函数的信息;
本申请实施例中,将获取系统函数的整个功能封装到一个全局函数中,目的是为了便于后续的全局变量调用,从而可以保障其能够在程序的入口函数之前执行,本实施例中,可以将JNI_OnLoad函数作为程序的入口函数,即所有的业务逻辑功能都是在JNI_OnLoad函数中来执行。设计全局函数在JNI_OnLoad函数之前执行的目的是为了保障系统函数能够尽早获取到,从而不会干扰到JNI_OnLoad函数的内部逻辑,避免出现JNI_OnLoad函数需要系统函数时获取不到的情况,同时也保障其他模块在获取系统函数时,一定能获取到系统函数的地址。
因此本申请中,该全局函数必须有一个返回值,才能给后续的全局变量进行赋值,以实现该全局函数在JNI_OnLoad函数之前执行。例如,可以将全局函数编写为BoolgetSystemFunction(){},该全局函数的返回值即为bool,实际应用中,也可以是其他类型,具体此处不做限定。
102、设置全局函数的功能;
为了实现通过全局函数来确定系统函数的信息的目的,需设置全局函数的功能,包括需要实现如何通过全局函数确定某个系统函数所属于哪个模块。思路可以为通过当前程序加载后,这些系统函数所属于的模块则会被系统加载,而由于不同的系统其模块的名称会变的不一样,那么则需要从当前加载的所有模块中查找到哪个是需要查找的系统函数所属于的模块。具体设置全局函数的功能可包括以下步骤:
步骤1、获取当前进程加载的所有目标so文件,并确定各目标so文件的导出表,目标so文件为系统模块;
通过函数getModuleInfoList()来获取加载的所有模块,为了规避多线程同时调用来获取模块信息,可以通过加锁来避免,具体实现函数如下:list<string>*getModuleInfoList(){
Lock(Lock);
再通过读取系统的"/proc/%d/maps"文件获取到当前进程加载了哪些模块,具体实现函数如下:
FILE*fp;
snprintf(data,sizeof(data),"/proc/%d/maps",getpid());
fp=fopen(data,"r");打
while(fgets(data,1024,fp)){
即通过函数snprintf(data,sizeof(data),"/proc/%d/maps",getpid())将系统的"/proc/%d/maps"文件拷贝至data中,sizeof(data)用于表示data的字节大小,getpid()用于表示当前进程的标识信息。再通过函数fopen打开data,并通过while循环读取data中的每一行信息。由于"/proc/%d/maps"文件存储了很多信息,因此需要进行过滤来获取我们需要的信息。由于系统函数所属于的肯定是系统模块,那么只需要在"/proc/%d/maps"文件中获取到所有加载的系统模块信息。所有系统模块都是如下:/system/lib/libc.so,因此必须是/system/lib/这个目录下的so才是系统模块。即我们只需要获取到所有匹配这个规则的所有目标so文件的名称即可。可以理解为,在读取到的data中的每一行信息中,确定/system/lib/目录下的所有so文件为目标so文件。
通过上述的读取系统的"/proc/%d/maps"文件则可以枚举到当前进程加载的所有目标so文件,即当前进程加载的系统模块。
需要说明的是,一个so文件要想提供接口供外部使用,那么其接口则一定会在so文件的导出表信息中,因此可以去枚举so文件的导出表,以查看该so文件有导出那些接口。故在获取了目标so文件的内存地址后,再获取目标so文件的导出表,导出表存储了目标so文件对外提供的所有系统函数接口。由于so文件是一个标准的elf文件,此文件格式是公开的,故可以安装标准的公开说明文档来获取目标so文件的导出表信息。具体确定各目标so文件的导出表可以包括:通过函数ElfW(Half)dlpi_phnum=so->info_.dlpi_phnum读取各目标so文件的头部信息来获取各目标so文件中的表格,dlpi_phnum用于表示表格的数目;再通过for函数for(int i=0;i<dlpi_phnum;++i)遍历各目标so文件中的表格,通过函数dlpi_phdr[i].p_type==PT_DYNAMIC将匹配PT_DYNAMIC类型的表确定为各目标so文件的导出表,需要说明的是,PT_DYNAMIC类型的表是动态链接可执行文件特有的,包含了动态链接器所需要的一些信息。主要包括程序运行时所需要链接的共享库列表,全局偏移表(GOT)的地址和重定位条目的相关信息。
步骤2、确定各导出表的初始导出函数地址和末尾导出函数地址;
在得到了各目标so文件的导出表后,再确定各导出表的初始导出函数地址和末尾导出函数地址。具体地,通过以下函数确定所述各导出表的初始导出函数地址和末尾导出函数地址:
*dyn=dlpi_addr+dlpi_phdr[i].p_vaddr;
*dyn_end=dyn+(dlpi_phdr[i].p_memsz/sizeof(Dyn));
其中dyn用于表示初始导出函数地址,dlpi_addr用于表示so文件的内存加载地址,dlpi_phdr[i].p_vaddr用于表示导出表的内存相对于so文件的起始地址偏移;
dyn_end用于表示末尾导出函数地址,sizeof(Dyn)用于表示每一个导出项的大小,dlpi_phdr[i].p_memsz用于表示整个导出表所占用的大小。
步骤3、从第一导出表的初始导出函数地址遍历至第一导出表的末尾导出函数地址,并按特定规则确定是否存在待查找系统函数的名称,第一导出表为各导出表中的任一导出表;
步骤4、若存在,则第一导出表对应的目标so文件为待查找系统函数对应的系统模块。
当有需要hook的待查找系统函数时,在所有导出表中任选出第一导出表,从第一导出表的初始导出函数地址遍历至第一导出表的末尾导出函数地址,看是否存在待查找系统函数的名称。
需要说明的是,由于一些非法模块或者是一些黑客编写的伪造模块,或者是黑客编写的用于对系统模块hook的伪造模块,也可能会有相关的系统函数导出,那么其一旦定义了一个同名的系统导出函数,则会导致查找时找错了系统模块而使得整个程序错误。因此可以设计按照特定规则进行查找,例如多函数查找,同类型函数一起查找或者增加不常用函数一起查找,具体此处不做限定。例如write系统函数,是用于写数据的系统函数,其相对应的是用于读数据的系统函数read,类似这种相匹配的函数则一定属于同一个系统模块。那么一定也会有用于无锁读取文件内容的系统函数fread_unlocked,也同属于同一个系统模块。而fread_unlocked系统函数属于偏的系统函数,很少外部调用,黑客也通常不会对其进行hook或者黑客模块也不会对其进行导出。因此如果需要查找系统函数write,可以一起查找write、read和fread_unlocked这3个函数是否同时存在于某一个so文件的导出表中,如果同时都存在则说明该so文件是需要查找的系统模块。
或者,
如果是需要查找系统函数open,那么可以增加查找用于关闭文件的系统函数close,这属于同一类函数,一定的在同一个模块中。
或者,
对于查找的系统模块的系统函数,如果查找到了,还可以通过汇编指令解析器来对其汇编指令进行解析,查看其是否有存在内联hook相关的代码。由于系统函数不会存在hook相关代码,而对于黑客模块则极有可能存在黑客相关代码。因此当还存在系统函数的hook相关代码时,则可以认为对应的系统模块为黑客的伪造模块,并不是该系统函数对应的系统模块。
或者,还可以基于某一个系统的汇编指令来查找,例如write这个函数目前已知的系统是android7.x系统,是可以获取其汇编指令的,将该汇编指令提取出来,然后在其他系统上查找到对应的系统模块和系统函数后,通过对比已经提取的汇编指令,来进行相似度比较。同一个系统函数,虽然在不同的系统上有差异,但是只是会有细微的区别,所以整体匹配度则会非常高,将整体匹配度值大于预设值的系统模块确定为需要查找的系统模块。
因此,通过上述特定规则,可以避免找错模块,提高找出待查找系统函数对应的系统模块的正确率。
通过上述步骤的设置,即可实现全局函数获取系统函数信息的功能,该系统函数信息包括系统函数的名称和系统函数对应的系统模块。
103、设置全局变量;
在设计全局函数时,可以通过设计全局变量,使得通过全局函数对该全局变量进行赋值,以保障全局函数在JNI_OnLoad函数之前执行,其中,全局变量的类型需与全局函数的类型一样。例如,当全局函数设置为Bool getSystemFunction(){}时,全局变量可以设置为Bool g_init=getSystemFunction();其中g_init用于表示全局变量,该全局变量的类型也为Bool,可以通过调用全局函数来对其进行初始化。
104、将全局函数和全局变量封装在初始模块中,并设置初始模块的导出函数;
设置好全局函数和全局变量后,将全局函数和全局变量封装在初始模块中,并设置初始模块的导出函数。具体设置初始模块的导出函数的方式包括以下步骤:
1、设计数据结构以记录所述系统函数的信息,所述系统函数的信息包括所述系统函数的内存地址,所述系统函数的名称,所述系统函数对应的模块的名称;例如,数据结构可以设计为以下结构:
Struct Data{
Uint64_t addr;
String name;
String module;}
其中,addr为地址信息,用于保存系统函数的内存地址;name为字符串用于表明是哪个系统函数;module为字符串用于记录是哪个系统模块。
2、通过动态链表存储多个所述数据结构,得到数据链表;
由于存在多个系统函数,因此需要设计一个data的数组来记录多个信息。可以设计一个链表list<Data>info;使用链表来存储多个Data数据结构。由于list可以方便动态增加新的数据,因此在获取的时候使用动态链表list来存储每个data结构的数据,这样便于对其中的数据进行增加删除修改。
3、将所述数据链表中的各数据结构依次转换为设定格式的字节信息,以得到一维数组;
在获取完成后给外部使用时,为了考虑各个模块的兼容性,以及跨模块的内存问题,因此会将list<Data>转换成一个一块内存信息,其中通过格式信息来区分每个data结构。转换方案如下:
首先是用n个字节设计list<Data>中存储的总的Data个数。list是一个复杂的链表结构,其需要依赖于系统的stl相关的模块才能正常工作,而对外为了保障跟多的兼容性需要将list的数据转换成一个一维的数组,一维数组则直接是一块连续的内存,其兼容性是最好的,不需要依赖于任何模块。
然后是每个Data结构的数据。分别将第一数据结构中的系统函数的内存地址转化为a个字节的地址信息,系统函数的名称转化为b个字节的函数名称信息,系统函数对应的模块的名称转化为c个字节的模块名称信息,其中第一数据结构为数据链表中的第一个数据结构;依次对数据链表中的数据结构进行格式转化直至数据链表中的最后一个数据结构,以得到一维数组。例如,分别转换成8个字节的地址信息,2个字节的函数名称信息,2个字节的模块名称信息。接下来则是下一个Data数据,直到最后一个完结。
4、将一维数组导出给外部模块使用。
在得到一维数组后,通过函数getInfo将一维数组导出给外部模块使用。具体函数实现如下:
extern"C"{
Uint8_t*getInfo(){
Return&mem_info;
}
其中,extern"C"表示告诉编译器在编译时按着C的规则去翻译相应的函数名,其返回的值为转换后的一维数组的内存首地址,以使得外部模块根据该内存首地址确定出数据结构记录的系统函数的信息。
因此,本申请实施例中,通过上述步骤即可完成初始模块的导出函数的设置。
105、当需要hook目标系统函数时,执行初始模块,并通过初始模块的全局函数确定目标系统函数的内存地址和目标系统函数对应的模块。
在通过上述步骤完成了初始模块的设计后,当需要hook目标函数时,执行该初始模块,需要说明的是,该初始模块为程序最先执行且最后释放的模块,并通过初始模块的全局函数确定目标系统函数的内存地址和目标系统函数对应的模块,以对该目标系统函数进行hook。
传统方案的问题是对于系统函数不知道其在哪个模块,而本申请实施例中,能够获取到系统函数的内存地址和其对应的模块名称,通过更智能化的处理,能够兼容各种系统,同时即使对未发布的系统也可以无须修改代码都可以兼容,提高了hook系统函数的效率。
上面对本申请实施例中获取系统函数信息的方法进行了描述,下面对本申请实施例中的获取装置进行描述。
请参阅图2,本申请实施例中获取装置的一个实施例,该获取装置包括:
编写单元201,用于编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;
设置单元202,用于设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
所述设置单元202还用于将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
执行单元203,用于当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
上面图2从模块化功能实体的角度对本申请实施例中的获取装置进行了描述,下面从硬件处理的角度对本申请实施例中的获取装置进行详细描述,请参阅图3,本申请实施例中的直播间的推荐装置300一个实施例,包括:
输入装置301、输出装置302、处理器303和存储器304(其中处理器303的数量可以一个或多个,图3中以一个处理器303为例)。在本申请的一些实施例中,输入装置301、输出装置502、处理器303和存储器304可通过总线或其它方式连接,其中,图3中以通过总线连接为例。
其中,通过调用存储器304存储的操作指令,处理器303,用于执行如下步骤:
编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;
设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
通过调用存储器304存储的操作指令,处理器303,还用于执行图1对应的实施例中的任一方式。
请参阅图4,图4为本申请实施例提供的电子设备的实施例示意图。
如图4所示,本申请实施例提供了一种电子设备,包括存储器410、处理器420及存储在存储器420上并可在处理器420上运行的计算机程序411,处理器420执行计算机程序411时实现以下步骤:
编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;
设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
在具体实施过程中,处理器420执行计算机程序411时,可以实现图1对应的实施例中任一实施方式。
由于本实施例所介绍的电子设备为实施本申请实施例中一种获取装置所采用的设备,故而基于本申请实施例中所介绍的方法,本领域所属技术人员能够了解本实施例的电子设备的具体实施方式以及其各种变化形式,所以在此对于该电子设备如何实现本申请实施例中的方法不再详细介绍,只要本领域所属技术人员实施本申请实施例中的方法所采用的设备,都属于本申请所欲保护的范围。
请参阅图5,图5为本申请实施例提供的一种计算机可读存储介质的实施例示意图。
如图5所示,本实施例提供了一种计算机可读存储介质500,其上存储有计算机程序511,该计算机程序511被处理器执行时实现如下步骤:
编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;
设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
在具体实施过程中,该计算机程序511被处理器执行时可以实现图1对应的实施例中任一实施方式。
需要说明的是,在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详细描述的部分,可以参见其它实施例的相关描述。
本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式计算机或者其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
本申请实施例还提供了一种计算机程序产品,该计算机程序产品包括计算机软件指令,当计算机软件指令在处理设备上运行时,使得处理设备执行如图1对应实施例中的风电场数字化平台设计的方法中的流程。
所述计算机程序产品包括一个或多个计算机指令。在计算机上加载和执行所述计算机程序指令时,全部或部分地产生按照本申请实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一计算机可读存储介质传输,例如,所述计算机指令可以从一个网站站点、计算机、服务器或数据中心通过有线(例如同轴电缆、光纤、数字用户线(digital subscriber line,DSL))或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。所述计算机可读存储介质可以是计算机能够存储的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质,(例如,软盘、硬盘、磁带)、光介质(例如,DVD)、或者半导体介质(例如固态硬盘(solid state disk,SSD))等。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的系统,装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
在本申请所提供的几个实施例中,应该理解到,所揭露的系统,装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本申请各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(Read-Only Memory,ROM)、随机存取存储器(Random Access Memory,RAM)、磁碟或者光盘等各种可以存储程序代码的介质。
以上所述,以上实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修该,或者对其中部分技术特征进行等同替换;而这些修该或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围。
Claims (10)
1.一种获取系统函数信息的方法,所述方法应用于android系统,其特征在于,包括:
编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在程序的入口函数之前执行;
设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
2.根据权利要求1所述的方法,其特征在于,所述编写全局函数并设置所述全局函数的功能包括:
设计所述全局函数Bool getSystemFunction(){},其中,所述getSystemFunction(){}用于表示所述全局函数,所述Bool用于表示所述全局函数的类型;通过以下步骤实现所述全局函数的功能:
获取当前进程加载的所有目标so文件,并确定所述各目标so文件的导出表,所述目标so文件为系统模块;
确定所述各导出表的初始导出函数地址和末尾导出函数地址;
从第一导出表的初始导出函数地址遍历至所述第一导出表的末尾导出函数地址,并按特定规则确定是否存在待查找系统函数的名称,所述第一导出表为所述各导出表中的任一导出表;
若存在,则所述第一导出表对应的目标so文件为所述待查找系统函数对应的系统模块。
3.根据权利要求2所述的方法,其特征在于,所述获取当前进程加载的所有目标so文件,并确定所述各目标so文件的导出表包括:
通过函数snprintf(data,sizeof(data),"/proc/%d/maps",getpid())将系统的"/proc/%d/maps"文件拷贝至data中,所述sizeof(data)用于表示所述data的字节大小,所述getpid()用于表示所述当前进程的标识信息;
通过函数fopen打开所述data,并通过while循环读取所述data中的每一行信息;
在所述每一行信息中,确定/system/lib/目录下的所有so文件为所述目标so文件;
通过函数ElfW(Half)dlpi_phnum=so->info_.dlpi_phnum读取所述各目标so文件的头部信息来获取所述各目标so文件中的表格,所述dlpi_phnum用于表示表格的数目;
通过for函数遍历所述各目标so文件中的表格,将匹配PT_DYNAMIC类型的表确定为所述各目标so文件的导出表。
4.根据权利要求2所述的方法,其特征在于,所述确定所述各导出表的初始导出函数地址和末尾导出函数地址包括:
通过以下函数确定所述各导出表的初始导出函数地址和末尾导出函数地址:
*dyn=dlpi_addr+dlpi_phdr[i].p_vaddr;
*dyn_end=dyn+(dlpi_phdr[i].p_memsz/sizeof(Dyn));
其中所述dyn用于表示所述初始导出函数地址,所述dlpi_addr用于表示so文件的内存加载地址,所述dlpi_phdr[i].p_vaddr用于表示导出表的内存相对于所述so文件的起始地址偏移;
所述dyn_end用于表示所述末尾导出函数地址,所述sizeof(Dyn)用于表示每一个导出项的大小,所述dlpi_phdr[i].p_memsz用于表示整个导出表所占用的大小。
5.根据权利要求2所述的方法,其特征在于,所述按特定规则确定是否存在待查找系统函数的名称包括:
确定所述待查找系统函数的匹配函数,所述匹配函数为当模块中有所述待查找系统函数时一定会存在的函数,所述匹配函数包括同类型函数;
判断所述第一导出表中是否存在所述待查找系统函数和所述系统函数的匹配函数;
若都存在,则确定存在所述待查找系统函数的名称。
6.根据权利要求1所述的方法,其特征在于,所述设置所述初始模块的导出函数包括:
设计数据结构以记录所述系统函数的信息,所述系统函数的信息包括所述系统函数的内存地址,所述系统函数的名称,所述系统函数对应的模块的名称;
通过动态链表存储多个所述数据结构,得到数据链表;
将所述数据链表中的各数据结构依次转换为设定格式的字节信息,以得到一维数组;
将所述一维数组导出给所述外部模块使用。
7.根据权利要求6所述的方法,其特征在于,所述将所述数据链表中的各数据结构依次转换为设定格式的字节信息,以得到一维数组包括:
分别将第一数据结构中的系统函数的内存地址转化为a个字节的地址信息,系统函数的名称转化为b个字节的函数名称信息,系统函数对应的模块的名称转化为c个字节的模块名称信息,所述第一数据结构为所述数据链表中的第一个数据结构;
依次对所述数据链表中的数据结构进行格式转化直至所述数据链表中的最后一个数据结构,以得到所述一维数组。
8.一种获取装置,其特征在于,包括:
编写单元,用于编写全局函数并设置所述全局函数的功能,以使得通过所述全局函数来确定系统函数的信息,所述全局函数包括返回值,所述全局函数在JNI_OnLoad函数之前执行;
设置单元,用于设置全局变量,所述全局变量用于调用所述全局函数,所述全局变量的类型与所述全局函数的变量类型相同;
所述设置单元还用于将所述全局函数和所述全局变量封装在初始模块中,并设置所述初始模块的导出函数,所述初始模块的导出函数用于外部模块获取所述系统函数的内存地址和所述系统函数对应的模块,所述初始模块为系统中最先加载且最后释放的模块;
执行单元,用于当需要hook目标系统函数时,执行所述初始模块,并通过所述初始模块的全局函数确定所述目标系统函数的内存地址和所述目标系统函数对应的模块,以使得所述外部模块通过所述导出函数获得所述目标系统函数的内存地址和所述目标系统函数对应的模块。
9.一种电子设备,包括存储器、处理器,其特征在于,所述处理器用于执行存储器中存储的计算机管理类程序时实现如权利要求1至7中任意一项所述的获取系统函数信息的方法的步骤。
10.一种计算机可读存储介质,其上存储有计算机管理类程序,其特征在于:所述计算机管理类程序被处理器执行时实现如权利要求1至7中任意一项所述的获取系统函数信息的方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011052935.6A CN114327467A (zh) | 2020-09-29 | 2020-09-29 | 一种获取系统函数信息的方法以及相关设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011052935.6A CN114327467A (zh) | 2020-09-29 | 2020-09-29 | 一种获取系统函数信息的方法以及相关设备 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN114327467A true CN114327467A (zh) | 2022-04-12 |
Family
ID=81010651
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011052935.6A Pending CN114327467A (zh) | 2020-09-29 | 2020-09-29 | 一种获取系统函数信息的方法以及相关设备 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114327467A (zh) |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20050010911A1 (en) * | 2003-07-12 | 2005-01-13 | Samsung Electronics Co., Ltd. | Shared library system and method of building the system |
US20190087208A1 (en) * | 2016-08-31 | 2019-03-21 | Beijing Qihoo Technology Company Limited | Method and apparatus for loading elf file of linux system in windows system |
CN110737892A (zh) * | 2018-07-20 | 2020-01-31 | 武汉斗鱼网络科技有限公司 | 一种针对apc注入的检测方法和相关装置 |
CN111290952A (zh) * | 2020-01-22 | 2020-06-16 | 北京深之度科技有限公司 | 一种动态链接库函数的跟踪方法及装置 |
-
2020
- 2020-09-29 CN CN202011052935.6A patent/CN114327467A/zh active Pending
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20050010911A1 (en) * | 2003-07-12 | 2005-01-13 | Samsung Electronics Co., Ltd. | Shared library system and method of building the system |
US20190087208A1 (en) * | 2016-08-31 | 2019-03-21 | Beijing Qihoo Technology Company Limited | Method and apparatus for loading elf file of linux system in windows system |
CN110737892A (zh) * | 2018-07-20 | 2020-01-31 | 武汉斗鱼网络科技有限公司 | 一种针对apc注入的检测方法和相关装置 |
CN111290952A (zh) * | 2020-01-22 | 2020-06-16 | 北京深之度科技有限公司 | 一种动态链接库函数的跟踪方法及装置 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN111967017B (zh) | 生成依赖关系的方法、装置、终端设备及存储介质 | |
CN110737892B (zh) | 一种针对apc注入的检测方法和相关装置 | |
CN112147987B (zh) | 一种车辆诊断方法、车辆诊断装置及终端设备 | |
CN112328631A (zh) | 一种生产故障分析方法、装置、电子设备及存储介质 | |
CN112433936A (zh) | 测试方法、装置及存储介质 | |
CN116680015A (zh) | 函数调用方法、装置、电子设备及可读存储介质 | |
CN104933096A (zh) | 数据库的异常键识别方法、装置与数据系统 | |
CN114528204A (zh) | 处理代码的方法、处理异常的方法以及各自的装置 | |
CN113704269A (zh) | 一种数据处理方法、系统、存储介质及电子设备 | |
CN114327467A (zh) | 一种获取系统函数信息的方法以及相关设备 | |
CN114154020B (zh) | 基于动态标签映射的大容量数据处理方法及装置 | |
CN112732644B (zh) | 应用程序的资源索引处理方法、计算机设备和存储介质 | |
CN113467761A (zh) | 一种基于Java反射原理的接口测试模板生成方法 | |
CN112433943A (zh) | 基于抽象语法树的环境变量检测方法、装置、设备及介质 | |
CN107203706B (zh) | App内部权限的检测方法及装置 | |
CN110764777A (zh) | 一种elf文件生成方法、elf文件、设备及存储介质 | |
CN117215965B (zh) | 基于测试用例识别的测试方法、装置、电子设备和介质 | |
CN112800005B (zh) | 一种文件系统深度检查方法、系统、终端及存储介质 | |
CN115422280B (zh) | 一种不确定数据结构的数据增删改的接口方法 | |
CN112765676B (zh) | 一种智能合约执行方法、智能合约执行装置及节点设备 | |
CN111324542B (zh) | 一种Web应用回归测试用例选择系统、方法以及设备 | |
CN114780952B (zh) | 敏感应用调用场景的检测方法、系统及存储介质 | |
CN112612477B (zh) | 业务实现方法、装置、设备和存储介质 | |
CN113836534B (zh) | 一种病毒家族识别方法、系统、设备及计算机存储介质 | |
CN115934160A (zh) | 一种dll格式相同文件快速比对确认方法、设备和介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |