CN110554998A - 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质 - Google Patents

一种通过替换函数内部指令的钩子方法、装置、终端及存储介质 Download PDF

Info

Publication number
CN110554998A
CN110554998A CN201810292020.9A CN201810292020A CN110554998A CN 110554998 A CN110554998 A CN 110554998A CN 201810292020 A CN201810292020 A CN 201810292020A CN 110554998 A CN110554998 A CN 110554998A
Authority
CN
China
Prior art keywords
instruction
jump
function
replacing
jump instruction
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.)
Granted
Application number
CN201810292020.9A
Other languages
English (en)
Other versions
CN110554998B (zh
Inventor
鲁可
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen Co Ltd
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN201810292020.9A priority Critical patent/CN110554998B/zh
Publication of CN110554998A publication Critical patent/CN110554998A/zh
Application granted granted Critical
Publication of CN110554998B publication Critical patent/CN110554998B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Landscapes

  • Executing Machine-Instructions (AREA)
  • Stored Programmes (AREA)

Abstract

本发明涉及一种通过替换函数内部指令的钩子方法、装置、终端及存储介质,所述方法包括:使用第一跳转指令替换函数内部的第一指令;当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。所述装置包括:指令替换模块、第一跳转模块和第二跳转模块。本发明仅替换函数内部一条指令,并通过中间空间进行跳转,指令修正成本小,又能扩大hook的使用范围。

Description

一种通过替换函数内部指令的钩子方法、装置、终端及存储 介质
技术领域
本发明涉及计算机技术领域,尤其涉及一种通过替换函数内部指令的钩子方法、装置、终端及存储介质。
背景技术
hook函数(钩子函数)是一个处理消息的代码段,采用hook函数可以钩住目标函数,此时如果有其他函数向该目标函数发送消息时,不会先运行该目标函数,而是先运行hook函数。在hook函数的运行过程中,可以先对传递给目标函数的消息进行加工处理再传递给该目标函数,也可以直接将该消息传递给目标函数,也可以强制结束该消息的传递。hook能够拦截指定函数或者具体函数某条汇编指令的功能,但是如果需要针对函数的特定位置进行hook,那么可以用inline hook(内联挂钩函数)。
为了解决上述问题,本发明提出了一种通过替换函数内部指令的钩子方法、装置、终端及存储介质。
发明内容
本发明所要解决的技术问题在于,提供一种通过替换函数内部指令的钩子方法、装置、终端及存储介质,通过替换函数内部的一条指令,采用可执行文件内部区域做中间跳转,指令修正成本小。
为了解决上述技术问题,第一方面,本发明提供了一种通过替换函数内部指令的钩子方法,包括:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
其中,所述替换函数内部的第一指令包括替换函数头部的一条指令;所述对应地址的空间为可执行文件内部区域。
进一步地,所述第二跳转指令包括预先存储在所述对应地址空间的指令和通过外部输入并存储在所述对应地址空间的指令。
第二方面,本发明提供了一种通过替换函数内部指令的钩子装置,包括:
指令替换模块,用于使用第一跳转指令替换函数内部的第一指令;
第一跳转模块,用于当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
第二跳转模块,用于当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
所述装置还包括:
第一指令执行模块,用于在执行所述预设函数后,执行被所述第一跳转指令替换的所述第一指令;
指令修正、备份模块,用于在执行被所述第一跳转指令替换的第一指令之前,对指令进行修正和备份;
第三跳转模块,用于根据第三跳转指令跳转并执行所述函数内所述第一指令的下一条指令。
第三方面,本发明提供了一种终端,包括:
处理器以及存储器,其中所述处理器用于调用并执行所述存储器中存储的程序,所述存储器,用于存储程序,所述程序用于:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
第四方面,本发明提供了一种计算机存储介质,所述存储介质中存储有计算机可执行指令,所述计算机可执行指令由处理器加载并执行以下步骤:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
实施本发明实施例,具有如下有益效果:
本发明采用替换原函数内部一条指令的方法,并通过可执行文件内部区域进行跳转,尽可能地挪走少量的指令,使得指令的修正成本小,又扩大了hook的使用范围。
附图说明
图1是本发明实施例提供的现有技术中inline hook的原理图;
图2是本发明实施例提供的现有技术中inline hook的实现流程图;
图3是本发明实施例提供的一种inline hook方案的跳转流程示意图;
图4是本发明实施例提供的一种inline hook的方法流程图;
图5是本发明实施例提供的另一种inline hook方案的跳转流程示意图;
图6是本发明实施例提供的另一种inline hook的方法流程图;
图7是本发明实施例提供的一种通过替换函数内部指令的钩子方法流程图;
图8是本发明实施例提供的一种通过替换函数内部指令的钩子方法跳转流程示意图;
图9是本发明实施例提供的一种通过替换函数内部指令的钩子装置示意图;
图10是本发明实施例提供的另一种通过替换函数内部指令的钩子装置示意图;
图11是本发明实施例提供的内存映射示意图;
图12是本发明实施例提供的一种终端示意图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明作进一步地详细描述。显然,所描述的实施例仅仅是本发明的一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本发明保护的范围。
在本发明的描述中,需要理解的是,术语“第一”、“第二”仅用于描述目的,而不能理解为指示或暗示相对重要性或者隐含指明所指示的技术特征的数量。由此,限定有“第一”、“第二”的特征可以明示或者隐含地包括一个或者更多个该特征。而且,术语“第一”、“第二”等适用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本发明的实施例能够以除了在这里图示或描述的那些以外的顺序实施。
inline hook(内联挂钩函数)的核心思想是:通过替换目标函数头部指令实现在函数执行之前跳转到其他的指令区域,执行完毕跳转回到原来的函数,跳转到的指令区域通常是编写的函数。inline hook在动态库执行内部函数调用时,改变函数内部指令,使系统跳转到预设函数上执行,通常还会保留原函数的调用接口。
请参见图1,其示出了inline hook的原理图,从图中可以看出,inline hook直接修改要hook位置的指令,用跳转指令替换了函数的原指令,通过跳转指令转到用户自定义的桩函数中。其中,在桩函数中,会处理寄存器等信息,并调用相应hook点用户自定义的桩函数,在执行完用户自定义的桩函数之后,再通过跳转指令跳转到原函数,继续执行原指令。
其中,需要注意的是:
(1)跳转指令的构建、从原指令跳转过去的底层桩函数,涉及系统汇编层,和inline hook的平台关系较大,即ARM和THUMB、X86等均有所不同;
(2)从底层桩函数跳转回原函数,即图1中第3步跳转,去执行原指令2的时候,有个关键的点:如果原指令2涉及到PC操作,则需要进行指令修复。比如说ADD R3,PC,R3,两处指令的PC完全不一样,不能直接复制,需要修复相应的PC值;
不论是arm指令集还是THUMB指令集,都存在很多的与PC值相关的指令,例如:B系列指令、literal系列指令等。原有函数的前几个被跳转指令替换的指令将会被搬移到trampoline instructions中,此时PC值已经变动,所以需要对PC相关指令进行修正(所谓修正即为计算出实际地址,并使用其他指令完成同样的功能);
(3)inline hook的指令覆盖顺序,优选地,原指令2的覆盖留在最后。即完成了底层桩函数构造、原函数构造后,再一次性填写跳转指令覆盖原指令2,这样的好处是防止hook一些频繁执行的函数可能导致的崩溃。在inline hook的过程中走入hook逻辑,而桩函数或者原函数可能未构造成功导致崩溃。
请参见图2,其示出了inline hook的实现流程图,包括:
S201.备份hook点信息,如hook点类型,原指令等;
S202.构建跳转桩stub,包括寄存器保存和跳转功能;
S203.构建hook点原指令,包括指令修复和跳转;
通过BuildArmJumpCode函数构建简单的指令跳转函数,
LDR PC,[PC-4]
Addr
该跳转指令范围是32位,不过对于32位系统来说,则是全地址跳转。构造原指令的同时,将原指令地址填充到stub中使之可实现图1中的第3步跳转。
S204.重构hook位置的指令,跳转到桩函数中。
重构hook位置的指令,直接填充一个跳转指令,该跳转指令是跳转到BuildStub构建的stub中。
跳转指令主要分为以下两种:
B系列指令:B、BL、BX和BLX;
直接写PC寄存器。
Arm的B系列指令跳转范围只有4M,Thumb的B系列指令跳转范围只有256字节,然而大多数情况下跳转范围都会大于4M,故采用LDR PC,[PC,?]构造跳转指令。另外Thumb16指令中并没有合适的跳转指令,如果单独使用Thumb16指令构造跳转指令,需要使用更多的指令完成,并且在后续对PC相关指令的修正也更加繁琐。
另外,Arm处理器采用3级流水线来增加处理器指令流的速度,也就是说程序计数器R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的,即PC总是指向当前正在执行的指令地址再加两条指令的地址。比如当前指令地址是0x8000,那么当前PC的值,在thumb下面是0×8000+2*2,在arm下面是0x8000+4*2。
对于Arm指令集,跳转指令为:
LDR PC,[PC,PC-4]
addr
LDR PC,[PC,PC-4]对应的机器码为:0xE51FF004,addr为要跳转的地址。该跳转指令范围为32位,对于32位系统来说即为全地址跳转。
本发明的一个实施例提供了一种通用inline hook方法,其跳转流程图请参见图3,通用inline hook是直接修改函数头部的两条指令,达到跳转到自定义的外部函数的目的,采用两条指令:LDR PC,[PC-4]和Addr替换原函数的头两条指令,即图3中的原指令一和原指令二;通过执行跳转指令一级跳转到预设函数中,并执行预设函数中的指令;执行完预设函数后,经过二级跳转到mmap(申请内存映射)出来的空间,进行指令修正的操作,并执行原函数中被替换的原指令一和原指令二,在通过执行跳转指令三级跳转到原函数的原指令三继续执行原指令三的操作。
其方法流程图请参见图4,一种通用inline hook方法,包括:
S401.使用第一跳转指令和第二跳转指令分别替换函数头部的第一指令和第二指令。
其中,所述第一跳转指令和第二跳转指令可以为:
LDR PC,[PC-4]
Addr
S402.当所述第一跳转指令和第二跳转指令被触发时,根据所述第一跳转指令和所述第二跳转指令跳转到预设函数并执行所述预设函数。
S403.当执行完所述预设函数时,执行被替换的所述第一指令和所述第二指令。
需要注意的是,由于涉及到与PC值相关的B系列指令,在执行所述第一指令和所述第二指令的之前,需要对被替换的原指令进行指令修正。
S404.当执行完所述第一指令和所述第二指令时,根据第三跳转指令跳转到原函数并继续执行所述第二跳转指令的下一条指令。
具体地,所述第三跳转指令用于跳转到所述原函数中被替换的所述第二指令两条指令的下一条指令,即所述第三跳转指令的跳转地址为所述第二跳转指令的下一条指令的地址。
本发明的一个实施例中提供了一种空间inline hook的方法,请参见图5,其示出了空间inline hook的整个跳转流程,空间inline hook首先在函数内找到需要调用hook函数的地方,比如方法A调用方法B,需要在父函数A方法的汇编里找到跳至方法B,需要在父函数A方法的汇编里找到跳至方法B的地方,比如BL B修改成BL可执行文件内部区域,优选地,本实施例中可执行文件内部区域,具体为so空闲空间,在so空闲空间处再填上两条跳转指令:
LDR PC,[PC-4]
Addr
达到跳转到自己实现的外部函数的目的。
如图5所示,首先执行原函数内的原指令一,只修改BL指令的跳转,如对原指令二进行地址偏移,通过一级跳转到so空闲空间;执行so空闲空间的LDR PC,[PC-4]和Addr两条指令,通过二级跳转到预设函数并执行预设函数;执行完预设函数后,经过三级跳自动跳回原函数,并继续执行原指令三。
一种空间inline hook的方法流程图如图6所示,包括:
S601.将函数内的一条BL指令修改为第一跳转指令。
其中,对BL指令的修改是指对其进行地址偏移,只修改指令的一部分。若原函数在BL指令之前还有其他指令,则先执行其他指令。
S602.当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令。
S603.当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
S604.当所述预设函数执行完之后,自动跳回原函数并继续执行被修改指令的下一条指令。
综上所述,通用inline hook方案,hook范围更广,替换指令过多,需要替换两条指令,指令修正成本大,稳定性差;空间inline hook方案使用受限,比如:A调用B,hook B,需要传父调用A,如果C方法也调用了B,需要多次hook。
本发明的一个实施例提供了一种通过替换函数内部指令的钩子方法,仅替换头部一条指令,通过可执行文件内部区域进行中间跳转,优选地,本实施例中可执行文件内部区域,具体为so空闲空间,指令修正成本小,又能扩大hook的适用范围,其流程图如图7所示,包括:
S701.使用第一跳转指令替换函数内部的第一指令。
在对一个函数进行inline hook时,首先需要判断当前函数指令是Arm指令还是Thumb指令,指令使用目标地址值的bit[0]来确定目标地址的指令类型。bit[0]的值为1时,目标程序为Thumb指令;bit[0]值为0时,目标程序为ARM指令。
其中,所述第一跳转指令可以为BLX my_addr,其中my_addr为所述第一跳转指令需要跳转的目的地。用所述第一跳转指令替换函数内部的一条指令,被替换的所述原第一指令可以是函数头部的一条指令,也可以是函数中间某处的一条指令。
这里所说的第一指令是指原函数中被所述第一跳转指令替换的一条指令。
S702.当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令。
根据第一跳转指令跳转到对应目的地址空间,对应的地址空间为可执行文件内部区域,这里的空间可以是so空闲空间,所述so空闲空间可以供多个函数使用。
所述第二跳转指令包括预先存储在所述对应地址空间的指令和通过外部输入并存储在所述对应地址空间的指令。
Linux下的.so是基于Linux下的动态链接,其功能和作用类似与windows下.dll文件。
linux下有两种库:动态库和静态库,二者的不同点在于代码被载入的时刻不同。静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库的实例。
静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
S703.当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
所述第二跳转指令可以为LDR PC,[PC-4]和my_func,其中my_func为需要跳转的预设函数的首地址。
在执行完预设函数之后,会继续执行被所述第一跳转指令替换的原第一指令,需要注意的是,由于在整个方法过程中用到了B系列指令,所以在执行原第一指令之前,还需要对指令进行修正和备份。在执行完所述原第一指令之后,通过第三跳转指令跳转并执行所述函数内所述第一指令的下一条指令,所述第三跳转指令包括所述函数内所述第一指令的下一条指令的地址。所述第三跳转指令可以是:LDR PC,[PC-4]和原第二指令的地址,所述原第二指令即为所述原函数中原第一指令的下一条指令。
以Arm指令的修正过程为例,对应的代码为relocateInstructionInArm函数,函数原型如下:
/*
target_addr:待Hook的目标函数地址,即为当前PC值,用于修正指令。
orig_instructions:存放原有指令的首地址,用于修正指令和后续对原有指令的恢复。
length:存放的原有指令的长度,Arm指令为8字节;Thumb指令为12字节。
trampoline_instructions:存放修正后指令的首地址,用于调用原函数。
orig_boundaries:存放原有指令的指令边界(所谓边界即为该条指令与起始地址的偏移量),用于后续线程处理中,对PC的迁移。
trampoline_boundaries:存放修正后指令的指令边界,用途与上相同。
count:处理的指令项数,用途与上相同。
*/
static void relocateInstructionInArm(uint32_t target_addr,uint32_t*orig_instructions,int length,uint32_t*trampoline_instructions,int*orig_boundaries,int*trampoline_boundaries,int*count);
具体实现中,首先通过函数getTypeInArm判断当前指令的类型,本函数通过类型,共分为4个处理分支:
1、BLX_ARM、BL_ARM、B_ARM、BX_ARM
2、ADD_ARM
3、ADR1_ARM、ADR2_ARM、LDR_ARM、MOV_ARM
4、其他指令
其中BLX_ARM、BL_ARM、B_ARM、BX_ARM指令的修正即为B系列指令(BLX<label>、BL<label>、B<label>、BX PC)的修正,其中BLX_ARM和BL_ARM需要修正LR寄存器的值,相关代码为:
接下来构造相应的跳转指令,即为:
trampoline_instructions[trampoline_pos++]=0xE51FF004;
//LDR PC,[PC,#-4]
最后解析指令,计算实际跳转地址value,并将其写入trampoline_instructions,相关代码为:
如此便完成了B系列指令的修正。
其中指令的修正和备份以及第三指令的跳转可以是在mmap出来的空间进行操作。
以上所述的一种通过替换函数内部指令的钩子方法的具体跳转流程图可参见图8,其示出了进行inline hook具体的跳转过程。
请参见图9,其示出了一种通过替换函数内部指令的钩子装置示意图,包括:
指令替换模块910,用于使用第一跳转指令替换函数内部的第一指令。
其中,使用第一跳转指令替换函数内部的第一指令,被替换的所述原第一指令可以是函数头部的一条指令,也可以是函数中间某处的一条指令。
第一跳转模块920,用于当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令。
根据第一跳转指令跳转到对应目的地址的空间,所述对应目的地址的空间为可执行文件内部区域,这里的空间可以是so空闲空间。所述第二跳转指令包括预先存储在所述对应地址空间的指令和通过外部输入并存储在所述对应地址空间的指令。
所述第二跳转指令包括需要跳转到的预设函数的地址。
第二跳转模块930,用于当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
请参见图10,所述装置还包括指令修正、备份模块940,用于在执行被所述第一跳转指令替换的原第一指令之前,对指令进行修正和备份。其中指令的修正和备份以及第三指令的跳转可以是在mmap(申请内存映射)出来的空间进行操作。
Linux提供了内存映射函数mmap,它把文件内容映射到一段内存上,准确说是虚拟内存上,通过对这段内存的读取和修改,实现对文件的读取和修改。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。
mmap的作用是映射文件描述符fd指定文件的[off,off+len]区域至调用进程的[addr,addr+len]的内存区域,如图11所示。
mmap内存映射区作用:让用户程序直接访问设备内存,在要求高性能的应用当中比较常用。应用程序使用的动态库映射到这个区域;应用程序调用mmap,将设备物理地址和这个区域的虚拟内存进行映射;mmap映射内存必须是页面大小的整数倍。
mmap系统调用的实现过程包括:
1.先通过文件系统定位要映射的文件;
2.权限检查,映射的权限不会超过文件打开的方式,也就是说如果文件是以只读方式打开,那么则不允许建立一个可写映射;
3.创建一个vma对象,并对之进行初始化;
4.调用映射文件的mmap函数,其主要工作是给vm_ops向量表赋值;
5.把该vma链入该进程的vma链表中,如果可以和前后的vma合并则合并;
6.如果是要求VM_LOCKED(映射区不被换出)方式映射,则发出缺页请求,把映射页面读入内存中。
所述装置还包括第一指令执行模块950,用于在执行完所述预设函数后,执行被所述第一跳转指令替换的原第一指令。
所述装置还包括第三跳转模块960,用于根据第三跳转指令跳转到所述原第一指令的下一条指令的地址。
请参见图12,其示出了本发明实施例提供的一种终端,所述终端1200可以是计算机或者移动设备,如手机、平板电脑等,所述终端1200中安装有至少一个基于客户端/服务机制的应用程序(Application,APP),终端可以与该APP所属的服务器建立通信连接,并向该服务器发送访问请求。
所述终端1200包括处理器1210、存储器1220、内存1230、网络接口1240、显示屏1250和输入装置1260等。其中,终端1200的存储器1220中存储有操作系统,该终端1200的操作系统可以为Android系统,本发明实施例对此不做限定。该终端1200的操作系统包括用户空间和内核空间,用户空间是进程独立的,相互之间不可访问,而内核空间是进程共享的,操作系统中只有一份内核空间。所述存储器1220中还存储有应用程序,所述程序用于:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
所述处理器1210通过运行存储在所述存储器1220上的应用程序及模块,从而执行各种功能应用以及数据处理。所述处理器1210可以是中央处理器(CPU)、特定应用集成电路(ASIC)、数字信号处理器(DSP)、专用集成电路(ASIC)、现场可编程门阵列(FPGA)或者其他可编程逻辑器件等。
内存1230为存储器1220中的应用程序的运行提供环境,内存1230一般采用半导体存储单元,包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE),RAM是其中最重要的存储器。内存1230是终端中重要的部件之一,它是与处理器1210进行沟通的桥梁,所有程序的运行都是在内存1230中进行的。
网络接口1240用于与服务器进行网络通信。显示屏1250可以是液晶显示屏或者电子墨水显示屏等,输入装置1260可以是显示屏上覆盖的触摸层,也可以是终端外壳上设置的按键、轨迹球或者触控板等。输入装置1260可以接受输入的数字或字符信息,以及产生与用户设置以及功能控制有关的信号输入。
本发明实施例还提供了一种计算机存储介质,所述计算机存储介质可以存储有多条指令,所述指令适于由处理器加载并执行如上述图7、图8所示实施例的方法步骤,具体执行过程可以参见图7、图8所示实施例的具体说明,在此不进行赘述。
本发明可以应用于移动终端的APP(Application,应用程序)中,如Android系统的手机QQ、QQ空间等,通过Native Hook(移动终端C语言的钩子)的方式帮助移动终端APP修复外网系统问题,通过native层(本地框架)的hook技术,实现方法的动态替换。在不需要重新安装新的APK(Android Package,安卓安装包)安装包的情况下,修复一些线上的bug。这样做可以免去发版、安装、重新打开等过程,就可以修复线上的bug,防止用户流失。
除了可以修复bug之外,本发明还可以用于收集性能数据,比如获取应用的安装时间、获取应用首页的开启时间、获取应用CPU信息、获取应用内存信息、获取应用流量消耗信息以及获取应用电量消耗信息等。根据收集到的性能数据,能够对应用程序的相关性能不断优化,提升用户体验。
本发明仅替换函数内部一条指令,通过可执行文件内部区域,具体为so空闲空间进行中间跳转,指令修正成本小,又扩大hook的使用范围。将本发明应用在手机APP的线上bug修复以及性能数据收集等方面,使得运行的性能更加稳定且功能更加强大。
本实施例中所示出的结构,仅仅是与本申请方案相关的部分结构,并不构成对本申请方案所应用于其上的设备的限定,具体的设备可以包括比示出的更多或更少的部件,或者组合某些部件,或者具有不同的部件的布置。应当理解到,本实施例中所揭露的方法、装置等,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述模块的划分仅仅为一种逻辑功能的划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元模块的间接耦合或通信连接。
基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,RandomAccess Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
本领域技术人员还可以进一步意识到,结合本说明书所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合实现,为了清除地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但这种实现不应认为超出本发明的范围。
以上所述,以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。

