-
-
[原创]2021 KCTF 春季赛 第二题 南冥神功 wp
-
2021-5-11 15:58 3824
-
初步分析
windows32位程序.
定位到main函数, 004B3CC0.
观察后看出是个走迷宫游戏.
分析游戏逻辑
整理main函数的代码
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | char g_szHex[] = "012345" "6789AB" "CDEFGH" "IJKLMN" "OPQRST" "UVWXYZ" ; DWORD g_nHexTableSize = 0x24 ; / / sizeof(g_szHex) #define ROW 10 char g_szMaze[][ROW] = { { 'S' , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 }, { 1 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 }, { 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 }, { 0 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 0 }, { 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 }, { 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 }, { 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 }, { 0 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 }, { 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 }, }; int main( int argc, const char * * argv, const char * * envp) { char ch; int nInputIdx; int nHexIdx; unsigned int nX; unsigned int nY; int nStep1; int nStep2; int flag; int nCount0; char * pNow; char * pNextRow; char szInput[ 76 ] = { 0 }; printf( "Input your code: " ); scanf( "%48s" , szInput); if (strlen(szInput) < = 0x30 ) { nX = 0 ; nY = 0 ; nInputIdx = 0 ; ch = szInput[nInputIdx]; if (ch ! = 0 ) { do { if (g_nHexTableSize > 0 ) { / / get nHexIdx nHexIdx = 0 ; do { if (g_szHex[nHexIdx] = = ch) break ; } while (g_nHexTableSize ! = + + nHexIdx); nStep1 = 5 - (nHexIdx + nInputIdx) % 6 ; nStep2 = (nInputIdx + nHexIdx / 6 ) % 6 ; switch (nStep1) { case 1 : / / x + + + + nX; break ; case 2 : / / if y = = red x + + ,y + + flag = (nY + + & 1 ) = = 0 ; nX + = flag; break ; case 3 : / / if y = = green x - - ,y + + flag = (nY + + & 1 ) ! = 0 ; nX - = flag; break ; case 4 : / / x - - - - nX; break ; case 5 : / / if y = = green x - - ,y - - flag = (nY - - & 1 ) ! = 0 ; nX - = flag; break ; default: / / if y = = red x + + ,y - - flag = (nY - - & 1 ) = = 0 ; nX + = flag; break ; } / / 检查越界 if (nX > 9 ) goto LABEL_F; if (nY > 8 ) goto LABEL_F; if (g_szMaze[nY][nX] = = 1 ) goto LABEL_F; g_szMaze[nY][nX] = 1 ; switch (nStep2) { case 1 : / / x + + + + nX; break ; case 2 : / / if y = = red x + + ,y + + flag = (nY + + & 1 ) = = 0 ; nX + = flag; break ; case 3 : / / if y = = green x - - ,y + + flag = (nY + + & 1 ) ! = 0 ; nX - = flag; break ; case 4 : / / x - - - - nX; break ; case 5 : / / if y = = green x - - ,y - - flag = (nY - - & 1 ) ! = 0 ; nX - = flag; break ; default: / / if y = = red x + + ,y - - flag = (nY - - & 1 ) = = 0 ; nX + = flag; break ; } / / 检查越界 if (nX > 9 ) goto LABEL_F; if (nY > 8 ) goto LABEL_F; if (g_szMaze[nY][nX] = = 1 ) goto LABEL_F; g_szMaze[nY][nX] = 1 ; } } while ( 0 ! = (ch = szInput[ + + nInputIdx])); } / / 检查迷宫, 迷宫全部为 1 则验证通过 pNow = (char * )g_szMaze; nCount0 = 0 ; do { pNextRow = pNow + ROW; do nCount0 + = * pNow + + = = 0 ; while (pNextRow ! = pNow); } while (&g_szMaze[ 0 ][ 0 ] + sizeof(g_szMaze) ! = (char * )pNextRow); if (nCount0 = = 0 ) { printf( "Good job!" ); return 0 ; } } LABEL_F: printf( "Try again..." ); return 0 ; } |
迷宫如下:
迷宫中总共有6中走法(指令0~5).
在红色格子和绿色格子上每个指令表示的走法不同, 见下表格:
迷宫走法:
根据上面走法的表格得出通关指令为:
1 | 1234321234321101210050543450501210121234322321 |
转换输入的字符串
输入的字符串, 每一个字符对应迷宫中走两步.
1 2 3 4 5 | nStep1 = 5 - (nHexIdx + nInputIdx) % 6 ; nStep2 = (nInputIdx + nHexIdx / 6 ) % 6 ; / / 推出: InputIdx_X = (nStep1 - nHexIdx) % 6 ; InputIdx_Y = (nStep2 - nHexIdx) % 6 ; |
把通关指令每2个分一组, 算出InputIdx_X和InputIdx_Y,查下表得出要输入的字符串.
1 | GJ0V4LA4VKEVQZSVCNGJ00N |
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
最后于 2021-5-12 00:08
被KuCha128编辑
,原因:
赞赏
他的文章
谁下载
看原图