首页
社区
课程
招聘
[原创]KCTF 2025 第四题 血色试炼wp
发表于: 2025-8-21 20:39 4734

[原创]KCTF 2025 第四题 血色试炼wp

2025-8-21 20:39
4734

由于动调没有起来,故从TlsCallback_0开始分析

注意到有两个很明显的key,以及base64的Table
ThisEncAndDecKeytweakKey_2024521

图片描述

而且这里还有两个动态加载,下面肯定有很难读的反调试

注意到两个很大的数组,都是256长度

图片描述

到这里其实已经开始猜是不是AES了,从后面看来是猜对了

继续往下看看到一堆不太看得懂的LoadLibraryW,感觉是hook相关代码,但是没影响我IDA调试

图片描述

从资源段读取数据,发现核心的解密函数

图片描述

其实是个蛮简单的反调试,主体在以下部分,主要靠syscall 0x19进行反调试

图片描述

总共应该是有3处,将恶意跳转改成强制jmp就解决了

然后就开始了漫长的逆向之路

开头就是当头一棒的Base64

图片描述

但是很显然,在线网站解出来的和题目给的不一样~~~

其实看着很复杂,但是魔改的核心其实很少很少,就只有下面这一小块

图片描述

也就是大伙熟悉的==相关流程,稍微对输入字符进行了一点点的位移,呈现在keyGen上面就是如下所示

这块是我觉得最折磨的部分,因为对AES不熟悉,对着标准AES一点点扣出来的

图片描述

但是捏,其实就只魔改了一个函数,也就是addRoundKey,其他其实一点都没改,invMixColumns看着很唬人,但是实际上没有任何魔改

图片描述

所以对应的代码如下

这块其实我没分析出来,但是有蛮力,通过替换资源段的方式,让代码运行过程中自吐了最大4轮所需要的xor Key

图片描述

对应到我的代码上,写的很丑))

图片描述

最后我们回到主函数,简单读读就能明白原来是加密了4轮

图片描述

本来以为是3轮,但是加密完感觉长度不对,于是改成了4轮,长度就对上了

按照每层加密的值排布

AES_ECB.hpp是标准AES,里面没有任何代码改动

int base64_encode(const uint8_t* input, int in_len, char* output) {
    int out_len = 0;
    for (int i = 0; i < in_len; i += 3) {
        uint32_t buf = 0;
        int remain = in_len - i;
 
        buf |= input[i];
        if (remain > 1) buf |= input[i + 1] << 8;
        if (remain > 2) buf |= input[i + 2] << 16;
 
        if (remain > 2) {
            output[out_len++] = base64_table[(buf) & 0x3F];
            output[out_len++] = base64_table[(buf >> 6) & 0x3F];
            output[out_len++] = base64_table[(buf >> 12) & 0x3F];
            output[out_len++] = base64_table[(buf >> 18) & 0x3F];
        }
        else {
            output[out_len++] = base64_table[(buf >> 0) & 0x3F];
            output[out_len++] = (remain > 1) ? base64_table[(buf >> 6) & 0x3F]: base64_table[((buf >> 6) & 0x3) << 4];
            output[out_len++] = (remain > 1) ? base64_table[((buf >> 12) & 0xF)<<2] : '=';
            output[out_len++] = '=';
        }
 
    }
    output[out_len] = '\0';
    return out_len;
}
int base64_encode(const uint8_t* input, int in_len, char* output) {
    int out_len = 0;
    for (int i = 0; i < in_len; i += 3) {
        uint32_t buf = 0;
        int remain = in_len - i;
 
        buf |= input[i];
        if (remain > 1) buf |= input[i + 1] << 8;
        if (remain > 2) buf |= input[i + 2] << 16;
 
        if (remain > 2) {
            output[out_len++] = base64_table[(buf) & 0x3F];
            output[out_len++] = base64_table[(buf >> 6) & 0x3F];
            output[out_len++] = base64_table[(buf >> 12) & 0x3F];
            output[out_len++] = base64_table[(buf >> 18) & 0x3F];
        }
        else {
            output[out_len++] = base64_table[(buf >> 0) & 0x3F];
            output[out_len++] = (remain > 1) ? base64_table[(buf >> 6) & 0x3F]: base64_table[((buf >> 6) & 0x3) << 4];
            output[out_len++] = (remain > 1) ? base64_table[((buf >> 12) & 0xF)<<2] : '=';
            output[out_len++] = '=';
        }
 
    }
    output[out_len] = '\0';
    return out_len;
}
int addRoundKey_self(uint8_t (*state)[4], const uint32_t *key)
{
    uint8_t k[4][4];
    /* i: row, j: col */
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            k[i][j] = (uint8_t) BYTE(key[j], i); 
            state[i][j] ^= k[i][j];
        }
    }
    return 0;
}
int addRoundKey_self(uint8_t (*state)[4], const uint32_t *key)
{
    uint8_t k[4][4];
    /* i: row, j: col */
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            k[i][j] = (uint8_t) BYTE(key[j], i); 
            state[i][j] ^= k[i][j];
        }
    }
    return 0;
}
KCTF
vCF5nc2wC5/sVISvceXVkY==
8g+JjodOZ4bcaurrKobFVzxuSGA2uDFJFyXqAlnTlKI=
l/SxsR0BCjRZTmc7XWscrMv38iYuoiUECvi9Tuvi+ZiJZmdR5EcvVnTZOZvrnOrw
tSzQkyqcvZLgkwDltPF9RpInibA5fTpH/bJni2yvLzTKao2uL5eLZ5QIxPj8bsYWe48ZohC5/Jw3cNNAaX8/rA==
KCTF
vCF5nc2wC5/sVISvceXVkY==
8g+JjodOZ4bcaurrKobFVzxuSGA2uDFJFyXqAlnTlKI=
l/SxsR0BCjRZTmc7XWscrMv38iYuoiUECvi9Tuvi+ZiJZmdR5EcvVnTZOZvrnOrw
tSzQkyqcvZLgkwDltPF9RpInibA5fTpH/bJni2yvLzTKao2uL5eLZ5QIxPj8bsYWe48ZohC5/Jw3cNNAaX8/rA==
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
#include <time.h>
using namespace std;
 
#include "DES-AES/AES_ECB.hpp"
#include "data.h"
uint32_t buf[8] = {};
#define BOOL bool
int invMixColumns_self(uint8_t (*state)[4])
{
    uint8_t tmp[4][4];
    uint8_t tmp2[4][4];
 
    for (int i = 0; i < 4; ++i )
    {
        uint8_t v3 = buf1[state[0][i]];
        uint8_t v4 = buf2[state[1][i]];
        uint8_t v5 = buf3[state[2][i]];
        tmp2[0][i] = v3 ^ v4 ^ v5 ^ buf4[state[3][i]];
        uint8_t v6 = buf4[state[0][i]];
        uint8_t v7 = buf1[state[1][i]];
        uint8_t v8 = buf2[state[2][i]];
        tmp2[1][i] = buf3[state[3][i]] ^ v6 ^ v7 ^ v8;
        uint8_t v9 = buf3[state[0][i]];
        uint8_t v10 = buf4[state[1][i]];
        uint8_t v11 = buf1[state[2][i]];
        tmp2[2][i] = v9 ^ v10 ^ v11 ^ buf2[state[3][i]];
        uint8_t v12 = buf2[state[0][i]];
        uint8_t v13 = buf3[state[1][i]];
        uint8_t v14 = buf4[state[2][i]];
        tmp2[3][i] = v14 ^ buf1[state[3][i]] ^ v12 ^ v13;
    }
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            state[i][j] = tmp2[i][j];
        }
    }
    return 0;
}
 
