南邮ctf php decode,南邮CTF RE5——MAZE

MAZE拖进winhex发现是elf文件,ida64打开,调出main函数,反编译:

__int64 __fastcall main(__int64 a1, char **a2, char **a3)

{

signed __int64 v3; // rbx@4

signed int v4; // eax@5

bool v5; // bp@5

bool v6; // al@8

const char *v7; // rdi@19

__int64 v9; // [sp+0h] [bp-28h]@1

v9 = 0LL;

puts("Input flag:");

scanf("%s", &s1, 0LL);

if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + 24) != 125 )

{

LABEL_22:

puts("Wrong flag!");

exit(-1);

}

v3 = 5LL;

if ( strlen(&s1) - 1 > 5 )

{

while ( 1 )

{

v4 = *(&s1 + v3);

v5 = 0;

if ( v4 > 78 )

{

v4 = (unsigned __int8)v4;

if ( (unsigned __int8)v4 == 'O' )

{

v6 = sub_400650((_DWORD *)&v9 + 1); //v6为v9的下一个字节

goto LABEL_14;

}

if ( v4 == 'o' )

{

v6 = sub_400660((int *)&v9 + 1); //v6为v9的下一个字节

goto LABEL_14;

}

}

else

{

v4 = (unsigned __int8)v4;

if ( (unsigned __int8)v4 == '.' )

{

v6 = sub_400670(&v9); //v6为v9的本字节

goto LABEL_14;

}

if ( v4 == '0' )

{

v6 = sub_400680((int *)&v9); //v6为v9

LABEL_14:

v5 = v6;

goto LABEL_15;

}

}

LABEL_15:

if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v9), v9) )

goto LABEL_22;

if ( ++v3 >= strlen(&s1) - 1 )

{

if ( v5 )

break;

LABEL_20:

v7 = "Wrong flag!";

goto LABEL_21;

}

}

}

if ( *(&asc_601060[8 * (signed int)v9] + SHIDWORD(v9)) != 35 ) ///v9为行数

goto LABEL_20;

v7 = "Congratulations!";

LABEL_21:

puts(v7);

return 0LL;

}

/SHIDWORD///查了一下IDA的宏定义 #define HIDWORD(x) (((_DWORD)&(x)+1))

太长了,简单看了一下,对输入的字符串限制了24的长度,保证以“nctf{”开头,“}”结尾。换成graph view:

3f4e1f8899efd3be84616bd81b917ea2.png

可以看到他根据判断是否为'.','0','o','O'来决定进行什么操作

bool __fastcall sub_400650(_DWORD *a1)//(_DWORD *)&v9 + 1

{

//为O(0x4f)的时候

int v1; // eax@1

v1 = (*a1)--;

return v1 > 0;

}

bool __fastcall sub_400660(int *a1)//(int *)&v9 + 1

{

///为o的时候

int v1; // eax@1

v1 = *a1 + 1;

*a1 = v1;

return v1 < 8;

}

bool __fastcall sub_400670(_DWORD *a1)//&v9

{

//为.的时候

int v1; // eax@1

v1 = (*a1)--;

return v1 > 0;

}

bool __fastcall sub_400680(int *a1)//(int *)&v9

{

//为0(0x30)的时候

int v1; // eax@1

v1 = *a1 + 1;

*a1 = v1;

return v1 < 8;

}

37cb4f6833fafb0923c016528e373672.png

猜测8个字节为一行,v9表示竖向,v9的下一个字节为横向,O为左移一位,o为右移一位,.为上移一位,0为下移一位。根据下图,判断出偏移为601060的地方放着我们要比较的东西,他依次把数据交给寄存器EDI,调用函数:

sub_400690 proc near

movsxd rax, esi

add rax, rdi

movsxd rcx, edx

movzx eax, byte ptr [rax+rcx*8]

cmp eax, 20h

setz cl

cmp eax, 23h

setz al

or al, cl

retn

sub_400690 endp

MAZE这个题目就是迷宫了,上面的函数说明了在将EDI中的数与20h和23h比较,不符合就GG,来看看我们需要走的那个迷宫,就是地址为0000000000601060的HEX:

a2e3d183f744cfc9a1c636ec8a0f0f10.png

整理一下得到8X8的矩阵:

e7b0e21498b531cf63d0975fc05ecc31.png

按照函数规则走一下

316ad7cc8b57e51ea3824f3481669da9.png

将走的线路换成上诉的四个字符,得到o0oo00O000oooo..OO即为flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值