创安杯

PREFACE:铁三决赛前,结果题很抽象

# Reverse-Python

需要一个 python3.11,然后就 ez 了

import marshal
import dis
import sys
import types
import struct
def load_pyc(file_path):
    with open(file_path, 'rb') as f:
        magic_number = f.read(4)
        if len(magic_number) < 4:
            raise ValueError("Invalid .pyc file: magic number is too short")
        # Read the rest of the header based on the Python version
        if sys.version_info >= (3, 7):
            # For Python 3.7+, the header includes 4 bytes for bitfield and 8 bytes for the hash
            header = f.read(12)
            if len(header) < 12:
                raise ValueError("Invalid .pyc file: header is too short for Python 3.7+")
            bitfield, hash = struct.unpack('I8s', header)
        elif sys.version_info >= (3, 3):
            # For Python 3.3 to 3.6, the header includes 4 bytes for timestamp and 4 bytes for source size
            header = f.read(8)
            if len(header) < 8:
                raise ValueError("Invalid .pyc file: header is too short for Python 3.3 to 3.6")
            timestamp, source_size = struct.unpack('II', header)
        else:
            # For Python 3.2 and earlier, the header includes only 4 bytes for timestamp
            header = f.read(4)
            if len(header) < 4:
                raise ValueError("Invalid .pyc file: header is too short for Python <= 3.2")
            timestamp = struct.unpack('I', header)[0]
        
        # Read the actual code object
        code_obj = marshal.load(f)
        return code_obj
def disassemble_pyc(file_path):
    code_obj = load_pyc(file_path)
    if isinstance(code_obj, types.CodeType):
        dis.dis(code_obj)
    else:
        print("Error: The loaded file is not a valid code object.")
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <pyc_file>")
    else:
        pyc_file = sys.argv[1]
        try:
            disassemble_pyc(pyc_file)
        except Exception as e:
            print(f"Error: {e}")

# Reverse-android

这题出了,但没出

核心加密用 so 调用 java 层,hook 一下打印看流程即可:

Java.perform(function() {
    var MainActivity = Java.use('net.bluelotus.tomorrow.easyandroid.MainActivity');
    // // Hook native chec method
    // var chec = MainActivity.chec;
    // chec.overload('int', 'int').implementation = function(arg1, arg2) {
    //     console.log('chec called with arg1:', arg1, 'arg2:', arg2);
    //     var result = chec.call(this, arg1, arg2);
    //     console.log('chec result:', result);
    //     return result;
    // };
    // Hook check method
    MainActivity.check.overload('int', 'int').implementation = function(arg2, arg3) {
        console.log('check called with arg2:', arg2, 'arg3:', arg3);
        var result = this.check(arg2, arg3);
        console.log('check result:', result);
        return result;
    };
    // Hook check1 method
    MainActivity.check1.overload('int', 'int').implementation = function(arg4, arg5) {
        console.log('check1 called with arg4:', arg4, 'arg5:', arg5);
        var result = this.check1(arg4, arg5);
        console.log('check1 result:', result);
        return result;
    };
    // Hook check2 method
    MainActivity.check2.overload('int', 'int').implementation = function(arg5, arg6) {
        console.log('check2 called with arg5:', arg5, 'arg6:', arg6);
        var result = this.check2(arg5, arg6);
        console.log('check2 result:', result);
        return result;
    };
    // Hook check3 method
    MainActivity.check3.overload('int', 'int').implementation = function(arg4, arg5) {
        console.log('check3 called with arg4:', arg4, 'arg5:', arg5);
        var result = this.check3(arg4, arg5);
        console.log('check3 result:', result);
        return result;
    };
    var TextView = Java.use("android.widget.TextView");
    TextView.setText.overload('java.lang.CharSequence').implementation = function (charSequence) {
        console.log("setText called with: " + charSequence);
        // Call the original setText method
        this.setText(charSequence);
    };
    var MainActivity = Java.use('net.bluelotus.tomorrow.easyandroid.MainActivity');
    // Hook stringFromJNI2 方法
    MainActivity.stringFromJNI2.implementation = function (arg1) {
        console.log('stringFromJNI2 called with argument:', arg1);
        
        var result = this.stringFromJNI2(arg1);
        
        console.log('stringFromJNI2 result:', result);
        
        return result; 
    };
});

可以观察到输入的数字进行了加减求和操作,最后拿一个比较,算出来输入,结果:

image-20240527102058180

说是假 flag,但这里能触发 The flag is 的应该是唯一的,也没看到藏什么东西,不会了 = =