逆向工程 (10题)

re

easy_reverse(python反编译)bugkuctf

1740977315009-12523273-a9a2-4b1f-a210-728c167d22e7.png

1740977452894-bff09cdc-aa7d-46fe-aaba-82333148cc3b.png

1740977526408-05b225e4-05b7-4408-91ff-473d227700b5.png

1740977628433-4bfccc3c-fa25-4d59-90c2-dd6483aad3d0.png

1740977665245-7d539bc9-d042-4435-8043-793a8df1e703.png

easy_XOr(Susctf)

int __fastcall main(int argc, const char **argv, const char **envp)

{

char v4; // [rsp+Fh] [rbp-91h]

int v5; // [rsp+10h] [rbp-90h]

int i; // [rsp+14h] [rbp-8Ch]

int v7; // [rsp+18h] [rbp-88h]

int v8[24]; // [rsp+20h] [rbp-80h]

char s[24]; // [rsp+80h] [rbp-20h] BYREF

unsigned __int64 v10; // [rsp+98h] [rbp-8h]

v10 = __readfsqword(0x28u);

v8[0] = 83;

v8[1] = 116;

v8[2] = 113;

v8[3] = 96;

v8[4] = 112;

v8[5] = 99;

v8[6] = 125;

v8[7] = 78;

v8[8] = 87;

v8[9] = 103;

v8[10] = 57;

v8[11] = 110;

v8[12] = 104;

v8[13] = 82;

v8[14] = 102;

v8[15] = 106;

v8[16] = 113;

v8[17] = 32;

v8[18] = 123;

v8[19] = 125;

v8[20] = 115;

v8[21] = 104;

v5 = 0;

v4 = 1;

puts(“Mercy: What do you want to tell me?”);

scanf(“%s”, s);

v7 = strlen(s);

if ( v7 != 22 )

puts("You Are Defented;");

for ( i = 0; i < v7; ++i )

{

if ( v5 )

{

  if ( v8[i] != (i ^ s[i]) )

    v4 = 0;

  v5 = 0;

}

else

{

  if ( v8[i] != (i ^ s[i]) )

    v4 = 0;

  v5 = 1;

}

}

if ( v4 )

puts("Heros never die~Victory~");

else

puts("You Are Defented;");

return 0;

}

1740978677264-a80fb091-9ae3-4abf-9a94-b70692408b9c.png

exp

自己写个脚本提取一下数据再解密

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
a=[199,  69, 128,  83,   0,   0,   0, 199,  69, 132,
116, 0, 0, 0, 199, 69, 136, 113, 0, 0,
0, 199, 69, 140, 96, 0, 0, 0, 199, 69,
144, 112, 0, 0, 0, 199, 69, 148, 99, 0,
0, 0, 199, 69, 152, 125, 0, 0, 0, 199,
69, 156, 78, 0, 0, 0, 199, 69, 160, 87,
0, 0, 0, 199, 69, 164, 103, 0, 0, 0,
199, 69, 168, 57, 0, 0, 0, 199, 69, 172,
110, 0, 0, 0, 199, 69, 176, 104, 0, 0,
0, 199, 69, 180, 82, 0, 0, 0, 199, 69,
184, 102, 0, 0, 0, 199, 69, 188, 106, 0,
0, 0, 199, 69, 192, 113, 0, 0, 0, 199,
69, 196, 32, 0, 0, 0, 199, 69, 200, 123,
0, 0, 0, 199, 69, 204, 125, 0, 0, 0,
199, 69, 208, 115, 0, 0, 0, 199, 69, 212,
104, 0, 0, 0]
b=[]
k=0
for i in range(len(a)):
if(a[i]==0):
continue
else:
if(k!=3):
k+=1
continue
else:
b.append(a[i])
k=0
#print(b,len(b))
v5=0
v4=1
for i in range(22):
if(v5==1):
b[i]=b[i]^i
v5=0
else:
b[i]=b[i]^i
v5=0
print(chr(b[i]),end='')

baby_re(强网先锋)net逆向

1740978789540-6afedada-be0e-4aa8-b406-671f8f4d68a7.png

1740979093577-f57100d1-c7c1-4a4f-aaf4-621565c01ded.png

1740979429774-a27ec7bd-00a0-4ed4-8081-30510b3fe6d1.png

还有一种方法是修改判断次数,修改num,调试后得到flag

1740979941838-de3ee6d3-1bb7-4cc6-9a7d-214fc162d4de.png

[DASCTF 2024最后一战|寒夜破晓,冬至终章]tryre

1740979985390-12da8882-2f22-4e57-955e-2e395890a007.png

1741066532680-7379b308-bf2e-4177-9e27-d34ae1c69e7d.png

1741066682709-60a5d2e8-d428-4eb1-942c-19855c1eda0b.png

1741066761427-6dac6017-b06a-43e4-a202-f6ac148323a7.png

DASCTF{454646fa-2462-4392-82ea-5f809ad5ddc2}

[DASCTF 2024最后一战|寒夜破晓,冬至终章]刻板印象re

1741067788345-54d5222e-ed2d-424a-a1e0-6f292075463f.png

1741067953657-7c1a018b-6e60-4b6a-91db-ccf6b0338f1a.png

len=48

猜测sub_401023为copy函数

看一下sub_40126C这个加密函数

下面是比较函数

1741067987602-c7fa999a-c3bd-41bb-ade3-2416ba4391d3.png

a1就是数据串的初始地址

密文

byte_42F090=”aughter_is_poison_to_fear”;

加密逻辑在sub_401740,但是401795处有修改堆栈返回值的代码,IDA误以为后面没有代码了,nop掉这部分,就可以看到完整的伪C代码。

我说怎么原来解出来是乱码

nop掉这部分

1741069568805-cd41cea8-c021-4bb8-8de5-36e83062dcab.png

方法1、nop掉中间部分,然后修改上面机器码跳转到下面的指令

1741071536293-0aced7b9-5f95-453c-95e8-90065324b866.png

1741071593504-4f420b6d-2dba-4e05-8d75-63b0cf80697f.png

发现是XXTEA

delta是0x11451419

密钥是{What_is_this_?}

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import struct
def XTEAdecrypt(rounds, v, k):
v0 = v[0]
v1 = v[1]
delta = 0x9E3779B9
x = delta * rounds
for i in range(rounds):
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (x + k[(x >> 11) & 3])
v1 = v1 & 0xFFFFFFFF
x -= delta
x = x & 0xFFFFFFFF
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (x + k[x & 3])
v0 = v0 & 0xFFFFFFFF
# v[0] = v0
# v[1] = v1
return [v0,v1]

def xor(a,b):
return bytes([i^j for i,j in zip(a,b)])
def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))