Claims (15)

1.一种通过替换函数内部指令的钩子方法,其特征在于,包括:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
2.根据权利要求1所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述替换函数内部的第一指令包括替换函数头部的一条指令。
3.根据权利要求1所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述对应地址空间为可执行文件内部区域。
4.根据权利要求3所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述第二跳转指令包括预先存储在所述对应地址空间的指令和通过外部输入并存储在所述对应地址空间的指令。
5.根据权利要求1所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述根据所述第二跳转指令跳转并执行预设函数后,执行被所述第一跳转指令替换的所述第一指令。
6.根据权利要求5所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述执行被所述第一跳转指令替换的所述第一指令之前还包括对指令进行修正和备份。
7.根据权利要求6所述的一种通过替换函数内部指令的钩子方法,其特征在于,所述执行被所述第一跳转指令替换的所述第一指令之后还包括根据第三跳转指令跳转并执行所述函数内所述第一指令的下一条指令。
8.一种通过替换函数内部指令的钩子装置,其特征在于,包括:
指令替换模块,用于使用第一跳转指令替换函数内部的第一指令;
第一跳转模块,用于当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
第二跳转模块,用于当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
9.根据权利要求8所述的一种通过替换函数内部指令的钩子装置,其特征在于,所述对应地址空间为可执行文件内部区域。
10.根据权利要求8所述的一种通过替换函数内部指令的钩子装置,其特征在于,所述第二跳转指令包括预先存储在所述对应地址空间的指令和通过外部输入并存储在所述对应地址空间的指令。
11.根据权利要求8所述的一种通过替换函数内部指令的钩子装置,其特征在于,所述装置还包括第一指令执行模块,用于在执行所述预设函数后,执行被所述第一跳转指令替换的所述第一指令。
12.根据权利要求8所述的一种通过替换函数内部指令的钩子装置,其特征在于,所述装置还包括指令修正、备份模块,用于在执行被所述第一跳转指令替换的所述第一指令之前,对指令进行修正和备份。
13.根据权利要求9所述的一种通过替换函数内部指令的钩子装置,其特征在于,所述装置还包括第三跳转模块,用于根据第三跳转指令跳转并执行所述函数内所述第一指令的下一条指令。
14.一种终端,其特征在于,包括:
处理器以及存储器,其中所述处理器用于调用并执行所述存储器中存储的程序,所述存储器,用于存储程序,所述程序用于:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
15.一种计算机存储介质,其特征在于,所述存储介质中存储有计算机可执行指令,所述计算机可执行指令由处理器加载并执行以下步骤:
使用第一跳转指令替换函数内部的第一指令;
当所述第一跳转指令被触发时,根据所述第一跳转指令跳转到对应地址空间,所述对应地址空间用于接收并存储第二跳转指令;
当所述第二跳转指令被触发时,根据所述第二跳转指令跳转并执行预设函数。
CN201810292020.9A 2018-03-30 2018-03-30 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质 Active CN110554998B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201810292020.9A CN110554998B (zh) 2018-03-30 2018-03-30 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201810292020.9A CN110554998B (zh) 2018-03-30 2018-03-30 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质

Publications (2)

Publication Number Publication Date
CN110554998A true CN110554998A (zh) 2019-12-10
CN110554998B CN110554998B (zh) 2024-02-13

Family

ID=68733617

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201810292020.9A Active CN110554998B (zh) 2018-03-30 2018-03-30 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质

Country Status (1)

Country Link
CN (1) CN110554998B (zh)

Cited By (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111142969A (zh) * 2019-12-27 2020-05-12 贵阳动视云科技有限公司 64位程序调用32位程序模块的方法、装置、介质及设备
CN113918935A (zh) * 2021-12-15 2022-01-11 飞天诚信科技股份有限公司 一种函数被hook时的处理方法及装置
CN115017058A (zh) * 2022-08-04 2022-09-06 飞腾信息技术有限公司 一种内核模块的测试方法、装置、电子设备及存储介质
CN115952491A (zh) * 2022-12-30 2023-04-11 北京基调网络股份有限公司 hook目标函数的方法、装置、电子设备及介质
CN118152044A (zh) * 2024-05-10 2024-06-07 海马云(天津)信息技术有限公司 非根权限挂钩Java方法的方法与装置

Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103677770A (zh) * 2012-09-06 2014-03-26 北京中天安泰信息科技有限公司 指令重组方法及装置
CN103885750A (zh) * 2014-04-04 2014-06-25 深圳市大成天下信息技术有限公司 在目标函数中挂钩新函数的装置、方法以及电子设备
CN104598809A (zh) * 2015-02-13 2015-05-06 北京奇虎科技有限公司 程序的监控方法及其防御方法以及相关装置
CN104809018A (zh) * 2015-05-18 2015-07-29 烽火通信科技股份有限公司 一种嵌入式系统软件注入热补丁的方法及系统
EP2940577A1 (en) * 2014-04-30 2015-11-04 Dialog Semiconductor GmbH Patching of program code executed from one time programmable memory
CN105573788A (zh) * 2015-12-15 2016-05-11 华为技术有限公司 补丁处理的方法和设备以及生成补丁的方法和设备
WO2017107706A1 (zh) * 2015-12-25 2017-06-29 北京奇虎科技有限公司 基于arm指令虚拟化的elf文件保护方法及系统

Patent Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103677770A (zh) * 2012-09-06 2014-03-26 北京中天安泰信息科技有限公司 指令重组方法及装置
CN103885750A (zh) * 2014-04-04 2014-06-25 深圳市大成天下信息技术有限公司 在目标函数中挂钩新函数的装置、方法以及电子设备
EP2940577A1 (en) * 2014-04-30 2015-11-04 Dialog Semiconductor GmbH Patching of program code executed from one time programmable memory
CN104598809A (zh) * 2015-02-13 2015-05-06 北京奇虎科技有限公司 程序的监控方法及其防御方法以及相关装置
CN104809018A (zh) * 2015-05-18 2015-07-29 烽火通信科技股份有限公司 一种嵌入式系统软件注入热补丁的方法及系统
CN105573788A (zh) * 2015-12-15 2016-05-11 华为技术有限公司 补丁处理的方法和设备以及生成补丁的方法和设备
WO2017107706A1 (zh) * 2015-12-25 2017-06-29 北京奇虎科技有限公司 基于arm指令虚拟化的elf文件保护方法及系统

Cited By (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111142969A (zh) * 2019-12-27 2020-05-12 贵阳动视云科技有限公司 64位程序调用32位程序模块的方法、装置、介质及设备
CN113918935A (zh) * 2021-12-15 2022-01-11 飞天诚信科技股份有限公司 一种函数被hook时的处理方法及装置
CN115017058A (zh) * 2022-08-04 2022-09-06 飞腾信息技术有限公司 一种内核模块的测试方法、装置、电子设备及存储介质
CN115017058B (zh) * 2022-08-04 2022-11-29 飞腾信息技术有限公司 一种内核模块的测试方法、装置、电子设备及存储介质
CN115952491A (zh) * 2022-12-30 2023-04-11 北京基调网络股份有限公司 hook目标函数的方法、装置、电子设备及介质
CN115952491B (zh) * 2022-12-30 2023-09-29 北京基调网络股份有限公司 hook目标函数的方法、装置、电子设备及介质
CN118152044A (zh) * 2024-05-10 2024-06-07 海马云(天津)信息技术有限公司 非根权限挂钩Java方法的方法与装置

Also Published As

Publication number Publication date
CN110554998B (zh) 2024-02-13

Similar Documents

Publication Publication Date Title
CN109976761B (zh) 软件开发工具包的生成方法、装置及终端设备
CN110554998B (zh) 一种通过替换函数内部指令的钩子方法、装置、终端及存储介质
US11694299B2 (en) Methods and apparatus to emulate graphics processing unit instructions
US9244854B2 (en) Transparent code patching including updating of address translation structures
CN107291480B (zh) 一种函数调用方法及装置
US6158045A (en) Portable debugging services utilizing a client debugger object and a server debugger object with flexible addressing support
US5815653A (en) Debugging system with portable debug environment-independent client and non-portable platform-specific server
US5787245A (en) Portable debugging service utilizing a client debugger object and a server debugger object
US20150277766A1 (en) Transparent code patching
CN107480476B (zh) 一种基于ELF感染的Android本地层指令编译虚拟化加壳方法
US10310863B1 (en) Patching functions in use on a running computer system
US8769498B2 (en) Warning of register and storage area assignment errors
CN114461223A (zh) 一种代码生成方法、装置及终端设备
WO2023169164A1 (zh) 应用程序的修复方法、装置、计算机设备以及存储介质
EP4278265B1 (en) Memory address compression within an execution trace
US11593113B2 (en) Widening memory access to an aligned address for unaligned memory operations
CN113971072B (zh) 信息处理方法、装置、设备、存储介质及计算机程序产品
CN115576766A (zh) 闪存管理算法调试方法、系统、设备和可读存储介质
Lyu et al. A procedure-based dynamic software update
CN112559336A (zh) 自适应调试异构计算芯片的方法、装置、系统及主板芯片
US11940900B1 (en) Determining and providing representations of program flow control
EP4278262B1 (en) Physical memory address omission or obfuscation within an execution trace
JP6691884B2 (ja) 計算機及びアプリケーション管理方法
CN113986740A (zh) 一种获取应用的代码执行记录的方法及装置
CN111045650A (zh) Mocker联调工具的设计方法、装置及计算机设备

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
GR01 Patent grant
GR01 Patent grant
TG01 Patent term adjustment