首页
社区
课程
招聘
[原创][分享]从开发的角度看看ollvm
发表于: 2022-11-4 20:43 27740

[原创][分享]从开发的角度看看ollvm

2022-11-4 20:43
27740

Ubuntu 20.04
CLion2022.02
llvm 9.0.1
ubuntu的镜像我这里就不提供了,直接去官网下载就好啦
clion我这里有一篇pojie文章分享给大家:CLion_pojie
然后llvm大家直接去官网下载就好啦 llvm官网

编译llvm
(这里我插一句,大家一定不要相信llvm官网的鬼话,说的用windows上的visual studio也可以编译,用他的那个powershell,呵呵,之后你就会遇到各种各样奇奇怪怪的错误,还是用linux系统吧)
图片描述
第一步用cmake生成相关的构建文件

其中-G Ninja参数表示生成Ninja系统的构建文件,采用Ninja系统会有比较快的编译速度
-DCMAKE_BUILD_TYPE=RELEASE表示生成Release版本的LLVM,这种构建方式会进行优化,并且生成的目标文件体积会更小
-DLLVM_TARGETS_TO_BUILD="X86"表示编译的目标平台是X86平台
-DLLVM_ENABLE_PROJECTS="clang"表示我们除了编译LLVM以外,还要编译clang

然后运行编译命令 ninja
这一步会等待很长时间,cpu基本处于满载状态:
图片描述
按照这样的顺序编译完成的环境中,clang应该在这个目录下:
图片描述
这样clang的环境就弄好了

图片描述
按照我之前发的pojie文章安装好clion之后直接打开这个CMakelists文件,按照project的方式打开:
图片描述
然后导入文件就好啦,然后再cmake的设置中加入debug和release:
图片描述
输入 -G Ninja -DLLVM_ENABLE_PROJECTS="clang"
就会生成两个文件:
图片描述
之后要从这两个文件的目录中编译出so文件,然后用opt命令操作
然后按照llvm官网的write pass的文章中,在这个目录下编写cpp和txt文件:
图片描述
图片描述
再添加一下:
图片描述
最后用ninja编译一下这个工程,建议编译release版本,速度快:
图片描述
如果能生成这个so文件,恭喜您,环境搭建完成
(windows的铁粉在win上搭环境弄了三天最后还是g了!)

我这里贴一下CLion中的cpp的代码是怎么实现函数加密的吧:

还有对应的CMakeList文件:
图片描述
然后使用ninja命令,就能生成so文件(作为函数加密的pass):

在这个路径下会找到生成的so文件

然后新建一个文件夹作为测试空间
将clang的路径添加到文件夹的环境变量中:
图片描述

首先新建一个文件夹,编写c文件(作为测试文件),然后生成ll文件,
这里我总结了几个命令:

这个是hello.c文件:

然后利用上面的命令生成ll文件
图片描述
到这里说明我们的文件夹的环境配置好了
然后接下来该使用opt了,(opt就是把刚刚编写的cpp文件生成的so文件加载编译的一个llvm工具)(所以刚刚的cpp文件中就应该实现对函数的加密),我这里遇到了一个问题,虽然设置了环境变量,但是opt不能用,所以直接从变量路径中拖出来opt使用也可以的:
图片描述

干脆直接拖吧,这样还省事
这里用哪个编译出来的clang和opt可以
location1

我又在release里面编译了一遍,所以之后的路径是
location2

这样就能生成bc文件

然后我们就可以发现对应的函数名称发生了变化

图片描述
然后使用clang编译一下:

图片描述
程序正常执行
然后用ida看看函数加密情况
图片描述
图片描述
发现函数加密成功!

贴一下cpp代码:

然后ninja编译一下,生成so文件
还是用刚刚的opt-load命令:
图片描述
发现main函数的名字已经被md5加密了
图片描述
这里说一句,刚刚的cpp文件把main函数的名字给md5加密了,这样是不可以的:
图片描述
所以刚刚的cpp文件应该修改这一处的文件
图片描述
修改完之后就没有问题了,将除了main函数以外的所有的函数的名字都进行了md5加密
图片描述
图片描述
然后尝试在源码之外开发一个pass,因为这样一直使用源码开发很麻烦:developing-llvm-passes-out-of-source
按照官方文档给的结构创建一个工程
图片描述
创建完工程后将工程导入clion中,然后根据报错信息一个个的改就好啦
这里学习了几个linux的命令,纪录一下:
在某个目录下找文件

