llvm学习日记十四:Xcode 调试开发 Pass

参考:https://mayuyu.io/2017/06/01/LLVMHacking-0x1/

一、目的:

使用xcode更方便的调试和开发pass

二、创建llvm的xcode工程:

cmake指定生成xcode工程之前,先创建一个新的空的pass,然后在cmake生成xcode工程,在xcode项目中可以看到新模块,我使用的版本是llvm9.0.0

  1. 创建空文件:
  • 头文件:
    include/llvm/Transforms/Obfuscation/SymbolObfuscation.h
  • cpp文件:
    lib/Transforms/SymbolObfuscation/SymbolObfuscation.cpp
  • 相关 CMakeLists 的配置不在赘述,看过前几小节的应该知道
  1. cmake指定xcode工程:
mkdir build_xcode
cd build_xcode
cmake -G Xcode CMAKE_BUILD_TYPE="Debug" ../llvm
  1. 打开xcode工程:
  • 首次打开时,时间充足时可以全部构建一遍,选择ALL BUILD,时间略长;
  • 也可以在 manage scheme 选择时选择手动管理,添加 opt 模块 、clang模块和 LLVMSymbolObfuscation 模块,这样节省时间,也只需要编译这俩模块;
  • 可以看到新创建的pass模块:loadabl modules --> LLVMSymbolObfuscation


    image.png

三、pass的调试与开发:

  1. 完善头文件与cpp文件内容,我这里参考张总的教程,创建一个简单符号混淆的pass
  • 头文件内容:

#include "llvm/Pass.h"

#define DEBUG_TYPE "symbolobf"

namespace llvm {
    ModulePass* createSymbolObfuscationPass();
//    void initializeSymbolObfuscationPass(PassRegistry &Registry);
}

  • cpp文件代码:

#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/Obfuscation/SymbolObfuscation.h"
#include 
#include 
#include 

using namespace llvm;
using namespace std;
static string obfcharacters="qwertyuiopasdfghjklzxcvbnm1234567890";
namespace llvm{
    struct SymbolObfuscation : public ModulePass {
        static char ID;
        int seed = 0;
        SymbolObfuscation() : ModulePass(ID) {}
        string randomString(int length){
            string name;
            name.resize(length);
            srand(seed);
            seed++;
            for(int i=0;i New Name: "< X("symbolobf", "Rewrite Symbols", false, false);

  1. 单独调试这一个pass需要使用opt模块调用:
  • 构建库LLVMSymbolObfuscation:
    选择 模块 LLVMSymbolObfuscation 构建,command + B 编译;


    image.png
  • 构建opt模块:
    选择 模块 opt 构建,command + B 编译,时间略长;


    image.png
  • 设置opt调用参数:
    opt的用法不再赘述,文档:https://llvm.org/docs/CommandGuide/opt.html

    image.png

输入的 .ll 文件时自己写的一个测试代码,如下:

#include 

static int add(int x, int y) {
    return x + y;
}

int sub(int x, int y) {
    return x - y;
}

int main(){
    printf("%d",add(3,4));
    printf("%d",sub(5,4));
    return 0;
}

生成 .ll 文件:
clang -c test_symbolobf.c -o test_symbolobf.ll -emit-llvm -S

  • 断点调试:
    上述全部OK后,可以直接在源文件打断点调试:
    如图,断点调试查看设置前的随机字符串。


    image.png
  1. 查看符号替换的结果:
  • 可以直接调试打印IR查看:


    image.png
  • 直接查看生成的文件:
    opt生成的bitcode,需要先转换为文本IR:
    llvm-dis /Users/qinyao/LLVM/test_symbolobf/test_symbolobf.ll.bc
    查看 llvm-dis 生成的IR:
    image.png

四、扩展:

符号混淆是一个比较难处理的点,涉及系统函数以及导出函数,所以 hikari 也并没有开放这个功能,作为学习还不错;
现在 llvm 在utils目录下有自带的 SymbolRewriter.cpp Pass,下一节章节分析一下。

你可能感兴趣的:(llvm学习日记十四:Xcode 调试开发 Pass)