首页
社区
课程
招聘
[原创]2022KCTF春季赛 第五题 危机四伏
发表于: 2022-5-20 01:36 9858

[原创]2022KCTF春季赛 第五题 危机四伏

2022-5-20 01:36
9858

搜索字符串,发现有一些Failed和一个Succeed,在开头下断点
图片描述
发现41ADCC是个比较长度0x10,得到加密数据的位置在0x8995f1
对0x8995f1下硬件断点,发现断在奇怪的地方
图片描述
同时偶然发现上方有一串base64,下个硬件断点
图片描述
输入64个0,观察,发现加密结果有点熟悉,这个和KCTF2021春季赛第7题差不多
图片描述
一血很快就出来了(6小时40分钟),在代码如此混淆加密严重的情况下,觉得是遇到了非预期
尝试把当时的flag输进去看下
发现有base64,然后有KCTF出现
图片描述
图片描述
不过要先确定需要比较的加密内容是什么
CheatEngine搜索KCTF得到答案
图片描述
下载出题人的keygen算法对比,修改下代码
图片描述
然后还发现xor数值不对,将得到的结果再次xor
最后代码(仅能注册KCTF)

得到39ED62B341BC560217EAB3BF90265D101067856B36495264144A5B487264CB4B,正确答案

完全绕过了代码的混淆与加密,希望下次能换个算法,不然对刚打KCTF的选手不太公平

// KenGen.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
 
#include <iostream>
#include <windows.h>
 
//#pragma pack(1)
//typedef struct tagShareData
//{
//    uint64_t g_lpCtf;
//    uint8_t g_szName[17];
//    uint8_t g_szSerial[32];
//    uint8_t g_szBase64Table[0x100];
//    uint64_t g_qwDecSuccess;
//    uint64_t g_qwStackSize;
//    uint8_t g_Stack[0x6008];
//    uint8_t g_szDec[16];
//    uint8_t tmp[24];
//}SHAREDATA, * PSHAREDATA;
//
//
//SHAREDATA g_sd;
 
uint8_t g_sd[0x6179] = { 0 };
 
#define g_sd_g_lpCtf               (*(uint64_t*)(g_sd))
#define g_sd_g_szName              ((uint8_t*)(g_sd+8))
#define g_sd_g_szSerial            ((uint8_t*)(g_sd+25))
#define g_sd_g_szBase64Table       ((uint8_t*)(g_sd+57))
#define g_sd_g_qwDecSuccess        (*(uint64_t*)(g_sd+313))
#define g_sd_g_qwStackSize         (*(uint64_t*)(g_sd+321))
#define g_sd_g_Stack               ((uint8_t*)(g_sd+329))
#define g_sd_g_szDec               ((uint8_t*)(g_sd+24913))
#define g_sd_tmp                   ((uint8_t*)(g_sd+24929))
 
 
#define LEFTMOVE(X,D) (( (X) >> (16 - ((D) ) )) | ( (X) << ( (D)  )))  
#define RIGHTMOVE(X,D) (( (X) << (16 - ((D) ) )) | ( (X) >> ( (D)  ))) 
 
#define XOR_NUMBER 0x8160C68FF6C4875E^0x090A0B004654434B
int hex2string(unsigned char* hex, int size, char* buf)
{
    int i = 0, j = 0;
    unsigned int val = 0;
 
    for (; i < size; ++i)
    {
        val = hex[i] >> 4;
        if (val < 10)
            buf[j + 0] = '0' + val;
        else
            buf[j + 0] = 'A' + val - 10;
 
        val = hex[i] & 0x0f;
        if (val < 10)
            buf[j + 1] = '0' + val;
        else
            buf[j + 1] = 'A' + val - 10;
 
        j += 2;
    }
 
    buf[j] = 0;
    return j;
}
 
void DecM(LPBYTE g_uhSerial, LPBYTE dec, BYTE x1, BYTE x2)
{
    unsigned short int d[8] = { 0 };
    for (int i = 0; i <= 7; i++)
    {
        d[i] = (((unsigned char*)(g_uhSerial))[(x2 ^ (x1 + 2 * i)) % 16] << 8) + ((unsigned char*)(g_uhSerial))[(x2 ^ (x1 + 2 * i + 1)) % 16];
    }
 
    unsigned short int A = d[0] ^ d[1];
    unsigned short int B = d[2] + d[3];
    unsigned short int C = d[4] - d[5];
 
    //这里面的操作是取d[6] ^ d[7]二进制中1的个数赋值给D
    unsigned short int D = d[6] ^ d[7];
    D = (D & 0x55555555) + ((D >> 1) & 0x55555555);
    D = (D & 0x33333333) + ((D >> 2) & 0x33333333);
    D = (D & 0x0F0F0F0F) + ((D >> 4) & 0x0F0F0F0F);
    D = (D & 0x00FF00FF) + ((D >> 8) & 0x00FF00FF);
    D = (D & 0x0000FFFF) + ((D >> 16) & 0x0000FFFF);
 
    unsigned short int S = (A & B) | ((~A) & C);
 
    d[6] ^= S;
    d[7] ^= S;
 
    d[6] = LEFTMOVE(d[6], D);
    d[7] = LEFTMOVE(d[7], D);
 
    unsigned short int R = (unsigned short int)(((unsigned int)A * S) >> D) + 24;
    d[4] += R; d[5] += R;
 
    unsigned short int U = R ^ C;
    d[2] += U; d[3] -= U;
 
 
    unsigned short int V = (R & S) | (S & U) | (U & R);
    d[0] ^= V; d[1] ^= V;
 
    for (int i = 0; i <= 7; i++)
    {
        *(unsigned short int*)((char*)(dec) + 2 * i) = d[i];
    }
}
 
 
void EncM(LPBYTE g_uhSerial, LPBYTE enc, BYTE x1, BYTE x2)
{
    unsigned short int X[8] = { 0 };
    for (int i = 0; i <= 7; i++)
    {
        X[i] = *(unsigned short int*)((char*)(g_uhSerial) + 2 * i);
    }
 
    unsigned short int d[8] = { 0 };
    unsigned short int A, B, C, D, S, R, U, V;
    C = X[4] - X[5];
    B = X[2] + X[3];
    A = X[0] ^ X[1];
 
    //这里面的操作是取X[6] ^ X[7]二进制中1的个数赋值给D
    D = X[6] ^ X[7];
    D = (D & 0x55555555) + ((D >> 1) & 0x55555555);
    D = (D & 0x33333333) + ((D >> 2) & 0x33333333);
    D = (D & 0x0F0F0F0F) + ((D >> 4) & 0x0F0F0F0F);
    D = (D & 0x00FF00FF) + ((D >> 8) & 0x00FF00FF);
    D = (D & 0x0000FFFF) + ((D >> 16) & 0x0000FFFF);
 
    S = (A & B) | ((~A) & C);
    R = (unsigned short int)(((unsigned int)A * S) >> D) + 24;
    U = R ^ C;
    V = (R & S) | (S & U) | (U & R);
    d[0] = X[0] ^ V; d[1] = X[1] ^ V;
    d[2] = X[2] - U; d[3] = X[3] + U;
    d[4] = X[4] - R; d[5] = X[5] - R;
    d[6] = RIGHTMOVE(X[6], D) ^ S; d[7] = RIGHTMOVE(X[7], D) ^ S;
    for (int i = 0; i <= 7; i++)
    {
        ((unsigned char*)(enc))[(x2 ^ (x1 + 2 * i)) % 16] = (d[i] >> 8);
        ((unsigned char*)(enc))[(x2 ^ (x1 + 2 * i + 1)) % 16] = (d[i]);
    }
}
 
 
 
bool KC_base64_encode(uint8_t* pIn, uint8_t* pOut)
{
    //定义base64编码表
    //0O/+KuChaNiUB1FAckL4Hot9zlWEMpm2TG5Sb6Ixdeq8YJPjygXQsRvwVZr73Dnf
 
    unsigned char base64_table[64] = {
        0x30, 0x4F, 0x2F, 0x2B, 0x4B, 0x75, 0x43, 0x68, 0x61, 0x4E, 0x69, 0x55, 0x42, 0x31, 0x46, 0x41,
        0x63, 0x6B, 0x4C, 0x34, 0x48, 0x6F, 0x74, 0x39, 0x7A, 0x6C, 0x57, 0x45, 0x4D, 0x70, 0x6D, 0x32,
        0x54, 0x47, 0x35, 0x53, 0x62, 0x36, 0x49, 0x78, 0x64, 0x65, 0x71, 0x38, 0x59, 0x4A, 0x50, 0x6A,
        0x79, 0x67, 0x58, 0x51, 0x73, 0x52, 0x76, 0x77, 0x56, 0x5A, 0x72, 0x37, 0x33, 0x44, 0x6E, 0x66
    };
 
 
    uint32_t nRound = 24 / 3;
    uint32_t nEnc = 0;
    uint32_t nDec = 0;
 
    //38位字符为一组进行编码 
    while (nRound-- > 0)
    {
        uint32_t idx;
 
        idx = ((pIn[nDec + 2] & 0xf) << 2) | (pIn[nDec] & 0x3);
        pOut[nEnc] = base64_table[idx];
 
        idx = (pIn[nDec + 1] & 0x3c) | ((pIn[nDec] & 0xc) >> 2);
        pOut[nEnc + 1] = base64_table[idx];
 
        idx = ((pIn[nDec + 1] & 0x3) << 4) | (pIn[nDec] >> 4);
        pOut[nEnc + 2] = base64_table[idx];
 
        idx = ((pIn[nDec + 1] & 0xc0) >> 2) | (pIn[nDec + 2] >> 4);
        pOut[nEnc + 3] = base64_table[idx];
 
        nDec += 3;
        nEnc += 4;
    }
 
    return true;
}
 
void KC_base64_decode(uint8_t* pIn, uint8_t* pOut)
{
    uint32_t nRound = 32 / 4;
    uint32_t nEnc = 0;
    uint32_t nDec = 0;
 
    //4个字符为一位进行解码 
    while (nRound-- > 0)
    {
        uint8_t tmp0 = g_sd_g_szBase64Table[pIn[nEnc]];
        uint8_t tmp1 = g_sd_g_szBase64Table[pIn[nEnc + 1]];
        uint8_t tmp2 = g_sd_g_szBase64Table[pIn[nEnc + 2]];
        uint8_t tmp3 = g_sd_g_szBase64Table[pIn[nEnc + 3]];
 
        if ((tmp0 & 0xC0) != 0 || (tmp1 & 0xC0) != 0 || (tmp2 & 0xC0) != 0 || (tmp3 & 0xC0) != 0)
        {
            //走这里就是解密出错了
            return;
        }
        g_sd_g_qwDecSuccess = g_sd_g_qwDecSuccess | (tmp0 & 0xC0);
        g_sd_g_qwDecSuccess = g_sd_g_qwDecSuccess | (tmp1 & 0xC0);
        g_sd_g_qwDecSuccess = g_sd_g_qwDecSuccess | (tmp2 & 0xC0);
        g_sd_g_qwDecSuccess = g_sd_g_qwDecSuccess | (tmp3 & 0xC0);
 
 
        pOut[nDec] =
            (((uint8_t)tmp2) << 4)
            | ((((uint8_t)tmp1) & 0x3) << 2)
            | (((uint8_t)tmp0) & 0x3);
        pOut[nDec + 1] =
            ((((uint8_t)tmp3) & 0x30) << 2)
            | (((uint8_t)tmp1) & 0x3c)
            | (((uint8_t)tmp2) >> 4);
        pOut[nDec + 2] =
            (((uint8_t)tmp3) << 4)
            | (((uint8_t)tmp0) >> 2);
 
        nEnc += 4;
        nDec += 3;
    }
 
 
    return;
}
 
uint64_t EncQWORD(uint64_t input)
{
    uint64_t result = 0;
 
    uint64_t xor_val = input ^ XOR_NUMBER;
 
    PBYTE pResult = (PBYTE)&result;
    PBYTE pXorVal = (PBYTE)&xor_val;
 
    pResult[0] = pXorVal[0] ^ pXorVal[1] ^ pXorVal[2] ^ pXorVal[3];
    pResult[1] = pXorVal[0] ^ pXorVal[1] ^ pXorVal[2];
    pResult[2] = pXorVal[0] ^ pXorVal[2];
    pResult[3] = pXorVal[0];
 
    pResult[4] = pXorVal[4] ^ pXorVal[5] ^ pXorVal[6] ^ pXorVal[7];
    pResult[5] = pXorVal[4] ^ pXorVal[5] ^ pXorVal[6];
    pResult[6] = pXorVal[4] ^ pXorVal[6];
    pResult[7] = pXorVal[4];
 
    return result;
}
 
uint64_t DecQWORD(uint64_t input)
{
    uint64_t result = 0;
 
    PBYTE pResult = (PBYTE)&result;
    PBYTE pInputVal = (PBYTE)&input;
 
 
    pResult[2] = pInputVal[2] ^ pInputVal[3];
    pResult[1] = pInputVal[1] ^ pInputVal[3] ^ pResult[2];
    pResult[3] = pInputVal[0] ^ pInputVal[3] ^ pResult[1] ^ pResult[2];
    pResult[0] = pInputVal[3];
 
    pResult[6] = pInputVal[6] ^ pInputVal[7];
    pResult[5] = pInputVal[5] ^ pInputVal[7] ^ pResult[6];
    pResult[7] = pInputVal[4] ^ pInputVal[7] ^ pResult[5] ^ pResult[6];
    pResult[4] = pInputVal[7];
 
    result ^= XOR_NUMBER;
    return result;
}
 
 
void Enc(LPBYTE Serial, LPBYTE enc)
{
    BYTE tmp[24] = { 0 };
    BYTE tmp2[32] = { 0 };
 
    EncM(Serial, tmp+8, 3, 8);
 
    *(uint64_t*)tmp = EncQWORD(*(uint64_t*)Serial);
 
    KC_base64_encode(tmp, tmp2);
 
 
    EncM(tmp2, enc, 11, 7);
 
    EncM(tmp2+16, enc+16, 5, 14);
}
 
void Dec()
{
    BYTE tmp[24] = { 0 };
 
    DecM(g_sd_g_szSerial, g_sd_g_szSerial, 11, 7);
    DecM(g_sd_g_szSerial + 16, g_sd_g_szSerial + 16, 5, 14);
 
    KC_base64_decode(g_sd_g_szSerial, tmp);
 
    *(uint64_t*)tmp = DecQWORD(*(uint64_t*)tmp);
 
    memcpy(g_sd_g_szDec, tmp + 8, 16);
 
    DecM(g_sd_g_szDec, g_sd_g_szDec, 3, 8);
 
    g_sd_g_qwDecSuccess = g_sd_g_qwDecSuccess | (*(uint64_t*)g_sd_g_szDec ^ *(uint64_t*)tmp);
 
}
 
 
 
int main()
{
 
 
    BYTE szInput[20] = { 0 };// { 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10 };
    BYTE szEnc[32] = { 0 };
 
    char szShow[200] = { 0 };
 
    for (int i = 0; i < 16; i++)
    {
        szInput[i] = 0x10 - i;
    }
 
    printf("input name:");
    scanf("%16s", &szInput);
 
 
 
    hex2string(szInput, 16, szShow);
    printf("\r\n\r\ng_userName : \r\n%s\r\n\r\n", szShow);
 
 
    Enc(szInput, szEnc);
 
    hex2string(szEnc, 32, szShow);
    printf("\r\n\r\nEnc : \r\n%s\r\n\r\n", szShow);
 
 
    memcpy(g_sd_g_szName, szInput, 16);
    memcpy(g_sd_g_szSerial, szEnc, 32);
 
    uint8_t table[256] = {
        0x95, 0xE2, 0x80, 0xC6, 0xEA, 0xC3, 0xD5, 0x8D, 0x9E, 0xC5, 0xB3, 0x62, 0x64, 0x4D, 0x76, 0xBA,   //0x00-0x0F
        0x92, 0xFD, 0xDE, 0x7F, 0x42, 0x72, 0x81, 0xAD, 0x79, 0x54, 0x73, 0x85, 0x86, 0x5E, 0xF1, 0x84,   //0x10-0x1F
        0x6A, 0xF5, 0x63, 0xD8, 0xFE, 0xA8, 0xC0, 0xC8, 0x4F, 0xC9, 0xC7, 0x03, 0x7B, 0xE5, 0xDF, 0x02,   //0x20-0x2F
        0x00, 0x0D, 0x1F, 0x3C, 0x13, 0x22, 0x25, 0x3B, 0x2B, 0x17, 0xAA, 0xA0, 0xF6, 0x97, 0x59, 0x58,   //0x30-0x3F
        0x6D, 0x0F, 0x0C, 0x06, 0x3D, 0x1B, 0x0E, 0x21, 0x14, 0x26, 0x2D, 0x04, 0x12, 0x1C, 0x09, 0x01,   //0x40-0x4F
        0x2E, 0x33, 0x35, 0x23, 0x20, 0x0B, 0x38, 0x1A, 0x32, 0x2C, 0x39, 0x7C, 0xD1, 0xF2, 0x5C, 0x75,   //0x50-0x5F
        0xA1, 0x08, 0x24, 0x10, 0x28, 0x29, 0x3F, 0x31, 0x07, 0x0A, 0x2F, 0x11, 0x19, 0x1E, 0x3E, 0x15,   //0x60-0x6F
        0x1D, 0x2A, 0x3A, 0x34, 0x16, 0x05, 0x36, 0x37, 0x27, 0x30, 0x18, 0x6C, 0x4A, 0x7A, 0x44, 0x98,   //0x70-0x7F
        0x96, 0x69, 0xC4, 0xEB, 0xCC, 0x49, 0xBE, 0xB5, 0x48, 0x71, 0x94, 0xE1, 0xA3, 0xB1, 0x78, 0xFA,   //0x80-0x8F
        0x53, 0x46, 0x40, 0xCB, 0xBC, 0x47, 0x83, 0xC1, 0xEE, 0xF9, 0xE8, 0x61, 0xA9, 0xFB, 0xC2, 0xD2,   //0x90-0x9F
        0x4C, 0x55, 0xDA, 0xF7, 0x7E, 0xD9, 0x8F, 0xAC, 0xE3, 0x52, 0x60, 0x9B, 0xE9, 0x56, 0x9C, 0x89,   //0xA0-0xAF
        0x57, 0xB4, 0x51, 0x7D, 0xB0, 0x74, 0x8E, 0xA2, 0x9D, 0xED, 0xB6, 0xE0, 0x5F, 0xFC, 0x4B, 0x6E,   //0xB0-0xBF
        0xA5, 0x41, 0xD0, 0xA7, 0xBB, 0xF0, 0x8C, 0x91, 0x65, 0xB9, 0xD4, 0xE6, 0x87, 0xB8, 0xBF, 0xF8,   //0xC0-0xCF
        0xEC, 0x9F, 0x9A, 0xD3, 0x6F, 0x93, 0x5D, 0x66, 0x88, 0x43, 0x5B, 0x50, 0xF3, 0x82, 0xB7, 0xCE,   //0xD0-0xDF
        0x67, 0xE7, 0xF4, 0xFF, 0xAF, 0xCD, 0xD6, 0xDC, 0xAB, 0x68, 0x5A, 0x8A, 0xDD, 0xEF, 0xE4, 0xBD,   //0xE0-0xEF
        0x4E, 0xA4, 0x77, 0xB2, 0x45, 0xA6, 0x99, 0x70, 0xDB, 0x6B, 0xD7, 0x90, 0xCF, 0xAE, 0x8B, 0xCA    //0xF0-0xFF
    };
 
 
 
 
    memcpy(g_sd_g_szBase64Table, table, sizeof(table));
 
 
    Dec();
 
    hex2string(g_sd_g_szDec, 16, szShow);
    printf("\r\n\r\nDec : %lld (<-- 必须要为0)\r\n%s\r\n\r\n",g_sd_g_qwDecSuccess, szShow);
 
 
    system("pause");
 
}
// KenGen.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
 
#include <iostream>
#include <windows.h>
 
//#pragma pack(1)
//typedef struct tagShareData
//{
//    uint64_t g_lpCtf;
//    uint8_t g_szName[17];
//    uint8_t g_szSerial[32];
//    uint8_t g_szBase64Table[0x100];
//    uint64_t g_qwDecSuccess;
//    uint64_t g_qwStackSize;
//    uint8_t g_Stack[0x6008];
//    uint8_t g_szDec[16];
//    uint8_t tmp[24];
//}SHAREDATA, * PSHAREDATA;
//
//
//SHAREDATA g_sd;
 
uint8_t g_sd[0x6179] = { 0 };
 
#define g_sd_g_lpCtf               (*(uint64_t*)(g_sd))
#define g_sd_g_szName              ((uint8_t*)(g_sd+8))
#define g_sd_g_szSerial            ((uint8_t*)(g_sd+25))
#define g_sd_g_szBase64Table       ((uint8_t*)(g_sd+57))
#define g_sd_g_qwDecSuccess        (*(uint64_t*)(g_sd+313))
#define g_sd_g_qwStackSize         (*(uint64_t*)(g_sd+321))
#define g_sd_g_Stack               ((uint8_t*)(g_sd+329))
#define g_sd_g_szDec               ((uint8_t*)(g_sd+24913))
#define g_sd_tmp                   ((uint8_t*)(g_sd+24929))
 
 
#define LEFTMOVE(X,D) (( (X) >> (16 - ((D) ) )) | ( (X) << ( (D)  )))  
#define RIGHTMOVE(X,D) (( (X) << (16 - ((D) ) )) | ( (X) >> ( (D)  ))) 
 
#define XOR_NUMBER 0x8160C68FF6C4875E^0x090A0B004654434B
int hex2string(unsigned char* hex, int size, char* buf)
{
    int i = 0, j = 0;
    unsigned int val = 0;
 
    for (; i < size; ++i)
    {
        val = hex[i] >> 4;
        if (val < 10)
            buf[j + 0] = '0' + val;
        else
            buf[j + 0] = 'A' + val - 10;
 
        val = hex[i] & 0x0f;
        if (val < 10)
            buf[j + 1] = '0' + val;
        else
            buf[j + 1] = 'A' + val - 10;
 
        j += 2;
    }
 
    buf[j] = 0;
    return j;
}
 
void DecM(LPBYTE g_uhSerial, LPBYTE dec, BYTE x1, BYTE x2)
{
    unsigned short int d[8] = { 0 };
    for (int i = 0; i <= 7; i++)
    {
        d[i] = (((unsigned char*)(g_uhSerial))[(x2 ^ (x1 + 2 * i)) % 16] << 8) + ((unsigned char*)(g_uhSerial))[(x2 ^ (x1 + 2 * i + 1)) % 16];
    }
 
    unsigned short int A = d[0] ^ d[1];
    unsigned short int B = d[2] + d[3];
    unsigned short int C = d[4] - d[5];
 
    //这里面的操作是取d[6] ^ d[7]二进制中1的个数赋值给D
    unsigned short int D = d[6] ^ d[7];
    D = (D & 0x55555555) + ((D >> 1) & 0x55555555);
    D = (D & 0x33333333) + ((D >> 2) & 0x33333333);
    D = (D & 0x0F0F0F0F) + ((D >> 4) & 0x0F0F0F0F);
    D = (D & 0x00FF00FF) + ((D >> 8) & 0x00FF00FF);
    D = (D & 0x0000FFFF) + ((D >> 16) & 0x0000FFFF);
 
    unsigned short int S = (A & B) | ((~A) & C);
 
    d[6] ^= S;
    d[7] ^= S;
 
    d[6] = LEFTMOVE(d[6], D);
    d[7] = LEFTMOVE(d[7], D);
 
    unsigned short int R = (unsigned short int)(((unsigned int)A * S) >> D) + 24;
    d[4] += R; d[5] += R;
 
    unsigned short int U = R ^ C;
    d[2] += U; d[3] -= U;
 
 
    unsigned short int V = (R & S) | (S & U) | (U & R);
    d[0] ^= V; d[1] ^= V;
 
    for (int i = 0; i <= 7; i++)
    {
        *(unsigned short int*)((char*)(dec) + 2 * i) = d[i];
    }
}
 
 
void EncM(LPBYTE g_uhSerial, LPBYTE enc, BYTE x1, BYTE x2)
{
    unsigned short int X[8] = { 0 };
    for (int i = 0; i <= 7; i++)
    {
        X[i] = *(unsigned short int*)((char*)(g_uhSerial) + 2 * i);
    }
 
    unsigned short int d[8] = { 0 };
    unsigned short int A, B, C, D, S, R, U, V;
    C = X[4] - X[5];
    B = X[2] + X[3];
    A = X[0] ^ X[1];
 
    //这里面的操作是取X[6] ^ X[7]二进制中1的个数赋值给D
    D = X[6] ^ X[7];
    D = (D & 0x55555555) + ((D >> 1) & 0x55555555);
    D = (D & 0x33333333) + ((D >> 2) & 0x33333333);
    D = (D & 0x0F0F0F0F) + ((D >> 4) & 0x0F0F0F0F);
    D = (D & 0x00FF00FF) + ((D >> 8) & 0x00FF00FF);
    D = (D & 0x0000FFFF) + ((D >> 16) & 0x0000FFFF);
 
    S = (A & B) | ((~A) & C);
    R = (unsigned short int)(((unsigned int)A * S) >> D) + 24;
    U = R ^ C;
    V = (R & S) | (S & U) | (U & R);
    d[0] = X[0] ^ V; d[1] = X[1] ^ V;
    d[2] = X[2] - U; d[3] = X[3] + U;
    d[4] = X[4] - R; d[5] = X[5] - R;
    d[6] = RIGHTMOVE(X[6], D) ^ S; d[7] = RIGHTMOVE(X[7], D) ^ S;
    for (int i = 0; i <= 7; i++)
    {
        ((unsigned char*)(enc))[(x2 ^ (x1 + 2 * i)) % 16] = (d[i] >> 8);
        ((unsigned char*)(enc))[(x2 ^ (x1 + 2 * i + 1)) % 16] = (d[i]);
    }
}
 
 
 
