创安杯
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; | |
}; | |
}); |
可以观察到输入的数字进行了加减求和操作,最后拿一个比较,算出来输入,结果:
说是假 flag,但这里能触发 The flag is
的应该是唯一的,也没看到藏什么东西,不会了 = =