首页
社区
课程
招聘
[原创]南冥神功
发表于: 2021-5-12 11:32 5997

[原创]南冥神功

2021-5-12 11:32
5997

通过阅读上述代码,我们知道这个算法的流程如下:

遍历我们输入的Flag值,每次取1个字母

计算取出的字母在g_szStr数组中的下标值,为nStrIdx

按照以下公式计算出两个Switch值

根据Swicth中的值,去改变byte_4B7080二维数组中的行列坐标值

最后若byte_4B7080数组中的值全部不为0,则说明Flag有效

通过阅读源代码得知,我们输入的Flag中的每个单个字母会影响Switch的值,进而影响在byte_4B7080数组中取出的值

根据Switch修改的nRow nCol,要满足

1

每个字母,会计算出两个Switch值,进而得到两个坐标

先来计算Flag的第一个字母

如行走路线为上图,则前两个坐标为(0, 1), (1, 2)

根据坐标初始值为(0, 0), 以及上述Switch影响坐标的规则,可以逆向推出两个Switch的值分别为 1 2

根据下述代码,得到Flag的第一个字母

最后按照上述路线图全部走完,利用上述代码计算单个Flag值,将其拼接起来就是有效的Flag

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
char g_szStr[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int g_StrLen = 0x24;
 
char byte_4B7080[] =
{
  0x53, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
  0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
  0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
  0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00
};
 
//计算cFlag在g_szStr中的下标
bool LuoCalcStrIndex(char cFlag, int& nStrIndex)
{
    bool bFlag = false;
    for (int i = 0; i < g_StrLen; i++)
    {
        if (g_szStr[i] == cFlag)
        {
            bFlag = true;
            nStrIndex = i;
        }
 
    }
 
    return bFlag;
}
 
int main()
{
    char szFlag[80] = {};
    memset(szFlag, 0, sizeof(szFlag));
 
    printf("Input your code: \r\n");
    scanf("%s", szFlag);
 
    int nStrIdx = 0;
    int nFlagIdx = 0;
    char cFlag = szFlag[0];
    int nSwitch = 0;
 
    int v7 = 0;
    int v8 = 0;
    int v12 = 0;
    char* v13 = NULL;
    int v17 = 0;
    int v18 = 0;
    int v19 = 0;
    int v20 = 0;
    int v22 = 0;
 
    unsigned int nCol = 0;
    unsigned int nRow = 0;
 
    int nFlagLen = strlen(szFlag);
    if (nFlagLen > 0x30)
    {
        printf("Try again...\r\n");
        return 0;
    }
 
    int i = 0;
    for (nFlagIdx = 0; nFlagIdx < nFlagLen; )
    {
        //计算cFlag在g_szStr中的下标
        if (!LuoCalcStrIndex(cFlag, nStrIdx))
        {
            printf("cFlag = %c 不在g_szStr数组中\r\n", cFlag);
            system("pause");
            return 0;
        }
 
        v20 = (nFlagIdx + nStrIdx / 6) % 6;
        nCol = v22;
        nSwitch = 5 - (nFlagIdx + nStrIdx) % 6;
 
        for (int i = 0; ;i = 1)
        {
            switch (nSwitch)
            {
            case 1:
                ++nCol;                              //++
                break;
            case 2:
                v17 = (nRow++ & 1) == 0;             //偶数行, 行++ ++
                nCol += v17;                         //奇数行, 行++ 列不变
                break;
            case 3:
                v12 = (nRow++ & 1) != 0;            //奇数行, 行++ --
                nCol -= v12;                        //偶数行, 行++ 列不变
                break;
            case 4:
                --nCol;                             //--
                break;
            case 5:
                v19 = (nRow-- & 1) != 0;            //奇数行, 行-- --
                nCol -= v19;                        //偶数行, 行-- 列不变
                break;
            default:
                v18 = (nRow-- & 1) == 0;            //偶数行, 行-- ++
                nCol += v18;                        //奇数行, 行-- 列不变
                break;
            }
 
            if (nCol > 9)
            {
                printf("Try again...\r\n");
                return 0;
            }
 
            if (nRow > 8)
            {
                printf("Try again...\r\n");
                return 0;
            }
 
            v13 = &byte_4B7080[0xA * nRow + nCol];
            if (*v13)
            {
                printf("Try again...\r\n");
                return 0;
            }
            *v13 = 1;
 
            if (i == 1)
            {
                ++nFlagIdx;
                v22 = nCol;
                cFlag = szFlag[nFlagIdx];
                break;
            }
 
            nSwitch = v20;
        }
 
    }
 
    int nSize = sizeof(byte_4B7080);
    bool bFlag = true;
    for (int i = 0; i < nSize; i++)
    {
        if (byte_4B7080[i] == 0)
        {
            bFlag = false;
        }
    }
 
    if (bFlag == true)
    {
        printf("Good job!\r\n");
    }
    else
    {
        printf("Try again...\r\n");
    }
 
    system("pause");
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
char g_szStr[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int g_StrLen = 0x24;
 
char byte_4B7080[] =
{
  0x53, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
  0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
  0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
  0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00
};
 
//计算cFlag在g_szStr中的下标
bool LuoCalcStrIndex(char cFlag, int& nStrIndex)
{
    bool bFlag = false;
    for (int i = 0; i < g_StrLen; i++)
    {
        if (g_szStr[i] == cFlag)
        {
            bFlag = true;
            nStrIndex = i;
        }
 
    }
 
    return bFlag;
}
 
int main()
{
    char szFlag[80] = {};
    memset(szFlag, 0, sizeof(szFlag));
 
    printf("Input your code: \r\n");
    scanf("%s", szFlag);
 
    int nStrIdx = 0;
    int nFlagIdx = 0;
    char cFlag = szFlag[0];
    int nSwitch = 0;
 
    int v7 = 0;
    int v8 = 0;
    int v12 = 0;
    char* v13 = NULL;
    int v17 = 0;
    int v18 = 0;
    int v19 = 0;
    int v20 = 0;
    int v22 = 0;
 
    unsigned int nCol = 0;
    unsigned int nRow = 0;
 
    int nFlagLen = strlen(szFlag);
    if (nFlagLen > 0x30)
    {
        printf("Try again...\r\n");
        return 0;
    }
 
    int i = 0;
    for (nFlagIdx = 0; nFlagIdx < nFlagLen; )
    {
        //计算cFlag在g_szStr中的下标
        if (!LuoCalcStrIndex(cFlag, nStrIdx))
        {
            printf("cFlag = %c 不在g_szStr数组中\r\n", cFlag);
            system("pause");
            return 0;
        }
 
        v20 = (nFlagIdx + nStrIdx / 6) % 6;
        nCol = v22;
        nSwitch = 5 - (nFlagIdx + nStrIdx) % 6;
 
        for (int i = 0; ;i = 1)
        {
            switch (nSwitch)
            {
            case 1:
                ++nCol;                              //++
                break;
            case 2:
                v17 = (nRow++ & 1) == 0;             //偶数行, 行++ ++
                nCol += v17;                         //奇数行, 行++ 列不变
                break;
            case 3:
                v12 = (nRow++ & 1) != 0;            //奇数行, 行++ --
                nCol -= v12;                        //偶数行, 行++ 列不变
                break;
            case 4:
                --nCol;                             //--
                break;
            case 5:
                v19 = (nRow-- & 1) != 0;            //奇数行, 行-- --
                nCol -= v19;                        //偶数行, 行-- 列不变
                break;
            default:
                v18 = (nRow-- & 1) == 0;            //偶数行, 行-- ++
                nCol += v18;                        //奇数行, 行-- 列不变
                break;
            }
 
            if (nCol > 9)
            {
                printf("Try again...\r\n");
                return 0;
            }
 
            if (nRow > 8)
            {
                printf("Try again...\r\n");
                return 0;
            }
 
            v13 = &byte_4B7080[0xA * nRow + nCol];
            if (*v13)
            {
                printf("Try again...\r\n");
                return 0;
            }
            *v13 = 1;
 
            if (i == 1)
            {
                ++nFlagIdx;
                v22 = nCol;
                cFlag = szFlag[nFlagIdx];
                break;
            }
 
            nSwitch = v20;
        }
 
    }
 

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

最后于 2021-5-12 11:34 被夏洛魂编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 385
活跃值: (90)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
闫总牛逼
2021-5-12 20:19
0
游客
登录 | 注册 方可回帖
返回
//