-
-
[HNCTF 2022 WEEK2]e@sy_flower
-
发表于:
2023-9-24 17:16
3784
-
[HNCTF 2022 WEEK2]e@sy_flower
花指令分析
如果没接触过花指令,先看这个博客,大致了解一下花指令
https://www.cnblogs.com/Here-is-SG/p/15802040.html
点击此处下载附件
查壳
32位,无壳
去除花指令
用32位ida打开,就看到红色字体的XREF(非自然程序流程,可以用它对程序流进行跟踪和控制,估计以后有的学了),这时候F5反编译,发现没有反应,再联系题目,推测有花指令(也就是红色字体的XREF)影响ida进行编译。
又看到它附近有jz和jnz
我们找到地址loc_4010D4,然后按u
可以发现loc_4010D4+1的+1没了,变成函数unk_4010D5
然后从有XREF的这一行选中下面所有数据,按c,选择Analyze
按完后,就变成正常的汇编代码了
然后需要把db 0E9h进行nop处理,使数据变成90,再按c,变成汇编代码
再在上面翻,找到主函数并在此处按p,解析成函数,即可F5了
F5,查看伪代码
分析代码
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 | int __cdecl __noreturn main( int argc, const char **argv, const char **envp)
{
signed int v3;
int i;
char v5;
unsigned int j;
int v7;
char v8;
char v9;
char Arglist[48];
sub_401020( "please input flag\n" , v8);
sub_401050( "%s" , ( char )Arglist);
v3 = strlen (Arglist);
for ( i = 0; i < v3 / 2; ++i )
{
v5 = Arglist[2 * i];
Arglist[2 * i] = Arglist[2 * i + 1];
Arglist[2 * i + 1] = v5;
}
for ( j = 0; j < strlen (Arglist); ++j )
Arglist[j] ^= 0x30u;
v7 = strcmp (Arglist, "c~scvdzKCEoDEZ[^roDICUMC" );
if ( v7 )
v7 = v7 < 0 ? -1 : 1;
if ( !v7 )
{
sub_401020( "yes" , v9);
exit (0);
}
sub_401020( "error" , v9);
exit (0);
}
|
这段代码的意思是将flag先后经过两次for循环加密,最后得到字符串c~scvdzKCEoDEZ[^roDICUMC
写脚本
1 2 3 4 5 6 7 8 9 10 11 12 | flag = [0] * 24
tmp = 'c~scvdzKCEoDEZ[^roDICUMC'
for i in range(0,24):
flag[i] = chr(ord(tmp[i]) ^ 48)
for i in range(0,12):
v5 = flag[2 * i]
flag[2 * i] = flag[2 * i + 1]
flag[2 * i + 1] = v5
print( "" .join(flag))
|
写这个脚本遇到的困难:
解决:
第一步:将flag初始化为固定长度的列表:flag = [0] * 24。
在Python中,[0] * 24
表示创建一个包含24个0的列表。这种语法可以用来快速创建指定长度的列表,并将其初始化为相同的值。在这个例子中,我们创建了一个长度为24的列表,并将其初始化为0。这个列表在后续的代码中被用来存储计算结果。
第二步:先将tmp字符串转换成整数,即加个ord()函数,然后与数字进行异或,异或完之后再转换成字符,即加个chr()函数。
ord()函数主要用于将字符转换为整数,即获取ASCII给定字符的值;返回的结果是对应字符的ASCII码;
chr()函数是ord()函数的配对函数,主要用一个范围内的整数作参数,返回的结果是对应的字符,可以用十进制或者十六进制。
解决:
使用Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
这样就好多了
flag:**NSSCTF{Just_junk_Bytess}**
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课