挂钩函数的方法、装置、移动终端及存储介质转让专利

申请号 : CN201510607328.4

文献号 : CN106547580B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 俞骁李伟

申请人 : 腾讯科技(深圳)有限公司

摘要 :

本发明涉及一种挂钩函数的方法和装置。所述方法包括以下步骤:获取待挂钩的原函数;判断所述原函数的返回值类型;根据原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数;将所述替换函数替换原函数,实现挂钩原函数。上述挂钩函数的方法和装置,获取到原函数后,判断原函数的返回值类型,根据返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,将替换函数替换原函数实现了原函数的挂钩,采用返回值类型配置替换函数,实现了一类返回值类型对应同一替换函数,不用每个函数对应一个替换函数,缩减了代码量,节省了空间。通过前置回调函数和后置回调函数判断是否修改原函数参数和返回值,实现对原函数的控制。

权利要求 :

1.一种挂钩函数的方法,包括:

获取待挂钩的原函数;

判断所述原函数的返回值类型;

根据所述原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,所述前置回调函数是所述原函数被调用前执行的回调函数,用于判断是否需要调用所述原函数;所述后置回调函数是所述原函数被调用后执行的回调函数,用于对所述原函数的返回值和/或参数进行修改;

将所述替换函数替换原函数,实现挂钩所述原函数。

2.根据权利要求1所述的方法,其特征在于,所述方法还包括:获取调用原函数请求;

根据所述请求进入所述原函数对应的替换函数,调用所述替换函数中的前置回调函数;

通过所述前置回调函数判断是否需要调用原函数,若需要则调用原函数,原函数返回后将原函数的返回值传入所述替换函数中的后置回调函数,若不需要调用原函数,则返回默认返回值;

通过所述后置回调函数判断是否修改返回值,若是,则修改返回值,若否,则不修改返回值。

3.根据权利要求2所述的方法,其特征在于,所述调用原函数的步骤包括:将原函数的返回值和参数压入栈中,模拟函数调用压栈方式调用原函数。

4.根据权利要求1所述的方法,其特征在于,所述方法还包括:建立返回值类型与替换函数的对应关系;

所述根据所述原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数的步骤包括:根据所述返回值类型从所述返回值类型与替换函数的对应关系中查找到对应的包含前置回调函数和后置回调函数的替换函数,并将对应的替换函数分配给所述原函数。

5.根据权利要求1所述的方法,其特征在于,所述方法还包括:提供统一的缺省处理函数;

当应用程序运行中需替换指定的原函数时,将所述指定的原函数的返回值和处理方式传入所述缺省处理函数,通过所述缺省处理函数调用自身的前置回调函数和后置回调函数修改所述原函数返回值,且不调用原函数。

6.根据权利要求1所述的方法,其特征在于,所述方法还包括:在所述前置回调函数和后置回调函数中存储有挂钩的原函数的参数和返回值的内存地址指针。

7.一种挂钩函数的装置,其特征在于,包括:

获取模块,用于获取待挂钩的原函数;

类型检测模块,用于判断所述原函数的返回值类型;

配置模块,用于根据所述原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,所述前置回调函数是所述原函数被调用前执行的回调函数,用于判断是否需要调用所述原函数;所述后置回调函数是所述原函数被调用后执行的回调函数,用于对所述原函数的返回值和/或参数进行修改;

替换模块,用于将所述替换函数替换原函数,实现挂钩所述原函数。

8.根据权利要求7所述的装置,其特征在于,所述装置还包括:请求获取模块,用于获取调用原函数请求;

第一调用模块,用于根据所述请求进入所述原函数对应的替换函数,调用所述替换函数中的前置回调函数;

第一判断模块,用于通过所述前置回调函数判断是否需要调用原函数;

第二调用模块,用于若判断出需要调用原函数,则调用原函数,且原函数返回后将原函数的返回值传入所述替换函数中的后置回调函数,若不需要调用原函数,则返回默认返回值;

第二判断模块,用于通过所述后置回调函数判断是否修改返回值,若是,则修改返回值,若否,则不修改返回值。

9.根据权利要求8所述的装置,其特征在于,所述第二调用模块还用于将原函数的返回值和参数压入栈中,模拟函数调用压栈方式调用原函数。

10.根据权利要求7所述的装置,其特征在于,所述装置还包括:关系建立模块,用于建立返回值类型与替换函数的对应关系;

