Last active
October 9, 2018 18:21
-
-
Save N4NU/e2d6a7355595a0e37a8b65fbc1cf9e45 to your computer and use it in GitHub Desktop.
SECCON Beginners NEXT 2018 Reversing Solver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
import numpy as np | |
d = open('./baby_nn', 'rb').read() | |
def inv_sigmoid(x): | |
return np.log(x / (1 - x)) | |
biases_info = [(0x0A8A0, 0x28), (0x07560, 0x28), (0x04220, 0x28), (0x00EE0, 0x28)] | |
biases = [] | |
for offset, length in biases_info: | |
b_bytes = d[offset:offset+length*8] | |
biases.append(np.array(struct.unpack('<'+'d'*length, b_bytes), dtype='float64').reshape(1, length)) | |
weights_info = [(0x0A9E0, 0x28, 0x28), (0x076A0, 0x28, 0x28), (0x04360, 0x28, 0x28), (0x01020, 0x28, 0x28)] | |
weights = [] | |
for offset, num_row, num_col in weights_info: | |
w_bytes = d[offset:offset+num_row*num_col*8] | |
weights.append(np.array(struct.unpack('<'+'d'*(num_row * num_col), w_bytes), dtype='float64').reshape(num_row, num_col)) | |
enc_bytes = d[0x00DA0:0x00DA0+0x28*8] | |
enc_flag = np.array(struct.unpack('<'+'d'*0x28, enc_bytes), dtype='float64').reshape(1, 0x28) | |
v = enc_flag | |
for i in range(3, -1, -1): | |
v = np.dot(inv_sigmoid(v) - biases[i], np.linalg.inv(weights[i])) | |
flag = '' | |
for c in np.round(v * 255)[0]: | |
flag += chr(int(c)) | |
print(repr(flag)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from z3 import * | |
xs = [BitVec("x%d" % i, 8) for i in range(40)] | |
for i in xrange(40): | |
exec('v' + str(i) + ' = xs[i]') | |
s = Solver() | |
for i in xrange(len(xs)): | |
s.add(0x20 <= xs[i], xs[i] <= 0x7f) | |
s.add(xs[0] == ord('c')) | |
s.add(xs[1] == ord('t')) | |
s.add(xs[2] == ord('f')) | |
s.add(xs[3] == ord('4')) | |
s.add(xs[4] == ord('b')) | |
s.add(xs[5] == ord('{')) | |
s.add(xs[-1] == ord('}')) | |
l = open('snapshot_dis.txt','rb').read().strip().split('\n') | |
t = [] | |
for i in xrange(len(l)): | |
t.append(eval(l[i])) | |
l2 = [] | |
tmp_l = [] | |
for i in xrange(len(t)): | |
if t[i][1] != 'Wide' and t[i][1] != 'ExtraWide': | |
tmp_l.append(t[i]) | |
if t[i][1] == 'Return': | |
l2.append(tmp_l) | |
tmp_l = [] | |
l2 = l2[1:-2] | |
condition_l = [] | |
for i in xrange(len(l2)): | |
index_l = [] | |
coef_l = [] | |
operator_l = [] | |
acc_reg = 0 | |
regs = {} | |
for j in xrange(10): | |
regs['r{0:d}'.format(j)] = 0 | |
for j in xrange(len(l2[i]) - 1): | |
opcode = l2[i][j][1] | |
if len(l2[i][j]) > 2: | |
oprand = l2[i][j][2] | |
if opcode == 'LdaSmi' or opcode == 'LdaConstant': | |
acc_reg = oprand | |
elif opcode == 'LdaKeyedProperty': | |
acc_reg = xs[acc_reg] | |
elif opcode == 'MulSmi': | |
acc_reg = oprand * acc_reg | |
elif opcode == 'Star': | |
regs[oprand] = acc_reg | |
elif opcode == 'Mul': | |
acc_reg = regs[oprand] * acc_reg | |
elif opcode == 'Sub': | |
acc_reg = regs[oprand] - acc_reg | |
elif opcode == 'Add': | |
acc_reg = regs[oprand] + acc_reg | |
elif opcode == 'TestEqual': | |
s.add(acc_reg == regs[oprand]) | |
elif opcode == 'LdaZero': | |
acc_reg = 0 | |
elif opcode == 'JumpIfTrue' or opcode == 'LdaFalse': | |
pass | |
else: | |
print('not implemented instruction : ' + opcode) | |
sys.exit(1) | |
r = s.check() | |
if r == sat: | |
m = s.model() | |
t = '' | |
for i in range(len(xs)): | |
t += chr(m[xs[i]].as_long()) | |
print(repr(t)) | |
else: | |
print r |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
opcodes = [['Wide', 'AccumulatorUse::kNone'], | |
['ExtraWide', 'AccumulatorUse::kNone'], | |
['DebugBreakWide', 'AccumulatorUse::kReadWrite'], | |
['DebugBreakExtraWide', 'AccumulatorUse::kReadWrite'], | |
['DebugBreak0', 'AccumulatorUse::kReadWrite'], | |
['DebugBreak1', 'AccumulatorUse::kReadWrite', 'OperandType::kReg'], | |
['DebugBreak2', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kReg'], | |
['DebugBreak3', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg'], | |
['DebugBreak4', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg'], | |
['DebugBreak5', 'AccumulatorUse::kReadWrite', 'OperandType::kRuntimeId', 'OperandType::kReg', 'OperandType::kReg'], | |
['DebugBreak6', 'AccumulatorUse::kReadWrite', 'OperandType::kRuntimeId', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg'], | |
['LdaZero', 'AccumulatorUse::kWrite'], | |
['LdaSmi', 'AccumulatorUse::kWrite', 'OperandType::kImm'], | |
['LdaUndefined', 'AccumulatorUse::kWrite'], | |
['LdaNull', 'AccumulatorUse::kWrite'], | |
['LdaTheHole', 'AccumulatorUse::kWrite'], | |
['LdaTrue', 'AccumulatorUse::kWrite'], | |
['LdaFalse', 'AccumulatorUse::kWrite'], | |
['LdaConstant', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['LdaGlobal', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['LdaGlobalInsideTypeof', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['StaGlobal', 'AccumulatorUse::kRead', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['PushContext', 'AccumulatorUse::kRead', 'OperandType::kRegOut'], | |
['PopContext', 'AccumulatorUse::kNone', 'OperandType::kReg'], | |
['LdaContextSlot', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['LdaImmutableContextSlot', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['LdaCurrentContextSlot', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['LdaImmutableCurrentContextSlot', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['StaContextSlot', 'AccumulatorUse::kRead', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['StaCurrentContextSlot', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['LdaLookupSlot', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['LdaLookupContextSlot', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['LdaLookupGlobalSlot', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['LdaLookupSlotInsideTypeof', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['LdaLookupContextSlotInsideTypeof', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['LdaLookupGlobalSlotInsideTypeof', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['StaLookupSlot', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx', 'OperandType::kFlag8'], | |
['Ldar', 'AccumulatorUse::kWrite', 'OperandType::kReg'], | |
['Star', 'AccumulatorUse::kRead', 'OperandType::kRegOut'], | |
['Mov', 'AccumulatorUse::kNone', 'OperandType::kReg', 'OperandType::kRegOut'], | |
['LdaNamedProperty', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['LdaKeyedProperty', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['LdaModuleVariable', 'AccumulatorUse::kWrite', 'OperandType::kImm', 'OperandType::kUImm'], | |
['StaModuleVariable', 'AccumulatorUse::kRead', 'OperandType::kImm', 'OperandType::kUImm'], | |
['StaNamedProperty', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['StaNamedPropertyNoFeedback', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kFlag8'], | |
['StaNamedOwnProperty', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['StaKeyedProperty', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['StaDataPropertyInLiteral', 'AccumulatorUse::kRead', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kFlag8', 'OperandType::kIdx'], | |
['CollectTypeProfile', 'AccumulatorUse::kRead', 'OperandType::kImm'], | |
['Add', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['Sub', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['Mul', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['Div', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['Mod', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['Exp', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['BitwiseOr', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['BitwiseXor', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['BitwiseAnd', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['ShiftLeft', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['ShiftRight', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['ShiftRightLogical', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['AddSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['SubSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['MulSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['DivSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['ModSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['ExpSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['BitwiseOrSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['BitwiseXorSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['BitwiseAndSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['ShiftLeftSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['ShiftRightSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['ShiftRightLogicalSmi', 'AccumulatorUse::kReadWrite', 'OperandType::kImm', 'OperandType::kIdx'], | |
['Inc', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['Dec', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['Negate', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['BitwiseNot', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['ToBooleanLogicalNot', 'AccumulatorUse::kReadWrite'], | |
['LogicalNot', 'AccumulatorUse::kReadWrite'], | |
['TypeOf', 'AccumulatorUse::kReadWrite'], | |
['DeletePropertyStrict', 'AccumulatorUse::kReadWrite', 'OperandType::kReg'], | |
['DeletePropertySloppy', 'AccumulatorUse::kReadWrite', 'OperandType::kReg'], | |
['GetSuperConstructor', 'AccumulatorUse::kRead', 'OperandType::kRegOut'], | |
['CallAnyReceiver', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['CallProperty', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['CallProperty0', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallProperty1', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallProperty2', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallUndefinedReceiver', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['CallUndefinedReceiver0', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallUndefinedReceiver1', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallUndefinedReceiver2', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CallWithSpread', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['CallRuntime', 'AccumulatorUse::kWrite', 'OperandType::kRuntimeId', 'OperandType::kRegList', 'OperandType::kRegCount'], | |
['CallRuntimeForPair', 'AccumulatorUse::kNone', 'OperandType::kRuntimeId', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kRegOutPair'], | |
['CallJSRuntime', 'AccumulatorUse::kWrite', 'OperandType::kNativeContextIndex', 'OperandType::kRegList', 'OperandType::kRegCount'], | |
['InvokeIntrinsic', 'AccumulatorUse::kWrite', 'OperandType::kIntrinsicId', 'OperandType::kRegList', 'OperandType::kRegCount'], | |
['Construct', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['ConstructWithSpread', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kIdx'], | |
['TestEqual', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestEqualStrict', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestLessThan', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestGreaterThan', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestLessThanOrEqual', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestGreaterThanOrEqual', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestEqualStrictNoFeedback', 'AccumulatorUse::kReadWrite', 'OperandType::kReg'], | |
['TestInstanceOf', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['TestIn', 'AccumulatorUse::kReadWrite', 'OperandType::kReg'], | |
['TestUndetectable', 'AccumulatorUse::kReadWrite'], | |
['TestNull', 'AccumulatorUse::kReadWrite'], | |
['TestUndefined', 'AccumulatorUse::kReadWrite'], | |
['TestTypeOf', 'AccumulatorUse::kReadWrite', 'OperandType::kFlag8'], | |
['ToName', 'AccumulatorUse::kRead', 'OperandType::kRegOut'], | |
['ToNumber', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['ToNumeric', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['ToObject', 'AccumulatorUse::kRead', 'OperandType::kRegOut'], | |
['ToString', 'AccumulatorUse::kReadWrite'], | |
['CreateRegExpLiteral', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kFlag8'], | |
['CreateArrayLiteral', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kFlag8'], | |
['CreateEmptyArrayLiteral', 'AccumulatorUse::kWrite', 'OperandType::kIdx'], | |
['CreateObjectLiteral', 'AccumulatorUse::kNone', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kFlag8', 'OperandType::kRegOut'], | |
['CreateEmptyObjectLiteral', 'AccumulatorUse::kWrite'], | |
['GetTemplateObject', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['CreateClosure', 'AccumulatorUse::kWrite', 'OperandType::kIdx', 'OperandType::kIdx', 'OperandType::kFlag8'], | |
['CreateBlockContext', 'AccumulatorUse::kReadWrite', 'OperandType::kIdx'], | |
['CreateCatchContext', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kIdx'], | |
['CreateFunctionContext', 'AccumulatorUse::kWrite', 'OperandType::kUImm'], | |
['CreateEvalContext', 'AccumulatorUse::kWrite', 'OperandType::kUImm'], | |
['CreateWithContext', 'AccumulatorUse::kReadWrite', 'OperandType::kReg', 'OperandType::kIdx'], | |
['CreateMappedArguments', 'AccumulatorUse::kWrite'], | |
['CreateUnmappedArguments', 'AccumulatorUse::kWrite'], | |
['CreateRestParameter', 'AccumulatorUse::kWrite'], | |
['JumpLoop', 'AccumulatorUse::kNone', 'OperandType::kUImm', 'OperandType::kImm'], | |
['Jump', 'AccumulatorUse::kNone', 'OperandType::kUImm'], | |
['JumpConstant', 'AccumulatorUse::kNone', 'OperandType::kIdx'], | |
['JumpIfNullConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfNotNullConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfUndefinedConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfNotUndefinedConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfTrueConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfFalseConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfJSReceiverConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfToBooleanTrueConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfToBooleanFalseConstant', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['JumpIfToBooleanTrue', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfToBooleanFalse', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfTrue', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfFalse', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfNull', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfNotNull', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfUndefined', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfNotUndefined', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['JumpIfJSReceiver', 'AccumulatorUse::kRead', 'OperandType::kUImm'], | |
['SwitchOnSmiNoFeedback', 'AccumulatorUse::kRead', 'OperandType::kIdx', 'OperandType::kUImm', 'OperandType::kImm'], | |
['ForInEnumerate', 'AccumulatorUse::kWrite', 'OperandType::kReg'], | |
['ForInPrepare', 'AccumulatorUse::kRead', 'OperandType::kRegOutTriple', 'OperandType::kIdx'], | |
['ForInContinue', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg'], | |
['ForInNext', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kReg', 'OperandType::kRegPair', 'OperandType::kIdx'], | |
['ForInStep', 'AccumulatorUse::kWrite', 'OperandType::kReg'], | |
['StackCheck', 'AccumulatorUse::kNone'], | |
['SetPendingMessage', 'AccumulatorUse::kReadWrite'], | |
['Throw', 'AccumulatorUse::kRead'], | |
['ReThrow', 'AccumulatorUse::kRead'], | |
['Return', 'AccumulatorUse::kRead'], | |
['ThrowReferenceErrorIfHole', 'AccumulatorUse::kRead', 'OperandType::kIdx'], | |
['ThrowSuperNotCalledIfHole', 'AccumulatorUse::kRead'], | |
['ThrowSuperAlreadyCalledIfNotHole', 'AccumulatorUse::kRead'], | |
['SwitchOnGeneratorState', 'AccumulatorUse::kNone', 'OperandType::kReg', 'OperandType::kIdx', 'OperandType::kUImm'], | |
['SuspendGenerator', 'AccumulatorUse::kRead', 'OperandType::kReg', 'OperandType::kRegList', 'OperandType::kRegCount', 'OperandType::kUImm'], | |
['ResumeGenerator', 'AccumulatorUse::kWrite', 'OperandType::kReg', 'OperandType::kRegOutList', 'OperandType::kRegCount'], | |
['Debugger', 'AccumulatorUse::kNone'], | |
['IncBlockCounter', 'AccumulatorUse::kNone', 'OperandType::kIdx'], | |
['Abort', 'AccumulatorUse::kNone', 'OperandType::kIdx'], | |
['Illegal', 'AccumulatorUse::kNone']] | |
import struct | |
buf = open('./src/snapshot.bin', 'rb').read() | |
const_buf = buf[0xc4:] | |
buf = buf[0xa70:0x28a8] | |
def disasm_v8(buf): | |
j = 0 | |
status = 0 | |
data = [] | |
ret = [] | |
buf = map(ord, buf) | |
currentCode = ['', '', ''] | |
skipBytes = 0 | |
for i in range(len(buf)): | |
top_byte = buf[i] | |
if status == 0: | |
prevCode = currentCode | |
currentCode = opcodes[top_byte] | |
data.append(i) | |
data.append(currentCode[0]) | |
status = 1 | |
j = 0 | |
realLength = len(currentCode) | |
if len(currentCode) == 2: | |
status = 0 | |
ret.append(data) | |
data = [] | |
realLength = 0 | |
if currentCode[0] == 'CallRuntime': | |
j -= 1 | |
elif status == 1: | |
j += 1 | |
if currentCode[0] == 'LdaConstant': | |
data.append(int(struct.unpack('<d', const_buf[(top_byte - 1)*8+(top_byte - 1)*4:(top_byte - 1)*8+(top_byte - 1)*4+8])[0])) | |
status = 0 | |
ret.append(data) | |
data = [] | |
realLength = 0 | |
elif currentCode[j + 1] == 'OperandType::kRegList': | |
pass | |
elif currentCode[j] == 'OperandType::kRegList': | |
data.append("list(r" + '{0:d}'.format(0xfb - buf[i - 1]) + " to " + '{0:d}'.format(top_byte) + ")") | |
data.append("") | |
elif currentCode[j + 1] == 'OperandType::kRuntimeId': | |
data.append("runtime=" + '{0:d}'.format(top_byte)) | |
j += 2 | |
data.append("list(r" + '{0:d}'.format(0xfb - buf[i+1]) + " to " + '{0:d}'.format(buf[i+2]) + ")") | |
i += 2 | |
status = 0 | |
ret.append(data) | |
data = [] | |
realLength = 0 | |
continue | |
else: | |
if prevCode[0] == 'ExtraWide' and currentCode[0] == 'LdaSmi': | |
t = struct.unpack('<i', ''.join(map(chr, buf[i:i+4])))[0] | |
data.append(t) | |
skipBytes = 3 | |
elif prevCode[0] == 'Wide' and currentCode[0] == 'LdaSmi': | |
t = struct.unpack('<h', ''.join(map(chr, buf[i:i+2])))[0] | |
data.append(t) | |
skipBytes = 1 | |
elif prevCode[0] == 'Wide': | |
t = struct.unpack('<h', ''.join(map(chr, buf[i:i+2])))[0] | |
if -32 <= t and t <= -5: | |
data.append("r" + '{0:d}'.format(-5 - t)) | |
else: | |
data.append(t) | |
t = struct.unpack('<h', ''.join(map(chr, buf[i+2:i+4])))[0] | |
data.append(t) | |
skipBytes = 3 | |
elif top_byte <= 0xfb and top_byte >= 0xe0: | |
data.append("r" + '{0:d}'.format(0xfb - top_byte)) | |
else: | |
data.append(top_byte) | |
if len(data) >= realLength: | |
status = 0 | |
ret.append(data) | |
data = [] | |
realLength = 0 | |
if skipBytes > 0: | |
status = -1 | |
elif status == -1: | |
skipBytes -= 1 | |
if skipBytes == 0: | |
status = 0 | |
return ret | |
fp = open('snapshot_dis.txt', 'wb') | |
for t in disasm_v8(buf): | |
fp.write(repr(t)+'\n') | |
fp.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment