IDAPRO

快捷键 功能
Esc 回到上一个位置
Enter 跳转到当前光标处的地址
- 折叠代码
+ 展开代码
* 创建一个结构
Alt + A 手动定义一个数组
Alt + F 寻找直接引用的函数
Alt + G 跳转到特定的地址
Alt + T 搜索
Alt + X 重命名
Ctrl + G 快速跳转到指定地址
Ctrl + J 显示引用列表
Ctrl + K 显示 XREF 到选中的函数/数据
Ctrl + N 创建一个函数
Ctrl + Q 快速重命名
Ctrl + X 显示从选中的函数/数据的 XREF
Ctrl + E 显示结构类型
Ctrl + R 手动定义一个数据结构
Ctrl + W 打开函数列表
Ctrl + D 以十进制显示当前值
Ctrl + B 以二进制显示当前值
Ctrl + H 以十六进制显示当前值
Space 在图形/文本视图中切换
shift + f12 打开字符串窗口
F5 转伪C代码

easyre

Exeinfo PE查壳

image-20231117214430774

64位,用ida64打开

image-20231117214439772

F5反汇编

image-20231117214448149

直接可得flag,程序通过判断输入的数a,b相等来输出flag,不过由于没有system.pause函数,窗口在输出flag后会直接关闭

reverse1

image-20231117214457031

image-20231117214510389

int __cdecl main(int argc, const char argv, const char envp)

这里的int 是main函数的完全格式

argc是执行程序时的命令行参数个数。

argv是具体的参数

envp是系统的环境变量,很少有介绍的。“名称=值”的形式,以NULL结束。

_cdecl 是C和C++中默认的调用约定。

参数从右向左依次入栈。

调用方负责清理堆栈。

编译后的函数名前缀以一个下划线字符

C语言函数调用栈(二) - clover_toeic - 博客园 (cnblogs.com)

F5反汇编后,进去main_0函数看一下

image-20231117214958376

1
2
3
4
5
6
7
8
for ( j = 0; ; ++j )
{
v10 = j;
if ( j > j_strlen(Str2) )
break;
if ( Str2[j] == 111 )
Str2[j] = 48;
}

这段代码将str2的O转化为0,可以按R键将ASCII码转化为字符

image-20231117215213573

image-20231117215230431

!strncmp()表示两个字符串相等

image-20231117215707859

image-20231117220023782

点开str2可以看到字符串数据

将o换成0得出flag{hell0_w0rld}

reverse2

image-20231117222342312

可以看到是elf文件

用ida打开她

image-20231117223034333

image-20231120213617202

1
2
3
4
5
6
flag1 = '{hacking_for_fun}'
flag = list(flag1)
for i in range(len(flag)):
if flag[i] == 'i' or flag[i] == 'r':
flag[i]='1'
print(''.join(flag))

flag{hack1ng_fo1_fun}

__readfsqword(0x28u) 是一个用于读取FS段偏移地址0x28处无符号64位(qword)值的操作。

fs寄存器,通常用于实现线程本地存储(Thread Local Storage,TLS)。

常用于多线程编程,其中每个线程可以有自己的本地存储区域.r

编译libc时,编译器会自动将其转换为scanf中的__isoc99_scanf函数

fork()函数详解 - _NewMan - 博客园 (cnblogs.com)

1
2
3
4
5
6
7
pid_t fpid;

fpid = fork();

**1)在父进程中,fork返回新创建子进程的进程ID;**
**2)在子进程中,fork返回0;**
**3)如果出现错误,fork返回一个负值;**

Linux中waitpid()函数的用法_linux waitpid函数用法-CSDN博客从博客中了解到如果在调用waitpid()函数时,当指定等待的子进程已经停止运行或结束了,则waitpid()会立即返回;但是如果子进程还没有停止运行或结束,则调用waitpid()函数的父进程则会被阻塞,暂停运行。

image-20231121213012496

分析得出folk()出子进程后,if(pid)判断当前进程是否为子进程,因为子进程调用的folk函数的返回值为0,因此进入else语句进行字符替换。父进程因为folk()函数返回子进程的进程id,所以执行waitpid()函数进入阻塞状态,暂停运行。当子进程执行完后,父进程继续执行,所以有两次flag输入与判断。