所述类型检测模块还用于根据所述返回值类型从所述返回值类型与替换函数的对应关系中查找到对应的包含所述前置回调函数和后置回调函数的替换函数,并将对应的替换函数分配给所述原函数。

11.根据权利要求7所述的装置,其特征在于,所述装置还包括:提供模块,用于提供统一的缺省处理函数;

修改模块,用于当应用程序运行中需替换指定的原函数时,将所述指定的原函数的返回值和处理方式传入所述缺省处理函数,通过所述缺省处理函数调用自身的前置回调函数和后置回调函数修改所述原函数返回值,且不调用原函数。

12.根据权利要求7所述的装置,其特征在于,所述装置还包括:存储模块,用于在所述前置回调函数和后置回调函数中存储有挂钩的原函数的参数和返回值的内存地址指针。

13.一种移动终端,包括存储器和处理器,所述存储器存储有计算机程序,其特征在于,所述处理器执行所述计算机程序时实现权利要求1至6中任一项所述的方法的步骤。

14.一种计算机可读存储介质,存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现权利要求1至6中任一项所述的方法的步骤。

说明书 :

挂钩函数的方法、装置、移动终端及存储介质

技术领域

[0001] 本发明涉及数据处理领域,特别是涉及一种挂钩函数的方法和装置。

背景技术

[0002] 在iOS开发中所使用的hook技术是通过系统函数class_replaceMethod来实现的,例如函数A有三个参数p1,p2,p3返回类型是r,如果想实现对此函数的hook就必须写一个和A函数参数和返回值一样的函数,传统的采用object-C 语法来描述函数A:-(r)FUN_A:(id)p1 p2:(id)p2 p3:(id)p3;替换函数应该写成类似下面这样,函数名可以随意:-(r)FAKE_FUN_A:(id)p1 p2:(id)p2 p3:(id)p3。
[0003] 然而,上述方式需要hook很多函数的时候需要对每一个函数写一个对应的替换函数,每个函数有不同返回值,不同参数,不能通过一个统一的处理函数一起处理,导致代码量增加。

发明内容

[0004] 基于此,有必要针对传统的hook很多函数时导致代码增加的问题,提供一种挂钩函数的方法,能缩减代码量,节省空间。
[0005] 此外,还有必要提供一种挂钩函数的装置,能缩减代码量,节省空间。
[0006] 一种挂钩函数的方法,包括以下步骤:
[0007] 获取待挂钩的原函数;
[0008] 判断所述原函数的返回值类型;
[0009] 根据所述原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数;
[0010] 将所述替换函数替换原函数,实现挂钩所述原函数。
[0011] 一种挂钩函数的装置,包括:
[0012] 获取模块,用于获取待挂钩的原函数;
[0013] 类型检测模块,用于判断所述原函数的返回值类型;
[0014] 配置模块,用于根据所述原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数;
[0015] 替换模块,用于将所述替换函数替换原函数,实现挂钩所述原函数。
[0016] 上述挂钩函数的方法和装置,获取到原函数后,判断原函数的返回值类型,根据返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,将替换函数替换原函数实现了原函数的挂钩,采用返回值类型配置替换函数,实现了一类返回值类型对应同一替换函数,不用每个函数对应一个替换函数,缩减了代码量,节省了空间。通过前置回调函数和后置回调函数判断是否修改原函数参数和返回值,实现对原函数的控制。

附图说明

[0017] 图1为一个实施例中终端的内部结构示意图;
[0018] 图2为一个实施例中挂钩函数的方法的流程图;
[0019] 图3为一个实施例中原函数被调用的方法流程图;
[0020] 图4为一个实施例中挂钩函数的装置的结构框图;
[0021] 图5为另一个实施例中挂钩函数的装置的结构框图;
[0022] 图6为另一个实施例中挂钩函数的装置;
[0023] 图7为另一个实施例中挂钩函数的装置;
[0024] 图8为另一个实施例中挂钩函数的装置。

具体实施方式

