LLVM从小白到放弃(三)- LLVM IR概述与常用指令

LLVM IR概述

  • 优化是对LLVM IR进行操作:

什么是LLVM IR

  • LLVM IR 是一门低级语言,语法类似于汇编
  • 任何高级编程语言(如C++)都可以用LLVM IR表示
  • 基于LLVM IR可以很方便地进行代码优化

LLVM IR的两种表示方法

  • 第一种是人类可以阅读的文本形式,文件后缀为.ll
  • 第二种是易于机器处理的二进制格式,文件后缀为.bc

LLVM IR结构

  • 源代码被编译为LLVM IR后,具有以下结构:

LLVM IR结构:模块 Module
  • 一个源代码对应LLVM IR中的一个模块。
  • 头部信息包含程序的目标平台,如X86、ARM等,和一些其他信息。
  • 全局符号包含全局变量、函数的定义与声明。

LLVM IR结构:函数 Function
  • LLVM IR中的函数表示源代码中的某个函数。
  • 参数,顾名思义为函数的参数。
  • 一个函数由若干基本块组成,其中函数最先执行的基本块为入口块。

LLVM IR结构:基本块 BasicBlock
  • 一个基本块由若干个指令和标签组成。
  • 正常情况下,基本块的最后一条指令为跳转指令(br或者switch),或返回指令(retn),也叫作终结指令(Terminator Instruction)。
  • PHI指令是一种特殊的指令。

LLVM IR结构
  • 了解LLVM IR的结构是我们学习代码混淆的基础,举个例子
    • 以函数为基本单位的混淆:控制流平坦化
    • 以基本块为基本单位的混淆:虚假控制流
    • 以指令为基本单位的混淆:指令替代

LLVM IR常用指令讲解

  • 终结指令 Terminator Instructions

    • ret指令
      • 函数返回指令,对应C/C++中的return。
    • br指令
      • br是“分支”的英文branch的缩写,分为非条件分支和条件分支,对应C/C++的if语句
      • 无条件分支类似有x86汇编中的jmp指令,条件分支类似于x86汇编中的jnz,je等条件跳转指令。
  • 比较指令

    • icmp指令
      • 整数或指针的比较指令
      • 条件cond可以是eq(相等),ne(不相等),ugt(无符号相等)
    • fcmp指令
      • 浮点数的比较指令
      • 条件cond可以是oeq(ordered and equal),ueq(unordered or equal)
    • switch指令
      • 分支指令,可看做是br指令的升级版,支持的分支更多,但使用也更复杂,对应C/C++中的switch。
  • 二元运算 Binary Operations

    • add指令
    • sub指令
    • mul指令
    • udiv指令
      • 无符号整数除法指令
    • sdiv指令
      • 有符号整数除法指令
    • urem指令
      • 无符号整数取余指令
    • srem指令
      • 有符号整数取余指令
  • 按位二元运算 Bitwise Binary Operations

    • shl指令
      • 整数左移操作指令
    • lshr指令
      • 整数右移指令
    • ashr指令
      • 整数算数右移指令
    • and指令
      • 整数按位与运算指令
    • or指令
      • 整数按位或运算指令
    • xor指令
      • 整数按位异或运算指令
  • 内存访问和寻址操作 Memory Access and Addressing Operations

    • alloca指令
      • 内存分配指令,在栈中分配一块空间并获得指向该空间的指针,类似与C/C++中的malloc函数
    • store指令
      • 内存存储指令,向指针指向的内存中存储数据,类似与C/C++中的指针引用后的赋值操作
  • 类型转换操作 Conversion Operations

    • trunc..to指令
      • 截断指令,将一种类型的变量截断为另一种类型的变量。
    • zext..to指令
      • 零扩展指令,将一种类型的变量拓展为另一种类型的变量,高位补0。
    • sext..to指令
      • 符号位拓展指令,通过复制符号位(最高位)将一种类型的变量拓展为另一种类型的变量。
  • 其他操作 Other Operations

    • phi指令:由静态单赋值引起的问题

    • select指令

      • ? : 三元运算符
    • call指令

      • call指令用来调用某个函数,对应C/C++中的函数调用,与x86汇编中的call指令类似。