fastboot no permission, add via checking lsusb and /etc/udev/rules.d/51-android.rules

If you got a new phone and try boot to fastboot mode

then you may encounter this

$ fastboot devices
no permissions (verify udev rules); see [] fastboot

simply the solution as below

$ lsusb
Bus 001 Device 014: ID 18d1:d00d Google Inc.

then add “d00d" to /etc/udev/rules.d/51-android.rules and then sudo udevadm control –reload-rules

SUBSYSTEM=="usb", ATTR{idVendor}=="d00d", MODE="0666", GROUP="plugdev"
$ sudo udevadm control --reload-rules

change Android SystemUI behavior with Xposed and jadx


先用 superr 做 Deodex ROM

再用 jadx 查看要修改的 method 在哪個 class 裡面

但是這還是要先對 Android system 有些感覺,否則你根本不知道要從哪個 apk 下手去找你要改的功能


這個在 SystemUI.apk 裡面

所以就 …

adb root

adb shell cp /system/priv-app/SystemUI/SystemUI.apk /data/local/tmp/

adb pull /data/local/tmp/SystemUI.apk

然後用 jadx 觀察 SystemUI.apk 裡面哪個 method 像是在控制低電量的通知

然後用 Xposed 去 hook 該 method ,例如 hook showLowBatteryWarningMethodHook  並且在 beforeHookedMethod 裡面直接呼叫 return 。這樣就不會真正執行到顯示低電量通知的程式碼了

bigchainDB code flow

  1. commands/
    1. main()
      1. argparse.ArgumentParser
      2. utils.start
        1. commands/
          1. func(args)
    2. run_start()
      1.‘BigchainDB Version {}’.format(bigchaindb.__version__))
      2. bigchaindb.config_utils.autoconfigure(filename=args.config, force=True)
      3. db.init()
        1. db/
          1. init()
            1. table_names = [‘bigchain’, ‘backlog’, ‘votes’]
            2. create_table(conn, dbname, table_name)
            3. create_bigchain_secondary_index(conn, dbname)
            4. create_backlog_secondary_index(conn, dbname)
            5. create_votes_secondary_index(conn, dbname)
            6. b.create_genesis_block()
              2. create_genesis_block()
                1. prepare_genesis_block()
                  1. create_transaction()
                      1. util.create_tx(owner_before, owner_after, tx_input, operation,payload)
                  2. sign_transaction()
                      1. util.sign_tx(transaction, private_key, bigchain=bigchain)
                          1. from bigchaindb import crypto
                          2. SigningKey = crypto.Ed25519SigningKey
                          3. VerifyingKey = crypto.Ed25519VerifyingKey
                          4. sign_tx(transaction, signing_keys, bigchain=None)
                            1. signing_key = crypto.SigningKey(sk)
                            2. vk = signing_key.get_verifying_key().to_ascii().decode()
      4. processes.start()


cryptoconditions/types/ 裡面有個 sign function 是真正執行 sign 的地方

先用 private key 產生了 verifying key 並且丟入 VerifyingKey 這個 class 產生 vk 這個 instance

vk 被存入 public_key ,並且這個 public_key 被使用在 validate, to_dict, write_payload, generate_hash, write_common_header

write_common_header 這個 function 似乎沒有被呼叫到,在 cryptoconditions and BigchaindDB 都 grep 不到

generate_hash 這個 function 單純回傳 self.public_key.to_bytes() , generate_hash 只在 裡面的 class Fulfillment 裡面的 condition 這個 method 被呼叫到

line 22 用 private key 執行 sign 並且回傳 sign 完成的 signature

def sign(self, message, private_key):
Sign the message.

This method will take the currently configured values for the message
prefix and suffix and create a signature using the provided Ed25519 private key.

message (string): message to be signed
private_key (string) Ed25519 private key
sk = private_key
vk = VerifyingKey(base58.b58encode(sk.get_verifying_key().to_bytes()))

self.public_key = vk

# This would be the Ed25519ph version (JavaScript ES7):
# const message = crypto.createHash('sha512')
# .update(Buffer.concat([this.messagePrefix, this.message]))
# .digest()

self.signature = sk.sign(message, encoding=None)

同一個檔案裡面的另一個 function validate, line 16 用 public key 這個 instance 執行了 verify function,然後 return true or false

def validate(self, message=None, **kwargs):
Verify the signature of this Ed25519 fulfillment.

The signature of this Ed25519 fulfillment is verified against the provided message and public key.

message (str): Message to validate against.

boolean: Whether this fulfillment is valid.
if not (message and self.signature):
return False

return self.public_key.verify(message, self.signature, encoding=None)

BigchainDB genesis block example

