1、初识 llvm源码编译 及virtualbox和ubuntu环境搭建

很久没更新了,最近准备研究逆向和加固,于是跟着看雪hanbing老师学习彻底搞懂ollvm,终于把所有流程跑通了,中间遇到了太多的坑,所以必须记录一下,能避免自己和帮助他人最好。

环境搭建太重要了,折腾了好几遍,老师的视频里对初始环境说得太少了,吃了太多这方面的亏,这里我是在windows中添加虚拟机完成的,原以为mac上应该也可以,但后面发现还是很多地方走不通。

系统使用VirtualBox-7.0.12-159484-Win和ubuntu-2204.3,从目前来说都是最新的,

virturalBox 下载地址:https://www.virtualbox.org/wiki/Downloads​​​​​​icon-default.png?t=N7T8https://www.virtualbox.org/wiki/Downloads

ubuntu 下载地址 : 

https://releases.ubuntu.com/jammy/ubuntu-22.04.3-desktop-amd64.isoicon-default.png?t=N7T8https://releases.ubuntu.com/jammy/ubuntu-22.04.3-desktop-amd64.iso

先安装虚拟机环境并配好网络,整个下载和安装过程大部分时间就是等

下载好这两个文件后,可以开始安装了

我准备了一个空盘,465G,为了防止llvm编译时内存报错,搞得很大

VirtualBox 安装,配置内存24000MB,差不多20G,处理器8,硬盘给到360G,因为llvm编译很容易内存溢出,所以硬件还是要跟上,这里我是吃过亏的。

配置完毕后,等待一段时间的安装,检查Terminal应用是否正常,默认浏览器是否能上网。

terminal无法打开的问题解决:

CTRL + ALT + F3 # 进入命令行模式(需要返回桌面时CTRL + ALT + F1)
cd /etc/default
sudo nano locale
# 把文件中的 “en_US” 改成 “en_US.UTF-8”
#注意是所有的en_US,我这边发现了两处
# 保存退出
sudo locale-gen --purge
reboot # 重启虚拟机

安装git,去官网下载llvm 9.0.1版本源代码,注意是linux的版本,然后上传到一个自己的git仓库,这里上传是为了后面有用,这里很重要,后面要做代码分支切换。

下载地址:https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/llvm-project-9.0.1.tar.xz

git 添加ssh命令

ssh-keygen -t ed25519 -C "your_email@example.com"

安装llvm编译命令,同Android源码编译的命令相同:

sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

 安装完毕后可以编译安卓源码也可以编译llvm。

安装cmake, sudo apt install cmake 

安装ninja , sudo apt-get install ninja-build

两个工具安装完毕后,mkdir build-debug  cd build-debug

cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_PROJECTS="clang" ../llvm

目录结构如上,命令正常后执行,ninja -j8,然后等待编译完成。3000多个文件,至少半个小时吧。

同样的操作,再编译release目录,先创建build-release文件夹,再执行

cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" ../llvm

同样执行 ninja -j8。

然后就是在clion中编译llvm了,先去官网下clion并安装,注意下载的是linux的版本,

clion下载地址:

Download CLion: A Smart Cross-Platform IDE for C and C++

打开llvm项目,目录为/home/nowind/llvm/llvm-project-9.0.1/llvm /CMakeLists.txt,然后手动配置CMake参数:

Debug和Release,-G Ninja -DLLVM_ENABLE_PROJECTS="clang",在llvm目录下会自动生成

cmake-build-debug和cmake-build-release目录,再使用命令行进入这两个目录,执行ninja -j8

debug模式在编译llc文件的时候,我等了将近半个小时,也是这里容易将内存给崩了,需要随时查看free -m,查看剩余内存还够不够,不够就添加swap内存。这个文件非常难过,编译完成后直接吞掉了我近100G,编译后debug包的大小有65G

这里我添加了40G的swap内存

sudo swapoff -asudo rm /swapfilesudo dd if=/dev/zero of=/swapfile bs=1M count=40960sudo chmod 600 /swapfilesudo mkswap /swapfilesudo swapon /swapfilesudo swapon --show

以上是在外层生成的编译文件,但我在后面看老师讲解的时候,并没有用到这个,所以很奇怪,为啥多这一步,如果时间不足可以先往后看,有空再来编译这边的。

终于编译完了。

编译遇到错误:

llvm-project-9.0.1/llvm/utils/benchmark/src/benchmark_register.h:17:30: error: ‘numeric_limits’ is not a member of ‘std’ 17 | static const T kmax = std::numeric_limits<T>::max();

需要在llvm-project-9.0.1/llvm/utils/benchmark/src/benchmark_register.h中增加

#include <limits>

无论在clion中编译还是使用cmake直接编译,都是后续的第一步,这步遇到问题,一定是要解决的

接下来我们使用编译后的clang和llvm来执行c文件

先配置环境变量:

export PATH=/home/nowind/llvm/llvm-project-9.0.1/llvm/cmake-build-debug/bin:$PATH
clang -emit-llvm -S hello_clang.c -o hello_clang.ll    其中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   同样可以把bc文件转ll文件,和上面使用clang的结果是一样的
opt --print-bb hello_clang.bc 打印内容

熟悉下c文件编译后的几种格式    灵活运用

clion断点调试,

使用clang命令行:

clang /home/nowind/llvm/pro/pro1/hello_clang.c -o /home/nowind/llvm/pro/pro1/hello_clang_s

使用clang 断点:clion 切换到Clang Debug模式,配置参数

/home/nowind/llvm/pro/pro1/hello_clang.c -o /home/nowind/llvm/pro/pro1/hello_clang_s

然后断点打在/home/nowind/llvm/llvm-project-9.0.1/clang/tools/driver/driver.cpp的main函数中,这里是clang的入口

使用pass:

bc或者ll文件使用hello pass

opt 命令行运行

 opt -load '/home/nowind/llvm/llvm-project-9.0.1/build-debug/lib/LLVMHello.so' -hello hello.bc

clion调试opt  切换至 opt debug,进行断点 在 llvm/lib/Transform/Hello/hello.cpp

配置参数 

-load /home/nowind/llvm/llvm-project-9.0.1/build-debug/lib/LLVMHello.so -hello hello.bc

以上基本是第一课的所有内容了,并不复杂,但编译时间会比较长,遇到相关问题也可以一起讨论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/256978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.1 U-boot的使用

由于Ubuntu出现了一些问题&#xff0c;后面都是使用正点原子官方版本。 一、U-boot使用 1. U-boot源码 Linux 系统要启动需要通过 bootloader 程序引导&#xff0c;也就说芯片上电以后先运行一段 bootloader 程序。这段 bootloader 程序会先初始化 DDR 等外设&#xff0c;然后…

Smart Link和Monitor Link

Smart Link和Monitor Link简介 Smart Link&#xff0c;又叫做备份链路。一个Smart Link由两个接口组成&#xff0c;其中一个接口作为另一个的备份。Smart Link常用于双上行组网&#xff0c;提供可靠高效的备份和快速的切换机制。 Monitor Link是一种接口联动方案&#xff0c;它…

2024黑龙江省职业院校技能大赛信息安全管理与评估赛项规程

2024黑龙江省职业院校技能大赛暨国赛选拔赛 “GZ032信息安全管理与评估”赛项规程 极安云科专注技能竞赛&#xff0c;包含网络建设与运维和信息安全管理与评估两大赛项&#xff0c;及各大CTF&#xff0c;基于两大赛项提供全面的系统性培训&#xff0c;拥有完整的培训体系。团队…

ComplexHeatmap热图专栏 | 6. 3D热图绘制教程

本期教程 原文链接https://mp.weixin.qq.com/s/EyBs6jn78zOomcTv1aP52g 6 3D热图的绘制教程 基于《热图绘制教程》专栏&#xff0c;本教程已更新了5个章节&#xff0c;不知道大家是否有所收获。对于小杜个人来说&#xff0c;真的需要不断的复习和练习才可以记住&#xff0c;但…

【Flink系列三】数据流图和任务链计算方式

上文介绍了如何计算并行度和slot的数量&#xff0c;本文介绍Flink代码提交后&#xff0c;如何生成计算的DAG数据流图。 程序和数据流图 所有的Flink程序都是由三部分组成的&#xff1a;Source、Transformation和Sink。Source负责读取数据源&#xff0c;Transformation利用各种…

【Python】np.save()和np.load()函数详解和示例

本文通过函数原理和运行示例&#xff0c;对np.save()和np.load()函数进行详解&#xff0c;以帮助大家理解和使用。 更多Numpy函数详解和示例&#xff0c;可参考 【Python】Numpy库近50个常用函数详解和示例&#xff0c;可作为工具手册使用 目录 np.save &#xff08;&#xff…

学会使用这个魔法棒,再也不用在容器里安装乱七八糟的命令工具了!

在构建镜像的时候&#xff0c;我总是倾向于极简构建&#xff0c;一切没有必要的软件包都不安装&#xff0c;以此来缩小镜像的容量。但是这种做法为后续运维带来了一些困难&#xff0c;如在日常查询、排查问题的时候发现很多命令用不了&#xff0c;不得不在容器中安装额外的命令…

Python Nuitka打包指南

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python Nuitka打包指南&#xff0c;全文2100字&#xff0c;阅读大约8分钟。 在Python应用程序开发中&#xff0c;打包是将代码和依赖项组合成可执行文件或库的关键步骤之一…

Django + Matplotlib:实现数据分析显示与下载为PDF或SVG

写作背景 首先&#xff0c;数据分析在当前的信息时代中扮演着重要的角色。随着数据量的增加和复杂性的提高&#xff0c;人们对于数据分析的需求也越来越高。 其次&#xff0c;笔者也确确实实曾经接到过一个这样的开发需求&#xff0c;甲方是一个医疗方面的科研团队&#xff0…

JavaSE基础50题:10. 计算1/1-1/2+1/3-……+1/99-1/100的值(两种方法)

概述 计算1/1 - 1/2 1/3 - …… 1/99 - 1/100的值。 当分母为偶数时&#xff0c;符号是负的&#xff0c;放分母为奇数时&#xff0c;符号是负的。 方法一 用 flg 做了一个正负交替 【代码】 public static double func() {double sum 0;int flg 1; //设置正负号的for (i…

LeetCode Hot100 46.全排列

题目&#xff1a; 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 代码&#xff1a; class Solution {private int[] nums;private List<Integer> path; // 记录路径上的数&#xff0c;已选数字private boo…

Linux学习笔记之八(进程间的共享内存)

Linux 1、引言2、实现共享内存2.1、创建一个共享内存2.2、将共享内存链接到进程空间2.3、断开与共享内存的链接2.4、对共享内存进行后续操作 3、应用实例 1、引言 在之前一篇文章Linux学习笔记之六&#xff08;进程之间的管道通信和信号处理&#xff09;中我讲了进程间可以通过…