我们试着在ubuntu上运行elf文件,可以输入两次flag,第一次正确flag为{hack1ng_fo1_fun},第二次正确flag为{hacking_for_fun},所以说我们的推断是正确的。

image-20231120230826944

flag{hack1ng_fo1_fun}

内涵的软件

image-20231121214552174

32位,ida打开,F5,main函数直接看到flag

image-20231121214702335

新年快乐

image-20231121214851517

upx壳,直接upx -d

image-20231121215141561

ida打开

image-20231121215521999

flag{HappyNewYear!}

image-20231121215606989

image-20231121215716907

通过x32dbg手脱upx壳

详情可见此博客BUUCTF 新年快乐 脱壳工具与手动脱壳 - M4r1s4 - 博客园 (cnblogs.com)

http://www.manongjc.com/detail/64-ilojvxvdaywqacj.html

https://www.52pojie.cn/thread-326995-1-1.html

笔者还在学习脱壳ing,贴几张博客。

XOR

发现题目有__MACOSX文件夹

__MACOSX 是 macOS 操作系统下的一个隐藏文件夹,它通常出现在存储着文件或文件夹的 ZIP 压缩包中。这个文件夹包含了与 macOS 系统相关的元数据和资源文件,例如图标、预览缩略图等。这些文件和文件夹在 macOS 上可能会有一些额外的属性或资源,而这些额外的信息就被存储在 __MACOSX 文件夹中。

在大多数情况下,如果你从 macOS 系统上打包文件或文件夹,并将其发送给其他操作系统的用户(例如 Windows 或 Linux 用户),__MACOSX 文件夹对于接收者来说可能没有实际用途。因此,在跨平台分享文件时,有时人们可能会删除或忽略 __MACOSX 文件夹。

能得知出题人用的是mac。

我们直接看题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+2Ch] [rbp-124h]
char __b[264]; // [rsp+40h] [rbp-110h] BYREF

memset(__b, 0, 0x100uLL);
printf("Input your flag:\n");
get_line(__b, 256LL);
if ( strlen(__b) != 33 )//flag长度为33,若不为33,直接goto输出false
goto LABEL_7;
for ( i = 1; i < 33; ++i )
__b[i] ^= __b[i - 1];// 从输入的第二位开始,将其与前一位异或
if ( !strncmp(__b, global, '!') )//与global
printf("Success");
else
LABEL_7:
printf("Failed");
return 0;
}

点击global进入文本视图

一下为chatGPT生成,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
__data:0000000100001050                               ; ===========================================================================
__data:0000000100001050
__data:0000000100001050 ; Segment type: Pure data
;‘;’通常表示一个注释,Pure data 表示这个段是用于存储纯粹的数据
__data:0000000100001050 ; Segment permissions: Read/Write
;Read/Write 表示该段具有读写权限。
__data:0000000100001050 __data segment qword public 'DATA' use64
;__data: 这是__data段。
;qword: 这表示这个段中的数据将以64位的大小进行存储。
;public: 这表示这个段是公共的,可以被其他模块或文件访问。
;'DATA': 段的数据类型
;use64: 这个指令表示使用64位模式。在64位汇编中,寄存器和地址等都使用64位宽度。
__data:0000000100001050 assume cs:__data
;它起到协助编译器的作用,它是将codesg与cs寄存器关联起来。
__data:0000000100001050 ;org 100001050h
;表示将程序的起始地址或偏移量设置为 100001050h。
__data:0000000100001050 public _global
;public _global: 表示 _global 是一个公共的标识符,可以被其他模块或文件访问。
__data:0000000100001050 ; char *global
__data:0000000100001050 6E 0F 00 00 01 00 00 00 _global dq offset aFKWOXZUPFVMDGH ;
;dq 指令通常用于声明变量或者数据块。
;_global dq offset aFKWOXZUPFVMDGH: 这行代码定义了一个 qword 大小的全局变量 _global,它的值被初始化为字符串 aFKWOXZUPFVMDGH 的偏移量(offset)。这个偏移量通常是指向内存中存储字符串的位置。这样的声明表明 _global 被视为一个指向字符串的指针。
DATA XREF: _main+10D↑r
;DATA XREF: 这是一个标记,表示这是数据交叉引用。
;_main+10D: 这表示在 _main 函数的地址偏移为 10D 处。
;↑r: 这可能表示引用的类型。
__data:0000000100001050 __data ends ; "f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M"... ;数据
__data:0000000100001050

shift+E

image-20231122211926034

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12

code=[
0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F, 0x00
]
flag=chr(code[0])
for i in range(1,len(code)-1):
flag+=chr(code[i]^code[i-1])

print(flag)

flag{QianQiuWanDai_YiTongJiangHu}

helloworld

image-20231123225255045

apk文件,用jadx-gui打开,点击MainActivity看到flag

image-20231123225352858

reverse3

shift+f12发现特征码,也可使用ida插件findcrypt3

image-20231124230122625

常见算法特征识别

7908d90b314fca621076f790480dcc6

image-20231124230512864

sub_4110BE函数有三个参数,输入的str,str的长度和v14,进入函数,明显的base64加解密

image-20231124231005059

对输入的字符串每个与其下标相加,最后与str2比较,最后的,0是字符串的结尾标志

image-20231124231718584

exp

1
2
3
4
5
6
7
8
9
import base64
list=['e','3','n','i','f','I','H','9','b','_','C','@','n','@','d','H','0']
for i in range(len(list)):
list[i]=chr(ord(list[i])-i)
a=''.join(list)
print( base64.b64decode(a).decode('utf-8'))

#b = base64.b64encode(s.encode('utf-8'))加密
#b = base64.b64decode(b).decode('utf-8')解密

image-20231125224828512

0加上去和不加上去都一样,因为base64是将3字节(24位比特)按照其值选择”ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/“中的字符输出,会把不足3字节的剩下的比特补0。

image-20231125224859687

不一样的flag

image-20231125225527731

运行程序,应该是一道迷宫题

进入main函数

image-20231125232414703

发现迷宫

1
2
3
4
5
*1111
01000
01010
00010
1111#

flag{222441144222}

假设我们有一只小鼠,我们对在迷宫的移动进行分析。我们发现,当我们左右移动时v4会做加减运算,上下移动时,会改变v3[25]的值。来看判断语句5 * *(_DWORD *)&v3[25] - 41 + v4] == '#'可以简化为`将我们上下左右移动的值进行运算,我们将终点<font color=Red>#</font>的值v4=4,v3[25]=4,运算得出v7[-17]`,

v7[12] ebp-Ch

v3[29] ebp-35h

35h-Ch=41,即v7[-41]为v3数组的首元素

我们通过计算得出v7[-17]=’*’

image-20231125235231197

判断v3[25]和v3[29]即v4的值不大于0x5,即不走出迷宫范围(5*5)

SimpleRev

image-20231127173618282

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h> 
int main()
{
char key[] = "adsfkndcls";
char text[] = "killshadow";
int i;
int v3=10;/
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 128; j++)
{
if (j < 'A' || j > 'z' || j > 'Z' && j < 'a')
{
continue;
}
if ((j - 39 - key[v3 % 10] + 97) % 26 + 97 == text[i])
{
printf("%c",j);
v3++;
break;
}
}
}
}

1
2
3
4
5
6
7
8
9
10
text='killshadow'

key= 'ADSFKNDCLS'.lower()

for x in range(0,10):
for j in range (0,128):
if (j<=96 and j>122 or j>64 and j<=90 ):
if (((j - 39 - ord(key[x]) + 97) % 26 + 97 )== ord(text[x])):
print(chr(j),end='')

Java逆向解密

jadx打开即可

image-20231127213732423

1
2
3
4
5
KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
for i in range(len(KEY)):
for x in range (0,127):
if (x+64)^32==KEY[i]:
print(chr(x),end='')

[GXYCTF2019]luck_guy1

image-20231127214632716

因为switch里是随机数,所以得出flag靠运气23333

执行顺序case4->case5->case1

解题脚本

1
2
3
4
5
6
7
8
9
f2=[0x7F,0x66,0x6F,0x60,0x67,0x75,0x63,0x69][::-1]
flag = 'GXY{do_not_'
for x in range(0,8):
if x%2==1:
f2[x]-=2
else:
f2[x]-=1
flag+=chr(f2[x])
print(flag)

[BJDCTF2020]JustRE 1

win32api

