矩阵杯2024 Re wp 前两题

1. packpy

UPX壳,但不能直接脱,应该是修改了头文件(l_info)

改一下就能脱了

脱完是个elf文件

进IDA看一眼

明显的Py打包标志,用pyinstxtractor解包出来(最好用对应的python3.8)

可以得到packpy.pyc文件,反编译得

import base58, zlib, marshal
try:scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'exec(marshal.loads(zlib.decompress(base58.b58decode(scrambled_code_string))))
except:pass

代码base58编码之后zlib压缩,然后marshal序列化了

稍微改一下就能看到类似字节码的东西

import base58, zlib, marshal
try:scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'print(zlib.decompress(base58.b58decode(scrambled_code_string)))
except:pass

法一:直接转为pyc

把marshal序列化后的文件取出来

import base58, zlib, marshal
try:scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'print(zlib.decompress(base58.b58decode(scrambled_code_string)))with open("dump", "wb") as f:d = zlib.decompress(base58.b58decode(scrambled_code_string))marshal.dump(d, f)
except:pass

添加pyc头

之后反编译

# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8import random
encdata = b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff'def generate_key(seed_value):key = list(range(256))random.seed(seed_value)random.shuffle(key)return bytes(key)def encrypt(data, key):encrypted = bytearray()for byte in data:encrypted.append(key[byte] ^ 95)return bytes(encrypted)try:flag = input('input your flag:')key = generate_key(len(flag))data = flag.encode()encrypted_data = encrypt(data, key)if encrypted_data == encdata:print('good')
finally:pass
return None

逆一下

import random
encdata = b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff'def generate_key(seed_value):key = list(range(256))random.seed(seed_value)random.shuffle(key)return bytes(key)def idx(value, key):for i in range(256):if key[i]==value:return idef decrypt(enc, key):flag = ''for i in encdata:flag += chr(idx(i^95, key))return flagkey = generate_key(len(encdata))
flag = decrypt(encdata, key) 
print(flag)
#flag{mar3hal_Is_3asy_t0_r3v3rse!!@}
法二:提取字节码

当时想的就是这个方法,不过有python版本问题,应该用3.8的,不然会报错