int addRoundKey_self(uint8_t (*state)[4], const uint32_t *key)
{
    uint8_t k[4][4];
    /* i: row, j: col */
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            k[i][j] = (uint8_t) BYTE(key[j], i);  /* 把 uint32 key[4] 先转换为矩阵 uint8 k[4][4] */
            state[i][j] ^= k[i][j];
        }
    }
    return 0;
}
int aesDecrypt_kctf(const uint8_t *key, uint32_t keyLen, const uint8_t *ct, uint8_t *pt, uint32_t len)
{
    AesKey aesKey;
    uint8_t *pos = pt;
    const uint32_t *ek = (uint32_t *)aes_key_ek;
    const uint32_t *rk = aesKey.dK;  //解密密钥指针
    uint8_t actualKey[16] = {0};
    uint8_t state[4][4] = {0};
    uint8_t xorKey[17] = {  0xA0, 0x81, 0x3E, 0x4D, 0x5B, 0x6A, 0xD4, 0xC2, 0x7B, 0xA5,
  0x46, 0x20, 0x82, 0xB5, 0x1C, 0xEF};
    uint8_t xorKey2[17] = {  0x43, 0x51, 0x8B, 0xC3, 0x5E, 0x57, 0xCC, 0x04, 0xF0, 0xBC,
  0x43, 0x85, 0x1E, 0x9C, 0xBB, 0x51};
    uint8_t xorKey3[17] = {  0xED, 0x59, 0x82, 0xE8, 0x1C, 0x04, 0xAC, 0x0B, 0xE4, 0xBA,
  0xC2, 0xBA, 0x53, 0x27, 0xF0, 0x1B};
    uint8_t xorKey4[17] = {  0xA1, 0x35, 0x01, 0xDF, 0xBB, 0x6F, 0xD2, 0x83, 0xEB, 0x49,
  0xB5, 0x4A, 0xF7, 0xE5, 0x40, 0x4B};
 
    if (NULL == key || NULL == ct || NULL == pt)
    {
        printf("param err.\n");
        return -1;
    }
    if (keyLen > 16)
    {
        printf("keyLen must be 16.\n");
        return -1;
    }
    if (len % BLOCKSIZE)
    {
        printf("inLen is invalid.\n");
        return -1;
    }
 
    memcpy(actualKey, key, keyLen);
    keyExpansion(actualKey, 16, &aesKey);  //密钥扩展,同加密
 
    for (int i = 0; i < len; i += BLOCKSIZE)
    {
        loadStateArray(state, ct);
        addRoundKey_self(state, &ek[40]);
        rk = &ek[36];
        for (int j = 1; j < 10; ++j)
        {
            invSubBytes(state);     // 逆字节替换,这两步顺序可以颠倒
            invShiftRows(state);    // 逆行移位
            addRoundKey_self(state, rk); // 轮密钥加,同加密
            rk -= 4;
            invMixColumns(state);   // 逆列混合
        }
        invSubBytes(state);   // 逆字节替换
        invShiftRows(state);  // 逆行移位
         
        addRoundKey_self(state, rk);  // 轮密钥加,同加密
 
        storeStateArray(state, pos);  // 保存明文数据
        if (i==0) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey[j];
            }
        }else if (i== 16) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey2[j];
            }
        }
        else if (i== 32) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey3[j];
            }
        }
        else if (i== 48) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey4[j];
            }
        }
        pos += BLOCKSIZE;  // 输出数据内存指针移位分组长度
        ct += BLOCKSIZE;   // 输入数据内存指针移位分组长度
        rk = aesKey.dK;    // 恢复rk指针到秘钥初始位置
    }
    return 0;
}
int aesEncrypt_kctf(const uint8_t *key, uint32_t keyLen, const uint8_t *ct, uint8_t *pt, uint32_t len)
{
    AesKey aesKey;
    uint8_t *pos = pt;
    const uint32_t *ek = (uint32_t *)aes_key_ek;
    const uint32_t *rk = aesKey.dK;  //解密密钥指针
    uint8_t actualKey[16] = {0};
    uint8_t state[4][4] = {0};
    uint8_t xorKey[17] = {  0xA0, 0x81, 0x3E, 0x4D, 0x5B, 0x6A, 0xD4, 0xC2, 0x7B, 0xA5,
  0x46, 0x20, 0x82, 0xB5, 0x1C, 0xEF};
    uint8_t xorKey2[17] = {  0x43, 0x51, 0x8B, 0xC3, 0x5E, 0x57, 0xCC, 0x04, 0xF0, 0xBC,
  0x43, 0x85, 0x1E, 0x9C, 0xBB, 0x51};
    uint8_t xorKey3[17] = {  0xED, 0x59, 0x82, 0xE8, 0x1C, 0x04, 0xAC, 0x0B, 0xE4, 0xBA,
  0xC2, 0xBA, 0x53, 0x27, 0xF0, 0x1B};
    uint8_t xorKey4[17] = {  0xA1, 0x35, 0x01, 0xDF, 0xBB, 0x6F, 0xD2, 0x83, 0xEB, 0x49,
  0xB5, 0x4A, 0xF7, 0xE5, 0x40, 0x4B};
    if (NULL == key || NULL == ct || NULL == pt)
    {
        printf("param err.\n");
        return -1;
    }
    if (keyLen > 16)
    {
        printf("keyLen must be 16.\n");
        return -1;
    }
    if (len % BLOCKSIZE)
    {
        printf("inLen is invalid.\n");
        return -1;
    }
 
    memcpy(actualKey, key, keyLen);
    keyExpansion(actualKey, 16, &aesKey);  //密钥扩展,同加密
 
    for (int i = 0; i < len; i += BLOCKSIZE)
    {
        uint8_t new_ct[17] = {0};
        if (i==0) {
            for (int j=0; j<16; j++) {
                new_ct[j] = ct[j] ^ xorKey[j];
            }
        }else if (i== 16) {
            for (int j=0; j<16; j++) {
                new_ct[j] = ct[j] ^ xorKey2[j];
            }
        }
        else if (i== 32) {
            for (int j=0; j<16; j++) {
                new_ct[j] = ct[j] ^ xorKey3[j];
            }
        }
        else if (i== 48) {
            for (int j=0; j<16; j++) {
                new_ct[j] = ct[j] ^ xorKey4[j];
            }
        }
        // 把16字节的密文转换为4x4状态矩阵来进行处理
        loadStateArray(state, new_ct);
        // 轮密钥加,同加密
        addRoundKey_self(state, ek);
        rk = &ek[4];
        for (int j = 1; j < 10; ++j)
        {
            subBytes(state);     // 逆字节替换,这两步顺序可以颠倒
            shiftRows(state);    // 逆行移位
            mixColumns(state);   // 逆列混合
            addRoundKey_self(state, rk); // 轮密钥加,同加密
            rk += 4;
        }
        subBytes(state);   // 逆字节替换
        shiftRows(state);  // 逆行移位
 
        // 此处没有逆列混合
        addRoundKey_self(state, rk);  // 轮密钥加,同加密
 
        storeStateArray(state, pos);  // 保存明文数据
 
        pos += BLOCKSIZE;  // 输出数据内存指针移位分组长度
        ct += BLOCKSIZE;   // 输入数据内存指针移位分组长度
    }
    return 0;
}
constexpr char base64_table[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789+/";
int get_by_table(char a) {
    for (int i=0;i<64;i++) {
        if (a == base64_table[i])
            return i;
    }
    return -1;
}
// Base64 编码
int base64_encode(const uint8_t* input, int in_len, char* output) {
    int out_len = 0;
    for (int i = 0; i < in_len; i += 3) {
        uint32_t buf = 0;
        int remain = in_len - i;
 
        buf |= input[i];
        if (remain > 1) buf |= input[i + 1] << 8;
        if (remain > 2) buf |= input[i + 2] << 16;
 
        if (remain > 2) {
            output[out_len++] = base64_table[(buf) & 0x3F];
            output[out_len++] = base64_table[(buf >> 6) & 0x3F];
            output[out_len++] = base64_table[(buf >> 12) & 0x3F];
            output[out_len++] = base64_table[(buf >> 18) & 0x3F];
        }
        else {
            output[out_len++] = base64_table[(buf >> 0) & 0x3F];
            output[out_len++] = (remain > 1) ? base64_table[(buf >> 6) & 0x3F]: base64_table[((buf >> 6) & 0x3) << 4];
            output[out_len++] = (remain > 1) ? base64_table[((buf >> 12) & 0xF)<<2] : '=';
            output[out_len++] = '=';
        }
 
    }
    output[out_len] = '\0';
    return out_len;
}
 
// Base64 解码
int base64_decode(const char* input, uint8_t* output) {
    int in_len = 0;
    while (input[in_len] && input[in_len] != '\n') in_len++;
 
    int out_len = 0;
    for (int i = 0; i < in_len; i += 4) {
        int n[4];
        for (int j = 0; j < 4; j++) {
            if (input[i + j] == '=')
                n[j] = -1;
            else
                n[j] = get_by_table(input[i + j]);
        }
 
        uint32_t buf = 0;
        buf |= (n[0] & 0x3F);
        buf |= (n[1] & 0x3F) << 6;
        if (n[2] >= 0) buf |= (n[2] & 0x3F) << 12;
        if (n[3] >= 0) buf |= (n[3] & 0x3F) << 18;
 
        if (n[2] >= 0 && n[3] >= 0) {
            output[out_len++] = (buf) & 0xFF;
            output[out_len++] = (buf >> 8) & 0xFF;
            output[out_len++] = (buf >> 16) & 0xFF;
        }
        else if (n[2] >= 0) {
            output[out_len++] = (buf) & 0xFF;
            output[out_len++] = ((buf & 0xFFF) + ((buf >> 2) & 0xF000)) >> 8;
        }
        else{
            output[out_len++] = ((buf) & 0x3F) + ((buf >> 4) & 0xC0);
        }
    }
    return out_len;
}
 
int run() {
    uint8_t aes_key[] = "ThisEncAndDecKey";
    uint8_t aes_pt[0x100] = {0};
    uint8_t aes_test_enc[0x100] = {0};
    const char test_base64[256] =
            "M3JIlKQv/ztrqDQc94MSRI==";
    char test_base64_enc[0x100] = {0};
    uint8_t test_base64_dec[0x100] = {0};
    base64_decode(test_base64, test_base64_dec);
    base64_encode(test_base64_dec, 16, test_base64_enc);
    for (int i = 0; i < 16; ++i) {
        if (test_base64_enc[i] != test_base64[i]) {
            printf("Error! index: 0x%02x\n", test_base64_enc[i]);
        }
    }
    aesDecrypt_kctf(aes_key, 16, test_base64_dec, aes_pt, 16);
    printf("%s\n", aes_pt);
    aesEncrypt_kctf(aes_key, 16, aes_pt, aes_test_enc, 16);
    for (int i = 0; i < 16; ++i) {
        if (aes_test_enc[i] != test_base64_dec[i]) {
            printf("Error! index: 0x%02x\n", i);
        }
    }
    uint8_t flag[17] = "KCTF";
    uint8_t enc_flag_aes1[0x100] = {0};
    char enc_flag_str1[0x100] = {0};
    aesEncrypt_kctf(aes_key, 16, flag, enc_flag_aes1, 16);
    base64_encode(enc_flag_aes1, 16, enc_flag_str1);
    printf("%s\n", enc_flag_str1);
    uint8_t enc_flag_aes2[0x100] = {0};
    char enc_flag_str2[0x100] = {0};
    aesEncrypt_kctf(aes_key, 16, (uint8_t*)enc_flag_str1, enc_flag_aes2, 32);
    base64_encode(enc_flag_aes2, 32, enc_flag_str2);
    printf("%s\n", enc_flag_str2);
    uint8_t enc_flag_aes3[0x100] = {0};
    char enc_flag_str3[0x100] = {0};
    aesEncrypt_kctf(aes_key, 16, (uint8_t*)enc_flag_str2, enc_flag_aes3, 48);
    base64_encode(enc_flag_aes3, 48, enc_flag_str3);
    printf("%s\n", enc_flag_str3);
    uint8_t enc_flag_aes4[0x100] = {0};
    char enc_flag_str4[0x100] = {0};
    aesEncrypt_kctf(aes_key, 16, (uint8_t*)enc_flag_str3, enc_flag_aes4, 64);
    base64_encode(enc_flag_aes4, 64, enc_flag_str4);
    printf("%s\n", enc_flag_str4);
    return 0LL;
}
 
int main() {
    run();
    return 0;
}
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
#include <time.h>
using namespace std;
 
#include "DES-AES/AES_ECB.hpp"
#include "data.h"
uint32_t buf[8] = {};
#define BOOL bool
int invMixColumns_self(uint8_t (*state)[4])
{
    uint8_t tmp[4][4];
    uint8_t tmp2[4][4];
 
    for (int i = 0; i < 4; ++i )
    {
        uint8_t v3 = buf1[state[0][i]];
        uint8_t v4 = buf2[state[1][i]];
        uint8_t v5 = buf3[state[2][i]];
        tmp2[0][i] = v3 ^ v4 ^ v5 ^ buf4[state[3][i]];
        uint8_t v6 = buf4[state[0][i]];
        uint8_t v7 = buf1[state[1][i]];
        uint8_t v8 = buf2[state[2][i]];
        tmp2[1][i] = buf3[state[3][i]] ^ v6 ^ v7 ^ v8;
        uint8_t v9 = buf3[state[0][i]];
        uint8_t v10 = buf4[state[1][i]];
        uint8_t v11 = buf1[state[2][i]];
        tmp2[2][i] = v9 ^ v10 ^ v11 ^ buf2[state[3][i]];
        uint8_t v12 = buf2[state[0][i]];
        uint8_t v13 = buf3[state[1][i]];
        uint8_t v14 = buf4[state[2][i]];
        tmp2[3][i] = v14 ^ buf1[state[3][i]] ^ v12 ^ v13;
    }
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            state[i][j] = tmp2[i][j];
        }
    }
    return 0;
}
 