找到该文件的绝对路径:

我这里贴一下clion中的代码和工程目录吧:
图片描述
CMakeLists.txt

EncodeFunctionName.cpp和原来一样
CmakeLists.txt

这两个cmakelists要根据自己的错误来配置,路径和版本是不一样的
然后build一下,生成so文件
图片描述
然后继续之前的操作:

这里不知道出了个什么问题,非要让我用encode2执行命令
这样每次输入命令很麻烦所以接下来尝试把pass注册到clang里面去

首先创建一个.h的头文件:
图片描述
然后在cpp文件中实现这个函数,并且导入相对应的头文件:
图片描述

.a是静态库文件
.so是一个共享的库
接下来我们要把pass编译成一个静态库也就是一个.a文件
修改EncodeFucntionName文件夹中的两个文件
图片描述
图片描述
然后修改ipo文件夹中的文件
在passermanagerbuilder.cpp里面加入头文件然后文件中加入参数
图片描述
图片描述
在llvmbuild.txt文件中加入EncodeFunctionName
图片描述
最后我贴上Encode_Function_name.cpp的代码:

这样所有的修改就ok了
然后用ninja编译一下release版本的就可以了
图片描述
成功编译出.a文件
然后重新编译一下clang

图片描述

然后用clang编译一下

(就能达到和之前一样的效果)
图片描述
这里总结一下思路:
就是把之前的opt -load xxxx.pass -encode命令替换成了clang,也就是我们之前说的将llvmpass集成到clang里面,也就是说只用clang就能实现函数加密,所以我们要先用ninja编译一下clang

首先从git上下载第四次分支的代码
然后复制代码obfuscation到llvm/lib/Tranforms和llvm/include/lib/Tranforms
图片描述
然后对着ollvm一个个的改,这里不是重点,就不一一介绍了
然后再修改代码的过程中,有一个AESsead需要注意一下:
这个是随机生成的种子,如果种子一样的画,就会生成一样的方案
如果是随机的种子,那么编译出来的方案也是随机的
然后修改完源码会由于环境版本不匹配问题产生很多错误,一个个的改就好啦google上github上面都有,放个链接吧
图片描述
这样就是编译成功了
图片描述
然后再编译一下clang:

这样所有的环境搭建好之后,看看官网上面的例子
图片描述

前面三种都是混淆用的
最后一个选项是自己创建函数选择要不要混淆函数
看第一个选项再官网中的描述,也就是其他文章中的指令替换
图片描述
前两种混淆再ida中都可以自动的帮我们优化掉,然后加了随机数之后ida就不行了

然后编写c文件作为测试用例:

然后用刚刚生成的clang(里面已经集成及ollvm的pass)编译一下:
从编译的结果并看不出来什么不同
图片描述
然后拖入ida7.5看看
图片描述
指令只有这一处发生了变化:
add eax, 8
变成了:
sub eax, 8BAA3A92h
add eax, 8
add eax, 8BAA3A92h
如果看伪c代码两个的结果是一样的
然后增加混淆力度看看:

拖入ida中看看:
图片描述

贴一下c源码:

执行一下混淆命令:

