美文网首页
逆向笔记(一)

逆向笔记(一)

作者: KG丿夏沫 | 来源:发表于2021-06-13 17:54 被阅读0次
    20210330001.png

    汇编语言的发展过程

    机器语言

    由0和1组成的机器指令

    为什么要用二进制作为机器语言?

    因为用0和1表示有电没电是最稳定的

    汇编语言

    使用助记符号代替机器语言,助记符号就是使用特定的单词或者字母组合表示一组机器码

    高级语言

    C/C++/Java/OC等更加接近人类的自然语言

    高级语言执行过程

    20210330002.png

    从图解我们可以得到以下结论:

    1、高级语言可以通过编译得到汇编语言,但是汇编语言几乎不可能还原成高级语言,我们只能通过推算得到高级语言的算法逻辑,不能完完全全还原高级语言

    2、汇编语言可以编译成机器语言,机器语言也可以通过反汇编得到汇编语言

    汇编语言的特点

    可以直接访问、控制各种硬件设备

    能够不受编译器的限制,对生成的二进制代码进行完全的控制

    目标代码简短,占用内存少,执行速度快

    汇编指令是机器指令的助记符,同机器指令一一对应。每一种CPU都有自己的机器指令集\汇编指令集,所以汇编语言不具备可移植性

    知识点过多,开发者需要对CPU等硬件结构有所了解,不易于编写、调试、维护

    不区分大小写

    总线

    每一个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互

    总线:一根根导线的集合

    总线的分类

    地址总线:CPU在内存中读取或写入数据进行操作的地址查找器

    数据总线:CPU在内存中进行数据读取或者写入时的传输器

    控制总线:CPU在内存中进行数据读取还是写入的控制器

    寄存器

    浮点和向量寄存器

    通用寄存器

    pc寄存器:主要存贮下一条指令操作地址

    寄存器主要研究ARM64,因为现在手机系统都是ARM64的,然后分为32位和64位操作系统,相对于iOS来说,5s以前都是32位操作系统,从5s开始都是64位操作系统,所以之后我的文章也是正对ARM64的64位系统下进行探索。64位系统对32位系统进行了兼容,所以在32位系统上的app可以运行在64位系统上。

    64位:在64位系统中X0~X30,XZR(零寄存器),以X开头的寄存器说明就是64位的

    32位:在32位系统中W0~W30,WZR(零寄存器),以W开头的寄存器说明是32位的

    在64位系统中,32的寄存器是64位寄存器的低32位部分,并不是独立存在的

    栈是一种居有特殊访问方式的存储空间,遵循先进后出的原则,拥有两个特殊寄存器SP和FP。

    在ARM64里面,对栈的操作是16字节对齐的

    栈需要一直保持栈的平衡,即开辟了栈空间,使用完成后就必须释放栈空间,在这里所说的开辟和释放正对于CPU来说,就是移动SP寄存器存储的地址

    针对内存来说,地址空间的分配是从低地址向高地址分配

    正对于栈空间来说,地址是从高地址向低地址扩展的一块连续的内存区域

    栈的开辟以及释放都是系统进行维护

    对栈溢出:是因为栈是向低地址扩展,而堆是向高地址的扩展,当两个区域碰撞的时候,就是我们所说的对栈溢出

    SP和FP寄存器

    SP寄存器在任意时刻都会保存我们栈顶的地址

    FP寄存器也称为x29寄存器,属于通用寄存器,但是在某些时刻我们利用他保存栈底的地址

    在ARM64下,函数的参数是存放在X0到X7(W0到W7)这8个寄存器中,如果超过8个参数,就会入栈,函数的返回值是存放在X0寄存器里面的。我们验证一下是否正确,所以声明并实现如下函数,并在ViewDidLoad方法里面进行调用

    int sum(int a,int b,int c,int d,int e,int f,int g,int h){
        return a+b+c+d+e+f+g+h;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        int l = sum(1, 2, 3, 4, 5, 6, 7, 8);
        
        printf("%d\n",l);
    }
    

    然后我们在调用函数的地方加上断点,运行程序,当程序运行起来后,走到断点,然后开启汇编模式,使用step into进入到函数调用栈中,然后就可以看到寄存器中保存的值,如下:

    20210330003.png

    从上图可以看到,寄存器x0~x7存储了传入的参数,然后进行一系列的运算后,最后的返回值保存在了x0当中,如下:

    20210330004.png

    从以上实践我们验证了先前的说法,到此对于ARM64架构以及CPU和内存间的数据读取有了大概的了解。

    相关文章

      网友评论

          本文标题:逆向笔记(一)

          本文链接:https://www.haomeiwen.com/subject/pxkleltx.html