[0025] 为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
[0026] 可以理解,本发明所使用的术语“第一”、“第二”等可在本文中用于描述各种元件,但这些元件不受这些术语限制。这些术语仅用于将第一个元件与另一个元件区分。举例来说,在不脱离本发明的范围的情况下,可以将第一客户端称为第二客户端,且类似地,可将第二客户端称为第一客户端。第一客户端和第二客户端两者都是客户端,但其不是同一客户端。
[0027] 图1为一个实施例中终端的内部结构示意图。如图1所示,该终端包括通过系统总线连接的处理器、存储介质、内存、网络接口、显示屏和输入装置。其中,终端的存储介质存储有操作系统,还包括一种挂钩函数的装置,该挂钩函数装置用于实现一种挂钩函数的方法。该处理器用于提供计算和控制能力,支撑整个终端的运行。终端中的内存为存储介质中的挂钩函数的装置的运行提供环境,网络接口用于与服务器进行网络通信,如发送数据请求至服务器,接收服务器返回的数据等。终端的显示屏可以是液晶显示屏或者电子墨水显示屏等,输入装置可以是显示屏上覆盖的触摸层,也可以是终端外壳上设置的按键、轨迹球或触控板,也可以是外接的键盘、触控板或鼠标等。该终端可以是手机、平板电脑或者个人数字助理。本领域技术人员可以理解,图1中示出的结构,仅仅是与本申请方案相关的部分结构的框图,并不构成对本申请方案所应用于其上的终端的限定,具体的终端可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
[0028] 图2为一个实施例中挂钩函数的方法的流程图。如图2所示,一种挂钩函数的方法,包括以下步骤:
[0029] 步骤202,获取待挂钩的原函数。
[0030] 具体地,待挂钩的原函数是指需要hook的原函数。原函数,例如get(int x,int y)、main(char a)等,不限于此。原函数是汇编代码。汇编代码是最原始的代码,是程序编译链接后的产物,可以直接通过汇编代码编写汇编函数,实现某些函数无法直接完成的功能。一条汇编代码直接对应一条机器码。
[0031] 步骤204,判断原函数的返回值类型。
[0032] 具体地,原函数的返回值类型可包括CGRect、id、void、char、uchar、short、 ushort、int、uint、long、ulong、int64、uint64、float、double、CGRange、CGPoint 等17种返回值类型。
[0033] CGRect函数是包含一个CGpoint(原点)和一个CGsize(大小)的结构体,表示一个在原点处画大小中表示的长和宽的矩形。
[0034] id是指返回值按照唯一id选择元素。
[0035] void用于指定main函数不向系统返回任何值。
[0036] char是将返回值为字符。
[0037] uchar是指返回值为无符号字符数函数。
[0038] short是指返回值为有符号短整型。
[0039] ushort是指返回值为无符号短整型。
[0040] int是指返回值为有符号整数数据。uint是指返回值为无符号整数数据。
[0041] long是指返回值为有符号长整型。
[0042] ulong是指返回值为无符号长整型。
[0043] int64是指返回值为有符号64位整数数据。
[0044] uint64是指返回值为无符号64位整数数据。
[0045] float是指返回值为单精度浮点数。
[0046] Double是指返回值为双精度浮点型。
[0047] CGRange是指返回值为范围。
[0048] CGPoint是指返回值为二位坐标系中的点。
[0049] 每一个函数都有自己的签名,通过签名可以获取函数的返回值类型和参数类型。函数签名是函数的声明信息,包括参数、返回值、调用约定等。
[0050] 步骤206,根据该原函数的返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数。
[0051] 具体地,判断原函数返回值类型后,需要对原函数注册一个对应的前置回调函数和后置回调函数。
[0052] 回调函数是一个通过函数指针调用的函数,将函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,称这个函数为回调函数。
[0053] 前置回调函数是指原函数被调用前执行的回调函数。
[0054] 后置回调函数是指原函数被调用后执行的回调函数。
[0055] 通过前置回调函数可判断是否需要调用原函数,通过后置回调函数可以对原函数的返回值和/或参数进行修改。
[0056] 根据原函数的返回值类型配置对应的替换函数,替换函数中,前置回调函数和后置回调函数是统一的,会将返回值类型作为参数进行传递。
[0057] 替换函数的返回值和参数需要与原函数的返回值和参数一致。且将替换函数中参数声明为变参,使得替换函数的参数与原函数的参数一致。替换函数在被调用时,判断参数个数和参数类型。参数类型可包括int、float、double、id 等。
[0058] 此外,预先建立返回值类型与替换函数之间的对应关系,也就是同一返回值类型配置同一替换函数。再者,也可将替换函数地址与返回值类型之间建立对应关系。
[0059] 步骤206包括:根据原函数的返回值类型从返回值类型与替换函数的对应关系中查找到对应的包含前置回调函数和后置回调函数的替换函数,并将对应的替换函数分配给该原函数。
[0060] 通过建立返回值类型与替换函数的对应关系,可方便快速查找到对应的替换函数,处理效率高。
[0061] 此外,也可根据原函数的返回值类型从返回值类型与替换函数地址的对应关系中查找到对应的替换函数地址,将替换函数地址返回给原函数,然后根据替换函数地址得到对应的替换函数,将替换函数配置给原函数。
[0062] 步骤208,将该替换函数替换原函数,实现挂钩该原函数。
[0063] 具体地,挂钩即hook,通过跳转或修改函数表来实现在系统或第三方函数调用前执行到自己的函数,这个函数被称为hook函数或替换函数。
[0064] 上述挂钩函数的方法,获取到原函数后,判断原函数的返回值类型,根据返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,将替换函数替换原函数实现了原函数的挂钩,采用返回值类型配置替换函数,实现了一类返回值类型对应同一替换函数,不用每个函数对应一个替换函数,缩减了代码量,节省了空间。通过前置回调函数和后置回调函数判断是否修改原函数参数和返回值,实现对原函数的控制。
[0065] 此外,通过挂钩函数可实现自己所需要实现功能,如在系统的输入框上加上自己的文字图片等,或者直接让某个函数返回一个与真正结果不同的返回值等。
[0066] 再者,通过挂钩某函数,不需要关心此函数的实现,只需要对原函数根据其返回值类型配置对应的替换函数,通过替换函数中的前置回调函数和后置回调函数执行即可。
[0067] 在一个实施例中,上述挂钩函数的方法还包括:在前置回调函数和后置回调函数中存储有挂钩的所有原函数的参数和返回值的内存地址指针。通过内存地址指针可方便用户修改参数或返回值。
[0068] 图3为一个实施例中原函数被调用的方法流程图。如图3所示,上述挂钩函数的方法还包括:原函数被调用,具体包括:
[0069] 步骤302,获取调用原函数请求。
[0070] 具体地,获取调用方发起的调用原函数请求。调用方可为第三方函数。第三方函数可为任意函数,如主函数等。
[0071] 步骤304,根据该请求进入该原函数对应的替换函数,调用该替换函数中的前置回调函数。
[0072] 具体地,调用前置回调函数可修改原函数的参数、修改原函数的返回值、判断是否调用原函数等。
[0073] 步骤306,通过前置回调函数判断是否需要调用原函数,若需要调用原函数,则执行步骤308,若不需要调用原函数,则执行步骤310。
[0074] 具体地,前置回调函数根据需要确定是否需要调用原函数,例如有些情况下,需要原函数返回值直接为0,则不需要调用原函数,直接在前置回调函数中修改返回值为0,并返回。
[0075] 调用原函数的步骤包括:将原函数的返回值和参数压入栈中,模拟函数调用压栈方式调用原函数。
[0076] 具体地,通过汇编代码实现裸函数,将原函数的返回值和参数压入栈中,模拟函数调用栈方式直接调用原函数。不同返回值类型调用压栈方式不同。不同返回值类型对应不同的栈。栈不同是指栈的大小不同。
[0077] 采用汇编代码构造调用栈。不同的函数返回值和参数对应的栈不同。例如函数有ABC三个参数,返回值放入D中,则压栈后栈从上到下为DABC。此外,有些返回值类型不需要使用压栈只需要使用系统寄存器就可以,例如id类型。
[0078] 步骤308,原函数返回后将原函数的返回值传入该替换函数中的后置回调函数,然后执行步骤312。
[0079] 步骤310,返回默认返回值。
[0080] 具体地,可预先设置默认返回值,例如默认返回值为0等。
[0081] 步骤312,通过后置回调函数判断是否修改返回值,若是,则执行步骤314,若否,执行步骤316。
[0082] 具体地,根据原函数的返回值判断是否需要修改返回值。例如若某个函数返回值为1会引起代码逻辑问题,则通过后置回调函数修改该返回值。
[0083] 步骤314,修改返回值。
[0084] 步骤316,不修改返回值。
[0085] 上述原函数被调用中,进入原函数对应的替换函数,调用替换函数中的前置回调函数,通过前置回调函数判断是否需要调用原函数,若需要调用原函数,则调用原函数,原函数返回后将返回值传入到后置回调函数,通过后置回调函数判断是否需要修改返回值,若要修改,则修改返回值,可有效控制返回值,若不需要调用原函数,则返回默认返回值,可不执行原函数。
[0086] 在一个实施例中,上述挂钩函数的方法还包括:提供统一的缺省处理函数;当应用程序运行中需替换指定的原函数时,将该指定的原函数的返回值和处理方式传入该缺省处理函数,通过该缺省处理函数调用自身的前置回调函数和后置回调函数修改该原函数返回值,且不调用原函数。
[0087] 具体地,在应用程序运行,提交到外网后如果遇到致命的问题,不需使用运行中替换这个函数,但是此时替换函数在原始代码中还没有实现,可以通过缺省处理函数调用自身的前置回调函数和后置回调函数修改原函数返回值,避免崩溃。比如某个函数在某种特殊情况下会导致崩溃,通过下发一个单独的处理文件格式如:函数A在第一个参数是X的情况下直接修改返回值为Y且不执行原函数A。可以不执行原函数A,避免崩溃。
[0088] 通过缺省处理函数可实现对程序运行中的任意函数的替换,提高了对程序的控制能力,避免出现崩溃。
[0089] 图4为一个实施例中挂钩函数的装置的结构框图。如图4所示,一种挂钩函数的装置,包括获取模块410、类型检测模块420、配置模块430和替换模块 440。其中:
[0090] 获取模块410用于获取待挂钩的原函数。
[0091] 具体地,待挂钩的原函数是指需要hook的原函数。原函数,例如get(int x,int y)、main(char a)等,不限于此。原函数是汇编代码。汇编代码是最原始的代码,是程序编译链接后的产物,可以直接通过汇编代码编写汇编函数,实现某些函数无法直接完成的功能。一条汇编代码直接对应一条机器码。
[0092] 类型检测模块420用于判断该原函数的返回值类型。
[0093] 具体地,原函数的返回值类型可包括CGRect、id、void、char、uchar、short、 ushort、int、uint、long、ulong、int64、uint64、float、double、CGRange、CGPoint 等。每一个函数都有自己的签名,通过签名可以获取函数的返回值类型和参数类型。函数签名是函数的声明信息,包括参数、返回值、调用约定等。
[0094] 配置模块430用于根据该原函数的返回值类型配置对应的包含该前置回调函数和后置回调函数的替换函数。
[0095] 具体地,判断原函数返回值类型后,需要对原函数注册一个对应的前置回调函数和后置回调函数。回调函数是一个通过函数指针调用的函数,将函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,称这个函数为回调函数。前置回调函数是指原函数被调用前执行的回调函数。后置回调函数是指原函数被调用后执行的回调函数。通过前置回调函数可判断是否需要调用原函数,通过后置回调函数可以对原函数的返回值和/或参数进行修改。
[0096] 替换函数的返回值和参数需要与原函数的返回值和参数一致。且将替换函数中参数声明为变参,使得替换函数的参数与原函数的参数一致。替换函数在被调用时,判断参数个数和参数类型。参数类型可包括int、float、double、id 等。
[0097] 替换模块440用于将该替换函数替换原函数,实现挂钩该原函数。
[0098] 具体地,挂钩即hook,通过跳转或修改函数表来实现在系统或第三方函数调用前执行到自己的函数,这个函数被称为hook函数或替换函数。
[0099] 上述挂钩函数的装置,获取到原函数后,判断原函数的返回值类型,根据返回值类型配置对应的包含前置回调函数和后置回调函数的替换函数,将替换函数替换原函数实现了原函数的挂钩,采用返回值类型配置替换函数,实现了一类返回值类型对应同一替换函数,不用每个函数对应一个替换函数,缩减了代码量,节省了空间。通过前置回调函数和后置回调函数判断是否修改原函数参数和返回值,实现对原函数的控制。
[0100] 图5为另一个实施例中挂钩函数的装置的结构框图。如图5所示,一种挂钩函数的装置,除了包括获取模块410、类型检测模块420、配置模块430和替换模块440,还包括关系建立模块450。其中:
[0101] 关系建立模块450用于建立返回值类型与替换函数的对应关系。
[0102] 类型检测模块420还用于根据该返回值类型从该返回值类型与替换函数的对应关系中查找到对应的替换函数,并将对应的替换函数分配给该原函数。
[0103] 此外,关系建立模块450也可将替换函数地址与返回值类型之间建立对应关系。类型检测模块420还可根据原函数的返回值类型从返回值类型与替换函数地址的对应关系中查找到对应的替换函数地址,将替换函数地址返回给原函数,然后根据替换函数地址得到对应的替换函数,将替换函数配置给原函数。
[0104] 图6为另一个实施例中挂钩函数的装置。如图6所示,一种挂钩函数的装置,除了包括获取模块410、类型检测模块420、配置模块430和替换模块440,还包括请求获取模块460、第一调用模块470、第一判断模块480、第二调用模块482、第二判断模块484。其中:
[0105] 请求获取模块460用于获取调用原函数请求。
[0106] 具体地,获取调用方发起的调用原函数请求。调用方可为第三方函数。第三方函数可为任意函数,如主函数等。
[0107] 第一调用模块470用于根据该请求进入该原函数对应的替换函数,调用该替换函数中的前置回调函数。
[0108] 具体地,调用前置回调函数可修改原函数的参数、修改原函数的返回值、判断是否调用原函数等。
[0109] 第一判断模块480用于通过该前置回调函数判断是否需要调用原函数。
[0110] 具体地,前置回调函数根据需要确定是否需要调用原函数,例如有些情况下,需要原函数返回值直接为0,则不需要调用原函数,直接在前置回调函数中修改返回值为0,并返回。
[0111] 第二调用模块482用于若判断出需要调用原函数,则调用原函数,且原函数返回后将原函数的返回值传入该替换函数中的后置回调函数,若不需要调用原函数,则返回默认返回值。
[0112] 具体地,可预先设置默认返回值,例如默认返回值为0等。
[0113] 第二调用模块482还用于将原函数的返回值和参数压入栈中,模拟函数调用压栈方式调用原函数。
[0114] 具体地,通过汇编代码实现裸函数,将原函数的返回值和参数压入栈中,模拟函数调用栈方式直接调用原函数。不同返回值类型调用压栈方式不同。
[0115] 采用汇编代码构造调用栈。不同的函数返回值和参数对应的栈不同。例如函数有ABC三个参数,返回值放入D中,则压栈后栈从上到下为DABC。此外,有些返回值类型不需要使用压栈只需要使用系统寄存器就可以,例如id类型。
[0116] 第二判断模块484用于通过该后置回调函数判断是否修改返回值,若是,则修改返回值,若否,则不修改返回值。
[0117] 上述原函数被调用中,进入原函数对应的替换函数,调用替换函数中的前置回调函数,通过前置回调函数判断是否需要调用原函数,若需要调用原函数,则调用原函数,原函数返回后将返回值传入到后置回调函数,通过后置回调函数判断是否需要修改返回值,若要修改,则修改返回值,可有效控制返回值,若不需要调用原函数,则返回默认返回值,可不执行原函数。
[0118] 图7为另一个实施例中挂钩函数的装置。如图7所示,一种挂钩函数的装置,除了包括获取模块410、类型检测模块420、配置模块430和替换模块440,还包括提供模块490、修改模块492。其中:
[0119] 提供模块490用于提供统一的缺省处理函数。
[0120] 修改模块492用于当应用程序运行中需替换指定的原函数时,将该指定的原函数的返回值和处理方式传入该缺省处理函数,通过该缺省处理函数调用自身的前置回调函数和后置回调函数修改该原函数返回值,且不调用原函数。
[0121] 具体地,在应用程序运行,提交到外网后如果遇到致命的问题,可以通过缺省处理函数调用自身的前置回调函数和后置回调函数修改原函数返回值,避免崩溃。比如某个函数在某种特殊情况下会导致崩溃,通过下发一个单独的处理文件格式如:函数A在第一个参数是X的情况下直接修改返回值为Y且不执行原函数A。可以不执行原函数A,避免崩溃。
[0122] 通过缺省处理函数可实现对程序运行中的任意函数的替换,提高了对程序的控制能力,避免出现崩溃。
[0123] 图8为另一个实施例中挂钩函数的装置。如图8所示,一种挂钩函数的装置,除了包括获取模块410、类型检测模块420、配置模块430和替换模块440,还包括存储模块494。其中:
[0124] 存储模块494用于在该前置回调函数和后置回调函数中存储有挂钩的原函数的参数和返回值的内存地址指针。
[0125] 通过内存地址指针可方便用户修改参数或返回值。
[0126] 在其他实施例中,一种挂钩函数的装置,可包括获取模块410、类型检测模块420、配置模块430、替换模块440、关系建立模块450、请求获取模块460、第一调用模块470、第一判断模块480、第二调用模块482、第二判断模块484、提供模块490、修改模块492、存储模块494中任意可能组合。
[0127] 本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于一非易失性计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,所述的存储介质可为磁碟、光盘、只读存储记忆体(Read-Only Memory,ROM)等。
[0128] 以上所述实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。因此,本发明专利的保护范围应以所附权利要求为准。