首页
社区
课程
招聘
[原创]Enigma Virtual Box 分析(KCTF2025 第九题 智斗邪首)
发表于: 2025-9-18 13:11 3135

[原创]Enigma Virtual Box 分析(KCTF2025 第九题 智斗邪首)

2025-9-18 13:11
3135

首先运行htg_Crackme.exe后 附加到进程

然后调试->窗口->模块 列出内存加载的模块

最后保存模块

查看脱壳后的文件,发现.NET.VirtualAddress和.NET.Size都不为0

说明Enigma在运行时修改了0x178和0x17c的值

可以先手动修改.NET.VirtualAddress值为0x400和.NET.Size为0x48,.NET的反编译代码就出来了

虽然可以看到.NET的代码,但是程序无法运行

如何恢复所有的被Enigma修改的PE头,可以在.NET.VirtualAddress的0x00000178处下内存的写断点;
程序断在了sub_1407E5560这个恢复PE头的函数;

首先是恢复PE NumberOfSections = 2 的代码

然后是.text PointerToRawData对齐.text VirtualAddress 和 .rsrc PointerToRawData对齐.rsrc VirtualAddress

最后将.NET.VirtualAddress设置为0x2000和.NET.Size设置为0x48 ,其他的值设置为0;

通过分析可知,AddressOfEntryPoint Exception.VirtualAddress Exception.Size TLS.VirtualAddress TLS.Size 这五个的值为硬编码0;其余的值是通过cs:qword_14084D050+偏移地址动态获取的;
继续下内存的写断点,程序断在了loc_1407AD150处;

loc_1407AD150是一系列的读值赋值操作

动态分析其值的来源发现其来自0x00000001407A8068开始的地址,位于enigma1的TlsCallbacks处;

根据以上的分析可以编写静态脱壳代码:

运行结果

mov     rax, [rbp+var_28]
sub     word ptr [rax+6], 2 ; 0x0000000140000086 = 0x2 (PE NumberOfSections)
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
sub     eax, 1
test    eax, eax
jl      short loc_1407E5630
mov     rax, [rbp+var_28]
sub     word ptr [rax+6], 2 ; 0x0000000140000086 = 0x2 (PE NumberOfSections)
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
sub     eax, 1
test    eax, eax
jl      short loc_1407E5630
loc_1407E5600:
add     [rbp+var_10], 1
mov     r9, [rbp+var_28]
mov     edx, [rbp+var_10]
imul    r8, rdx, 28h ; '('
mov     rcx, [rbp+var_28]
mov     edx, [rbp+var_10]
imul    rdx, 28h ; '('
mov     edx, [rcx+rdx+114h] ; 0x0000000140000194(.text VirtualAddress)
                        ; 0x00000001400001BC(.rsrc VirtualAddress)
mov     [r9+r8+11Ch], edx ; 0X000000014000019C = 0X2000(.text PointerToRawData)
                        ; 0X00000001400001C4 = 0X7A6000(.rsrc PointerToRawData)
cmp     eax, [rbp+var_10]
jg      short loc_1407E5600
loc_1407E5600:
add     [rbp+var_10], 1
mov     r9, [rbp+var_28]
mov     edx, [rbp+var_10]
imul    r8, rdx, 28h ; '('
mov     rcx, [rbp+var_28]
mov     edx, [rbp+var_10]
imul    rdx, 28h ; '('
mov     edx, [rcx+rdx+114h] ; 0x0000000140000194(.text VirtualAddress)
                        ; 0x00000001400001BC(.rsrc VirtualAddress)
mov     [r9+r8+11Ch], edx ; 0X000000014000019C = 0X2000(.text PointerToRawData)
                        ; 0X00000001400001C4 = 0X7A6000(.rsrc PointerToRawData)
