Arm64 中 B跳转汇编的使用是如何实现的

branch 跳转是arm中常用的汇编跳转

例如

c 复制代码
void a(){
    xxx
}

void call_a(){
    a();//调用a函数
}

此时编译器就会产生

asm 复制代码
lable a
    nop;

lable call_a
    bl a:

这里的bl 就是 跳转[b] 并 拿回返回值[l] 尽管a是一个 void 函数 但是执行流程还是要回来的

如果是

c 复制代码
void aexit(){
    exit(1);
}

aexit()

此时就会产生 b aexit的汇编了 因为一去不回了

现在假设 我们需要在已经编译完成的函数上改变既有的执行流程 那么 在不考虑栈平衡和寄存器的变量的问题的基础上

我们来对测试的代码进行测试 如

c 复制代码
#include <stdio.h>

 void asmc(){
    char c;
    int i;
    int j;

    i = 0;
    while (1) {
        c = getchar();
        if (c == '\n') {
            break;
        }
        if (c == ' ') {
            continue;
        }
        if (c == '(') {
            i++;
            continue;
        }
        if (c == ')') {
            i--;
            continue;
        }
        if (i == 0) {
            putchar(c);
        }
    }
    return;
}


 void asme(){
    printf("this is asme\n");
    return;
}


 int main() {
    asmc();
    asme();
    return 0;
}

在编译完成的asm是

main_asm 复制代码
; Attributes: bp-based frame

; int __cdecl main(int argc, const char **argv, const char **envp)
main

var_8= -8
var_4= -4
var_s0=  0

; __unwind {
SUB             SP, SP, #0x20
STP             X29, X30, [SP,#0x10+var_s0]
ADD             X29, SP, #0x10
MOV             W8, WZR
STR             W8, [SP,#0x10+var_8]
STUR            WZR, [X29,#var_4]
BL              asmc
BL              asme    ; asme()
LDR             W0, [SP,#0x10+var_8]
LDP             X29, X30, [SP,#0x10+var_s0]
ADD             SP, SP, #0x20 ; ' '
RET
; } // starts at 7E0
; End of function main

; .text ends
asmc_asm 复制代码
; Attributes: bp-based frame

asmc

var_8= -8
var_1= -1
var_s0=  0

; __unwind {
SUB             SP, SP, #0x20
STP             X29, X30, [SP,#0x10+var_s0]
ADD             X29, SP, #0x10
STR             WZR, [SP,#0x10+var_8]

loc_744
BL              .getchar
STURB           W0, [X29,#var_1]
LDURB           W8, [X29,#var_1]
SUBS            W8, W8, #0xA
B.NE            loc_75C
B               loc_7B8

loc_75C
LDURB           W8, [X29,#var_1]
SUBS            W8, W8, #0x20 ; ' '
B.NE            loc_76C
B               loc_744

loc_76C
LDURB           W8, [X29,#var_1]
SUBS            W8, W8, #0x28 ; '('
B.NE            loc_788
LDR             W8, [SP,#0x10+var_8]
ADD             W8, W8, #1
STR             W8, [SP,#0x10+var_8]
B               loc_744

loc_788
LDURB           W8, [X29,#var_1]
SUBS            W8, W8, #0x29 ; ')'
B.NE            loc_7A4
LDR             W8, [SP,#0x10+var_8]
SUBS            W8, W8, #1
STR             W8, [SP,#0x10+var_8]
B               loc_744

loc_7A4
LDR             W8, [SP,#0x10+var_8]
CBNZ            W8, loc_7B4
LDURB           W0, [X29,#var_1] ; c
BL              .putchar

loc_7B4
B               loc_744

loc_7B8
LDP             X29, X30, [SP,#0x10+var_s0]
ADD             SP, SP, #0x20 ; ' '
RET
; } // starts at 734
; End of function asmc
asme_asm 复制代码
; asme()
; Attributes: bp-based frame

; __int64 asme()
asme

var_s0=  0

; __unwind {
STP             X29, X30, [SP,#-0x10+var_s0]!
MOV             X29, SP
; 2:   return printf("this is asme\n");
ADRL            X0, aThisIsAsme ; "this is asme\n"
BL              .printf
LDP             X29, X30, [SP+var_s0],#0x10
RET
; } // starts at 7C4
; End of function asme

其中 各个函数的偏移量是

offsetsinfo 复制代码
asmc	.text	0000000000000734	00000090	00000020		R	.	.	.	.	B	.	.
asme	.text	00000000000007C4	0000001C	00000010		R	.	.	.	.	B	T	.
main	.text	00000000000007E0	00000030	00000020		R	.	.	.	.	B	T	.

那么跳转到 asme函数的就是 bl asme = bl 7C4

不过这是常规的情况下 也就是 ida的自动patch插件会自动的将7C4转换成 当前所在地址的位置和 7C4 的距离 然后生成目标的汇编

不然直接 bl 7C4 会出现刻舟求剑的情况

不过在ida中 确实可以直接填写 bl 7C4

但是原始逻辑也并没有那么的简单

通常情况下寄存器执行到b的跳转汇编的时候一般都是计算偏移量 因为b跳转的上限距离是±的xxxx

因此 在cpu的实际运行中 是类似于

asm 复制代码
b 0x8(向下两个地址)
b -0x16(向上四个地址)

而如果是期望直接真的跳转到一个地址上 那么汇编会变成

asm 复制代码
LDR X8 = XXXX(这里通常会是一个栈地址或者是一个已经准备好的寄存器)
BR X8 直接跳转寄存器实现了 C语言的指针跳转

但是这种条寄存器一般只有是inlineHook时才会出现的汇编 在正常的使用中几乎没有这种汇编的出现

相关推荐
坤虫debug8 天前
面试官:你会不会汇编?啊?我会不会编?
汇编语言
Terasic友晶科技13 天前
第22篇 基于ARM A9处理器用汇编语言实现中断<四>
fpga开发·汇编语言·de1-soc开发板·按键和定时器中断
Terasic友晶科技14 天前
第23篇 基于ARM A9处理器用汇编语言实现中断<五>
fpga开发·汇编语言·de1-soc开发板·定时器中断周期
Terasic友晶科技18 天前
第20篇 基于ARM A9处理器用汇编语言实现中断<二>
fpga开发·汇编语言·中断·de1-soc开发板
hummhumm20 天前
第30章 汇编语言--- 性能优化技巧
开发语言·性能优化·程序设计·优化·汇编语言·高级语言·低级语言
Terasic友晶科技21 天前
第21篇 基于ARM A9处理器用汇编语言实现中断<三>
fpga开发·汇编语言·中断·de1-soc开发板
Terasic友晶科技25 天前
第19篇 基于ARM A9处理器用汇编语言实现中断<一>
汇编语言·中断·de1-soc开发板
hummhumm1 个月前
第8章 汇编语言--- 循环结构
java·运维·开发语言·汇编·数据结构·算法·汇编语言
Kent_J_Truman1 个月前
微机接口课设——基于Proteus和8086的打地鼠设计(8255、8253、8259)Proteus中Unknown 1-byte opcode / Unknown 2-byte opcode错误
proteus·汇编语言