
老样子,下载、查壳、32位、IDA打开

看到红色地址,
.text:004010D0 jz short near ptr loc_4010D4+1
.text:004010D2 jnz short near ptr loc_4010D4+1
明显又是花指令,跳转到
.text:004010D4 loc_4010D4+1
所以
.text:004010D4 loc_4010D4: ; CODE XREF: .text:004010D0↑j
大概率就是脏字节, 光标放到这一行,然后按U,右键NOP掉,再按C,可以看到汇编程序正常了。
左侧还是红的,说明需要重新分析,按P,再按f5,得到伪码
进行代码分析
1. 输入读取
sub_401020("please input flag\n", v8);
sub_401050("%s", (char)Arglist);
v3 = strlen(Arglist);
- 打印提示语,读取用户输入的 flag 字符串,存入
Arglist数组。 - 计算并获取输入字符串的总长度。v3是用户输入字符串的长度。
2. 第一步变换:奇偶位两两交换
for ( i = 0; i < v3 / 2; ++i )
{
v5 = Arglist[2 * i];
Arglist[2 * i] = Arglist[2 * i + 1];
Arglist[2 * i + 1] = v5;
}
- 以 2 个字符为一组,将每组内前后两个字符交换位置。
- 举例:原始字符串
abcdef→ 交换后变为badcfe(第 0 位与第 1 位交换、第 2 位与第 3 位交换,以此类推)。 - 特性:这是自逆操作,对结果再执行一次完全相同的交换,就会还原为原始字符串。
for ( j = 0; j < strlen(Arglist); ++j )
Arglist[j] ^= 0x30u;
- 对字符串中每个字符的 ASCII 码,与固定值
0x30执行按位异或运算。 - 特性:异或运算具有自反性,同一个值连续异或两次会还原为原值。
v7 = strcmp(Arglist, "c~scvdzKCEoDEZ[^roDICUMC");
if ( !v7 )
{
sub_401020("yes", v9);
exit(0);
}
- 将经过两步加密后的字符串,与内置密文
c~scvdzKCEoDEZ[^roDICUMC逐字节对比。 - 完全一致则输出
yes,校验通过;否则输出error。
写解密脚本:
chiper="c~scvdzKCEoDEZ[^roDICUMC"
flag=""
step1=""
for i in range(len(chiper)):
s = ord(chiper[i]) ^ 0x30
step1 += chr(s)
flag=list(step1)
for j in range(len(chiper)//2):
temp = flag[2*j]
flag[2*j] = flag[2*j+1]
flag[2 * j + 1] = temp
print(''.join(flag))
运行得到,原路逆向就行

774

被折叠的 条评论
为什么被折叠?