cmp     eax, [rbp+var_10]
jg      short loc_1407E5600
loc_1407E5630:
mov     r8, [rbp+var_28]
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
imul    rdx, rax, 28h ; '('
mov     rcx, [rbp+var_28]
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
imul    rax, 28h ; '('
mov     edx, [r8+rdx+0ECh]
mov     eax, [rcx+rax+0E8h]
lea     ecx, [edx+eax]
mov     rax, [rbp+var_28]
mov     edx, [rax+38h]
call    sub_1407E5510   ; 计算文件大小
mov     rdx, [rbp+var_28] ; 0X0000000140000080
mov     [rdx+50h], eax  ; 0X00000001400000D0 = 0X7A8000(PE SizeOfImage)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+78h]
mov     [rdx+90h], eax  ; 0X0000000140000110 = 0X0(PE Import.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+7Ch]
mov     [rdx+94h], eax  ; 0X0000000140000114 = 0X0(PE Import.Size)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+28h], 0 ; 0X00000001400000A8 = 0X0(PE AddressOfEntryPoint)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0A0h], 0 ; 0X0000000140000120 = 0X0(PE Exception.VirtualAddress)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0A4h], 0 ; 0X0000000140000124 = 0X0(PE Exception.Size)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+80h]
mov     [rdx+0B0h], eax ; 0X0000000140000130 = 0X0(PE Base Reloc.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+84h]
mov     [rdx+0B4h], eax ; 0X0000000140000134 = 0X0(PE Base Reloc.Size)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+88h]
mov     [rdx+0F8h], eax ; 0X0000000140000178 = 0X2000(PE .NET.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+8Ch]
mov     [rdx+0FCh], eax ; 0X000000014000017C = 0X48(PE .NET.Size)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0D0h], 0 ; 0x0000000140000150 = 0x0(PE TLS.VirtualAddress)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0D4h], 0 ; 0x0000000140000154 = 0x0(PE TLS.Size)
mov     rax, [rbp+var_28]
mov     edx, [rax+54h]  ; dwSize
lea     r9, [rbp+flOldProtect] ; lpflOldProtect
mov     r8d, [rbp+flOldProtect] ; flNewProtect
mov     rcx, cs:lpAddress ; lpAddress
call    VirtualProtect
loc_1407E5630:
mov     r8, [rbp+var_28]
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
imul    rdx, rax, 28h ; '('
mov     rcx, [rbp+var_28]
mov     rax, [rbp+var_28]
movzx   eax, word ptr [rax+6]
imul    rax, 28h ; '('
mov     edx, [r8+rdx+0ECh]
mov     eax, [rcx+rax+0E8h]
lea     ecx, [edx+eax]
mov     rax, [rbp+var_28]
mov     edx, [rax+38h]
call    sub_1407E5510   ; 计算文件大小
mov     rdx, [rbp+var_28] ; 0X0000000140000080
mov     [rdx+50h], eax  ; 0X00000001400000D0 = 0X7A8000(PE SizeOfImage)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+78h]
mov     [rdx+90h], eax  ; 0X0000000140000110 = 0X0(PE Import.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+7Ch]
mov     [rdx+94h], eax  ; 0X0000000140000114 = 0X0(PE Import.Size)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+28h], 0 ; 0X00000001400000A8 = 0X0(PE AddressOfEntryPoint)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0A0h], 0 ; 0X0000000140000120 = 0X0(PE Exception.VirtualAddress)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0A4h], 0 ; 0X0000000140000124 = 0X0(PE Exception.Size)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+80h]
mov     [rdx+0B0h], eax ; 0X0000000140000130 = 0X0(PE Base Reloc.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+84h]
mov     [rdx+0B4h], eax ; 0X0000000140000134 = 0X0(PE Base Reloc.Size)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+88h]
mov     [rdx+0F8h], eax ; 0X0000000140000178 = 0X2000(PE .NET.VirtualAddress)
mov     rdx, [rbp+var_28]
mov     rax, cs:qword_14084D050
mov     eax, [rax+8Ch]
mov     [rdx+0FCh], eax ; 0X000000014000017C = 0X48(PE .NET.Size)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0D0h], 0 ; 0x0000000140000150 = 0x0(PE TLS.VirtualAddress)
mov     rax, [rbp+var_28]
mov     dword ptr [rax+0D4h], 0 ; 0x0000000140000154 = 0x0(PE TLS.Size)
mov     rax, [rbp+var_28]
mov     edx, [rax+54h]  ; dwSize
lea     r9, [rbp+flOldProtect] ; lpflOldProtect
mov     r8d, [rbp+flOldProtect] ; flNewProtect
mov     rcx, cs:lpAddress ; lpAddress
call    VirtualProtect
loc_1407AD150:
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+68h]  ; 0x1407A8068
mov     [rdx+68h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     rax, [rax+70h]  ; 0x1407A8070
mov     [rdx+70h], rax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+78h]  ; 0x1407A8078
mov     [rdx+78h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+7Ch]  ; 0x1407A807C
mov     [rdx+7Ch], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+80h]  ; 0x1407A8080
mov     [rdx+80h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+84h]  ; 0x1407A8084
mov     [rdx+84h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+88h]  ; 0x1407A8088
mov     [rdx+88h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+8Ch]  ; 0x1407A808C
mov     [rdx+8Ch], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+0B0h] ; 0x1407A80B0
mov     [rdx+90h], eax
mov     rdx, cs:qword_14084D050
mov     rax, cs:qword_14084D050
cmp     dword ptr [rax+88h], 0
setnz   byte ptr [rdx+94h]
mov     rcx, cs:qword_14084CFC0
call    sub_1407E5560
loc_1407AD150:
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+68h]  ; 0x1407A8068
mov     [rdx+68h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     rax, [rax+70h]  ; 0x1407A8070
mov     [rdx+70h], rax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+78h]  ; 0x1407A8078
mov     [rdx+78h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+7Ch]  ; 0x1407A807C
mov     [rdx+7Ch], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+80h]  ; 0x1407A8080
mov     [rdx+80h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+84h]  ; 0x1407A8084
mov     [rdx+84h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+88h]  ; 0x1407A8088
mov     [rdx+88h], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+8Ch]  ; 0x1407A808C
mov     [rdx+8Ch], eax
mov     rdx, cs:qword_14084D050
mov     rax, [rbp+var_30]
mov     eax, [rax+0B0h] ; 0x1407A80B0
mov     [rdx+90h], eax
mov     rdx, cs:qword_14084D050
mov     rax, cs:qword_14084D050
cmp     dword ptr [rax+88h], 0
setnz   byte ptr [rdx+94h]
mov     rcx, cs:qword_14084CFC0
call    sub_1407E5560
* 修复字段  脱壳文件偏移  值来源/计算方式    描述
* NumberOfSections  0x86    固定值: 0x2    节区数量设置为2
* .text PointerToRawData    0x19C   原始文件偏移: 0x194   .text节区的文件偏移
* .rsrc PointerToRawData    0x1C4   原始文件偏移: 0x1BC   .rsrc节区的文件偏移
* SizeOfImage   0xD0    计算值: (原始文件0x7A4690 + 原始文件0x7A4694) 按0x2000对齐    映像大小
* AddressOfEntryPoint   0xA8    固定值: 0x0    入口点地址
* Exception.VirtualAddress  0x120   固定值: 0x0    异常表虚拟地址
* Exception.Size    0x124   固定值: 0x0    异常表大小
* TLS.VirtualAddress    0x150   固定值: 0x0    TLS表虚拟地址
* TLS.Size  0x154   固定值: 0x0    TLS表大小
* Import.VirtualAddress 0x110   原始文件偏移: 0x7A4678    导入表虚拟地址
* Import.Size   0x114   原始文件偏移: 0x7A467C    导入表大小
* BaseReloc.VirtualAddress  0x130   原始文件偏移: 0x7A4680    重定位表虚拟地址
* BaseReloc.Size    0x134   原始文件偏移: 0x7A4684    重定位表大小
* .NET.VirtualAddress   0x178   原始文件偏移: 0x7A4688    .NET头虚拟地址
* .NET.Size 0x17C   原始文件偏移: 0x7A468C    .NET头大小
* 修复字段  脱壳文件偏移  值来源/计算方式    描述
* NumberOfSections  0x86    固定值: 0x2    节区数量设置为2
* .text PointerToRawData    0x19C   原始文件偏移: 0x194   .text节区的文件偏移
* .rsrc PointerToRawData    0x1C4   原始文件偏移: 0x1BC   .rsrc节区的文件偏移
* SizeOfImage   0xD0    计算值: (原始文件0x7A4690 + 原始文件0x7A4694) 按0x2000对齐    映像大小
* AddressOfEntryPoint   0xA8    固定值: 0x0    入口点地址
* Exception.VirtualAddress  0x120   固定值: 0x0    异常表虚拟地址
* Exception.Size    0x124   固定值: 0x0    异常表大小
* TLS.VirtualAddress    0x150   固定值: 0x0    TLS表虚拟地址
* TLS.Size  0x154   固定值: 0x0    TLS表大小
* Import.VirtualAddress 0x110   原始文件偏移: 0x7A4678    导入表虚拟地址
* Import.Size   0x114   原始文件偏移: 0x7A467C    导入表大小
* BaseReloc.VirtualAddress  0x130   原始文件偏移: 0x7A4680    重定位表虚拟地址
* BaseReloc.Size    0x134   原始文件偏移: 0x7A4684    重定位表大小
* .NET.VirtualAddress   0x178   原始文件偏移: 0x7A4688    .NET头虚拟地址
* .NET.Size 0x17C   原始文件偏移: 0x7A468C    .NET头大小
import struct
import os
 
