Skip to content

rotriw/UnlockHuaweiBootloader

Repository files navigation

重要

  1. 可能随platform-tools更新而失效

  2. 新版本依赖AdbWinApi.dll,老版本依赖fastboot.exe

  3. 因为platform-tools没有x86_64的,所以新版本的x86_64可能无法运行,老版本则同时支持两种

这是什么

用于解锁华为bootloader,它需要向fastboot输入oem unlock <16位解锁码>这条命令

你也可以自定义命令格式,此工具帮助你高效的用枚举法来不断的尝试16位解锁码

我们的工具是纯c写的,且使用比较底层的api,虽代码质量一般,但得益于clang llvm,它又小又快

在之前的版本(称为老版本,现在重命名为cmdline),它使用CreateProcess来运行命令行解锁

(protocol,称为新版本)现在则直接使用fastboot协议通信,避免一些创建进程,连接/断开的开销

老版本的优势是命令行调用,具有高兼容性,并且相对于脚本语言来说具有高性能

新版本的优势是超高性能,但兼容性可能不好,且仅支持原版fastboot的一小部分功能(usb)

platform-tools是cpp写的,这让我非常头疼,幸好最终我完成了新版本的工作

参考(官方的python和cpp版本,cpp版本就是我们常用的工具包):

https://github.com/google/python-adb

https://github.com/aosp-mirror/platform_system_core

ps:我没有可供测试的设备,有问题欢迎反馈

运行要求

windows xp及以上

release提供x86(i686)和x86_64体系的可执行文件

同时编译脚本里有编译native(专为本机)的命令,可以自己编译

注:native不一定是性能最好的,请根据实际情况为准

platform-tools

安卓提供的工具包,无论新老版本都需要,且不要改任何文件的名字(包括这个目录名)

https://dl.google.com/android/repository/platform-tools-latest-windows.zip

build.bat

用于编译二进制文件,输出到build文件夹,里面的子文件夹标识了适用于什么机器

temp文件夹编译结束后可以安全删除(如果有)

提供了clang的命令,脚本很短,只是为我自己写的! :)

使用的版本:

https://github.com/mstorsjo/llvm-mingw/releases/tag/20230919

test_speed.exe

一个速度测试程序,测试更新解锁码的速度,不依赖platform-tools,Exit前会Sleep两秒

会不断记录更新10w次解锁码的耗时,然后打印10w次的平均耗时,可以读取通用的环境变量和写入log

使用了windows的高分辨率计时器,并且没有错误检查,耗时的单位需要自己想办法获取

(因为新版本的加入,我将两个版本共同的部分单独抽出来了(初始化,程序退出和更新解锁码))

(而每个版本只专注于自己如何呼叫fastboot,这样还可以减小主函数和代码段的大小,有助于优化)

它可以测试源代码中新老版本共同部分的正确性,还可以测试/比较运行速度

这只是一个小demo,对于有些人来说可能有用,如果你不知道它是干嘛的,忽略就好

test_fastboot.exe

一个测试cmdline版本的程序,不依赖platform-tools,它只有i686版本,并且不在构建脚本里

把它复制到platform-tools\fastboot.exe即可

会从自己的stdin读取4字节数据,然后把读取到的数据写入自己的stdout

随后打印出数据长度(printf("%lu\n"))并退出

cmdine版本从fastboot的stdout读取到OKAY四个字节时会视作解锁成功

它可以测试cmdline的进程间通信是否正确,以及等待超时是否正确等

这只是一个小demo,对于有些人来说可能有用,如果你不知道它是干嘛的,忽略就好

unlockhwbl_(cmdline | protocol).exe

主程序,程序运行完毕后不会暂停,如果需要查看信息请不要双击运行

没有打印信息的时候说明正在解锁,不要关闭,有几种情况会打印信息:

  1. 会打印一段开头告诉你程序是活的(包括CODE_ORDER,CHAR_ORDER和第一个开始的解锁码)

  2. 错误,然后退出程序(仅致命错误)

  3. 解锁成功,打印成功的命令,然后退出程序(已经解锁,不需要再次输入命令)

  4. 结尾会打印一个Exit告诉你程序是优雅关闭的(不论错误与否)

如果程序没有显示任何东西,可能是你的标准输出句柄有问题

如果程序直接退出,可能是出错了

重要

不需要命令行参数,我们使用环境变量传递参数

多余输入会被忽略,且程序内没有过多的错误检查

一切输入请参考文档,如果不规范可能导致严重问题

