IDA常用快捷键
F5 | 切换成伪代码 |
Tab | 汇编指令和伪代码切换 |
空格 | 反汇编窗口切换(列表视图、图形视图) |
shift+F12 | 字符串窗口 |
N | 重命名 |
: | 注释只在该处出现 |
; | 注释在所有交叉参考处出现 |
H | 10进制和16进制切换 |
R | 字符转换 |
汇编 Ollydbg使用
https://blog.csdn.net/weixin_42172261/article/details/104055638
bugku 入门逆向
ExeinfoPe显示无壳,放到IDA中,发现很多字符,选中按R键可以发现flag。
或者找到调用printf的地址00401475, 去OD中Ctrl+G搜索到地址后下个断点,F9运行后F8单步调试,在堆区发现flag。
Easy_vb
在IDA里ALT+T搜索CTF就能找到
在OD里中文只能搜索也能找到
Easy_Re
IDA观察流程图,到最后有一个分支输出的是flag不对,另一个分支应该就是输出flag。
双击过去,发现一些数字,R键可以转换到flag。
OD中文智能搜索也可以发现flag。
游戏过关
游戏流程:输入n的值,修改灯的状态,然后判断是否全亮,输出结果。
丢进OD,中文只能搜索到flag输出的地方,加一个断点,并且记住这个地址。
中文智能搜索n=的地方,输入n后,找个位置直接跳转到调用输出flag的地址。
然后一直运行就能找到flag。
逆向入门
ExeinfoPe查看属性,显示不是pe文件
用记事本打开,发现是网页图片的base64编码,加上头部和尾部,
格式<img src="https://img-blog.csdnimg.cn/2022010701503252526.png" />
文件格式改成html,打开发现二维码扫一下就有flag。
love
第1步:od中文智能搜索找到right flag和wrong flag的信息,双击跳到对应的地址。
第2步:
发现重要信息,在调用结果信息的上面有一个字符串的比较。下断点后多次到这里看传进栈的信息,有两个字符串,一个是自己输入的,只要输入变就跟着变;另一个是用于比较的,每次都一样。
第3步:去IDA中查看代码
判断输入的字符先经过了一个函数变换后,再每个字符加上自己的下标值变成新的字符,然后这个字符串去和内置的字符串比较。内置的字符串在od和ida中都能找到。就剩下这个函数变换了。
第4步:shirf+F12后看到了base64,猜测这个函数应该是对输入字符串进行了base64编码。
第5步:脚本一跑,flag爆出。
>>> import base64
>>> ls = "e3nifIH9b_C@n@dH"
>>> lt = ""
>>> for i in range(len(ls)):
lt += chr(ord(ls[i]) - i)
>>> flag = base64.b64decode(lt).decode()
>>> flag
'{i_l0ve_you}'
不好用的ce
第1步:说是不好用的ce,那就先用ce试试吧,不过确实不好用,搜不到地址,题目没有骗我们
第2步:丢进od,智能搜索,就几个字符串,都下个断点,调试后发现有一个字符串上面有个跳转,正好越了过去,把跳转改成nop,再单步跳过就能出来那串字符串,base58解密。
base58是在base64的基础上去掉了O 0 I l + /
这几个容易混淆和判断的字符后的字符编码
Mountain climbing
查壳发现upx壳,先脱下来,然后运行一下看看啥反应。
随便输入后给了个error。
放到ida中看看。
代码跑一下找一个最优的路径
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <algorithm>
using namespace std;
int a[25][25];
int path[25];
int ans=0;
void dfs(int i, int j, int step, int sum){
if (step == 20){
if (sum > ans){
ans = sum;
for (int i=1; i<=step-1; i++)
printf("%d", path[i]);
printf("\n");
}
return;
}
for (int k=0; k<=1; k++){
path[i]=k;
int ti = i+1;
int tj = j+k;
dfs(ti, tj, step+1, sum+a[ti][tj]);
}
}
int main(){
srand(12);
for (int i=1; i<=20; i++){
for (int j=1; j<=i; j++){
a[i][j] = rand() % 100000;
printf("%d ", a[i][j]);
}
printf("\n");
}
dfs(1, 1, 1, a[1][1]);
return 0;
}
最优为1111100111010111010
即RRRRRLLRRRLRLRRRLRL
,依旧是error。
丢进OD里看看吧。
经过了call 1.0041114f
这个指令后字符串就变了。当位序是偶数时,L互换换成H,R互换换成V
然后重新输入一遍就好了。
Take the maze
无壳,丢进IDA中,分析代码,输入字符串给V6,并且长度要是24
这个v6经过一个函数处理,然后是if,然后又是一个函数的if判断,最后会生成一个png。
直接丢进OD吧。想办法让它跳转到我们需要的函数那里。
最后出来一个二维码,扫码得到信息Congratulations! The flag is your input + "Docupa"
???还要输入???
经历绝望了,看write up。
后面两个函数关系不太大,主要是if里面的,真的太麻烦了,以后再回来看吧。
待更…
file
64位ELF文件,无壳,先放到IDA分析一波
根据异或的可逆性,用已知的三个值再给异或回去,输出结果是乱码,所以应该直接输出到文件。
def func1(a1):
if (ord(a1) > 47 and ord(a1) <= 57):
return ord(a1) - 48
if (ord(a1) > 64 and ord(a1) <=70):
return ord(a1) - 55
if (ord(a1) <= 96 or ord(a1) > 105):
return 0xFFFFFFFF
return ord(a1) - 87
def func2(a1, a2):
t = func1(a1) * 16
return t + func1(a2)
sttr_home = "664e06226625425d562e766e042d422c072c45692d125c7e6552606954646643"
v13 = []
for i in range(0, 64, 2):
v13.append(func2(sttr_home[i], sttr_home[i+1]))
print(v13)
flllag = "flag{hello_player_come_on_hahah}"
flag = ""
for i in range(len(flllag)):
flag += chr(ord(flllag[i]) ^ i ^ v13[i])
# print(flag)
"""
with open("C:\\Users\\dell\\Desktop\\1.txt", "w") as fp:
fp.write(flag)
fp.close()
"""
import hashlib
md5obj = hashlib.md5()
with open("C:\\Users\\dell\\Desktop\\1.txt", "rb") as fp:
md5obj.update(fp.read())
fp.close()
print(md5obj)
print(md5obj.hexdigest())
提示是文件的MD5值,那就再求个md5。
RE_Cirno
下载图片用binwalk看一下,有一个隐藏的zip包,foremost提取出来,里面有一个re.exe
32位pe文件,无壳。运行一下,直接运行完了。丢IDA看看。
前面做了一些比较复杂的分析,这个代码是真的简单。python跑一下
>>> lt = [115, 94, 97, 114, 103, 47, 114, 65, 48, 49, 105, 117, 118, 101, 48, 113, 95, 99, 47, 92, 116, 93, 102]
>>> ls = ""
>>> for i in range(len(lt)):
ls += chr(lt[i]+9)
>>> ls
'|gj{p8{J9:r~\x7fn9zhl8e}fo'
已经有了flag的雏形了,之前做过密码学方向的题,很明显是栅栏密码嘛。
找个在线解密,半天弄不出来…搜write up吧,看了一篇wp,说是有个异或
可是这怎么想的出来,丢进OD看看吧。
这里怎么会有个异或,没有在IDA中显示出来。。。。
再和9异或一下吧。异或的优先级低于加减
>>> lt = [115, 94, 97, 114, 103, 47, 107, 114, 65, 48, 49, 105, 117, 118, 101, 48, 113, 95, 99, 47, 92, 116, 93, 102]
>>> ls = ""
>>> for i in range(len(lt)):
ls += chr(lt[i] + 9 ^ 9)
>>> ls
'uncry1}rC03{wvg0sae1ltof'
>>> flag = ls[::-1]
>>> flag
'fotl1eas0gvw{30Cr}1yrcnu'
再就是注意一下这里的栅栏数是9,不能整除24,所以需要自动补全,好在一些在线解密有这个功能。