def mmap():
    # 定义输入和输出文件名
    input_file = "./htg_Crackme.exe"
    output_file = "./htg_Crackme.exeunpacked.exe"
     
    try:
        # 打开原始文件
        with open(input_file, "rb") as f_in:
            # 创建输出文件
            with open(output_file, "wb") as f_out:
                # 1. 读取前0x2000字节数据到新文件
                first_part = f_in.read(0x2000)
                f_out.write(first_part)
                 
                # 2. 定位到原始文件的0x400位置
                f_in.seek(0x400)
                 
                # 3. 计算需要读取的字节数
                read_size = 0x7a4000 - 0x400
                second_part = f_in.read(read_size)
                f_out.write(second_part)
 
                # 4. 在新文件的0x7A5C00处填充0x00
                padding_size = 0x400
                padding = b'\x00' * padding_size
                f_out.write(padding)
 
                # 5. 定位到原始文件的0x7a4000位置
                f_in.seek(0x7a4000)
                read_size = 0x7a4600 - 0x7a4000
                third_part = f_in.read(read_size)
                f_out.write(third_part)
 
                # # 6. 在新文件的0x7A6600处填充0x00
                padding_size = 0xA00
                padding = b'\x00' * padding_size
                f_out.write(padding)
 
                print("\n建立内存映射完成!")
                 
    except FileNotFoundError:
        print(f"错误: 找不到文件 {input_file}")
    except Exception as e:
        print(f"发生错误: {str(e)}")
 
 
