-
-
[原创]BUUCTF逆向题:[ACTF新生赛2020]Oruga
-
2022-3-27 17:33 8828
-
1.基本信息探查:
1.EXEinfo:
2.运行一下:
2.IDA分析:
1.主函数分析:
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 | __int64 __fastcall main( int a1, char * * a2, char * * a3) { __int64 result; / / rax int i; / / [rsp + 0h ] [rbp - 40h ] char s1[ 6 ]; / / [rsp + 4h ] [rbp - 3Ch ] BYREF char s2[ 6 ]; / / [rsp + Ah] [rbp - 36h ] BYREF char s[ 40 ]; / / [rsp + 10h ] [rbp - 30h ] BYREF unsigned __int64 v8; / / [rsp + 38h ] [rbp - 8h ] v8 = __readfsqword( 0x28u ); memset(s, 0 , 0x19uLL ); printf( "Tell me the flag:" ); scanf( "%s" , s); strcpy(s2, "actf{" ); for ( i = 0 ; i < = 4 ; + + i ) s1[i] = s[i]; s1[ 5 ] = 0 ; if ( !strcmp(s1, s2) ) { if ( (unsigned __int8)sub_78A(s) ) printf( "That's True Flag!" ); else printf( "don't stop trying..." ); result = 0LL ; } else { printf( "Format false!" ); result = 0LL ; } return result; } |
第一个for循环是将输入的字串的前5个字符拿出来和“actf{”进行比较,配对成功则调用sub_78A()
函数
2.sub_78A分析:
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 | _BOOL8 __fastcall sub_78A(__int64 a1) { int v2; / / [rsp + Ch] [rbp - Ch] int v3; / / [rsp + 10h ] [rbp - 8h ] int v4; / / [rsp + 14h ] [rbp - 4h ] v2 = 0 ; v3 = 5 ; v4 = 0 ; while ( byte_201020[v2] ! = 0x21 ) { v2 - = v4; if ( * (_BYTE * )(v3 + a1) ! = 'W' || v4 = = - 16 ) { if ( * (_BYTE * )(v3 + a1) ! = 'E' || v4 = = 1 ) { if ( * (_BYTE * )(v3 + a1) ! = 'M' || v4 = = 16 ) { if ( * (_BYTE * )(v3 + a1) ! = 'J' || v4 = = - 1 ) return 0LL ; v4 = - 1 ; / / J表示左移 } else { v4 = 16 ; / / M表示下移 } } else { v4 = 1 ; / / E表示右移 } } else { v4 = - 16 ; / / W表示上移 } + + v3; while ( !byte_201020[v2] ) / / 当前值为 0 则继续循环 { if ( v4 = = - 1 && (v2 & 0xF ) = = 0 ) / / 当前在最左边一列的时候,不能过左移 return 0LL ; if ( v4 = = 1 && v2 % 16 = = 15 ) / / 当前在最右边一列的时候,不能够右移 return 0LL ; if ( v4 = = 16 && (unsigned int )(v2 - 240 ) < = 0xF ) / / 在最后一行时,不能下移 return 0LL ; if ( v4 = = - 16 && (unsigned int )(v2 + 15 ) < = 0x1E ) / / 在第一行,不能上移 return 0LL ; v2 + = v4; / / 当值为 0 就一直移动,但要注意退出循环时一定已经处于不满 } / / 的状态所以对于走迷宫来说时多移动了一次,在 12 行做了一 } / / 个往后退一步的处理 return * (_BYTE * )(v3 + a1) = = 125 ; } |
这里看到一个迷宫题的特征就是13到19行的四个字母,发现这个点后就去找地图,发现byte_201020里面的值:
通过v4要么加16,要么加1,和这个数组的大小为256可知,这是张16*16的地图,直接去Hex窗口里看:
大概是个这么个走法:
转换成字母就是:MEWEMEWJMEWJM
flag为:flag{MEWEMEWJMEWJM}
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
看原图