From e904b3f220864b5011c654f39a2c912be2cd3668 Mon Sep 17 00:00:00 2001
From: Rasmus Moorats <xx@nns.ee>
Date: Sun, 14 Feb 2021 18:17:37 +0200
Subject: [PATCH] initial commit

---
 README.md          | 21 +++++++++++++++
 alipay_debug.patch | 33 ++++++++++++++++++++++++
 alipay_subst.patch | 16 ++++++++++++
 bipos_subst.patch  | 11 ++++++++
 fw_patcher.py      | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 145 insertions(+)
 create mode 100644 README.md
 create mode 100644 alipay_debug.patch
 create mode 100644 alipay_subst.patch
 create mode 100644 bipos_subst.patch
 create mode 100644 fw_patcher.py

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e80e34c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+## fw_patch
+Amazfit Bip Firmware Patch Tool with patches
+
+python script for patching
+
+* fw_patcher.py
+
+patch to redirect Alipay debug messages to the standard log service
+
+* alipay_debug.patch (latin 1.1.5.36)
+
+patch for data exchange via BLE Service
+
+* alipay_subst.patch (latin 1.1.5.36)
+* bipos_subst.patch (non-latin 1.1.2.05)
+
+these patches let you use the [alipay-bt library](https://github.com/neonsea/libbip/blob/master/alipay-bt.h)
+
+thanks to:
+* x27 (research)
+* MNVolkov (libbip)
\ No newline at end of file
diff --git a/alipay_debug.patch b/alipay_debug.patch
new file mode 100644
index 0000000..56b1a95
--- /dev/null
+++ b/alipay_debug.patch
@@ -0,0 +1,33 @@
+# patch for drain LATIN 1.1.5.36
+# enable debug messages for the ALIPAY service
+# nullproc aka _alipay_log (0x80150c8) is called in the stock
+# replace with log_printf (0x804e6e0)
+# also make sure all messages are debug
+
+0802071E 0220F4F7D2FC 05202DF0DEFF  # BL _alipay_log(2) -> BL _log_printf(5)
+0802114C 0220F3F7BBFF 05202DF0C7FA  # BL _alipay_log(2) -> BL _log_printf(5)
+08031B20 E3F7D2FA 1CF0DEFD          # BL _alipay_log(5) -> BL _log_printf(5)
+08031B7C E3F7A4FA 1CF0B0FD          # BL _alipay_log(5) -> BL _log_printf(5)
+08031BD8 E3F776FA 1CF082FD          # BL _alipay_log(5) -> BL _log_printf(5)
+08031BF0 0220E3F769FA 05201CF075FD  # BL _alipay_log(2) -> BL _log_printf(5)
+080325FE 0220E2F762FD 05201CF06EF8  # BL _alipay_log(2) -> BL _log_printf(5)
+08036A84 DEF720FB 17F02CFE          # BL _alipay_log(5) -> BL _log_printf(5)
+08042180 D2F7A2FF 0CF0AEFA          # BL _alipay_log(5) -> BL _log_printf(5)
+080421D8 0220D2F775FF 05200CF081FA  # BL _alipay_log(2) -> BL _log_printf(5)
+0804220E D2F75BFF 0CF067FA          # BL _alipay_log(5) -> BL _log_printf(5)
+08044F1E D0F7D3F8 09F0DFFB          # BL _alipay_log(5) -> BL _log_printf(5)
+08044F78 0220D0F7A5F8 052009F0B1FB  # BL _alipay_log(2) -> BL _log_printf(5)
+08044F8E D0F79BF8 09F0A7FB          # BL _alipay_log(5) -> BL _log_printf(5)
+08044FC4 D0F780F8 09F08CFB          # BL _alipay_log(5) -> BL _log_printf(5)
+08045018 0220D0F755F8 052009F061FB  # BL _alipay_log(2) -> BL _log_printf(5)
+08045028 D0F74EF8 09F05AFB          # BL _alipay_log(5) -> BL _log_printf(5)
+08045076 0220D0F726F8 052009F032FB  # BL _alipay_log(2) -> BL _log_printf(5)
+080450E6 0220CFF7EEFF 052009F0FAFA  # BL _alipay_log(2) -> BL _log_printf(5)
+0804510C 0220CFF7DBFF 052009F0E7FA  # BL _alipay_log(2) -> BL _log_printf(5)
+08045412 CFF759FE 09F065F9          # BL _alipay_log(5) -> BL _log_printf(5)
+0804546C CFF72CFE 09F038F9          # BL _alipay_log(5) -> BL _log_printf(5)
+0804C37C 0220C8F7A3FE 052002F0AFF9  # BL _alipay_log(2) -> BL _log_printf(5)
+0804C490 0220C8F719FE 052002F025F9  # BL _alipay_log(2) -> BL _log_printf(5)
+08057462 BDF731FE F7F73DF9          # BL _alipay_log(5) -> BL _log_printf(5)
+080574B6 0220BDF706FE 0520F7F712F9  # BL _alipay_log(2) -> BL _log_printf(5)
+ 
\ No newline at end of file
diff --git a/alipay_subst.patch b/alipay_subst.patch
new file mode 100644
index 0000000..a5c4bb5
--- /dev/null
+++ b/alipay_subst.patch
@@ -0,0 +1,16 @@
+# for: latin 1.1.5.36
+# substitution of the ble message handler of the alipay service
+
+# do not allow to install the alipay message handler
+8054408 691F0308 00000000
+
+# remove the check for binding in the _alipay_svc_gattc_write_cmd_confirm handler
+# which will give us the ability to upload our data to the alipay message queue
+
+08031A00 28B1 00BF 
+
+# output to debug the length of the data uploaded to the alipay message queue
+# -> [%d] [WARN] recv alipay msg while not binding
+
+#08031A0C E6E7 00BF
+#08031A12 0246 6288
\ No newline at end of file
diff --git a/bipos_subst.patch b/bipos_subst.patch
new file mode 100644
index 0000000..3511009
--- /dev/null
+++ b/bipos_subst.patch
@@ -0,0 +1,11 @@
+# FOR: MNVolkov_BipOS_0.5.4_Mili_chaohu_1.1.2.05.fw or stock
+
+# block installing alipay message handler
+08054B28 F12B0308 00000000
+
+# nop _alipay_svc_gattc_write_cmd_confirm handler check
+08032678 28B1 00BF
+
+# replace tick count with received message count in debug logs
+08032684 E6E7 00BF
+0803268A 0246 6288
diff --git a/fw_patcher.py b/fw_patcher.py
new file mode 100644
index 0000000..7aa14f6
--- /dev/null
+++ b/fw_patcher.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Amazfit Bip Firmware Patcher (fw_patcher)
+
+import sys
+from pathlib import Path
+
+FW_START_ADDRESS = 0x8008000
+
+def main(argv):
+    if len(argv) < 2:
+        print('fw_patcher v0.1 by x27')
+        print('usage: <fw_file> <patch_file_0> ...<patch_file_n>')
+        sys.exit(2)
+
+    with open(argv[0],'rb') as content:
+        fw = bytearray(content.read())
+        content.close()
+
+    bytesPatched = 0
+    for patch in argv[1:]:
+        f = open(patch,'r')
+        line_count = 0;
+        for line in f.readlines():
+            line_count = line_count + 1
+            arr = line.split('#')
+            if len(arr[0].strip()) == 0:
+                continue
+            arr = arr[0].split()
+            if len(arr) != 3:
+                print('err [wrong arg count] -> '+patch+':'+str(line_count),'->',line.rstrip())
+                sys.exit(-1)
+            address = int(arr[0],16)
+            if address < FW_START_ADDRESS or address > len(fw) + FW_START_ADDRESS:
+                print('err [address out range] -> '+patch+':'+str(line_count),'->',line.rstrip())
+                sys.exit(-1)
+            before = bytes.fromhex(arr[1])
+            after = bytes.fromhex(arr[2])
+            if len(before) != len(after):
+                print('err [check and patch data size mismatch] -> '+patch+':'+str(line_count),'->',line.rstrip())
+                sys.exit(-1)
+            offset = address - FW_START_ADDRESS
+            for i in range(len(before)):
+                if fw[offset+i] != before[i]:
+                    print('err [fw and check data mismatch] -> '+patch+':'+str(line_count),'->',line.rstrip())
+                    sys.exit(-1)
+                if fw[offset+i] == after[i]:
+                    continue
+                fw[offset+i] = after[i]
+                bytesPatched = bytesPatched + 1
+    
+    if bytesPatched == 0:
+        print('no patch data found')                
+    else:
+        filename = Path(argv[0]).stem+'_patched'+Path(argv[0]).suffix
+        with open(filename,'wb') as content:
+            content.write(fw)
+        content.close()
+        print('created',filename)        
+        print('applied patches:',bytesPatched,'bytes')
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
\ No newline at end of file