首页
社区
课程
招聘
[原创]2021 KCTF 春季赛 第二题 南冥神功 wp
发表于: 2021-5-11 15:58 4500

[原创]2021 KCTF 春季赛 第二题 南冥神功 wp

2021-5-11 15:58
4500

windows32位程序.
定位到main函数, 004B3CC0.
观察后看出是个走迷宫游戏.

整理main函数的代码

迷宫如下:

迷宫中总共有6中走法(指令0~5).
在红色格子和绿色格子上每个指令表示的走法不同, 见下表格:

迷宫走法:

根据上面走法的表格得出通关指令为:

输入的字符串, 每一个字符对应迷宫中走两步.

把通关指令每2个分一组, 算出InputIdx_X和InputIdx_Y,查下表得出要输入的字符串.

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;
}
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:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2021-5-12 00:08 被KuCha128编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//