Windows 和消息 - Win32 apps | Microsoft Learn

image-20231220182713411

image-20231129172751369

flag{1999902069a45792d233ac}

刮开有奖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
int sub_4010F0(char *a1, int a2, int a3)
// sub_4010F0((int)v7, 0, 10);
{
int result; // eax
int i; // esi
int v5; // ecx
int v6; // edx

result = a3;
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = a1[i];
if ( a2 < result && i < result )
{
do
{
if ( v6 > a1[result] )
{
if ( i >= result )
break;
++i;
a1[v5] = a1[result];
if ( i >= result )
break;
while ( a1[i] <= v6 )
{
if ( ++i >= result )
goto LABEL_13;
}
if ( i >= result )
break;
v5 = i;
a1[result] = a1[i];
}
--result;
}
while ( i < result );
}
LABEL_13:
a1[result] = v6;
sub_4010F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
int main()
{
char v7[]="ZJSECaNH3ng";
sub_4010F0(v7, 0, 10);
printf("%s",v7);
}

输出3CEHJNSZagn

同时我们在

image-20231223204339998

我们发现flag第一二位已经确定,为UJ同时输入3个字符,输出4个字符,可以看到base64表,所以sub_401000为base64加密。``

image-20231223205639700

ak1wV1Ax=jMpWP1

flag{UJjMpWP1}

[GWCTF 2019]pyre 1

image-20231223211518873

1
2
3
4
5
6
7
8
9
10
11
12
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num

for i in range(l - 1):
code[i] = code[i] ^ code[(i + 1)]

print code
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']

解题脚本

1
2
3
4
5
6
7
8
9
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']

for i in range(len(code)-2,-1,-1):
code[i] = chr(ord(code[i]) ^ ord(code[(i + 1)]))


for i in range(len(code)):
num = chr((ord(code[i])-i)%128)
print(num,end='')

[ACTF新生赛2020]easyre1

upx脱壳

wp

1
2
3
4
5
6
7
8
9
v4 = [42,70,39,34,78,44,34,40,73,63,43,64]
data_start__ = chr(0x7E)+"}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(" + chr(0x27) + '&%$# !"'
flag = ""
for i in v4:
for j in range(len(data_start__)):
if i==ord(data_start__[j]):
flag+=chr(j+1)

print(flag)

[ACTF新生赛2020]rome1

1
2
3
4
5
6
7
8
9
10
11
12
13
v12='Qsw3sj_lz4_Ujw@l'

for i in range(16):
for j in range(0,128):
key=j
if j > 64 and j <= 90:
j=(j-51)%26+65
if j>96 and j<=122:
j= (j-79)%26 +97
if j == ord(v12[i]):
print(chr(key),end='')


findit 1

关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
final char[] a = {'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'};
final char[] b = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};
btn.setOnClickListener(new View.OnClickListener() { // from class: com.example.findit.MainActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View v) {
char[] x = new char[17];
char[] y = new char[38];
for (int i = 0; i < 17; i++) {
if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) {
x[i] = (char) (a[i] + 18);
} else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) {
x[i] = (char) (a[i] - '\b');
} else {
x[i] = a[i];
}
}
String m = String.valueOf(x);
if (m.equals(edit.getText().toString())) {
for (int i2 = 0; i2 < 38; i2++) {
if ((b[i2] >= 'A' && b[i2] <= 'Z') || (b[i2] >= 'a' && b[i2] <= 'z')) {
y[i2] = (char) (b[i2] + 16);
if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') {
y[i2] = (char) (y[i2] - 26);
}
} else {
y[i2] = b[i2];
}
}
String n = String.valueOf(y);
text.setText(n);
return;
}
text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
}
});

发现是凯撒加密,解题脚本:

1
2
3
4
5
6
7
8
9
10
11
12
model = "abcdefghijklmnopqrstuvwxyz"

str1 = "pvkq{m164675262033l4m49lnp7p9mnk28k75}"

for i in range(1,27):
print("key=%d"%i)
for s in str1:
if s.isalpha():
n = model.find(s)
s = model[n-i]
print(s, end='')
print('\n')

[FlareOn4]login

