← 返回目录

使用GDB动态补丁ARM64的程序 跳转到任意地址

发布时间: 2024-01-18 13:44:58
浏览量: 845
收藏数: 10
点赞数: 7
标签: linux, 运维, 服务器
正常的 arm64跳转转令B,BL,BLX只有+-128M, 我们很多时候要跳到大于这个值的地址。我们在arm64下可以选的指令就只有br指令了。原来在ARM/Thumb中使用的 ldr pc, [pc, #?] , 但arm64是不能这样了。但是它也需要给一个寄存器赋值一个64bit的地址, 可是arm的指令是固定的32bit的,即使给一个寄存器赋值一个64bit的值都麻烦。如 set *(int*)0xabc1234 = 0x58000070。补丁就是简单了,就是直接使用set命令就好了。

补丁就是简单了,就是直接使用set命令就好了。

如 set *(int*)0xabc1234 = 0x58000070

那就么就是把0xabc1234改成指令:

ldr x16, #12 

但是 跳转到任意地址就很麻烦了。 正常的 arm64跳转转令B,BL,BLX只有+-128M, 我们很多时候要跳到大于这个值的地址。我们在arm64下可以选的指令就只有br指令了。原来在ARM/Thumb中使用的 ldr pc, [pc, #??] , 但arm64是不能这样了。

根据NDK的编译结果,我们br的时候 x16和x17可以随便用。

但是它也需要给一个寄存器赋值一个64bit的地址, 可是arm的指令是固定的32bit的,即使给一个寄存器赋值一个64bit的值都麻烦。

如

mov x0, #0x830082008100

这个是无法执行的,你必须拆开来,使用逻辑位移分几次来做。就是这么麻烦!

MOV      x0,#0x8100
MOVK     x0,#0x8200,LSL #16
MOVK     x0,#8300,LSL #32

比较方便就是ldr 

下面例子是补丁pairip的,让它在某个点直接跳去调用系统api,sleep(0x7fffffff);

define patchpairip

#ldr x16, #12   //70000058 >  0x58000070
#ldr x0, #12    //60000058 >  0x58000060
#br	x16   //00021FD6 >       0xd61f0200

	set $pairip_patch= $libpairipcorebase + 0x46F04
	#set call sleep forevevr..
	set $sleepFunc = &sleep
	set *(int*)($pairip_patch)=0x58000070
	set *(int*)($pairip_patch+4)=0x58000060
	set *(int*)($pairip_patch+8)=0xd61f0200
	set *(long *)($pairip_patch+12)= $sleepFunc 
	set *(long *)($pairip_patch+20)= 0x7fffffff

end