非致命错误有哪些

  1. 获取标准输出句柄失败,此时程序不会显示任何内容

  2. 打开log文件失败,此时会导致读取和写入log文件失败

  3. 读取log文件失败,此时会从头开始枚举解锁码(视为没有log)

  4. 写入log文件失败(此操作包括文件指针设置为0),此时log文件可能会损坏,或记录没有被保存等

  5. 获取某个环境变量失败(包括不存在),此时这个环境变量使用默认值

  6. SetConsoleCtrlHandler失败,此时程序可能不会尽可能优雅退出

code.log

由程序运行产生,储存了最后的code记录(索引表),用于实现保存进度功能

并不会储存你的CODE_ORDER,CHAR_ORDER,PRE_STRING和END_STRING,请自己妥善保管

程序仅在结束时写入一次log,但使用了SetConsoleCtrlHandler注册了一个优雅结束程序的函数

注册的这个函数收到任何信号都会结束程序,在以后的windows版本中可能导致程序神奇退出

经过测试,程序运行时(打印Exit时已经写入log)使用ctrl+c/break是安全的,直接关闭窗口不安全

参考"windows控制台程序如何优雅退出"文章,这做不到,至少很难,目前ctrl+c/break就足够了

环境变量

注:如果输入了奇怪的值导致奇怪的问题,那么不是程序的问题

这两个是用于自定义枚举行为

自定义枚举行为的程序结构是这样(伪代码):


CHAR 解锁码[16];

CHAR CODE_ORDER[16];

LPSTR CHAR_ORDER = 获取环境变量("CHAR_ORDER");

CHAR 索引表[16] = {0};

CHAR 最大索引 = strlen(CHAR_ORDER)-1;

//初始化CODE_ORDER

LPSTR temp = 获取环境变量("CODE_ORDER");

for(i=0 ; i<16 ; i++){

    CODE_ORDER[i] = temp[i]-'a';

}

//更新解锁码

for(i=0 ; i<16 ; i++){

    //实际上并不会每次都刷新每一位,我们会判断,如果当前索引是最大索引

    //即需要进位,就将当前索引归0,然后再处理下一位

    //否则是不需要进位的,只需要把当前索引+1,然后退出循环

    //更新解锁码的速度是很快的,十几年前的cpu也可以每毫秒更新数万次,不要低估现代cpu的速度

    解锁码[CODE_ORDER[i]] = CHAR_ORDER[idx[i]];

}

  1. "CODE_ORDER"

一个16字节字符串,每个字节代表一个索引(0-15),默认为"abcdefghijklmnop"

每个索引的数值+97就是这16个字符"abcdefghijklmnop"(可以理解为另一种十六进制!)

这个索引表代表了枚举解锁码中字节进位的顺序,长度应至少为16,超长的忽略

  1. "CHAR_ORDER"

一个n字节字符串,代表解锁码每字节的字符枚举顺序,默认为"0123456789"

例如默认的0123456789代表每个字节从0枚举到9,然后进位

而9876543210则从9枚举到0,然后进位

这个参数让解锁码的可用字符不再局限于0123456789,长度不能超过255(正常情况下)

注:fastboot协议除了DATA之后的数据流,其他都是ascii文本,所以正常情况绝不会超长

接下来这两个是为了自定义命令而来

我们将一条fastboot命令视为四个部分:

<前置字符串><16位解锁码><后置字符串>\x00

其中16位解锁码和结尾的空字节由程序填充,整条命令中有且只有结尾的一个空字节

用户想要自定义命令只需要修改前置字符串和后置字符串即可

注:整条命令(不包括空字节)长度不能超过256,也就是这两个变量的有效部分总共不超过240字节

  1. "PRE_STRING"

前置字符串,默认"oem unlock "

  1. "END_STRING"

后置字符串,默认""

是的,就是空字符串!因为默认的命令是oem unlock <16位解锁码>

(fastboot协议中并不需要这个空字节,但引入它可以极大简化某些操作)

老版本的变量

暂无

注:fastboot进程完全继承环境变量和stdin,当前目录是platform-tools

新版本的变量

  1. "ANDROID_SERIAL"

fastboot设备字符串(现版本为usb的serial number,即序列号),长度不可超过255

默认没有,尝试使用最后连接的usb设备(fastboot文档是这样写的,但源码里是第一个枚举到的设备)

注:0字节的环境变量内容(如果可以设置这种的话)和"没有"是不一样的

(fastboot里是这样检查此变量的:如果没有则不检查,如果有则把它和usb的序列号和设备路径比较)

(两者中有一个和它完全相同就可以,而设备路径目前未使用,所以此变量目前含义是usb序列号)

(当然匹配设备并不只有这一个匹配即可,还需要一些其他参数的匹配,fastboot代码写的真丑啊)

About

适用于windows的解锁华为bootloader的高性能工具,可自定义解锁码更新行为

Resources

Stars

Watchers

Forks

Packages

No packages published