import base58
import zlib
import marshal# The scrambled code string
scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'# Step 1: Base58 decode
decoded_data = base58.b58decode(scrambled_code_string)# Step 2: Decompress using zlib
decompressed_data = zlib.decompress(decoded_data)# Step 3: Unmarshal the data
original_code = marshal.loads(decompressed_data)import dis# Disassemble the code object to inspect its content
dis.dis(original_code)# Print the original code
print(original_code)
  1           0 LOAD_CONST               0 (0)2 LOAD_CONST               1 (None)4 IMPORT_NAME              0 (random)6 STORE_NAME               0 (random)3           8 LOAD_CONST               2 (b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff')10 STORE_NAME               1 (encdata)5          12 LOAD_CONST               3 (<code object generate_key at 0x000001F1E47BAC90, file "run.py", line 5>)14 LOAD_CONST               4 ('generate_key')16 MAKE_FUNCTION            018 STORE_NAME               2 (generate_key)12          20 LOAD_CONST               5 (<code object encrypt at 0x000001F1E47BA870, file "run.py", line 12>)22 LOAD_CONST               6 ('encrypt')24 MAKE_FUNCTION            026 STORE_NAME               3 (encrypt)19          28 SETUP_FINALLY           58 (to 88)20          30 LOAD_NAME                4 (input)32 LOAD_CONST               7 ('input your flag:')34 CALL_FUNCTION            136 STORE_NAME               5 (flag)21          38 LOAD_NAME                2 (generate_key)40 LOAD_NAME                6 (len)42 LOAD_NAME                5 (flag)44 CALL_FUNCTION            146 CALL_FUNCTION            148 STORE_NAME               7 (key)22          50 LOAD_NAME                5 (flag)52 LOAD_METHOD              8 (encode)54 CALL_METHOD              056 STORE_NAME               9 (data)23          58 LOAD_NAME                3 (encrypt)60 LOAD_NAME                9 (data)62 LOAD_NAME                7 (key)64 CALL_FUNCTION            266 STORE_NAME              10 (encrypted_data)25          68 LOAD_NAME               10 (encrypted_data)70 LOAD_NAME                1 (encdata)72 COMPARE_OP               2 (==)74 POP_JUMP_IF_FALSE       8426          76 LOAD_NAME               11 (print)78 LOAD_CONST               8 ('good')80 CALL_FUNCTION            182 POP_TOP>>   84 POP_BLOCK86 JUMP_FORWARD            12 (to 100)27     >>   88 POP_TOP90 POP_TOP92 POP_TOP28          94 POP_EXCEPT96 JUMP_FORWARD             2 (to 100)98 END_FINALLY>>  100 LOAD_CONST               1 (None)102 RETURN_VALUEDisassembly of <code object generate_key at 0x000001F1E47BAC90, file "run.py", line 5>:7           0 LOAD_GLOBAL              0 (list)2 LOAD_GLOBAL              1 (range)4 LOAD_CONST               1 (256)6 CALL_FUNCTION            18 CALL_FUNCTION            110 STORE_FAST               1 (key)8          12 LOAD_GLOBAL              2 (random)14 LOAD_METHOD              3 (seed)16 LOAD_FAST                0 (seed_value)18 CALL_METHOD              120 POP_TOP9          22 LOAD_GLOBAL              2 (random)24 LOAD_METHOD              4 (shuffle)26 LOAD_FAST                1 (key)28 CALL_METHOD              130 POP_TOP10          32 LOAD_GLOBAL              5 (bytes)34 LOAD_FAST                1 (key)36 CALL_FUNCTION            138 RETURN_VALUEDisassembly of <code object encrypt at 0x000001F1E47BA870, file "run.py", line 12>:14           0 LOAD_GLOBAL              0 (bytearray)2 CALL_FUNCTION            04 STORE_FAST               2 (encrypted)15           6 LOAD_FAST                0 (data)8 GET_ITER>>   10 FOR_ITER                22 (to 34)12 STORE_FAST               3 (byte)16          14 LOAD_FAST                2 (encrypted)16 LOAD_METHOD              1 (append)18 LOAD_FAST                1 (key)20 LOAD_FAST                3 (byte)22 BINARY_SUBSCR24 LOAD_CONST               1 (95)26 BINARY_XOR28 CALL_METHOD              130 POP_TOP32 JUMP_ABSOLUTE           1017     >>   34 LOAD_GLOBAL              2 (bytes)36 LOAD_FAST                2 (encrypted)38 CALL_FUNCTION            140 RETURN_VALUE
<code object <module> at 0x000001F1E47BD030, file "run.py", line 1>

或者用这篇博客的脚本

https://www.cnblogs.com/Chang-LeHung/p/17266334.html

import base58, zlib
import marshal
import dis
import struct
import time
import types
import binasciidef print_metadata(fp):amagic = struct.unpack('<l', fp.read(4))[0]print(f"magic number = {hex(magic)}")bit_field = struct.unpack('<l', fp.read(4))[0]print(f"bit filed = {bit_field}")t = struct.unpack('<l', fp.read(4))[0]print(f"time = {time.asctime(time.localtime(t))}")file_size = struct.unpack('<l', fp.read(4))[0]print(f"file size = {file_size}")def show_code(code, indent=''):print ("%scode" % indent)indent += '   'print ("%sargcount %d" % (indent, code.co_argcount))print ("%snlocals %d" % (indent, code.co_nlocals))print ("%sstacksize %d" % (indent, code.co_stacksize))print ("%sflags %04x" % (indent, code.co_flags))show_hex("code", code.co_code, indent=indent)dis.disassemble(code)print ("%sconsts" % indent)for const in code.co_consts:if type(const) == types.CodeType:show_code(const, indent+'   ')else:print("   %s%r" % (indent, const))print("%snames %r" % (indent, code.co_names))print("%svarnames %r" % (indent, code.co_varnames))print("%sfreevars %r" % (indent, code.co_freevars))print("%scellvars %r" % (indent, code.co_cellvars))print("%sfilename %r" % (indent, code.co_filename))print("%sname %r" % (indent, code.co_name))print("%sfirstlineno %d" % (indent, code.co_firstlineno))show_hex("lnotab", code.co_lnotab, indent=indent)def show_hex(label, h, indent):h = binascii.hexlify(h)if len(h) < 60:print("%s%s %s" % (indent, label, h))else:print("%s%s" % (indent, label))for i in range(0, len(h), 60):print("%s   %s" % (indent, h[i:i+60]))if __name__ == '__main__':scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'code_object = marshal.loads(zlib.decompress(base58.b58decode(scrambled_code_string)))show_code(code_object)
codeargcount 0nlocals 0stacksize 6flags 0040codeb'640064016c005a0064025a016403640484005a026405640684005a037a3a'b'6504640783015a05650265066505830183015a076505a008a1005a096503'b'6509650783025a0a650a65016b027254650b64088301010057006e0c0100'b'0100010059006e02580064015300'1           0 LOAD_CONST               0 (0)2 LOAD_CONST               1 (None)4 IMPORT_NAME              0 (random)6 STORE_NAME               0 (random)3           8 LOAD_CONST               2 (b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff')10 STORE_NAME               1 (encdata)5          12 LOAD_CONST               3 (<code object generate_key at 0x00000257A48BEBE0, file "run.py", line 5>)14 LOAD_CONST               4 ('generate_key')16 MAKE_FUNCTION            018 STORE_NAME               2 (generate_key)12          20 LOAD_CONST               5 (<code object encrypt at 0x00000257A48BEA80, file "run.py", line 12>)22 LOAD_CONST               6 ('encrypt')24 MAKE_FUNCTION            026 STORE_NAME               3 (encrypt)19          28 SETUP_FINALLY           58 (to 88)20          30 LOAD_NAME                4 (input)32 LOAD_CONST               7 ('input your flag:')34 CALL_FUNCTION            136 STORE_NAME               5 (flag)21          38 LOAD_NAME                2 (generate_key)40 LOAD_NAME                6 (len)42 LOAD_NAME                5 (flag)44 CALL_FUNCTION            146 CALL_FUNCTION            148 STORE_NAME               7 (key)22          50 LOAD_NAME                5 (flag)52 LOAD_METHOD              8 (encode)54 CALL_METHOD              056 STORE_NAME               9 (data)23          58 LOAD_NAME                3 (encrypt)60 LOAD_NAME                9 (data)62 LOAD_NAME                7 (key)64 CALL_FUNCTION            266 STORE_NAME              10 (encrypted_data)25          68 LOAD_NAME               10 (encrypted_data)70 LOAD_NAME                1 (encdata)72 COMPARE_OP               2 (==)74 POP_JUMP_IF_FALSE       8426          76 LOAD_NAME               11 (print)78 LOAD_CONST               8 ('good')80 CALL_FUNCTION            182 POP_TOP>>   84 POP_BLOCK86 JUMP_FORWARD            12 (to 100)27     >>   88 POP_TOP90 POP_TOP92 POP_TOP28          94 POP_EXCEPT96 JUMP_FORWARD             2 (to 100)98 END_FINALLY>>  100 LOAD_CONST               1 (None)102 RETURN_VALUEconsts0Noneb'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff'codeargcount 1nlocals 2stacksize 3flags 0043codeb'740074016401830183017d017402a0037c00a10101007402a0047c01a101'b'010074057c0183015300'7           0 LOAD_GLOBAL              0 (list)2 LOAD_GLOBAL              1 (range)4 LOAD_CONST               1 (256)6 CALL_FUNCTION            18 CALL_FUNCTION            110 STORE_FAST               1 (key)8          12 LOAD_GLOBAL              2 (random)14 LOAD_METHOD              3 (seed)16 LOAD_FAST                0 (seed_value)18 CALL_METHOD              120 POP_TOP9          22 LOAD_GLOBAL              2 (random)24 LOAD_METHOD              4 (shuffle)26 LOAD_FAST                1 (key)28 CALL_METHOD              130 POP_TOP10          32 LOAD_GLOBAL              5 (bytes)34 LOAD_FAST                1 (key)36 CALL_FUNCTION            138 RETURN_VALUEconstsNone256names ('list', 'range', 'random', 'seed', 'shuffle', 'bytes')varnames ('seed_value', 'key')freevars ()cellvars ()filename 'run.py'name 'generate_key'firstlineno 5lnotab b'00020c010a010a01''generate_key'codeargcount 2nlocals 4stacksize 5flags 0043codeb'740083007d027c0044005d167d037c02a0017c017c03190064014100a101'b'0100710a74027c0283015300'14           0 LOAD_GLOBAL              0 (bytearray)2 CALL_FUNCTION            04 STORE_FAST               2 (encrypted)15           6 LOAD_FAST                0 (data)8 GET_ITER>>   10 FOR_ITER                22 (to 34)12 STORE_FAST               3 (byte)16          14 LOAD_FAST                2 (encrypted)16 LOAD_METHOD              1 (append)18 LOAD_FAST                1 (key)20 LOAD_FAST                3 (byte)22 BINARY_SUBSCR24 LOAD_CONST               1 (95)26 BINARY_XOR28 CALL_METHOD              130 POP_TOP32 JUMP_ABSOLUTE           1017     >>   34 LOAD_GLOBAL              2 (bytes)36 LOAD_FAST                2 (encrypted)38 CALL_FUNCTION            140 RETURN_VALUEconstsNone95names ('bytearray', 'append', 'bytes')varnames ('data', 'key', 'encrypted', 'byte')freevars ()cellvars ()filename 'run.py'name 'encrypt'firstlineno 12lnotab b'0002060108011401''encrypt''input your flag:''good'names ('random', 'encdata', 'generate_key', 'encrypt', 'input', 'flag', 'len', 'key', 'encode', 'data', 'encrypted_data', 'print')varnames ()freevars ()cellvars ()filename 'run.py'name '<module>'firstlineno 1lnotab b'0802040208070807020108010c0108010a0208010c010601'

然后逆字节码就是了

2. jvm

IDA看一下

是Quickjs

GitHub - bellard/quickjs: Public repository of the QuickJS Javascript Engine.

下载好源码之后直接在文件夹内make进行编译(这道题需要最新版本,就是上面链接的版本)

参考该文章

[讨论] 看雪.安恒2020 KCTF春季赛 第三题 寻踪觅源 Writeup-CTF对抗-看雪-安全社区|安全招聘|kanxue.com

quickjs本身是有输出字节码的功能的,需要我们对quickjs.c文件进行一些修改

首先在宏定义部分把这一行#define DUMP_BYTECODE  (1)的注释删去

还有#define DUMP_READ_OBJECT

这个位置加一段,输出字节码

修改后需要把题目文件的字节码加载进去

qjsc_src就是字节码,取出来做一个.c文件

#include "quickjs-libc.h"const uint32_t qjsc_hello_size = 3881;const uint8_t qjsc_hello[3884] = {...
};int main(int argc, char **argv)
{JSRuntime *rt;JSContext *ctx;rt = JS_NewRuntime();ctx = JS_NewContextRaw(rt);JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);JS_AddIntrinsicBaseObjects(ctx);JS_AddIntrinsicDate(ctx);JS_AddIntrinsicEval(ctx);JS_AddIntrinsicStringNormalize(ctx);JS_AddIntrinsicRegExp(ctx);JS_AddIntrinsicJSON(ctx);JS_AddIntrinsicProxy(ctx);JS_AddIntrinsicMapSet(ctx);JS_AddIntrinsicTypedArrays(ctx);JS_AddIntrinsicPromise(ctx);JS_AddIntrinsicBigInt(ctx);js_std_add_helpers(ctx, argc, argv);js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0);js_std_loop(ctx);JS_FreeContext(ctx);JS_FreeRuntime(rt);return 0;
}