然后拖入ida看看
先看看bcf_loop=1的时候:
图片描述
他就比源程序混淆出来一个while语句(然后我刚刚动态调试的时候发现x,y的值都是0,所以这个while分支是不成立的):
图片描述
这个时候还能看看,然后加到3:
图片描述
发现他的混淆力度还是可以的一条if语句出来这么多分支
然后要是动态跟着一路走过去发现,所有的while语句都只判断了前半部分,剩下的都没执行
图片描述
图片描述
走到了最后函数的返回值是10,然后返回linux虚拟机看看返回值,确实是10
图片描述
这一大堆不成立的while语句就是其他文章中的虚假控制流吧
我给大家贴一下程序的执行流程吧:
图片描述
图片描述
图片描述
然后一直到这里才是我们程序的原始的分支
图片描述
然后又是虚假控制流:
图片描述
图片描述
一直到这里程序才执行完:
图片描述
混淆到9的时候直接出不来了xswl:
图片描述
然后改成999:
图片描述
然后如果想看伪c代码的话也会耗费很长时间:
图片描述
bcf:
图片描述
太6了
然后我们会发现一个规律,就是无论你bcf_loop到多少,总会有一段或者两端的while1的内容来恶心你:
图片描述
图片描述
如果要是混淆用到这个手法的话,可以用动态调试的方法来跟着程序执行,不过这样比较慢,应为许多不执行的while语句(但是ida不这么认为啊)也会跟到程序的执行过程中,所以我想出来了一种跟踪变量的方法,可以正着跟,也可以从函数的返回值出发:
这里我简单的说一下我的想法,当然网上也有很多别的更好的方法,一会会说一下unicorn模拟执行,我这个跟踪变量的方法只能用于比较简单的程序:
先从v19-》v22
图片描述
然后往上跟,发现了两个值,正好是我们刚刚源程序中写的值1,10:
图片描述
然后这样一直网上跟也能发现程序的逻辑,不过这种方法比较恶心,还是学习一下其他大佬的unicorn方法吧,还有符号执行方法
然后这个虚假控制流还可以指定混淆的百分比:

发现他的混淆力度也是很强的:
图片描述

看官方文档介绍就是将if-else分支的基本块,转化成switch的基本快
图片描述
我们这里还是用官网中给的c代码:

执行一下混淆代码:

然后拖入ida看看:
混淆的也比较明显了
图片描述
ida中识别的switch-case语句不是很准确
然后生成一下.ll文件看看程序流程就比较明显了:

代码如下:

然后加一些参数看看:

图片描述
然后把混淆力度加到三看看:

cfg:
图片描述
其实也没有很复杂这样看来
然后还可以指定函数来进行混淆:

然后输入命令:

看看cfg:
我们会发现,main函数没有被混淆
图片描述
然后这个foo函数被混淆了
然后融合所有科技来看看:
可见混淆的力度是很大的,编译过程中都花费了很多时间

图片描述
还有clang的调试啥的,字数太多了,打字都卡了
最后感谢一下imyang大佬的讲解
还有就是,一定不要删快照,mdzz,删了一个快照都不能用了呜呜呜
图片描述

cmake -G Ninja -DCMAKE_BUILD_TYPE=RELEASE -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="clang"  -DLLVM_OPTIMIZED_TABLEGEN=ON ../llvm
cmake -G Ninja -DCMAKE_BUILD_TYPE=RELEASE -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="clang"  -DLLVM_OPTIMIZED_TABLEGEN=ON ../llvm
 
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  EncodeFunctionName() : FunctionPass(ID) {}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: ";
    if(F.getName().compare("test_hello1") == 0){
      F.setName("kanxue function");
    }
    errs()<<F.getName()<< '\n';
    return false;
  }
};
}
char EncodeFunctionName::ID = 0;
static RegisterPass<EncodeFunctionName> X("Encode", "Encode Function Name Pass",
                                          false /* Only looks at CFG */,
                                          false /* Analysis Pass */);
 
static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  EncodeFunctionName() : FunctionPass(ID) {}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: ";
    if(F.getName().compare("test_hello1") == 0){
      F.setName("kanxue function");
    }
    errs()<<F.getName()<< '\n';
    return false;
  }
};
}
char EncodeFunctionName::ID = 0;
static RegisterPass<EncodeFunctionName> X("Encode", "Encode Function Name Pass",
                                          false /* Only looks at CFG */,
                                          false /* Analysis Pass */);
 
static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
ninja LLVMEncodeFunctionName
ninja LLVMEncodeFunctionName
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/LLVMEncodeFunctionName.so'
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/LLVMEncodeFunctionName.so'
export PATH=/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin:$PATH
export PATH=/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin:$PATH
clang -emit-llvm -S hello_clang.c -o hello_clang.ll
lli  hello_clang.ll
llvm-as hello_clang.ll -o hello_clang.bc
llc hello_clang.bc -o hello_clang.s
clang hello_clang.s -o hello_clang_s
llvm-dis hello_clang.bc -o hello_clang_re.ll
clang -emit-llvm -S hello_clang.c -o hello_clang.ll
lli  hello_clang.ll
llvm-as hello_clang.ll -o hello_clang.bc
llc hello_clang.bc -o hello_clang.s
clang hello_clang.s -o hello_clang_s
llvm-dis hello_clang.bc -o hello_clang_re.ll
#include <stdio.h>
 