<!DOCTYPE Html />

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE Html />
<html>
<head>
<title>FLARE On 2017</title>
</head>
<body>
<input type="text" name="flag" id="flag" value="Enter the flag" />
<input type="button" id="prompt" value="Click to check the flag" />
<script type="text/javascript">
document.getElementById("prompt").onclick = function () {
var flag = document.getElementById("flag").value;
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
}
</script>
</body>
</html>

ROT13

(c <= "Z" ? 90 : 122) >= 确保加密后的字母仍在字母表范围内.

1
2
3
4
5
6
7
8
9
10
11
str1='PyvragFvqrYbtvafNerRnfl@syner-ba.pbz'
result=''
for x in str1:
if 'a' <= x <= 'z':
result += chr((ord(x) - ord('a') - 13) % 26 + ord('a'))
elif 'A' <= x <= 'Z':
result += chr((ord(x) - ord('A') - 13) % 26 + ord('A'))
else:
result += x

print(result)

[WUSTCTF2020]level11

image-20231226221722346

1
2
3
4
5
6
7
8
9
10
11
12
13
14
f = open("output.txt",'r') 
i=1
while True:
tmp = f.readline()

if not tmp:
break
tmp=int(tmp)
if i & 1!= 0 :
tmp=tmp>>i
else:
tmp=tmp/i
i=i+1
print(chr(int(tmp)),end='')

[GUET-CTF2019]re1

见z3求解器

CrackRTF

见CrackRTF

[MRCTF2020]Transform

image-20231228225228337

1
byte_414040[i] ^= LOBYTE(dword_40F040[i]);

LOBYTE,提取dowrd的低字节,即十六bit。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
key =[
0x09, 0x0A, 0x0F,
0x17, 0x07,
0x18, 0x0C, 0x06,
0x01, 0x10,
0x03, 0x11, 0x20,
0x1D, 0x0B,
0x1E, 0x1B, 0x16,
0x04, 0x0D,
0x13, 0x14, 0x15,
0x02, 0x19,
0x05, 0x1F, 0x08,
0x12, 0x1A,
0x1C, 0x0E, 0x0
]#转化为字符串,加上'\0'
result=[
0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79,
0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E,
0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45,
0x6F, 0x62, 0x4D ]

print(len(key))
print(len(result))

flag=''
for x in range(32):
flag+=chr(key[x]^result[x])
print(flag)

但是这样输出的flag是乱序的nsthr30TRiTO}_p31pFs_ClCr{z4N_sl,我们再观察下函数,发现这是中括号,对输入进行了排列,且可以发现dword_40F040里的数据都是较小的。因此正确脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
key =[
0x09, 0x0A, 0x0F,
0x17, 0x07,
0x18, 0x0C, 0x06,
0x01, 0x10,
0x03, 0x11, 0x20,
0x1D, 0x0B,
0x1E, 0x1B, 0x16,
0x04, 0x0D,
0x13, 0x14, 0x15,
0x02, 0x19,
0x05, 0x1F, 0x08,
0x12, 0x1A,
0x1C, 0x0E, 0x0
]#转化为字符串,加上'\0'
result=[
0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79,
0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E,
0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45,
0x6F, 0x62, 0x4D ]

print(len(key))
print(len(result))
flag=[0]*33
tmp=''
for x in range(0,33):
tmp+=chr(key[x]^result[x])
for x in range(33):
flag[key[x]]=tmp[x]
print("".join(flag))

[MRCTF2020]Xor

image-20231230231925775

找到地址为401095的call调用的函数,将其反汇编为c代码,然后就可以将main函数反汇编。无法直接F5的原因:1.反编译器无法确定调用约定(the decompiler could not determine the calling convention) 2. 反编译器无法确定参数个数和类型

image-20240101231742951

很简单的异或

1
2
3
4
5
key='MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'
flag=''
for i in range(0,27):
flag+=chr(i^ord(key[i]))
print(flag)

[ACTF新生赛2020]usualCrypt1

换表

1
2
3
4
5
6
7
8
9
10
11
key='zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'
key=key.swapcase()
print(key)
base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
base=list(base)
for i in range (6,15):
tmp=base[i]
base[i]=base[i+10]
base[i+10]=tmp

print("".join(base))

image-20240119225308383

[HDCTF2019]Maze1

1
2
3
4
5
6
7
*******+**
******* **
**** **
** *****
** **F****
** ****
****