open on your browser and click tab “Data Explorer"

    "block": {
        "node_pubkey":  "8SjBRtHvxKkZeb4L6e7tERsSzhHVD1uP6y2crSm4WRdt" ,
            "timestamp":  "1475829027" ,
            "transactions": [
                "id":  "00255feada6b34b22e854d9b23c429a75263b32e0bb4ce6be1318448f0d6a442" ,
                "transaction": {
                    "conditions": [
                        "cid": 0 , 
                        "condition": {
                            "details": {
                                "bitmask": 32 ,
                                "public_key":  "8SjBRtHvxKkZeb4L6e7tERsSzhHVD1uP6y2crSm4WRdt" ,
                                "signature": null ,
                                "type":  "fulfillment" ,
                                "type_id": 4
                            } , 
                            "uri":  "000"
                        } , 
                        "owners_after": [
                    ] , 
                        "data": {
                            "payload": {
                                "message":  "Hello World from the BigchainDB"
                            } , 
                            "uuid":  "561cb60a-e112-41a0-9e03-f2313acbdc65"
                        } , 
                        "fulfillments": [
                            "fid": 0 , 
                            "fulfillment": "cf:4:bpkFhfzB3r8vcaTJacAE77FhqqemJApf8LECu2HbPLONQw2eHU40BAgO5P6dwHdwHbaPl-KbVy_Rarq2rDx4goYwQDkI61Li7vC7BYNkLpv-q-eUrLk9D3dfDJJFLzwJ" ,
                            "input": null ,
                            "owners_before": [
                    ] , 
                        "operation":  "GENESIS" ,
                        "timestamp":  "1475829027" ,
                        "version": 1
        ] , 
            "voters": [
    } , 
        "id":  "0d22db9fe7d8de0335f3ffeacda04864c1091ffdb66135dc7f01105fd5a8a5b5" ,
        "signature":  "3TzakE12fDVsjbrKXpJ8p4ysE73U2bfsZJVuGYbFyHkp6E8FZev7VpsYnxoHvhiePW9JawiceRmmmAYq4LfUAkXV"

bitcoin private/public key generate with python3

I have search for days to find a good python3 lib to generate private/public key and address lib

and this lib seems to be the best one

you can find “create private key, public key, address, sign and verify" at below link

跑了這個範例之後,產生的 private key 應該是 WIF 格式

L4vB5fomsK8L95wQ7GFzvErYGht49JsCPJyJMHpB4xGM6xgi2jvG 1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G
Address: 1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G
Message: Hey I just met you, and this is crazy, but I'll verify my address, maybe ...

Signature: b'H4yj969O4ZdVyDoB0wYdgKzb2qjGwg4t4/pf/SuDSowJTBn7eEkP84gmp9KuStQFSNSldylDtP+uIwuEtUVU/TE='

Verified: True

To verify using bitcoin core;
`bitcoin-cli verifymessage 1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G "H4yj969O4ZdVyDoB0wYdgKzb2qjGwg4t4/pf/SuDSowJTBn7eEkP84gmp9KuStQFSNSldylDtP+uIwuEtUVU/TE=" "Hey I just met you, and this is crazy, but I'll verify my address, maybe ..."`

但實際上把 L4vB5fomsK8L95wQ7GFzvErYGht49JsCPJyJMHpB4xGM6xgi2jvG 開頭L拿掉之後再去  bitcoin test 網站產生 private key

產生出來的 private key 長這樣DDE713F429AA5B4624076448BF6A9FDEACAE68F6FB800C50D4D6B393CFACDE01

再把這個 private key 拿去 bitcoin test 網站跑

產生出來的 address 長這樣 1GAehh7TsJAHuUAeKZcXf5CnwuGuGgyX2S

跟上面範例的 address 不吻合…



產生出來的 private key 長這樣 DDE713F429AA5B4624076448BF6A9FDEACAE68F6FB800C50D4D6B393CFACDE01

最後面有 01,則代表這個 WIF 裡面隱含了 「private key」 以及 「public key 需要是壓縮過的格式」這兩個資訊

如果 private key 最後面沒有 01 ,則代表這個 WIF 裡面隱含了「private key」以及「public key 需要是非壓縮過的格式」

所以要把 01 拿掉之後才是 private key

並且這個 python-bitcoinlib 產生的 WIF 有帶 01 ,這代表 python-bitcoinlib 產生的 address 是用 compressed public key 產生的 address

但是 bitcoin test 這個網站是用 uncompressed public key 去產生 address 的

所以 lib 產生的結果勢必會跟 bitcoin test 不同

#!/usr/bin/env python3
from __future__ import absolute_import, division, print_function, unicode_literals

from bitcoin.wallet import CBitcoinSecret, P2PKHBitcoinAddress
from bitcoin.signmessage import BitcoinMessage, VerifyMessage, SignMessage
import os
import bitcoin

# A base58-encoded secret key as input
key = CBitcoinSecret.from_secret_bytes(os.urandom(32),compressed=False)
print("private key base58 WIF format:\t%s(%d)" % (key, len(str(key)) ))
address = P2PKHBitcoinAddress.from_pubkey(
print("Address:\t\t\t%s" % address)
print("public key hex format:\t\t%s" % bitcoin.core.b2x(
message = "Hey I just met you, and this is crazy, but I'll verify my address, maybe ..."

message = BitcoinMessage(message)

signature = SignMessage(key, message)

print("Message: %s" % message)
print("\nSignature: %s" % signature)
print("\nVerified: %s" % VerifyMessage(address, message, signature))

print("\nTo verify using bitcoin core;")
print("`bitcoin-cli verifymessage %s \"%s\" \"%s\"`" % (address, signature.decode('ascii'), message))

在產生 WIF format private key 的時候加上 compressed=False 就可以得到非壓縮格式的 public key and address