def read_byte_at_offset(file_path, offset):
    """从文件指定偏移读取1字节值"""
    with open(file_path, 'rb') as f:
        f.seek(offset)
        data = f.read(1)
        return struct.unpack('<B', data)[0] if data else 0
 
def read_word_at_offset(file_path, offset):
    """从文件指定偏移读取2字节值"""
    with open(file_path, 'rb') as f:
        f.seek(offset)
        data = f.read(2)
        return struct.unpack('<H', data)[0] if len(data) == 2 else 0
 
def read_dword_at_offset(file_path, offset):
    """从文件指定偏移读取4字节值"""
    with open(file_path, 'rb') as f:
        f.seek(offset)
        data = f.read(4)
        return struct.unpack('<I', data)[0] if len(data) == 4 else 0
 
def write_byte_at_offset(file_path, offset, value):
    """向文件指定偏移写入1字节值"""
    with open(file_path, 'r+b') as f:
        f.seek(offset)
        f.write(struct.pack('<B', value))
 
def write_word_at_offset(file_path, offset, value):
    """向文件指定偏移写入2字节值"""
    with open(file_path, 'r+b') as f:
        f.seek(offset)
        f.write(struct.pack('<H', value))
 
def write_dword_at_offset(file_path, offset, value):
    """向文件指定偏移写入4字节值"""
    with open(file_path, 'r+b') as f:
        f.seek(offset)
        f.write(struct.pack('<I', value))
 
