Android逆向学习66——LLVM Pass(函数名称加密Pass)

admin 2024年5月10日02:00:41评论3 views字数 1798阅读5分59秒阅读模式

Android逆向学习66——LLVM Pass(函数名称加密Pass)

1.函数名称加密PASS

首先创建一个目录
Android逆向学习66——LLVM Pass(函数名称加密Pass)

创建下面两个文件

Android逆向学习66——LLVM Pass(函数名称加密Pass)
我们可以参考文档,不同版本的文档不一样,我们是12.0.0,就用12.0.0的文档

[https://releases.llvm.org/12.0.0/docs/WritingAnLLVMPass.html)]

Android逆向学习66——LLVM Pass(函数名称加密Pass)

我们在文件中加入信息

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

编写PASS

Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里PASS编写完成

然后我们来编译一下
Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里我们直接编译这个项目的名字
Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里就编译完成

首先我们需要设置PASS环境变量

Android逆向学习66——LLVM Pass(函数名称加密Pass)
我们先查询PASS的路径

Android逆向学习66——LLVM Pass(函数名称加密Pass)

使用opt运行

Android逆向学习66——LLVM Pass(函数名称加密Pass)

经过错误调试,这是因为opt版本不一致导致的

Android逆向学习66——LLVM Pass(函数名称加密Pass)

当然我们在执行前可以设置opt的环境变量

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后我们修改名字

Android逆向学习66——LLVM Pass(函数名称加密Pass)

再次编译

Android逆向学习66——LLVM Pass(函数名称加密Pass)

再次执行

Android逆向学习66——LLVM Pass(函数名称加密Pass)

这里说明一个简单的PASS就完成了,然后我们添加功能

我们这里给函数改名字

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后再次编译运行

Android逆向学习66——LLVM Pass(函数名称加密Pass)

我们就可以成功的改名了

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后我们给函数名加密
这里我们使用MD5进行加密

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

再次编译运行

Android逆向学习66——LLVM Pass(函数名称加密Pass)

函数名就被hash加密

2.在LLVM源码之外开发PASS

[https://llvm.org/docs/CMake.html#cross-compiling]

在源码之外开发PASS,需要创建这样结构的工程
Android逆向学习66——LLVM Pass(函数名称加密Pass)

首先创建文件CmakeList.txt

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后我们使用CLion打开该项目

Android逆向学习66——LLVM Pass(函数名称加密Pass)

我们就发现了一些错误,然后我们需要一次补全这些错误
我们根据代码提示配置环境

Android逆向学习66——LLVM Pass(函数名称加密Pass)

环境配置完成

Android逆向学习66——LLVM Pass(函数名称加密Pass)

编译成功
我们编译一个release版本,设置添加release版本

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

错误分析,这里是因为没有加入llvm的环境,所以编译时找不到符号

set(LLVM_DIR /root/Desktop/llvm-Compiler/llvm/llvm-project-12.0.0.src/llvm/cmake-build-release/lib/cmake/llvm)

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里就成功的编译了

编译流程参考官网:Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后我们要clang可以使用这个Pass
clang -Xclang -load -Xclang /root/Desktop/llvm-Compiler/llvm/llvm-project/lesson2/outlesson2/cmake-build-release/EncodeFunctionName2/LLVMEncodeFunctionName2.so -encode hello.ll -o hello_clang.bc
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
clang也可以直接编译可执行文件

我们将pass注册到clang里面

Android逆向学习66——LLVM Pass(函数名称加密Pass)

首先创建一个EncodeFunctionName的头文件

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

调用头文件,并实现相应的函数

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后我们需要将PASS加进来

Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)

这里我们将PASS加入
然后编译一下

现在我们的PASS是一个动态库,但是别的都是静态库,我们需要编译成静态库

我们可以参考一个静态库

Android逆向学习66——LLVM Pass(函数名称加密Pass)

我们修改原PASS的文件

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后还要在静态配置文件加上

由于我们使用的是12.0.0,LLVMBuild.txt被删除
Android逆向学习66——LLVM Pass(函数名称加密Pass)
然后我们进行编译

Android逆向学习66——LLVM Pass(函数名称加密Pass)

我们可以看见就成功生成静态链接库,比以往的方式更加简单

然后我们编译一下clang  ninja clang

Android逆向学习66——LLVM Pass(函数名称加密Pass)

编译错误
Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里报错,我们采用放入IPO的方式
Android逆向学习66——LLVM Pass(函数名称加密Pass)
编译成功
我们还要加上参数
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
并修改完成

我们采用IPO的方式

编译成功

Android逆向学习66——LLVM Pass(函数名称加密Pass)
clang -mllvm -encode_name hello_clang.c
报错

Android逆向学习66——LLVM Pass(函数名称加密Pass)

这里是没有返回导致的

Android逆向学习66——LLVM Pass(函数名称加密Pass)

再次编译

Android逆向学习66——LLVM Pass(函数名称加密Pass)
这样就嵌入成功

回顾IPO嵌入的流程:
(1)在include/…/IPO下添加头文件
Android逆向学习66——LLVM Pass(函数名称加密Pass)

(2)在lib/…/IPO下添加代码文件Android逆向学习66——LLVM Pass(函数名称加密Pass)

(3)在IPO配置文件CmakeList.txt中加入c文件
Android逆向学习66——LLVM Pass(函数名称加密Pass)

(4)在IPO下PassManagerbuilder下添加参数和加载选项
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
Android逆向学习66——LLVM Pass(函数名称加密Pass)
然后结果是
Android逆向学习66——LLVM Pass(函数名称加密Pass)
这里打印两次是因为我们注册了两次
Android逆向学习66——LLVM Pass(函数名称加密Pass)

3.Clion调试

首先编译一下opt

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后设置一下编译器

Android逆向学习66——LLVM Pass(函数名称加密Pass)

-load /root/Desktop/llvm-Compiler/llvm/llvm-project/lesson2/outlesson2/cmake-build-debug/EncodeFunctionName2/LLVMEncodeFunctionName2.so -encode /root/Desktop/llvm-Compiler/llvm/llvm-project/lesson2/hello_clang.ll

然后下断点

Android逆向学习66——LLVM Pass(函数名称加密Pass)

然后进行调试

Android逆向学习66——LLVM Pass(函数名称加密Pass)

Android逆向学习66——LLVM Pass(函数名称加密Pass)

原文始发于微信公众号(安全后厨):Android逆向学习66——LLVM Pass(函数名称加密Pass)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月10日02:00:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Android逆向学习66——LLVM Pass(函数名称加密Pass)http://cn-sec.com/archives/2725326.html

发表评论

匿名网友 填写信息