gcc -ggdb jvm.c libquickjs.a -lm -ldl

./a.out

执行一下,就可输出字节码

主要逻辑是runVM和eval两个函数

还定义了一些虚拟机指令,但是内容和名字不太一样,非常抽象

./src.js:127: function: runVMlocals:0: var flag1: var regId2: var num3: var regid14: var regid25: var regid6: var bufIdx7: var dataIdxstack_size: 6opcodes:push_0 0put_loc0 0: flag2:  get_var programget_var ipget_array_elpush_0 0neqif_false 890get_var programget_var ipget_array_elpush_1 1eqif_false8 61get_var getRegcall0 0put_loc1 1: regIdget_var getNumcall0 0put_loc2 2: numget_var setRegget_loc1 1: regIdget_loc2 2: numcall2 2dropgoto16 87361:  get_var programget_var ipget_array_elpush_2 2eqif_false8 104get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var setReg2get_loc3 3: regid1get_loc8 4: regid2call2 2dropgoto16 873104:  get_var programget_var ipget_array_elpush_3 3eqif_false8 147get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var addRegget_loc3 3: regid1get_loc8 4: regid2call2 2dropgoto16 873147:  get_var programget_var ipget_array_elpush_4 4eqif_false8 190get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var subRegget_loc3 3: regid1get_loc8 4: regid2call2 2dropgoto16 873190:  get_var programget_var ipget_array_elpush_5 5eqif_false8 247get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elmulput_array_elgoto16 873247:  get_var programget_var ipget_array_elpush_6 6eqif_false8 310get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var parseIntget_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elmodcall1 1put_array_elgoto16 873310:  get_var programget_var ipget_array_elpush_7 7eqif_false8 367get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elsarput_array_elgoto16 873367:  get_var programget_var ipget_array_elpush_i8 8eqif_false8 425get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elshlput_array_elgoto16 873425:  get_var programget_var ipget_array_elpush_i8 9eqif_false8 483get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elorput_array_elgoto16 873483:  get_var programget_var ipget_array_elpush_i8 10eqif_false8 541get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elxorput_array_elgoto16 873541:  get_var programget_var ipget_array_elpush_i8 11eqif_false8 599get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var REGget_loc3 3: regid1to_propkey2get_var REGget_loc3 3: regid1get_array_elget_var REGget_loc8 4: regid2get_array_elandput_array_elgoto16 873599:  get_var programget_var ipget_array_elpush_i8 12eqif_false8 641get_var getRegcall0 0put_loc1 1: regIdget_var getBytecall0 0put_loc2 2: numget_var cmpRegget_loc1 1: regIdget_loc2 2: numcall2 2dropgoto16 873641:  get_var programget_var ipget_array_elpush_i8 13eqif_false8 670get_var jneIpcall0 0droppush_1 1inc_loc 0: flaggoto16 873670:  get_var programget_var ipget_array_elpush_i8 14eqif_false8 696get_var jmpIpcall0 0dropgoto16 873696:  get_var programget_var ipget_array_elpush_i8 15eqif_false8 764get_var getRegcall0 0put_loc8 5: regidget_var getBytecall0 0put_loc8 6: bufIdxget_var getBytecall0 0put_loc8 7: dataIdxget_var REGget_loc8 5: regidto_propkey2get_var bufget_loc8 6: bufIdxget_array_elget_var REGget_loc8 7: dataIdxget_array_elget_array_elput_array_elgoto8 873764:  get_var programget_var ipget_array_elpush_i8 16eqif_false8 832get_var getBytecall0 0put_loc8 6: bufIdxget_var getBytecall0 0put_loc8 7: dataIdxget_var getRegcall0 0put_loc8 5: regidget_var bufget_loc8 6: bufIdxget_array_elget_var REGget_loc8 7: dataIdxget_array_elto_propkey2get_var REGget_loc8 5: regidget_array_elput_array_elgoto8 873832:  get_var programget_var ipget_array_elpush_i8 17eqif_false8 873get_var getRegcall0 0put_loc3 3: regid1get_var getRegcall0 0put_loc8 4: regid2get_var modRegget_loc3 3: regid1get_loc8 4: regid2call2 2drop873:  get_var ippush_1 1divdupput_var ipdropgoto16 2890:  return_undef