void test_hello2();
 
void test_hello1() {
    printf("test_hello1\r\n");
}
 
 
int main(int argc, char const *argv[])
{
    if (argc > 2) {
        printf("hello kanxue clang!\r\n");
    } else {
        printf("hello pediy clang!\r\n");
    }
    test_hello1();
    test_hello2();
    return 0;
}
 
 
void test_hello2() {
    printf("test_hello2\r\n");
}
#include <stdio.h>
 
void test_hello2();
 
void test_hello1() {
    printf("test_hello1\r\n");
}
 
 
int main(int argc, char const *argv[])
{
    if (argc > 2) {
        printf("hello kanxue clang!\r\n");
    } else {
        printf("hello pediy clang!\r\n");
    }
    test_hello1();
    test_hello2();
    return 0;
}
 
 
void test_hello2() {
    printf("test_hello2\r\n");
}
 
'/home/linuxer/llvm/build/bin/'
'/home/linuxer/llvm/build/bin/'
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/'
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/'
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/opt'
-load
 '/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/LLVMEncodeFunctionName.so'
-Encode hello_clang.ll -o hello_clang_encode.bc
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/opt'
-load
 '/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/LLVMEncodeFunctionName.so'
-Encode hello_clang.ll -o hello_clang_encode.bc
 
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/clang'
 hello_clang_encode.bc  -o hello_clang_encode
然后执行一下:
'/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/clang'
 hello_clang_encode.bc  -o hello_clang_encode
然后执行一下:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  EncodeFunctionName() : FunctionPass(ID) {}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: "<<F.getName()<<" -> ";
    if(F.getName().compare("main") == 0){
      llvm::MD5 Hasher;
      llvm::MD5::MD5Result Hash;
      Hasher.update("kanxue_");
      Hasher.update(F.getName());
      Hasher.final(Hash);
 
      SmallString<32> HexString;
      llvm::MD5::stringifyResult(Hash, HexString);
 
      F.setName(HexString);
    }
    errs()<<F.getName()<< '\n';
    return false;
  }
};
}
char EncodeFunctionName::ID = 0;
static RegisterPass<EncodeFunctionName> X("Encode", "Encode Function Name Pass",
                                          false /* Only looks at CFG */,
                                          false /* Analysis Pass */);
 
static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  EncodeFunctionName() : FunctionPass(ID) {}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: "<<F.getName()<<" -> ";
    if(F.getName().compare("main") == 0){
      llvm::MD5 Hasher;
      llvm::MD5::MD5Result Hash;
      Hasher.update("kanxue_");
      Hasher.update(F.getName());
      Hasher.final(Hash);
 
      SmallString<32> HexString;
      llvm::MD5::stringifyResult(Hash, HexString);
 
      F.setName(HexString);
    }
    errs()<<F.getName()<< '\n';
    return false;
  }
};
}
char EncodeFunctionName::ID = 0;
static RegisterPass<EncodeFunctionName> X("Encode", "Encode Function Name Pass",
                                          false /* Only looks at CFG */,
                                          false /* Analysis Pass */);
 
static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
find . -name "LLVMConfig.cmake"
find . -name "LLVMConfig.cmake"
readlink -f ./lib/cmake/llvm/LLVMConfig.cmake
readlink -f ./lib/cmake/llvm/LLVMConfig.cmake
add_library( LLVMEncodeFunctionName2 MODULE
        EncodeFunctionName.cpp
 
        )
add_library( LLVMEncodeFunctionName2 MODULE
        EncodeFunctionName.cpp
 
        )
cmake_minimum_required(VERSION 3.23)
 
project(OUTPASS)
 
set(LLVM_DIR /home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/cmake/llvm/)
 
find_package(LLVM REQUIRED CONFIG)
 
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)
 
 
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
include_directories(${LLVM_INCLUDE_DIRS})
 
add_subdirectory(EncodeFunctionName2)
cmake_minimum_required(VERSION 3.23)
 
project(OUTPASS)
 
set(LLVM_DIR /home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/lib/cmake/llvm/)
 
find_package(LLVM REQUIRED CONFIG)
 
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)
 
 
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
include_directories(${LLVM_INCLUDE_DIRS})
 
