第一话:起源

首先啊,打了强网杯,关于强网杯还是要狠狠的吐槽一下的.难难难,只能说难啊
那么接下来的这里是解出来的butterfly,本来之前就想吐槽出题人来着,结果拖到现在了.

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
__int64 __fastcall sub_4018D0(int n3, _QWORD *a2, __int64 a3, int a4, int a5, int a6)
{
int v6; // ecx
int v7; // r8d
int v8; // r9d
__int64 v10; // r14
__int64 v11; // r13
__int64 v12; // rax
int v13; // ecx
int v14; // r8d
int v15; // r9d
__int64 v16; // r12
__int64 n7; // rbx
__int64 v18; // rax
__m64 *v19; // rbp
__int64 n7_1; // r15
int v21; // ecx
int v22; // r8d
int v23; // r9d
__m128i v24; // xmm0
int v25; // ecx
int v26; // r8d
int v27; // r9d
__m64 *v28; // rax
__m64 v29; // mm0
__m64 v30; // mm2
int v31; // ecx
int v32; // r8d
int v33; // r9d
int v34; // ecx
int v35; // r8d
int v36; // r9d
int v37; // ecx
int v38; // r8d
int v39; // r9d
_QWORD v40[2]; // [rsp+0h] [rbp-158h] BYREF
__m128i v41; // [rsp+10h] [rbp-148h]
__m64 v42[39]; // [rsp+20h] [rbp-138h] BYREF

if ( n3 != 3 )
{
sub_4776D0(2, (unsigned int)"Usage: %s <input_file> <output_file>\n", *a2, a4, a5, a6, v40[0]);
sub_4776D0(2, (unsigned int)"Example: %s plaintext.txt encoded.dat\n", *a2, v6, v7, v8, v40[0]);
return 1;
}
v10 = a2[1];
v11 = a2[2];
v12 = sub_405540(v10, "rb");
v16 = v12;
if ( !v12 )
{
sub_4776D0(2, (unsigned int)"Error: Cannot open file %s\n", v10, v13, v14, v15, v40[0]);
return 1;
}
sub_407480(v12, 0, 2);
n7 = sub_405640(v16);
sub_407480(v16, 0, 0);
v18 = sub_412620(n7 + 8);
v19 = (__m64 *)v18;
if ( !v18 )
{
sub_405180(v16);
sub_4774A0("Error: Memory allocation failed");
return 1;
}
n7_1 = sub_41CC80(v18, n7 + 8, 1, n7, v16);
sub_405180(v16);
if ( n7 != n7_1 )
{
sub_412CF0(v19);
sub_4774A0("Error: File read failed");
return 1;
}
*(__int16 *)((char *)v19->m64_i16 + n7) = n7;
v24 = _mm_loadu_si128((const __m128i *)"MMXEncode2024");
v40[1] = v24.m128i_i64[1];
v41 = _mm_loadu_si128((const __m128i *)"coding file: %s\n");
sub_4776D0(2, (unsigned int)"Encoding file: %s\n", v10, v21, v22, v23, v24.m128i_i8[0]);
sub_4776D0(2, (unsigned int)"Original size: %zu bytes\n", n7, v25, v26, v27, v40[0]);
v42[0] = (__m64)v40[0];
if ( (int)n7 > 7 )
{
v28 = v19;
do
{
v29 = _m_pxor((__m64)v28->m64_u64, v42[0]);
v30 = _m_por(_m_psrlwi(v29, 8u), _m_psllwi(v29, 8u));
v28->m64_u64 = (unsigned __int64)_m_paddb(_m_por(_m_psllqi(v30, 1u), _m_psrlqi(v30, 0x3Fu)), v42[0]);
if ( &v19[(unsigned int)(n7 - 1) >> 3] == v28 )
break;
++v28;
}
while ( &v19[((unsigned int)(n7 - 8) >> 3) + 1] != v28 );
}
_m_empty();
if ( (unsigned int)sub_401CA0(v11, v19, n7) )
{
sub_4776D0(2, (unsigned int)"Successfully encoded to: %s\n", v11, v31, v32, v33, v40[0]);
sub_4776D0(2, (unsigned int)"Encoded size: %zu bytes\n", n7, v34, v35, v36, v40[0]);
sub_4777A0((unsigned int)v42, 256, 2, 256, (unsigned int)"%s.key", v11, v40[0]);
if ( (unsigned int)sub_401CA0(v42, v40, 32) )
sub_4776D0(2, (unsigned int)"Key saved to: %s\n", (unsigned int)v42, v37, v38, v39, v40[0]);
}
sub_412CF0(v19);
return 0;
}

可以看出来这里主要就是使用了MMXEncode来加密了文件.只需要把密钥放进去,密文最后就后就输出了.
解密脚本

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

int decrypt_file(const char* encrypted_file, const char* key_file, const char* output_file) {
    FILE* f_enc = fopen(encrypted_file, "rb");
    FILE* f_key = fopen(key_file, "rb");
    if (!f_key) {
        printf("错误:无法打开密钥文件 %s\n", key_file);
        fclose(f_enc);
        return 1;
    }
    FILE* f_out = fopen(output_file, "wb");
    uint8_t key_buffer[32];
    fclose(f_key);
    uint64_t key = 0;
    for (int i = 0; i < 8; i++) {
        key |= ((uint64_t)key_buffer[i]) << (i * 8);
    }
    fseek(f_enc, 0, SEEK_END);
    long file_size = ftell(f_enc);
    fseek(f_enc, 0, SEEK_SET);
        uint8_t* encrypted_data = (uint8_t*)malloc(file_size);
    if (!encrypted_data) {
        printf("错误:内存分配失败\n");
        fclose(f_enc);
        fclose(f_out);
        return 1;
    }
    fclose(f_enc);
    memcpy(decrypted_data, encrypted_data, file_size);
    for (long i = 0; i <= file_size - 8; i += 8) {
        uint64_t* block = (uint64_t*)(decrypted_data + i);
        uint64_t encrypted = *block;
        uint64_t temp = encrypted;
        for (int j = 0; j < 8; j++) {
            uint8_t* byte_ptr = (uint8_t*)&temp + j;
            uint8_t key_byte = (key >> (j * 8)) & 0xFF;
            *byte_ptr = (*byte_ptr - key_byte) & 0xFF;
        }
        temp = (temp >> 1) | (temp << 63);
        uint64_t swapped = 0;
        for (int j = 0; j < 4; j++) {
            uint16_t word = (temp >> (j * 16)) & 0xFFFF;
            word = ((word & 0xFF) << 8) | ((word & 0xFF00) >> 8);
            swapped |= (uint64_t)word << (j * 16);
        }
        temp = swapped;
        temp = temp ^ key;
        *block = temp;
    }
    fclose(f_out);
    free(encrypted_data);
    free(decrypted_data);
    return 0;
}
int main() {
    int result = decrypt_file("encode.dat", "encode.dat.key", "decoded.txt");
    if (result == 0) {
        printf("\n解密完成!请检查 decoded.txt 文件。\n");
    } else {
        printf("\n解密失败!\n");
    }
    
    return result;
}

第一话:起源
https://boke-git-main-huang-chaos-projects.vercel.app/2025/10/17/第一话-起源/
作者
Ined
发布于
2025年10月17日
许可协议