def fix_pe_header(original_file, unpacked_file):
    """
    修复脱壳后文件的PE头
    从原始带壳文件读取值,写入脱壳后文件的PE头相应位置
    """
    print("开始修复PE头...")
 
    # PE NumberOfSections 修复为2
    write_word_at_offset(unpacked_file, 0x86, 2)
    print(f"修复 NumberOfSections: 0x2 (写入脱壳文件 0x86)")
 
    # PE .text PointerToRawData 和 .text VirtualAddress 对齐
    # PE .rsrc PointerToRawData 和 .rsrc VirtualAddress 对齐
    field_mappings = [
        (0x194, 0x19C, ".text PointerToRawData"),
        (0x1BC, 0x1C4, ".rsrc PointerToRawData")
    ]
         
    # 处理每个字段映射
    for original_file_offset, pe_header_offset, description in field_mappings:       
        # 从原始文件读取值
        value = read_dword_at_offset(original_file, original_file_offset)
         
        # 写入脱壳后文件
        write_dword_at_offset(unpacked_file, pe_header_offset, value)
         
        print(f"修复 {description}: 0x{value:08X} (从原始文件 0x{original_file_offset:08X} 写入脱壳文件 0x{pe_header_offset:08X})")
     
    struct_rva = 0x7A4600
    size_image_value = read_dword_at_offset(original_file, struct_rva + 0x90)
    size_image_value_ = read_dword_at_offset(original_file, struct_rva + 0x94)
    size_image = size_image_value + size_image_value_
    mod_value = size_image % 0x2000
    size_image = size_image + 0x2000 - mod_value
 
    field_mappings = [
        (size_image, 0xD0, "SizeOfImage"),
        (0x0, 0xA8, "AddressOfEntryPoint"),
        (0x0, 0x120, "Exception.VirtualAddress"),
        (0x0, 0x124, "Exception.Size"),
        (0x0, 0x150, "TLS.VirtualAddress"),
        (0x0, 0x154, "TLS.Size")
    ]
         
    # 处理每个字段映射
    for value, pe_header_offset, description in field_mappings:               
        # 写入脱壳后文件
        write_dword_at_offset(unpacked_file, pe_header_offset, value)
         
        print(f"修复 {description}: 0x{value:08X} (写入脱壳文件 0x{pe_header_offset:08X})")
     
 
    struct_rva = 0x7A4600  # 根据实际文件偏移调整
     
    # 定义需要修复的字段映射
    # 格式: (原始文件结构体偏移, 脱壳文件PE头偏移, 描述)
    field_mappings = [
        (0x78, 0x110, "Import.VirtualAddress"),
        (0x7C, 0x114, "Import.Size"),
        (0x80, 0x130, "BaseReloc.VirtualAddress"),
        (0x84, 0x134, "BaseReloc.Size"),
        (0x88, 0x178, ".NET.VirtualAddress"),
        (0x8C, 0x17C, ".NET.Size")
    ]
         
    # 处理每个字段映射
    for struct_offset, pe_header_offset, description in field_mappings:
        # 计算原始文件中的绝对偏移
        original_file_offset = struct_rva + struct_offset
         
        # 从原始文件读取值
        value = read_dword_at_offset(original_file, original_file_offset)
         
        # 写入脱壳后文件
        write_dword_at_offset(unpacked_file, pe_header_offset, value)
         
        print(f"修复 {description}: 0x{value:08X} (从原始文件 0x{original_file_offset:08X} 写入脱壳文件 0x{pe_header_offset:08X})")
 
    print("PE头修复完成!")
 
def fix():
    # 文件路径
    original_file = "./dnSpy-net-win64/Crackme.exe"  # 原始带壳文件
    unpacked_file = "./dnSpy-net-win64/Crackme_unpacked.exe"  # 脱壳后的文件
     
    # 检查文件是否存在
    if not os.path.exists(original_file):
        print(f"错误: 找不到原始文件 {original_file}")
        exit(1)
     
    if not os.path.exists(unpacked_file):
        print(f"错误: 找不到脱壳文件 {unpacked_file}")
        exit(1)
     
    # 修复PE头
    fix_pe_header(original_file, unpacked_file)
 
if __name__ == "__main__":
    mmap()
    fix()
import struct
import os
 
def mmap():
    # 定义输入和输出文件名
    input_file = "./htg_Crackme.exe"
    output_file = "./htg_Crackme.exeunpacked.exe"
     
    try:
        # 打开原始文件
        with open(input_file, "rb") as f_in:
            # 创建输出文件
            with open(output_file, "wb") as f_out:
                # 1. 读取前0x2000字节数据到新文件
                first_part = f_in.read(0x2000)
                f_out.write(first_part)
                 
                # 2. 定位到原始文件的0x400位置
                f_in.seek(0x400)
                 
                # 3. 计算需要读取的字节数
                read_size = 0x7a4000 - 0x400
                second_part = f_in.read(read_size)
                f_out.write(second_part)
 
                # 4. 在新文件的0x7A5C00处填充0x00
                padding_size = 0x400
                padding = b'\x00' * padding_size
                f_out.write(padding)
 

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2025-9-27 22:08 被kanxue编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 32
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
谢谢分享
2025-9-29 13:40
0
游客
登录 | 注册 方可回帖
返回