int addRoundKey_self(uint8_t (*state)[4], const uint32_t *key)
{
    uint8_t k[4][4];
    /* i: row, j: col */
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            k[i][j] = (uint8_t) BYTE(key[j], i);  /* 把 uint32 key[4] 先转换为矩阵 uint8 k[4][4] */
            state[i][j] ^= k[i][j];
        }
    }
    return 0;
}
int aesDecrypt_kctf(const uint8_t *key, uint32_t keyLen, const uint8_t *ct, uint8_t *pt, uint32_t len)
{
    AesKey aesKey;
    uint8_t *pos = pt;
    const uint32_t *ek = (uint32_t *)aes_key_ek;
    const uint32_t *rk = aesKey.dK;  //解密密钥指针
    uint8_t actualKey[16] = {0};
    uint8_t state[4][4] = {0};
    uint8_t xorKey[17] = {  0xA0, 0x81, 0x3E, 0x4D, 0x5B, 0x6A, 0xD4, 0xC2, 0x7B, 0xA5,
  0x46, 0x20, 0x82, 0xB5, 0x1C, 0xEF};
    uint8_t xorKey2[17] = {  0x43, 0x51, 0x8B, 0xC3, 0x5E, 0x57, 0xCC, 0x04, 0xF0, 0xBC,
  0x43, 0x85, 0x1E, 0x9C, 0xBB, 0x51};
    uint8_t xorKey3[17] = {  0xED, 0x59, 0x82, 0xE8, 0x1C, 0x04, 0xAC, 0x0B, 0xE4, 0xBA,
  0xC2, 0xBA, 0x53, 0x27, 0xF0, 0x1B};
    uint8_t xorKey4[17] = {  0xA1, 0x35, 0x01, 0xDF, 0xBB, 0x6F, 0xD2, 0x83, 0xEB, 0x49,
  0xB5, 0x4A, 0xF7, 0xE5, 0x40, 0x4B};
 
    if (NULL == key || NULL == ct || NULL == pt)
    {
        printf("param err.\n");
        return -1;
    }
    if (keyLen > 16)
    {
        printf("keyLen must be 16.\n");
        return -1;
    }
    if (len % BLOCKSIZE)
    {
        printf("inLen is invalid.\n");
        return -1;
    }
 
    memcpy(actualKey, key, keyLen);
    keyExpansion(actualKey, 16, &aesKey);  //密钥扩展,同加密
 
    for (int i = 0; i < len; i += BLOCKSIZE)
    {
        loadStateArray(state, ct);
        addRoundKey_self(state, &ek[40]);
        rk = &ek[36];
        for (int j = 1; j < 10; ++j)
        {
            invSubBytes(state);     // 逆字节替换,这两步顺序可以颠倒
            invShiftRows(state);    // 逆行移位
            addRoundKey_self(state, rk); // 轮密钥加,同加密
            rk -= 4;
            invMixColumns(state);   // 逆列混合
        }
        invSubBytes(state);   // 逆字节替换
        invShiftRows(state);  // 逆行移位
         
        addRoundKey_self(state, rk);  // 轮密钥加,同加密
 
        storeStateArray(state, pos);  // 保存明文数据
        if (i==0) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey[j];
            }
        }else if (i== 16) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey2[j];
            }
        }
        else if (i== 32) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey3[j];
            }
        }
        else if (i== 48) {
            for (int j=0; j<16; j++) {
                pos[j] ^= xorKey4[j];
            }
        }

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

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