GPT翻译一下

def runVM(program, getReg, getNum, setReg, setReg2, addReg, subReg, mul, mod, sar, shl, or_, xor, and_, cmpReg, jneIp, jmpIp, getByte, buf, REG, modReg):flag = 0ip = 0while True:opcode = program[ip]if opcode == 0:breakelif opcode == 1:regId = getReg()num = getNum()setReg(regId, num)elif opcode == 2:regid1 = getReg()regid2 = getReg()setReg2(regid1, regid2)elif opcode == 3:regid1 = getReg()regid2 = getReg()addReg(regid1, regid2)elif opcode == 4:regid1 = getReg()regid2 = getReg()subReg(regid1, regid2)elif opcode == 5:regid1 = getReg()regid2 = getReg()REG[regid1] *= REG[regid2]elif opcode == 6:regid1 = getReg()regid2 = getReg()REG[regid1] = int(REG[regid1] % REG[regid2])elif opcode == 7:regid1 = getReg()regid2 = getReg()REG[regid1] = REG[regid1] >> REG[regid2]elif opcode == 8:regid1 = getReg()regid2 = getReg()REG[regid1] = REG[regid1] << REG[regid2]elif opcode == 9:regid1 = getReg()regid2 = getReg()REG[regid1] = REG[regid1] | REG[regid2]elif opcode == 10:regid1 = getReg()regid2 = getReg()REG[regid1] = REG[regid1] ^ REG[regid2]elif opcode == 11:regid1 = getReg()regid2 = getReg()REG[regid1] = REG[regid1] & REG[regid2]elif opcode == 12:regId = getReg()num = getByte()cmpReg(regId, num)elif opcode == 13:jneIp()flag += 1elif opcode == 14:jmpIp()elif opcode == 15:regid = getReg()bufIdx = getByte()dataIdx = getByte()REG[regid] = buf[bufIdx][REG[dataIdx]]elif opcode == 16:bufIdx = getByte()dataIdx = getByte()regid = getReg()buf[bufIdx][REG[dataIdx]] = REG[regid]elif opcode == 17:regid1 = getReg()regid2 = getReg()modReg(regid1, regid2)ip += 1

除了几个运算符,其他的函数作用和名字大致一样

def getReg(ip, program):# 获取变量 ip 的值ip_value = ip# 将 1 推送到堆栈,并将 ip_value 除以 1result = ip_value / 1# 复制结果result_copy = result# 将结果存储到变量 ipip = result_copy# 弹出堆栈顶部的值(在这里实际上不需要,因为 result_copy 已经存储了值)# 获取变量 program 的值program_value = program# 获取变量 ip 的值(已经在上面更新)ip_value = ip# 从数组 program 中获取索引为 ip_value 的元素array_element = program_value[int(ip_value)]# 返回获取的数组元素return array_elementdef getNum():# 初始化局部变量 sum 和 isum = 0i = 0# 循环执行操作while i < 4:ip = ip // 1sum += program[ip] // 16i += 1return sumdef setReg(regid, data):# 将 data 存入 regid 索引处的数组中REG[regid] = data# 返回 undefinedreturn Nonedef setReg2(regid1, regid2):# 将 regid2 索引处的值存入 regid1 索引处REG[regid1] = REG[regid2]# 返回 undefinedreturn Nonedef addReg(regid1, regid2):#除# 获取寄存器数组REG = globals().get('REG')# 获取寄存器数组中键为regid1的元素val1 = REG[regid1]# 获取寄存器数组中键为regid2的元素val2 = REG[regid2]# 对两个寄存器数组元素进行除法操作,并将结果放回寄存器数组中键为regid1的位置REG[regid1] = val1 / val2# 返回None(相当于JavaScript中的return undefined)return Nonedef subReg(regid1, regid2): #加# 获取寄存器数组REG = globals().get('REG')# 获取寄存器数组中键为regid1的元素val1 = REG[regid1]# 获取寄存器数组中键为regid2的元素val2 = REG[regid2]# 对两个寄存器数组元素进行加法操作,并将结果放回寄存器数组中键为regid1的位置REG[regid1] = val1 + val2# 返回None(相当于JavaScript中的return undefined)return Nonedef modReg(regid1, regid2):#减# 获取寄存器数组REG = globals().get('REG')# 获取寄存器数组中键为reg1的元素val1 = REG[reg1]# 获取寄存器数组中键为reg2的元素val2 = REG[reg2]# 对两个寄存器数组元素进行减法操作,并将结果放回寄存器数组中键为reg1的位置REG[reg1] = val1 - val2# 返回None(相当于JavaScript中的return undefined)return Nonedef cmpReg(regid, num, REG, FLAG):# 获取变量 REG 的值REG_value = REG# 获取第一个参数 regid 的值regid_value = regid# 从数组 REG 中获取索引为 regid_value 的元素reg_value = REG_value[int(regid_value)]# 获取第二个参数 num 的值num_value = num# 比较 reg_value 和 num_value 是否相等if reg_value == num_value:# 将 1 存储到变量 FLAGFLAG = 1else:# 否则返回 undefined(在Python中用 None 表示)return None# 返回 undefined(在Python中用 None 表示)return Nonedef jneIp():# 获取 getNum 函数的返回值addrTrue = getNum()# 如果 FLAG 不等于 1,则跳转到 addrTrue+1 处if FLAG != 1:ip = addrTrue + 1FLAG = 0return Noneelse:FLAG = 0return Nonedef jmpIp():# 获取 getNum 函数的返回值addr = getNum()# 将 ip 设置为 addr + 1ip = addr + 1return Nonedef getByte():# 计算并获取 program[ip] 的值byte = program[ip // 1]return byte

然后就是要通过opcode打印log,看看指令是什么

在eval函数开头可以看到一些变量的定义

比如说这个是定义ip

push_0 0
dup
put_var ip