def XXTEAdecrypt(v, k):
delta = 0x11451419
n = len(v)
rounds = 6 + 52 // (n)
x = (rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x - delta) & 0xFFFFFFFF
return v
if __name__ == '__main__':
key=[]
keys=b'{What_is_this_?}'
for i in range(4):
key.append(struct.unpack('<I',keys[i*4:i*4+4])[0])
enc=bytes.fromhex('18091C14371D162D3C05163E0203102C0E313915043A39030D132B3E06083700170B001D1C0016060717300330060A71')
enc=xor(enc,bytes.fromhex('8f6ca63f943df5d9366651d7662fb38fc0619ecee9d7e1bf13141614c2e7c33a7f94a1e7240ea75cd377fe4f11dc6923'))
encrypted=[]
for i in range(len(enc)//4):
encrypted.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
decrypted = XXTEAdecrypt(encrypted, key)
flag=b''
for i in range(len(decrypted)):
flag+=struct.pack('<I',decrypted[i])
key = [0x756F797B,0x6E69665F,0x74695F64,0x7D3F215F]
rounds = 32
enc=flag
enc=xor(enc,bytes.fromhex('DA3023E3DC398260A54468C2437ABBE450E102C28159EA1EC68B7138278394D8F48D1A2A568A4AD454DC243FB9ED7B9A'))
encrypted=[]
flag=b''
for i in range(len(enc)//4):
encrypted.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
for i in range(len(encrypted)//2):
decrypted = XTEAdecrypt(rounds,encrypted[i*2:i*2+2], key)
x=struct.pack('<2I',decrypted[0],decrypted[1])
flag+=x
print(xor(flag,b'Laughter_is_poison_to_fearLaughter_is_poison_to_fear'))
#DASCTF{You_come_to_me_better_than_all_the_good.}

例题xctf chase(nes逆向)

mapper为0

1741419256964-69856734-4fc1-42ab-9929-d319c6c1fe01.png

1741418395482-843dfd13-99ea-4389-9718-783a3594f4eb.png

1741419165702-57bad6fd-0b9c-4cac-a85f-f4fe2a9d7f28.png

看到机器码从8000

ida用二进制打开 以6502的形式

flag01

1741419767757-5cfb67c8-a43c-4092-b050-7fa0f8a78105.png

可以直接ce开挂,

1741420056271-4f8d75df-b34b-48b9-8325-9b2cb0e792dc.png

TPCTF{D0_Y0U_L1KE_

也可用FCEUX自带的cheat改动1741709266224-553180e2-fb39-44d6-a16b-2e2d6e5e2545.png

flag02

法1

经过不断调试发现AB对应的值和场景有关,每个场景对应值固定且范围普遍在0-60之间,那么尝试爆破,调整AB的值,改内存时发现会有随机性,相同的值不保证每次的闪烁结果相同,这里是尝试到0x15时看到flag2:

1741709756176-dbd26352-cb02-462d-8549-d69b24d71089.png

法2

第二段有点misc的感觉,猜测也是在内存里面只不过不会加载到屏幕上,由于每段flag开头都会有THE FLAG PT我们搜索这几个字符的tile 34 28 25,一共发现两个其实一个是第一段flag,tile D2就是代表字符2 D1也就是字符1

这段是flag1

1741710181978-c9534bf4-ebe6-4cf7-8cd9-45a6069a9013.png

1741710552358-b2720dac-228b-4429-bc6f-d7ad34761324.png

第二段是flag2

1741710162833-33cee26d-da76-4d11-87dc-0609309ade76.png

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
import binascii

data = "34282500262C21270030340ED200262F3200392F35002933000112A4000118302C2139D12ED93DD6202DD3333D00019ABDADAD6D000103B9ADAD6E000103B9ADAD6E0001030D01030001100001000F0F0F0F0F1C2C3C0F1222320F1424340F1132300F1C2C3C0F0927380F1121310F1132300F1121310F0727380F1323330F1132300F1525350F0527380F1323330F1132300F1929390F0B27380F1727370F1132300F1626360F0727380F1828380F0F29300F0F26300F0F24300F0F213000FF490008FF4A0000074B0008074C008000FF4D0108FF4E0100074F01080750018000FF4D0208FF4E0200074F02080750028000FF4D0308FF4E0300074F03080750038077F488F499F4AAF4B0E717F4E1E827F4ACEA37F4C8EC37F448EF37F49BF217F4280044280044280044280044204F10205010205110FF2C2536252C1A000027252D331A0000000F000000002C293625331A000304037A7B7C7D7C7D7E7F80819A9B867B8788898A8B8C8D7D807D909192939495967F94959C9500000000000058E5ADE40BE7FEE48D1C038E1D038D23038E240388B9FFFF8D2D0388B9FFFF8D2C038C2F0320FFFFA0FFD0E860000000000000"

data = binascii.a2b_hex(data)

table = {}
str_1 = ord("A")
for i in range(0x21,0x3B):
table[i] = chr(str_1)
str_1 += 1
table[0x20] = "@"
table[0] = " "
table[0x3d] = "_"
str_1 = ord("0")
for i in range(0xD0,0xDA):
table[i] = chr(str_1)
str_1 += 1
flag = ""

for i in range(len(data)):
for key,value in table.items():
if data[i] == key:
flag += value
print(flag)

1741710467489-0446e5ee-e3bc-4afd-a9bc-27269875e8eb.png

THE FLAG PT2 FOR YOU IS PLAY1N9_6@M3S_ LBRDTRPLGXAQRPAQGXCSRPEUGXCSRPIYGXGWRPFVGXHXIPFPDPAP GWWWH H H H @@@LEVEL GEMS LIVES CDMLO@0

flag03

看ppu viewer

1741708666856-c2b8147d-30a2-4fe3-91ba-9775a25f2426.png

ON_Y0UR_N3S?}

FLAG:TPCTF{D0_Y0U_L1KE_PLAY1N9_6@M3S_ ON_Y0UR_N3S?}

A_game-MOECTF

看了一下是个数独题目

1748414863970-eee04499-9ae7-495c-80cf-6379bb4c403d.png

提取box,顺便整理一下

1748415326666-9f8543c6-d1a1-4bb9-9c55-af44a9198b9d.png

https://sudokusolving.bmcx.com/

1748415414031-78f0bc0f-c726-4d51-8089-5c774b6c3a01.png

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
box=[
0, 0, 5, 0, 0, 4, 3, 6, 0,
0, 0, 0, 0, 5, 0, 0, 2, 4,
0, 4, 9, 6, 7, 0, 0, 0, 0,
1, 0, 6, 0, 2, 0, 0, 3, 0,
9, 0, 0, 7, 0, 0, 1, 0, 8,
0, 3, 0, 0, 0, 5, 0, 9, 0,
2, 0, 0, 5, 0, 7, 0, 0, 9,
7, 0, 4, 0, 0, 0, 8, 0, 0,
0, 9, 0, 0, 4, 0, 0, 0, 6]
'''for i in range(len(box)):
print(box[i],end='')'''
magic=[0x6B,0x2,0x66,0x70,0x44,0x69,0x7E,0x6E,0x43,0x4A,0x78,0x4A,0x6D,0x60,0x56,0x0,0x51,0x59,0x50,0x43,0x50,0x51,0x6D,0x74,0x2,0x55,0x50,0x52,0x6E,0x6F,0x79,0x40,0x5D,0x4B,0x1E,0x19,0x1C,0x74,0x3,0x54,0x7,0x4C,0x52,0x6A,0x60,0x50,0x58,0x40,0x58,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0]
buf1='825914367671358924349672581186429735952763148437185692268537419714296853593841276'
buf2='005004360000050024049670000106020030900700108030005090200507009704000800090040006'
buf3='8291767138932581849755263447186268341129653538127'
for i in range(len(buf1)):
if buf1[i] !=buf2[i]:
print(buf1[i],end='')
print('\n')
#print(len(buf),len(magic))
for k in range(len(buf3)):
flag=ord(buf3[k])^magic[k]
print(chr(flag),end='')
#flag='moectf{S0_As_I_prAy_Un1imited_B1ade_WOrks---E1m1ya_Shiro}'

FeatureExtraction-Litctf2025

1748482301251-90b681db-daac-4b45-814c-503ac2502e4e.png

题目提示要特征提取,可能是动调提取44位密文

看加密函数

1748483247730-c9cce732-284c-4fb2-877d-9034d3c357e9.png

key

1748483413217-2b54e9b3-3c6f-487c-875a-43ca42128435.png

1748483476083-756616be-7ab2-46da-b162-f364d63405a1.png

下完断点后提取数据

1748483683733-ed939bcf-8a63-4a84-8ec8-785bb78a7cfb.png

1748483704369-9621be44-8c96-4237-97e9-4bb9978c539b.png

数据以dword形式提取出来

1748484162961-a707b2c0-1bf8-4c34-a53d-d705f1709245.png

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
key = [ord(c) for c in "LitCTF2025"]

a = [
5776, 15960, 28657, 34544, 40294, 43824, 51825, 53033, 58165, 58514,
61949, 56960, 53448, 49717, 47541, 45519, 40607, 40582, 38580, 42320,
41171, 41269, 39370, 44224, 48760, 49558, 48128, 46531, 47088, 46181,
46707, 46879, 48098, 52047, 53933, 56864, 60564, 64560, 66744, 63214,
60873, 58245, 55179, 56857, 51532, 44308, 32392, 27577, 19654, 14342,
11721, 9112, 6625
]

b = [0] * 44
for k in range(44):
s = a[k]
for j in range(1, min(10, k + 1)):
s -= b[k - j] * key[j]
if s % key[0] != 0:
print("Invalid division at k =", k)
b[k] = s // key[0]

flag = ''
for x in b:
flag += chr(x)

print(flag)

harre-鸿蒙逆向了解

主要还是熟悉这个hap怎么逆向的

进去后直接就看到一个base64变表加密

1747036391551-833e913b-1e3a-4554-afd8-edaadb09221e.png

1747036402437-f6099d0d-c0b1-4744-9b67-e4a8c0bc4891.png

1747036261199-f5e1e789-eb78-4835-be0f-3a1b09eae051.png

Android Cracker-MOECTF

看一下然后放到模拟器里试试

好像直接看到flag了

1748484698529-102b5c77-6008-4767-ac3f-c60b878963f5.png

ART-MOECTF

看一下特征码没修改,那就直接脱壳逆

1748485056264-ed916702-effa-4f38-9a7b-453fb0c73097.png

1748485177854-2fa17bb7-42f4-486e-80e2-43de661d4ddc.png

1748485231288-063e1c07-4d9c-4d97-abf7-c7af98211ad9.png

dfs,不然是多解乱码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tmp=[0]*27+[125]
enc=[2, 24, 15, 248, 25, 4, 39, 216, 235, 0,
53, 72, 77, 42, 69, 107, 89, 46, 67, 1,
24, 92,9, 9, 9, 9, 181, 125]
#Str1[i - 1] ^= (Str1[i - 1] % 17 + Str1[i]) ^ 25
def dfs(index):
if index ==0:
for j in tmp:
print(chr(j),end='')
print()
else:
for i in range(255):
if (i^25)^(i%17+tmp[index])==enc[index-1]:
tmp[index-1]=i
dfs(index-1)
dfs(27)

更新: 2025-06-04 14:39:27
原文: https://www.yuque.com/chaye-apqbl/vsc85q/dc9gz10hoac0q8rq


http://example.com/2026/01/19/WP/2025/逆向工程(10题)/
Author
chaye
Posted on
January 19, 2026
Licensed under