I have been working reverse engineering a Aqara N200 as I'd like to now control it in Home Assistant rather than just near the lock with the Mi Home app, my plan is to use a ESP32 running ESPHome to communicate with it.
I've successfully captured the Bluetooth packets using a Google Pixel 6 with Bluetooth HCI Snoop feature in Developer options. I managed to find what I think is the correct packet by doing multiple captures and unlocking the door 3 and 5 times and filtering for the packet using btatt.opcode == 0x12
I am now at loss since the value for all 8 packets are different and I'm not sure how they are generated.
These are the Values of the 8 packets
0700cdec690302
0d00866d396b9b
11005b56ae6119
16001b9e831efd
1b00c3e9628037
0600e0c02ef088
0d00399b1eab25
I'm pretty new to reverse engineering and have learnt a lot at a loss at this bit but I'm trying my best.
Update:
I was able to use frida.re to see values of the packets being sent using this script.
Java.perform(function() {
// Define the UUIDs you're interested in
var targetUUIDs = [
'00001001-0065-6c62-2e74-6f696d2e696d'
];
// Function to convert byte array to hex string
function bytesToHex(bytes) {
var hex = [];
for (var i = 0; i < bytes.length; i++) {
hex.push(('0' + (bytes[i] & 0xFF).toString(16)).slice(-2));
}
return hex.join('');
}
// Hook the writeCharacteristic method of BluetoothGatt
var BluetoothGatt = Java.use('android.bluetooth.BluetoothGatt');
BluetoothGatt.writeCharacteristic.overload('android.bluetooth.BluetoothGattCharacteristic').implementation = function(characteristic) {
// Extract UUID and value
var uuid = characteristic.getUuid().toString();
var value = characteristic.getValue();
// Check if UUID is in the list of target UUIDs
if (targetUUIDs.includes(uuid)) {
var hexValue = bytesToHex(value);
console.log('writeCharacteristic called');
console.log('Characteristic UUID: ' + uuid);
console.log('Characteristic Value (hex): ' + hexValue);
// Print stack trace
var stackTrace = Java.use('java.lang.Thread').currentThread().getStackTrace();
stackTrace.forEach(function(element) {
console.log(element.toString());
});
}
return this.writeCharacteristic(characteristic);
};
});
Which outputs this when I unlock the lock using the app.
writeCharacteristic called
Characteristic UUID: 00001001-0065-6c62-2e74-6f696d2e696d
Characteristic Value (hex): 1a00b793f92f48
dalvik.system.VMStack.getThreadStackTrace(Native Method)
java.lang.Thread.getStackTrace(Thread.java:1841)
android.bluetooth.BluetoothGatt.writeCharacteristic(Native Method)
_m_j.r00.writeCharacteristic(SourceFile:98)
_m_j.p50.writeCharacteristic(Unknown Source:2)
_m_j.k90.OooO0Oo(SourceFile:25)
_m_j.p50.process(SourceFile:69)
_m_j.c00.handleMessage(SourceFile:34)
android.os.Handler.dispatchMessage(Handler.java:103)
android.os.Looper.loopOnce(Looper.java:232)
android.os.Looper.loop(Looper.java:317)
android.os.HandlerThread.run(HandlerThread.java:85)
_m_j.vr6.run(SourceFile:16)
I pulled the APK from my Pixel using ADB and decompiled it using JADX. I'm currently having trouble finding where the packet is created