bool KC_base64_encode(uint8_t* pIn, uint8_t* pOut)
{
    //定义base64编码表
    //0O/+KuChaNiUB1FAckL4Hot9zlWEMpm2TG5Sb6Ixdeq8YJPjygXQsRvwVZr73Dnf
 
    unsigned char base64_table[64] = {
        0x30, 0x4F, 0x2F, 0x2B, 0x4B, 0x75, 0x43, 0x68, 0x61, 0x4E, 0x69, 0x55, 0x42, 0x31, 0x46, 0x41,
        0x63, 0x6B, 0x4C, 0x34, 0x48, 0x6F, 0x74, 0x39, 0x7A, 0x6C, 0x57, 0x45, 0x4D, 0x70, 0x6D, 0x32,
        0x54, 0x47, 0x35, 0x53, 0x62, 0x36, 0x49, 0x78, 0x64, 0x65, 0x71, 0x38, 0x59, 0x4A, 0x50, 0x6A,
        0x79, 0x67, 0x58, 0x51, 0x73, 0x52, 0x76, 0x77, 0x56, 0x5A, 0x72, 0x37, 0x33, 0x44, 0x6E, 0x66
    };
 
 
    uint32_t nRound = 24 / 3;
    uint32_t nEnc = 0;
    uint32_t nDec = 0;
 
    //38位字符为一组进行编码 
    while (nRound-- > 0)
    {
        uint32_t idx;
 
        idx = ((pIn[nDec + 2] & 0xf) << 2) | (pIn[nDec] & 0x3);
        pOut[nEnc] = base64_table[idx];
 
        idx = (pIn[nDec + 1] & 0x3c) | ((pIn[nDec] & 0xc) >> 2);
        pOut[nEnc + 1] = base64_table[idx];
 
        idx = ((pIn[nDec + 1] & 0x3) << 4) | (pIn[nDec] >> 4);
        pOut[nEnc + 2] = base64_table[idx];
 
        idx = ((pIn[nDec + 1] & 0xc0) >> 2) | (pIn[nDec + 2] >> 4);
        pOut[nEnc + 3] = base64_table[idx];
 
        nDec += 3;
        nEnc += 4;
    }
 
    return true;
}
 
void KC_base64_decode(uint8_t* pIn, uint8_t* pOut)

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

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//