arm汇编学习笔记

Arm32

  1. 基本寄存器:
    • R0-R3 作为 参数寄存器
    • R4-R11 作为 局部变量寄存器
    • R12 作为 内部调用暂时寄存器 (ip)
    • R13 作为 栈指针 (sp)
    • R14 作为 链接寄存器 (lr)
    • R15 作为 程序计数器 (pc)
  2. Tips:
    • 中断产生时编译器会自动保存R4-R11
    • 程序返回时需恢复使用过的局部变量寄存器
    • Thumb16模式下,只能使用R0-R7,R13,R14,R15这几个寄存器
    • Arm下R11默认FP,Thumb下R7默认为FP
    • LR在遇到BL/BLX/CALL时候自动保存下一条指令
举例七个参数的参数传递情况
arm32传7个参的情况

原c++代码
  • 这里看着参数不匹配是由于是C++写法,封装了一成调用,看FindClass()函数原型:
    jclass (FindClass)(JNIEnv, const char*);
  • LDR R2, [R0,#0x18]
    至于这条指令的偏移为什么是0x18,我们可以看jni.h中定义的:


    jni函数偏移计算

    env dump

for while switch

for循环
while
switch
func_circulation(JNIEnv *env, jobject thiz,int c) {
    printf("----- for -----");
    for (int i = 0; i < 5; ++i) {
        printf("count %d",i);
    }

    printf("----- while -----");
    int s = 3;
    while(s>0){
        printf("count run %d",s--);
    }

    printf("----- switch -----");
    switch (c){
        case 1:
            printf("count run 1");
            break;
        case 2:
            printf("count run 2");
            break;
        case 10:
            printf("count run 10");
            break;
        default:
            printf("count run default");
            break;
    }
}![DF$2{RX[9N$YP[PH7S8`0L5.png](https://upload-images.jianshu.io/upload_images/9548468-b91e01ec2d39c85d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

***当然还有其他版本的swith汇编代码
switch分支

常用的汇编指令
------------------- ARM 32 -------------------
return;
bx lr
1E FF 2F E1

return true;
MOV R0, #1
bx lr
01 00 A0 E3 1E FF 2F E1

return false;
MOV R0, #0
bx lr
00 00 A0 E3 1E FF 2F E1

return 99;
E7 03 00 E3 1E FF 2F E1

return 999f;
7A 04 04 E3 1E FF 2F E1

空指令
NOP
00 00 A0 E1                    

------------------- ARM 64 -------------------
nop   1F2003D5
ret   C0035FD6

Arm64

ARM64 有34个寄存器,包括31个通用寄存器、SP、PC、CPSR

x0-x30      通用寄存器(w0-w30用作32位/x0-x30用作64位)

        x0-x7       用于子程序调用时的参数传递,X0还用于返回值传递

        x8          用于保存子程序返回地址

        X9~X15      临时寄存器,使用时不需要保存

        X16~X17     子程序内部调用寄存器,使用时不需要保存

        X18         平台寄存器

        X19~X28     临时寄存器,使用时必须保存

        FP(x29)     保存栈帧地址(栈底指针)

        LR(x30)     链接寄存器LR

        SP/ZXR(X31)     堆栈指针寄存器SP或零寄存器ZXR

SP          保存栈指针,使用 SP/WSP来进行对SP寄存器的访问

PC          程序计数器,俗称PC指针,总是指向即将要执行的下一条指令,在arm64中,软件是不能改写PC寄存器的

CPSR        状态寄存器

        NZCV是状态寄存器的条件标志位,分别代表运算过程中产生的状态,其中:

            N, negative condition flag,一般代表运算结果是负数
            Z, zero condition flag, 指令结果为0时Z=1,否则Z=0;
            C, carry condition flag, 无符号运算有溢出时,C=1。
            V, oVerflow condition flag 有符号运算有溢出时,V=1

MOV 指令只能用于寄存器之间传值,寄存器和内存之间传值通过 LDR 和 STR

MOVZ 、MOVK 和MOVN

    MOVZ 赋值一个16位的立即数到寄存器中,该寄存器中除了立即数占用到的位之外的其他位都设为0,立即数可以设置向左移位0、16、32或者48(lsl:向左移位)

    instruction                           value of x0
    movz    x0, #0x1234           |         0x1234
    movz    x0, #0x1234, lsl #16  |         0x12340000

    MOVK 赋值一个立即数到寄存器,保持立即数没用到的位保持不变
    
    instruction                    value of x0
    mov x0, xzr               | 0x0000000000000000
    movk x0, #0x0123, lsl #48 | 0x0123000000000000
    movk x0, #0x4567, lsl #32 | 0x0123456700000000
    movk x0, #0x89ab, lsl #16 | 0x0123456789ab0000
    movk x0, #0xcdef          | 0x0123456789abcdef

    MOVN 用于赋值立即数的位掩码,例如想要将0xffffffff0000ffff赋值给x0,只需要使用MOVN将向左移位16的0xffff赋值位寄存器就可以实现,会自动求移位后的立即数位掩码然后赋值

    instruction                             value of x0
    MOVN x0, 0xFFFF, lsl 16       |       0xffffffff0000ffff

    ARM32 为 STR LDR
    STP  x29, x30, [sp, #0x10]    ;入栈指令
    LDP  x29, x30, [sp, #0x10]    ;出栈指令

    CBZ     比较(Compare),如果结果为零(Zero)就转移(只能跳到后面的指令)
    CBNZ    比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)

    CMP     比较指令,相当于SUBS,影响程序状态寄存器CPSR 

    B/BL    绝对跳转#imm, 返回地址保存到LR(X30)

    RET     子程序返回指令,返回地址默认保存在LR(X30)

Arm 汇编层面理解inlinehook (arm32)

//dobby 64

执行hook之前
执行hook之后
  • 明显看到了替换了前面4条thumb指令,共计8字节
  • DF F8 00 F0 这条指令翻译过来就是 ldr.w pc, [pc, #0]
    (三级流水线,也就是说ADD R2, PC指令在取码的时候,刚好我们准备的跳转指令正在译码,而最终执行的代码是我们译码的代码,译码这个时刻我们的pc就是当前跳转的指令位置,具体可以结合下面字符串寻址的思路理解0xCE010E62)
  • 前面被跳转指令替换的四条thrumb指令会被写到我们的自定义新函数开始
  • 在thumb指令集中R7一般用来作为FP

- 怎么进入新函数

函数进入
新函数分析

- 函数调用

  • 新函数源码在此
jstring new_Func1(JNIEnv *env, jobject *jobject) {
    LOGD("Called new_Func1");
    jstring ret = (jstring) old_fuc_1(env, jobject);
    const char *str_stc = env->GetStringUTFChars(ret, NULL);
    LOGD("修改前的ret = %s", str_stc);
    jclass jMainAct=env->FindClass("com/lzy/inlinehook/MainActivity");
    jmethodID jm_makeText=env->GetStaticMethodID(jMainAct,"show","()V");
    env->CallStaticVoidMethod(jMainAct,jm_makeText,NULL);
    return env->NewStringUTF("Hook this return value");
}
  • C函数调用其实和正常的没啥区别,着重看他调用原函数
    (这里我就直接定位0xCE3CE448)


    定位0xCE3CE448
  • 接着进去R2看他做了什么事情
    (简单来说就是修改了进入之前已经压栈的LR,这样老函数退出的时候才能返回新函数调用老函数的下一条指令)
调用原函数

这里涉及到的静态值是inlinehook onhook时候做的事情,这个debug区域都是动态生成的,这里这涉及已经形成的代码逻辑分析,怎么算的还请看源码

老函数调用返回位置修改
新函数的返回位置

- 怎么退出新函数的

函数退出
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345