add_subdirectory(EncodeFunctionName2)
linuxer@ubuntu:~/llvm/study_llvm/01$ '/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/opt'
-load
'/home/linuxer/llvm/study_llvm/02/outPass/cmake-build-release/EncodeFunctionName2/LLVMEncodeFunctionName2.so'  
-encode2
 hello_clang.ll -o hello_clang_encode.bc
EncodeFunctionName22: test_hello1 -> 9c119247aefaa12cdd417eb3d57d5b2a
EncodeFunctionName22: main -> main
EncodeFunctionName22: test_hello2 -> af0aaac8b98b759ace7b9eacbd2238a6
linuxer@ubuntu:~/llvm/study_llvm/01$ '/home/linuxer/llvm/llvm_source_code/llvm/cmake-build-release/bin/opt'
-load
'/home/linuxer/llvm/study_llvm/02/outPass/cmake-build-release/EncodeFunctionName2/LLVMEncodeFunctionName2.so'  
-encode2
 hello_clang.ll -o hello_clang_encode.bc
EncodeFunctionName22: test_hello1 -> 9c119247aefaa12cdd417eb3d57d5b2a
EncodeFunctionName22: main -> main
EncodeFunctionName22: test_hello2 -> af0aaac8b98b759ace7b9eacbd2238a6
 
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/EncodeFunctionName/EncodeFunctionName.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  bool enable_flag;
  EncodeFunctionName() : FunctionPass(ID) {}
  EncodeFunctionName(bool flag) : FunctionPass(ID) {enable_flag = flag;}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: "<<F.getName()<<" -> ";
    if(enable_flag){
      if(F.getName().compare("main") != 0){
        llvm::MD5 Hasher;
        llvm::MD5::MD5Result Hash;
        Hasher.update("kanxue_");
        Hasher.update(F.getName());
        Hasher.final(Hash);
 
        SmallString<32> HexString;
        llvm::MD5::stringifyResult(Hash, HexString);
 
        F.setName(HexString);
      }
    }
 
    errs()<<F.getName()<< '\n';
    return false;
  }
};
}
char EncodeFunctionName::ID = 0;
static RegisterPass<EncodeFunctionName> X("Encode", "Encode Function Name Pass",
                                          false /* Only looks at CFG */,
                                          false /* Analysis Pass */);
 
static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
 
 
 
Pass* llvm::createEncodeFunctionName(bool flag){return new EncodeFunctionName(flag);}
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/EncodeFunctionName/EncodeFunctionName.h"
using namespace llvm;
namespace {
struct EncodeFunctionName : public FunctionPass {
  static char ID;
  bool enable_flag;
  EncodeFunctionName() : FunctionPass(ID) {}
  EncodeFunctionName(bool flag) : FunctionPass(ID) {enable_flag = flag;}
  bool runOnFunction(Function &F) override {
    errs() << "Encode Function Name: "<<F.getName()<<" -> ";
    if(enable_flag){
      if(F.getName().compare("main") != 0){
        llvm::MD5 Hasher;
        llvm::MD5::MD5Result Hash;
        Hasher.update("kanxue_");
        Hasher.update(F.getName());
        Hasher.final(Hash);
 
        SmallString<32> HexString;
        llvm::MD5::stringifyResult(Hash, HexString);
 
        F.setName(HexString);
      }
    }
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-11-27 19:41 被以和爲貴编辑 ,原因:
收藏
免费 11
支持
分享
最新回复 (4)
雪    币: 859
活跃值: (945)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
果然巨佬发的帖子,我是啥也看不懂
2022-11-8 16:47
0
雪    币: 6036
活跃值: (7603)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
TrumpWY 果然巨佬发的帖子,我是啥也看不懂
也没啥跟着别人复现了一遍就是
2022-11-14 14:12
0
雪    币: 525
活跃值: (677)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
怎么在linux下用ollvm 编译windows程序啊
2023-1-6 09:18
0
雪    币: 6036
活跃值: (7603)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
Rixo_叶默 怎么在linux下用ollvm 编译windows程序啊[em_4]
首先得知道程序的源码。然后翻译成c代码。然后直接用ollvm clang编译就可以啦
2023-1-6 12:20
0
游客
登录 | 注册 方可回帖
返回
//