• 前言:仅供参考,笔者刚学,言语之间还有很多错误,欢迎交流和指正

● 题目

● 查壳,无壳,32位

● 放入ida32,看导航条棕红色的地方

● 点击去到那里,有两个爆红的,是花指令

● 把两个jmp改成nop

● 在红色开始处选中按p,转换函数(两个花指令都是)
○ 加密函数1

○ 加密函数2

● 按F5进去看伪代码
○ 加密函数1,for循环将 a1[i + 1] 的值加到 a1[i] 上,然后将这个加法的结果赋值给 a1[i]。

○ 加密函数2,将数组 a1 中索引为 i 的元素值乘以16后与该元素值右移4位的结果进行按位或(OR)操作,并将最终结果赋值给 a1[i]。

● 接下来是要找他的密文,一开始不知道在哪,后面去看了他的main函数

○ sub_401000是加密函数1,sub_401080是加密函数2(想想其实一开始不知道这是一道花指令的题的话,就会先找main函数,得到密文,然后会发现这两函数里有花指令,再去清除花指令,破解密文,得到flag)
○ 密文应该在这,因为此句下面的else语句说了再尝试,可以推断出上面的是密文。都点进去看看

■ sub_401110
![](https://img2024.cnblogs.com/blog/3483850/202407/3483850-20240726144500390-877037676.png)

■ unk_403000
![](https://img2024.cnblogs.com/blog/3483850/202407/3483850-20240726144605882-511893943.png)

○ unk_403000是密文,shift+E提取

● shift+F2写exp,逆过来就行

enc=[ 205,  77, 140, 125, 173,  30, 190,  74, 138, 125, 188, 124,
252,  46,  42, 121, 157, 106,  26, 204, 61,  74, 248,  60, 121,
105,  57, 217, 221, 157, 169, 105,  76, 140, 221,  89, 233, 215]
## 初始化flag列表,长度与enc相同
flag=[0]*len(enc)

for i in range (len(enc)):
    #0xff 用作掩码,与操作的结果确保数值在一个字节的范围内(即0到255之间)
    flag[i]=((enc[i]//16)|(enc[i]<<4))&0xff  

for i in range(len(flag)-1, 0, -1):
    flag[i-1]-=flag[i]

print(bytes(flag)) 

range(len(flag)-1, 0, -1): 这是一个 range 函数调用,它生成一个从 len(flag)-1 到 0 的整数序列,步长为 -1。这意味着它将生成从 flag 列表的倒数第一个索引开始的递减序列。

len(flag)-1: 这是 flag 列表的最后一个元素的索引。len(flag) 给出 flag 的长度,减去1得到最后一个元素的索引。

0: 这是循环的结束索引,但不包含0。由于步长是-1,循环会在索引达到0之前停止。

-1: 这是步长,表示每次迭代索引减少1。