-
-
Save 14roiron/77fb45ef17576f727d3e2b87e81d4f6f to your computer and use it in GitHub Desktop.
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
/* | |
to launch on a root device: | |
https://blog.huli.tw/2023/04/27/en/android-apk-decompile-intro-4/ | |
Term1: | |
adb shell | |
su /data/local/tmp/frida-server & | |
Term2: | |
frida -U -l Frida.js -f "com.cxw.zhiguang" | |
It may raise an error, as the sharelib is not loaded yet, | |
Best way is then to modify and save the js, it will be reloaded. | |
*/ | |
Java.perform(function () { | |
// Hooking into the BLERequest class | |
var BLERequestClass = Java.use("com.cxw.cxwblelight.core.bluetooth.BLERequest"); | |
// Hooking sendMessage method with specific overload | |
BLERequestClass.sendMessage.overload('byte', '[B', 'byte', '[B', 'long').implementation = function (b, bArr, b2, bArr2, j) { | |
// Print call trace | |
var Log = Java.use('android.util.Log'); | |
var Exception = Java.use('java.lang.Exception'); | |
// console.log("Call trace:\n" + Log.getStackTraceString(Exception.$new())); | |
console.log(`sendMessage (1st overload) called with params: b: ${b} bArr: ${byteArrayToHex(bArr)} b2: ${b2} bArr2: ${byteArrayToHex(bArr2)} j: ${j}`); | |
return this.sendMessage(b, bArr, b2, bArr2, j); | |
}; | |
// Example of another sendMessage overload - Adjust based on actual signatures | |
// For demonstration purposes only | |
BLERequestClass.sendMessage.overload('byte', '[B', 'byte', '[B').implementation = function (b, bArr, b2, bArr2) { | |
console.log(`sendMessage (2nd overload) called with params: b: ${b} bArr: ${byteArrayToHex(bArr)} b2: ${b2} bArr2: ${byteArrayToHex(bArr2)}`); | |
return this.sendMessage(b, bArr, b2, bArr2); | |
}; | |
var MSC26Class = Java.use("com.iflytek.msc26.MSC26"); | |
// Hooking getAdvData to print its parameters and the result of calling msc26 | |
BLERequestClass.getAdvData.implementation = function (b, bArr) { | |
console.log("[getAdvData] b: " + b + ", bArr: " + byteArrayToHex(bArr)); | |
// Get groupId and sn values via their methods (they seem to be part of BLERequestClass) | |
var groupId = this.getGroupId(); | |
var sn = this.getSN(); | |
console.log("[getAdvData] mMAC: " + byteArrayToHex(this.mMAC.value) + ", mUUID: " + byteArrayToHex(this.mUUID.value) + ", groupId: " + groupId + ", sn: " + sn); | |
// Call the original getAdvData method | |
var result = this.getAdvData(b, bArr); | |
// Log the result | |
console.log("[getAdvData] Result: " + byteArrayToHex(result)); | |
return result; | |
}; | |
/*Optionally hook msc26 directly to print its parameters | |
MSC26Class.msc26.implementation = function (mMAC, mUUID, groupId, b, sn, bArr) { | |
console.log("[msc26] mMAC: " + byteArrayToHex(mMAC) + ", mUUID: " + byteArrayToHex(mUUID) + ", groupId: " + groupId + ", b: " + b + ", sn: " + sn + ", bArr: " + byteArrayToHex(bArr)); | |
// Call the original msc26 method | |
var result = this.msc26(mMAC, mUUID, groupId, b, sn, bArr); | |
// Log the result | |
console.log("[msc26] Result: " + byteArrayToHex(result)); | |
return result; | |
};//*/ | |
// Optionally hook msc26 directly to print its parameters | |
MSC26Class.msc26.implementation = function (mMAC, mUUID, mUUID1, groupId, b, sn, bArr) { | |
console.log("[msc26] mMAC: " + byteArrayToHex(mMAC) + ", mUUID: " + byteArrayToHex(mUUID) + ", mUUID1: " + byteArrayToHex(mUUID1) +", groupId: " + groupId + ", b: " + b + ", sn: " + sn + ", bArr: " + byteArrayToHex(bArr)); | |
// Call the original msc26 method | |
var result = this.msc26(mMAC, mUUID,mUUID1, groupId, b, sn, bArr); | |
// Log the result | |
console.log("[msc26] Result: " + byteArrayToHex(result)); | |
return result; | |
}; | |
// Helper function to convert byteArray to Hex string | |
function byteArrayToHex(byteArray) { | |
//return Java.array('byte', byteArray); | |
const HexClass = Java.use('org.apache.commons.codec.binary.Hex'); | |
const StringClass = Java.use('java.lang.String'); | |
const hexChars = HexClass.encodeHex(byteArray); | |
return StringClass.$new(hexChars).toString(); | |
} | |
var BLERequestClass = Java.use("com.cxw.cxwblelight.core.bluetooth.BLERequest"); | |
// Hooking setBeganBrightness method | |
BLERequestClass.setBeganBrightness.implementation = function (i, i2) { | |
console.log("[*] setBeganBrightness called with params:"); | |
console.log(" i: " + i); | |
console.log(" i2: " + i2); | |
// Call the original method | |
this.setBeganBrightness(i, i2); | |
console.log("[+] setBeganBrightness executed successfully"); | |
}; | |
// Hooking setEndedBrightness method | |
BLERequestClass.setEndedBrightness.implementation = function (i, i2) { | |
console.log("[*] setEndedBrightness called with params:"); | |
console.log(" i: " + i); | |
console.log(" i2: " + i2); | |
// Call the original method | |
this.setEndedBrightness(i, i2); | |
console.log("[+] setEndedBrightness executed successfully"); | |
// Since the method is void, playVibrate is part of this method's execution | |
}; | |
}); | |
// Replace 'an_exported_function_from_MSC26' with an actual exported function name from msc26 | |
// This is used to ensure msc26 is loaded. | |
var libraryLoaded = false; | |
var targetFunctionName = 'get_rf_payload'; | |
function waitForLibraryLoad() { | |
// Check if the library is already loaded (optional) | |
var modules = Process.enumerateModules(); | |
for (var i = 0; i < modules.length; i++) { | |
//console.log(`${modules[i].name} `); | |
if (modules[i].name === 'libmsc26.so') { | |
libraryLoaded = true; | |
console.log(`libmsc26 found ---------------`); | |
hookTargetFunction(); | |
return; | |
} | |
} | |
// Wait for any function from msc26 to be called | |
Interceptor.attach(Module.findExportByName('libmsc26.so', 'Java_com_iflytek_msc26_MSC26_msc26'), { | |
onEnter: function (args) { | |
console.log(`${targetFunctionName} called`); | |
if (!libraryLoaded) { | |
libraryLoaded = true; | |
hookTargetFunction(); | |
// Optionally detach the interceptor if it's no longer needed | |
//this.detach(); | |
} | |
} | |
}); | |
} | |
function hookTargetFunction() { | |
var targetFunctionAddress = Module.findExportByName('libmsc26.so', targetFunctionName); | |
if (targetFunctionAddress !== null) { | |
Interceptor.attach(targetFunctionAddress, { | |
onEnter: function (args) { | |
console.log(`${targetFunctionName} called`); | |
// Assuming 'address' is binary data, but if it's a string, use Memory.readUtf8String(args[0]) | |
let addressHex = "Address (Hex): "; | |
for (let i = 0; i < args[1].toInt32(); ++i) { | |
const byte = Memory.readU8(args[0].add(i)); | |
addressHex += byte.toString(16).padStart(2, '0') + " "; | |
} | |
console.log(addressHex); | |
console.log("Address Length: " + args[1].toInt32()); | |
let rfPayloadHex = "RF Payload (Hex): "; | |
for (let i = 0; i < args[3].toInt32(); ++i) { | |
const byte = Memory.readU8(args[2].add(i)); | |
rfPayloadHex += byte.toString(16).padStart(2, '0') + " "; | |
} | |
console.log(rfPayloadHex); | |
console.log("RF Payload Width: " + args[3].toInt32()); | |
this.output_ble_payload = args[4]; | |
}, | |
onLeave: function (retval) { | |
let outputDataHex = "OutPutData (Hex): "; | |
for (let i = 0; i < 16; ++i) { | |
const byte = Memory.readU8(this.output_ble_payload.add(i)); | |
outputDataHex += byte.toString(16).padStart(2, '0') + " "; | |
} | |
console.log(outputDataHex); | |
} | |
}); | |
} else { | |
console.log(`${targetFunctionName} not found in msc26`); | |
} | |
/* | |
Interceptor.attach(Module.findExportByName("libmsc26.so", "check_crc16"), { | |
onEnter: function (args) { | |
this.log = "check_crc16 called with parameters:\n"; | |
// Log 'addr' in hex format | |
let addrHex = "addr (Hex): "; | |
for (let i = 0; i < args[1].toInt32(); ++i) { | |
const byte = Memory.readU8(args[0].add(i)); | |
addrHex += "0x"+byte.toString(16).padStart(2, '0') + ", "; | |
} | |
this.log += addrHex + "\n"; | |
this.log += "addr_length: " + args[1].toInt32() + "\n"; | |
// Log 'rf_payload' in hex format | |
let rfPayloadHex = "rf_payload (Hex): "; | |
for (let i = 0; i < args[3].toInt32(); ++i) { | |
const byte = Memory.readU8(args[2].add(i)); | |
rfPayloadHex += "0x"+byte.toString(16).padStart(2, '0') + ", "; | |
} | |
this.log += rfPayloadHex + "\n"; | |
this.log += "payload_width: " + args[3].toInt32(); | |
}, | |
onLeave: function (retval) { | |
// Log the return value | |
let returnValueHex = "Return value (CRC16): 0x" + retval.toInt32().toString(16).padStart(4, '0'); | |
this.log += "\n" + returnValueHex; | |
console.log(this.log); | |
} | |
}); | |
Interceptor.attach(Module.findExportByName("libmsc26.so", "whitening_encode"), { | |
onEnter: function (args) { | |
this.log = "whitening_encode called with parameters:\n"; | |
// Log 'data' in hex format (before execution) | |
let dataHexBefore = "data before (Hex): "; | |
for (let i = 0; i < args[1].toInt32(); ++i) { | |
const byte = Memory.readU8(args[0].add(i)); | |
dataHexBefore += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
this.log += dataHexBefore + "\n"; | |
// Store arguments for use in onLeave | |
this.dataPtr = args[0]; | |
this.length = args[1].toInt32(); | |
this.regPtr = args[2]; | |
this.log += "length: " + this.length + "\n"; | |
// Log 'reg' before execution | |
let regBefore = "reg before (Hex): "; | |
for (let i = 0; i < 7; ++i) { | |
const value = Memory.readS32(this.regPtr.add(i * 4)); | |
regBefore += "0x" + value.toString(16).padStart(8, '0') + ", "; | |
} | |
this.log += regBefore + "\n"; | |
}, | |
onLeave: function (retval) { | |
// Log 'data' in hex format (after execution) | |
let dataHexAfter = "data after (Hex): "; | |
for (let i = 0; i < this.length; ++i) { | |
const byte = Memory.readU8(this.dataPtr.add(i)); | |
dataHexAfter += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
this.log += dataHexAfter + "\n"; | |
// Log 'reg' after execution | |
let regAfter = "reg after (Hex): "; | |
for (let i = 0; i < 7; ++i) { | |
const value = Memory.readS32(this.regPtr.add(i * 4)); | |
regAfter += "0x" + value.toString(16).padStart(8, '0') + ", "; | |
} | |
this.log += regAfter; | |
console.log(this.log); | |
} | |
}); | |
/* | |
Interceptor.attach(Module.findExportByName("libmsc26.so", "aes26Encrypt"), { | |
onEnter: function (args) { | |
// Logging input parameters | |
console.log("aes26Encrypt called with parameters:"); | |
// Log 'mac' parameter (size: 3 bytes) | |
let macHex = "mac: "; | |
for (let i = 0; i < 4; ++i) { | |
const byte = Memory.readU8(args[0].add(i)); | |
macHex += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
console.log(macHex); | |
// Log 'uuid' parameter (size: 3 bytes, adjusted from provided size) | |
let uuidHex = "uuid: "; | |
for (let i = 0; i < 3; ++i) { | |
const byte = Memory.readU8(args[1].add(i)); | |
uuidHex += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
console.log(uuidHex); | |
// Log 'uid' parameter (size: 3 bytes) | |
let uidHex = "uid: "; | |
for (let i = 0; i < 3; ++i) { | |
const byte = Memory.readU8(args[2].add(i)); | |
uidHex += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
console.log(uidHex); | |
// Log 'groupId' parameter | |
console.log("groupId: " + args[3].toInt32()); | |
// Log 'cmd' parameter | |
console.log("cmd: " + args[4].toInt32()); | |
// Log 'sn' parameter | |
console.log("sn: " + args[5].toInt32()); | |
// Log 'data' parameter (size: 3 bytes) | |
let dataHex = "data: "; | |
for (let i = 0; i < 3; ++i) { | |
const byte = Memory.readU8(args[6].add(i)); | |
dataHex += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
console.log(dataHex); | |
// Preserve 'outputData' pointer for use in onLeave | |
this.outputData = args[7]; | |
}, | |
onLeave: function (retval) { | |
// Log 'outputData' after function execution (size: 26 bytes) | |
let outputDataHex = "outputData: "; | |
for (let i = 0; i < 26; ++i) { | |
const byte = Memory.readU8(this.outputData.add(i)); | |
outputDataHex += "0x" + byte.toString(16).padStart(2, '0') + ", "; | |
} | |
console.log(outputDataHex); | |
} | |
}); | |
//*/ | |
} | |
// Start the monitoring process | |
waitForLibraryLoad(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment