笔记是按照当时的题目排序写的,顺序可能有出入
做题是从0开始做起,所以前面部分也会尽可能写的详细一点
只要能记录并且了解到怎么做即可,所以就没有去在意排版
遇到不会的函数尽可能去百度了解
因为前面的题难度不大,所以前面的每道题都没有去查壳,除非有特殊:)
题目:easyre、reverse1、reverse2、内涵的软件、新年快乐、helloword、xor、reverse3、不一样的flag、SimpleRev
1.easyre
非常简单的逆向
拖入winhex,搜索flag即可
flag{this_Is_a_EaSyRe}
2.reverse1
reverse1 注意:得到的 flag 请包上 flag{} 提交
64位程序,用IDA pro(64 bit)打开
shift+F12打开字符串窗口,按ctrl+f搜索flag
双击这行,跳转至IDA view-A窗口
右键这行,选择第一个(List cross references to),点击OK跳转
可以看到调用了一个判断,并且str2为{hello_world}
F5查看伪代码
可以发现,我们需要输入str1与str2做比较,str2会将字母o替换为0,最终得到flag
flag{hell0_w0rld}
3.reverse2
reverse2 注意:得到的 flag 请包上 flag{} 提交
下载得到ELF文件,使用IDA PRO(64 bits)打开
和第一题一样,shift+f12,跳转至IDA view页面,F5查看伪代码
当然,还能看到一个hacking_for_fun},先记着
先把105 114 49转成字符(选中按R即可)
可以发现,输入的v2要和&flag做比较,而双击&flag发现内容就是之前的hacking_for_fun}
再分析循环,会将flag中的i和r替换成1,使用最后得到flag
flag{hack1ng_fo1_fun}
4.内涵的软件
图片有内涵,exe也可以有内涵,也许你等不到答案,赶快行动起来吧!!! 注意:得到的 flag 请包上 flag{} 提交
运行发现会提示逆向,用IDA pro(32 bits)打开即可
flag{49d3c93df25caad81232130f3d2ebfad}
5.新年快乐
过年了要不做个逆向题庆祝一下新年?说不定会有惊喜哦!注意:flag并非是flag{XXX}形式,就是一个字符串,考验眼力的时候到了! 注意:得到的 flag 请包上 flag{} 提交
用winhex打开能明显看到加了UPX壳,我使用的UPXShell脱壳
脱壳后再用IDA打开,搜索flag字符串,跳转。
flag很明显了
flag{HappyNewYear!}
6.helloword
有难的题目,也就有简单的题目,就像程序员一辈子编写的第一个程序,极有可能是helloword,它很普通,但是也很让人怀念。你猜这题flag在哪里?让我们怀念第一次编写的easy程序吧! 注意:得到的 flag 请包上 flag{} 提交
是一个apk安装包,android逆向。
我使用GDA3.80打开
flag{7631a988259a00816deda84afb29430a}
7.xor
or的敌人,and 有个兄弟叫or,or有个敌人叫xor,那么你能帮助or战胜他的敌人xor吗,xor的奥秘就在附件中,开始战斗吧! 注意:得到的 flag 请包上 flag{} 提交
放入IDA,反汇编main查看伪代码
查看一下global的值
输入的v6进行一顿异或之后得到,其中第一个f是没有被处理的
f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv"M
双击前面的aFKW0XZUPFVMDGH跳转过去
写python脚本
tmp = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v',
'"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']
flag = 'f'
for i in range(1, len(tmp)):
if (isinstance(tmp[i], str)):
if (isinstance(tmp[i - 1], str)):
flag += chr(ord(tmp[i]) ^ ord(tmp[i - 1]))#如果都是字符串
else:#tmp[i]为字符串,tmp[i-1]不是字符串
flag += chr(ord(tmp[i]) ^ tmp[i- 1])
else:#tmp[i]和tmp[i-1]都不是字符串
flag += chr(tmp[i] ^ ord(tmp[i - 1]))
print(flag)
其中,isinstance函数的作用是检测是否为已知类型,这里即比较tmp[i]与tmp[i-1]是否为字符串
flag{QianQiuWanDai_YiTongJiangHu}
8.reverse3
reverse3 注意:得到的 flag 请包上 flag{} 提交
IDA打开,搜字符串能明显看到base
查看main伪代码,简单来说,输入的str加密后得到v1,再进入for循环后得到Dest后的字符与str2进行比较
其中 str2的内容为e3nifIH9b_C@n@dH
跟进sub_4110BE函数
发现使用了这个进行数组变换,跟进发现就是之前的base64。
解码过程:
首先for循环将Dest每一位都加了j,所以写脚本还原v1,然后进行base64解码
import base64
str = 'e3nifIH9b_C@n@dH'
flag = ''
for i in range(len(str)):
flag+=chr(ord(str[i])-i)
flag = base64.b64decode(flag)
print(flag)
得到{i_l0ve_you}
flag{i_l0ve_you}
9.不一样的flag
是不是做习惯了常规的逆向题目?试试这道题,看你在能不能在程序中找到真正的flag!注意:flag并非是flag{XXX}形式,就是一个’字符串‘,考验眼力的时候到了! 注意:得到的 flag 请包上 flag{} 提交
__main();
v4 = 0;
v5 = 0;
qmemcpy(&v3, _data_start__, 0x19u);
while ( 1 )
{
puts("you can choose one action to execute");
puts("1 up");
puts("2 down");
puts("3 left");
printf("4 right\n:");
scanf("%d", &v6);
if ( v6 == 2 )
{
++v4;
}
else if ( v6 > 2 )
{
if ( v6 == 3 )
{
--v5;
}
else
{
if ( v6 != 4 )
LABEL_13:
exit(1);
++v5;
}
}
else
{
if ( v6 != 1 )
goto LABEL_13;
--v4;
}
for ( i = 0; i <= 1; ++i )
{
if ( *(&v4 + i) < 0 || *(&v4 + i) > 4 )
exit(1);
}
if ( *((_BYTE *)&v8 + 5 * v4 + v5 - 41) == '1' )
exit(1);
if ( *((_BYTE *)&v8 + 5 * v4 + v5 - 41) == '#' )
{
puts("\nok, the order you enter is the flag!");
exit(0);
}
}
}
可以发现有上下左右四个方向,并且碰到1退出,碰到#输出flag,应该是一个迷宫,再查看01串长度正好25
得到222441144222
flag{222441144222}
10.SimpleRev
SimpleRev(flag需加上flag{}再提交) 注意:得到的 flag 请包上 flag{} 提交
ELF文件,还是IDA打开,发现需要输入D进入游戏,跟进Decry
其中text=key3+v9
key3为kills,因为是小端序存储,则text为killshadow
key为key1+src,key1为ADSFK
则key为ADSFKNDCLS
下面查看加密过程
最后text需要和str2进行比较,既然已经知道了加密后的字符串和key(注意key在第2张图被+32,即大写变成了小写),所以可以直接写脚本一位一位的进行爆破
key = "adsfkndcls"
text = "killshadow"
flag = ""
dict = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
v5 = len(text)
for i in range(v5):
for v1 in dict:
if ord(text[i]) == (ord(v1) - 39 - ord(key[i % v5]) + 97) % 26 + 97:
flag += v1
print(flag)
运行得到KLDQCUDFZO
flag{KLDQCUDFZO}