这部分是定义program,稍加分析可以知道是opcode

        push_1 1push_1 1push_0 0push_0 0push_0 0push_0 0push_1 1push_2 2push_0 0push_0 0push_0 0push_0 0push_1 1push_3 3push_0 0push_0 0push_0 0push_0 0push_i8 16push_1 1push_1 1push_1 1push_1 1push_2 2push_0 0push_0 0push_0 0push_i8 8push_2 2push_3 3push_1 1push_i8 17array_from 32push_3 3define_field "32"push_2 2define_field "33"push_i8 15define_field "34"push_2 2define_field "35"push_3 3define_field "36"push_3 3define_field "37"push_i8 16define_field "38"push_2 2define_field "39"push_1 1define_field "40"push_2 2define_field "41"push_1 1define_field "42"push_2 2define_field "43"push_0 0define_field "44"push_0 0define_field "45"push_0 0define_field "46"push_1 1define_field "47"push_3 3define_field "48"push_1 1define_field "49"push_2 2define_field "50"push_i8 12define_field "51"push_1 1define_field "52"push_i16 256define_field "53"push_i8 13define_field "54"push_0 0define_field "55"push_0 0define_field "56"push_0 0define_field "57"push_i8 18define_field "58"push_1 1define_field "59"push_0 0define_field "60"push_0 0define_field "61"push_0 0define_field "62"push_0 0define_field "63"push_0 0define_field "64"push_1 1define_field "65"push_1 1define_field "66"push_0 0define_field "67"push_0 0define_field "68"push_0 0define_field "69"push_0 0define_field "70"push_i8 15define_field "71"push_2 2define_field "72"push_1 1define_field "73"push_0 0define_field "74"push_3 3define_field "75"push_1 1define_field "76"push_2 2define_field "77"push_i8 15define_field "78"push_2 2define_field "79"push_2 2define_field "80"push_0 0define_field "81"push_3 3define_field "82"push_1 1define_field "83"push_2 2define_field "84"push_1 1define_field "85"push_2 2define_field "86"push_0 0define_field "87"push_0 0define_field "88"push_0 0define_field "89"push_i16 256define_field "90"push_i8 17define_field "91"push_1 1define_field "92"push_2 2define_field "93"push_i8 15define_field "94"push_2 2define_field "95"push_1 1define_field "96"push_1 1define_field "97"push_i8 15define_field "98"push_3 3define_field "99"push_1 1define_field "100"push_0 0define_field "101"push_i8 16define_field "102"push_1 1define_field "103"push_0 0define_field "104"push_2 2define_field "105"push_i8 16define_field "106"push_1 1define_field "107"push_1 1define_field "108"push_3 3define_field "109"push_1 1define_field "110"push_2 2define_field "111"push_0 0define_field "112"push_0 0define_field "113"push_0 0define_field "114"push_1 1define_field "115"push_3 3define_field "116"push_0 0define_field "117"push_2 2define_field "118"push_i8 12define_field "119"push_0 0define_field "120"push_i16 256define_field "121"push_i8 13define_field "122"push_0 0define_field "123"push_0 0define_field "124"push_0 0define_field "125"push_i8 71define_field "126"push_1 1define_field "127"push_0 0define_field "128"push_0 0define_field "129"push_0 0define_field "130"push_0 0define_field "131"push_0 0define_field "132"push_1 1define_field "133"push_1 1define_field "134"push_0 0define_field "135"push_0 0define_field "136"push_0 0define_field "137"push_0 0define_field "138"push_1 1define_field "139"push_2 2define_field "140"push_0 0define_field "141"push_0 0define_field "142"push_0 0define_field "143"push_0 0define_field "144"push_1 1define_field "145"push_3 3define_field "146"push_0 0define_field "147"push_0 0define_field "148"push_0 0define_field "149"push_1 1define_field "150"push_3 3define_field "151"push_1 1define_field "152"push_3 3define_field "153"push_1 1define_field "154"push_3 3define_field "155"push_0 0define_field "156"push_0 0define_field "157"push_0 0define_field "158"push_i16 256define_field "159"push_i8 17define_field "160"push_1 1define_field "161"push_3 3define_field "162"push_i8 15define_field "163"push_3 3define_field "164"push_1 1define_field "165"push_1 1define_field "166"push_3 3define_field "167"push_2 2define_field "168"push_3 3define_field "169"push_1 1define_field "170"push_3 3define_field "171"push_0 0define_field "172"push_0 0define_field "173"push_0 0define_field "174"push_i16 256define_field "175"push_i8 17define_field "176"push_2 2define_field "177"push_3 3define_field "178"push_i8 15define_field "179"push_3 3define_field "180"push_1 1define_field "181"push_1 1define_field "182"push_i8 15define_field "183"push_4 4define_field "184"push_1 1define_field "185"push_2 2define_field "186"push_i8 16define_field "187"push_1 1define_field "188"push_2 2define_field "189"push_3 3define_field "190"push_i8 16define_field "191"push_1 1define_field "192"push_1 1define_field "193"push_4 4define_field "194"push_3 3define_field "195"push_3 3define_field "196"push_4 4define_field "197"push_1 1define_field "198"push_4 4define_field "199"push_0 0define_field "200"push_0 0define_field "201"push_0 0define_field "202"push_i16 256define_field "203"push_i8 17define_field "204"push_3 3define_field "205"push_4 4define_field "206"push_i8 15define_field "207"push_4 4define_field "208"push_0 0define_field "209"push_0 0define_field "210"push_i8 11define_field "211"push_4 4define_field "212"push_3 3define_field "213"push_i8 16define_field "214"push_0 0define_field "215"push_0 0define_field "216"push_4 4define_field "217"push_1 1define_field "218"push_4 4define_field "219"push_0 0define_field "220"push_0 0define_field "221"push_0 0define_field "222"push_1 1define_field "223"push_3 3define_field "224"push_0 0define_field "225"push_4 4define_field "226"push_i8 12define_field "227"push_0 0define_field "228"push_i8 27define_field "229"push_i8 13define_field "230"push_0 0define_field "231"push_0 0define_field "232"push_0 0define_field "233"push_i16 145define_field "234"push_0 0define_field "235"dupput_var program

gpt搓个脚本提取出来

import redef extract_numbers(data):# 使用正则表达式匹配指令后的数字pattern = re.compile(r'\bpush_\w+\s+(-?\d+)')# 查找所有匹配的数字numbers = pattern.findall(data)# 将匹配的数字转换为整数并返回return [int(num) for num in numbers]# 示例数据
data = """...
"""# 提取数字并存储到数组中
numbers = extract_numbers(data)
print(numbers)

并不是所有的值都在0-17之间,这是因为该指令集是几个opcode一组,因为有参数

像1指令是mov一个数进入寄存器内,第一个opcode是1,第二个是寄存器的编号1,第3-6个是小端序存储的数据

矩阵杯初赛逆向题解 – z221x-blog

参考该文章写log

#log
program = [1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 16, 1, 1, 1, 1, 2, 0, 0, 0, 8, 2, 3, 1, 17, 3, 2, 15, 2, 3, 3, 16, 2, 1, 2, 1, 2, 0, 0, 0, 1, 3, 1, 2, 12, 1, 256, 13, 0, 0, 0, 18, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 15, 2, 1, 0, 3, 1, 2, 15, 2, 2, 0, 3, 1, 2, 1, 2, 0, 0, 0, 256, 17, 1, 2, 15, 2, 1, 1, 15, 3, 1, 0, 16, 1, 0, 2, 16, 1, 1, 3, 1, 2, 0, 0, 0, 1, 3, 0, 2, 12, 0, 256, 13, 0, 0, 0, 71, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 3, 0, 0, 0, 1, 3, 1, 3, 1, 3, 0, 0, 0, 256, 17, 1, 3, 15, 3, 1, 1, 3, 2, 3, 1, 3, 0, 0, 0, 256, 17, 2, 3, 15, 3, 1, 1, 15, 4, 1, 2, 16, 1, 2, 3, 16, 1, 1, 4, 3, 3, 4, 1, 4, 0, 0, 0, 256, 17, 3, 4, 15, 4, 0, 0, 11, 4, 3, 16, 0, 0, 4, 1, 4, 0, 0, 0, 1, 3, 0, 4, 12, 0, 27, 13, 0, 0, 0, 145, 0]
ip = 0while True:if ip > 230:breakif program[ip] == 0:passelif program[ip] == 1:print("%d mov reg[%d],%d" % (ip, program[ip + 1], ((program[ip+2]*16+program[ip+3])*16+program[ip+4])*16+program[ip+5]))ip += 6elif program[ip] == 2:print("%d mov reg[%d],reg[%d]" % (ip, program[ip + 1],program[ip+2]))ip += 3elif program[ip] == 3:print("%d div reg[%d],reg[%d]" % (ip, program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 4:print("%d add reg[%d],reg[%d]" % (ip, program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 5: print(ip, "%d REG[%d] *= REG[%d]" % (ip, program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 6:print(ip, "%d REG[%d] = int(REG[%d] % REG[%d])" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 7:print(ip, "%d REG[%d] = REG[%d] >> REG[%d]" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 8:print("%d REG[%d] = REG[%d] << REG[%d]" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 9:print("%d REG[%d] = REG[%d] | REG[%d]" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 10:print("%d REG[%d] = REG[%d] ^ REG[%d]" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 11:print("%d REG[%d] = REG[%d] & REG[%d]" % (ip, program[ip + 1], program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 12:print("%d cmp reg[%d],%d" % (ip, program[ip + 1], program[ip + 2]))ip += 3elif program[ip] == 13:print("%d jne %d" % (ip, ((program[ip + 1] * 16 + program[ip + 2]) * 16 + program[ip + 3]) * 16 + program[ip + 4]))print("flag += 1")ip += 5elif program[ip] == 14:print("%d jmp %d" % (ip, ((program[ip + 1] * 16 + program[ip + 2]) * 16 + program[ip + 3]) * 16 + program[ip + 4]))ip += 5elif program[ip] == 15:print(ip, "REG[%d] = buf[%d][REG[%d]]" % (program[ip + 1], program[ip + 2], program[ip + 3]))ip += 4elif program[ip] == 16:print(ip, "buf[%d][REG[%d]] = REG[%d]" % (program[ip + 1], program[ip + 2], program[ip + 3]))ip += 4elif program[ip] == 17:print("%d sub reg[%d],reg[%d]" % (ip, program[ip + 1], program[ip + 2]))ip += 3
0 mov reg[1],0
6 mov reg[2],0
12 mov reg[3],0
18 buf[1][REG[1]] = REG[1]
22 mov reg[2],8
28 mov reg[3],reg[1]
31 sub reg[3],reg[2]
34 REG[2] = buf[3][REG[3]]
38 buf[2][REG[1]] = REG[2]
42 mov reg[2],1
48 div reg[1],reg[2]
51 cmp reg[1],256
54 jne 18
flag += 1
59 mov reg[0],0
65 mov reg[1],0
71 REG[2] = buf[1][REG[0]]
75 div reg[1],reg[2]
78 REG[2] = buf[2][REG[0]]
82 div reg[1],reg[2]
85 mov reg[2],256
91 sub reg[1],reg[2]
94 REG[2] = buf[1][REG[1]]
98 REG[3] = buf[1][REG[0]]
102 buf[1][REG[0]] = REG[2]
106 buf[1][REG[1]] = REG[3]
110 mov reg[2],1
116 div reg[0],reg[2]
119 cmp reg[0],256
122 jne 71
flag += 1
127 mov reg[0],0
133 mov reg[1],0
139 mov reg[2],0
145 mov reg[3],1
151 div reg[1],reg[3]
154 mov reg[3],256
160 sub reg[1],reg[3]
163 REG[3] = buf[1][REG[1]]
167 div reg[2],reg[3]
170 mov reg[3],256
176 sub reg[2],reg[3]
179 REG[3] = buf[1][REG[1]]
183 REG[4] = buf[1][REG[2]]
187 buf[1][REG[2]] = REG[3]
191 buf[1][REG[1]] = REG[4]
195 div reg[3],reg[4]
198 mov reg[4],256
204 sub reg[3],reg[4]
207 REG[4] = buf[0][REG[0]]
211 REG[4] = REG[4] & REG[3]
214 buf[0][REG[0]] = REG[4]
218 mov reg[4],1
224 div reg[0],reg[4]
227 cmp reg[0],27
230 jne 145
flag += 1

从数组的套娃格式和256这样的特征值可以猜测RC4,不过211指令似乎应该是异或,不知道为什么打出来是与

然后就是解密

这部分buf数组看长度像key

        array_from 0array_from 0array_from 0push_i16 222push_i16 173push_i16 190push_i8 15push_i8 15push_i16 190push_i16 173push_i16 222array_from 8array_from 4dupput_var buf

buf = [222, 173, 190, 15, 15, 190, 173, 222]

        push_0 0push_0 0push_0 0push_0 0array_from 4dupput_var REGput_loc0 0: "<ret>"push_0 0dupput_var FLAG

寄存器和标志位

        push_i8 32push_i16 213push_i16 149push_i16 247push_i8 50push_i8 47push_i8 116push_i16 149push_i8 112push_i16 249push_i16 206push_i8 89push_i16 213push_i16 222push_i16 155push_i16 194push_i8 81push_i8 18push_i16 212push_i16 246push_i8 96push_i16 190push_i16 150push_i8 51push_i8 12push_i8 69push_3 3array_from 27dupput_var ans

这部分应该就是密文

ans = [ 32, 213, 149, 247, 50, 47, 116, 149, 112, 249, 206, 89, 213, 222, 155, 194, 81, 18, 212, 246, 96, 190, 150, 51, 12, 69, 3 ]

但是传统RC4解不出来,他魔改了!!!真不是人啊

结合GPT的整理理解吧……

def custom_algorithm(key, v):buf = [[0]*256 for _ in range(4)]reg = [0] * 5flag = 0# First block of instructionsreg[1] = 0reg[2] = 0reg[3] = 0buf[1][reg[1]] = reg[1]reg[2] = 8reg[3] = reg[1]reg[3] -= reg[2]reg[2] = buf[3][reg[3]]buf[2][reg[1]] = reg[2]reg[2] = 1reg[1] //= reg[2]if reg[1] != 256:while True:buf[1][reg[1]] = reg[1]reg[2] = 8reg[3] = reg[1]reg[3] -= reg[2]reg[2] = buf[3][reg[3]]buf[2][reg[1]] = reg[2]reg[2] = 1reg[1] //= reg[2]if reg[1] == 256:breakflag += 1# Second block of instructionsreg[0] = 0reg[1] = 0reg[2] = buf[1][reg[0]]reg[1] //= reg[2]reg[2] = buf[2][reg[0]]reg[1] //= reg[2]reg[2] = 256reg[1] -= reg[2]reg[2] = buf[1][reg[1]]reg[3] = buf[1][reg[0]]buf[1][reg[0]] = reg[2]buf[1][reg[1]] = reg[3]reg[2] = 1reg[0] //= reg[2]if reg[0] != 256:while True:reg[2] = buf[1][reg[0]]reg[1] //= reg[2]reg[2] = buf[2][reg[0]]reg[1] //= reg[2]reg[2] = 256reg[1] -= reg[2]reg[2] = buf[1][reg[1]]reg[3] = buf[1][reg[0]]buf[1][reg[0]] = reg[2]buf[1][reg[1]] = reg[3]reg[2] = 1reg[0] //= reg[2]if reg[0] == 256:breakflag += 1# Third block of instructionsreg[0] = 0reg[1] = 0reg[2] = 0reg[3] = 1reg[1] //= reg[3]reg[3] = 256reg[1] -= reg[3]reg[3] = buf[1][reg[1]]reg[2] //= reg[3]reg[3] = 256reg[2] -= reg[3]reg[3] = buf[1][reg[1]]reg[4] = buf[1][reg[2]]buf[1][reg[2]] = reg[3]buf[1][reg[1]] = reg[4]reg[3] //= reg[4]reg[4] = 256reg[3] -= reg[4]reg[4] = buf[0][reg[0]]reg[4] &= reg[3]buf[0][reg[0]] = reg[4]reg[4] = 1reg[0] //= reg[4]if reg[0] != 27:while True:reg[1] //= reg[3]reg[3] = 256reg[1] -= reg[3]reg[3] = buf[1][reg[1]]reg[2] //= reg[3]reg[3] = 256reg[2] -= reg[3]reg[3] = buf[1][reg[1]]reg[4] = buf[1][reg[2]]buf[1][reg[2]] = reg[3]buf[1][reg[1]] = reg[4]reg[3] //= reg[4]reg[4] = 256reg[3] -= reg[4]reg[4] = buf[0][reg[0]]reg[4] &= reg[3]buf[0][reg[0]] = reg[4]reg[4] = 1reg[0] //= reg[4]if reg[0] == 27:breakflag += 1return buf[0][:27]# Example usage
key = [ord(c) for c in "examplekey"]  # Replace "examplekey" with the actual key
v = [ord(c) for c in "examplevalue"]  # Replace "examplevalue" with the actual vresult = custom_algorithm(key, v)
print(''.join(chr(c) for c in result))
#jvm wpdef rc4(key, v):s = list(range(256))k = [key[i % 8] for i in range(256)]j = 0# Initial permutation of sfor i in range(256):j = (j + s[i] + k[i]) % 256s[i], s[j] = s[j], s[i]  # Swap s[i] and s[j]j = 0s2 = [0] * 256# Further permutation and creation of s2for i in range(1, 256):j = (j + s[i]) % 256s2[i - 1] = (s[i] + s[j]) % 256s[i], s[j] = s[j], s[i]  # Swap s[i] and s[j]# XOR s2 with v and print the resultresult = ''.join(chr(s2[i] ^ v[i]) for i in range(27))return resultdata = [32, 213, 149, 247, 50, 47, 116, 149, 112, 249, 206, 89, 213, 222, 155, 194, 81, 18, 212, 246, 96, 190, 150, 51, 12, 69, 3]
key = [222, 173, 190, 15, 15, 190, 173, 222]
decrypted = rc4(key, data)
print(decrypted)#flag{js3ng1n7lik3m1r0uter!}

主要是换盒子的时候改了一些算法,s2是逆序异或的

要是动调跑出密钥流就很方便了,但不知道怎么做到的

矩阵杯 2024 战队攻防对抗赛初赛 Writeup | CTF导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/25789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Prov-GigaPath:新型数字病理基础模型|顶刊精析·2024-06-10

小罗碎碎念 顶刊精析&#xff5c;2024-06-10 首先祝各位老师、师兄师姐、师弟师妹们端午节快乐&#xff01;&#xff01;小罗是社恐&#xff0c;所以就不一一发消息问候了&#xff0c;哈哈。 今天这篇推文是昨天下午写完的&#xff0c;想着时间有点晚了&#xff0c;所以就放到…

作业07 递推算法2

作业&#xff1a; #include <iostream> using namespace std; int main(){int a[110][110]{0},b[110][110]{0},n;cin>>n;for(int i1;i<n;i){for(int j1;j<i;j){cin>>a[i][j];}}for(int in-1;i>1;i--){for(int j1;j<i;j){a[i][j]a[i][j]max(a[i1]…

SpringBoot中实现一个通用Excel导出功能

SpringBoot中实现一个通用Excel导出功能 文章目录 SpringBoot中实现一个通用Excel导出功能这个导出功能的特色看效果代码解析1、依赖2、Excel 入参(ExcelExportRequest)3、Excel 出参(ExcelExportResponse)4、ExcelExportField5、ExcelExportUtils 工具类6、ExcelHead 头部…

0元白嫖阿里云4G内存云服务器——感谢伟大的CSDN和阿里云

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) 学生邮箱白嫖/免费安装JetBrains全家桶(IDEA/pycharm等) —— 保姆级教程-CSDN博客 目录 1、学生认证领取300元优惠券 ​2、购买云服务器 1、学生认证领取…

深度学习500问——Chapter10:迁移学习(1)

文章目录 11.1 迁移学习基础知识 11.1.1 什么是迁移学习 11.1.2 为什么需要迁移学习 11.1.3 迁移学习的基本问题有哪些 11.1.4 迁移学习有哪些常用概念 11.1.5 迁移学习与传统机器学习有什么区别 11.1.6 迁移学习的核心及度量准则 11.1.7 迁移学习与其他概念的区别 11.1.8 什么…

tcp协议中机制的总结

目录 总结 分析 三次握手 总结 分析 其中,序列号不止用来排序,还可以用在重传时去重 确认应答是机制中的核心 因为都需要依靠应答来拿到协议字段,从而判断是否触发机制 保证可靠性的策略也可以提高效率,比如: 流量控制,可以根据多个因素来动态调整数据发送量拥塞控制也是,让…

揭开FFT时域加窗的奥秘

FFT – Spectral Leakage 假设用于ADC输出数据分析的采样点数为N&#xff0c;而采样率为Fs&#xff0c;那我们就知道&#xff0c;这种情况下的FFT频谱分辨率为δf&#xff0c;那么δfFs/N。如果此时我们给ADC输入一个待测量的单频Fin&#xff0c;如果此时Fin除以δf不是整数&a…

翻译《The Old New Thing》- Why do messages posted by PostThreadMessage disappear?

Why do messages posted by PostThreadMessage disappear? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20090930-00/?p16553 Raymond Chen 2008年09月30日 为什么 PostThreadMessage 发布的信息会消失&#xff1f; 在显示用户界面的线…

【Java】网制焦,实也难,0基础,学反射

【Java】网制焦&#xff0c;实也难&#xff0c;0基础&#xff0c;学反射 文章目录 【Java】网制焦&#xff0c;实也难&#xff0c;0基础&#xff0c;学反射反射的概述 获取Class对象的三种方式通过对象的getClass()方法通过类的静态属性class通过Class.forName()方法 通过反射获…

新技术前沿-2023-大模型学习根据个人数据集微调一个Transformer模型

参考如何根据自己的数据集微调一个 Transformer 模型 我们将通过NLP中最常见的文本分类任务来学习如何在自己的数据集上利用迁移学习(transfer learning)微调一个预训练的Transformer模型——DistilBERT。DistilBERT是BERT的一个衍生版本&#xff0c;它的优点在它的性能与BERT相…

Vue14-监视属性

一、天气案例 1-1、方式一&#xff1a;{{三目运算符}} 1-2、方式二&#xff1a;计算属性 1-3、方式三&#xff1a;click中写简单逻辑 click里面可以写简单的逻辑语句。不用this 解决方式&#xff1a; 小结&#xff1a; 绑定事件的时候&#xff0c;xxx"yyy" xxx&…

C语言学习系列:GCC编译器Windows版本MinGW-w64的安装教程

本文图文分享如何安装C语言编译器——MinGW-w64。 只要看到这篇文章&#xff0c;就可以按照文中步骤正确安装MinGW-w64并使用。 一、什么是 MinGW-w64 &#xff1f; 我们知道C语言是高级语言&#xff0c;必须编译为二进制文件&#xff0c;才能为计算机运行&#xff0c;MinGW…

理解我的积木编程思想

1 学习教程&#xff0c;至少7139手册2 编程实践&#xff0c;遇到实际问题后&#xff0c;在技术资料中查找关键词3 选择适合的条目找到代 码。修正&#xff0c;组合。

[发布]嵌入式系统远程测控软件-基于Qt

目录 一. 引言二. 软件功能2.1 原理2.2 软件功能2.3 运行环境 三. 软件操作使用3.1 软件界面3.2 软件功能使用详解3.2.1 连接3.2.2 数据监测3.2.3 数据修改3.2.4 数据保存 3.3 软件的硬件连接 四. 通信协议——STM32移植篇4.1 通信协议4.2 STM32如何传输浮点数4.3 简单移植&…

shell编程(三)—— 控制语句

程序的运行除了顺序运行外&#xff0c;还可以通过控制语句来改变执行顺序。本文介绍bash的控制语句用法。 一、条件语句 Bash 中的条件语句让我们可以决定一个操作是否被执行。结果取决于一个包在[[ ]]里的表达式。 bash中的检测命令由[[]]包起来&#xff0c;用于检测一个条…

第一次视频学习

1、了解AI答题应用 1.1 业务流程架构图 1.2 自定义上传题目流程 1.3 时序图 这个比较困难&#xff0c;第一次了解到流式&#xff0c;便于前端与用户交互

【微服务】springcloud-alibaba 配置多环境管理使用详解

目录 一、前言 二、配置多环境问题概述 2.1 什么是微服务多环境配置管理 2.1.1 微服务多环境配置管理问题起源 2.2 为什么要做多环境配置管理 2.3 微服务多环境配置管理解决方案 三、springboot 配置多环境管理解决方案 3.1 前置准备 3.1.1 搭建一个springboot工程 3.…

【PowerDesigner】创建和管理CDM之使用实体间关系

目录 &#x1f30a;1. PowerDesigner简介 &#x1f30d;1.1 常用模型文件 &#x1f30d;1.2 PowerDesigner使用环境 &#x1f30a;2. 创建和管理CDM &#x1f30d;​​​​​​2.1 新建CDM &#x1f30d;2.2 使用实体间关系 &#x1f30c;a. 使用联系 &#x1f30c;b. …

嵌入式仪器模块:DMM LCR SMU 及自动化测试软件

• 6 位数字表显示 • 24 位分辨率 • 250 KSPS 采样率 • 电源和数字 I/O 均采用隔离抗噪技术 应用场景 • 电压、电流、电阻、电感、电容的高精度测量 • 二极管/三极管测试 通道1222输入阻抗电压10 MΩHigh-Z, 10 MΩHigh-Z电流10 Ω50 mΩ / 2 Ω / 2 KΩ2 KΩ / 2 M…

如何理解external

external 函数应该只被外部函数调用但也可以被内部调用&#xff0c;但是这种内部调用也是有外部调用机制&#xff0c;即新产生message! 例子1 // SPDX-License-Identifier: GPL-3.0pragma solidity >0.8.2 <0.9.0;contract ExternalDemo{address public caller;functi…