[TOOL][HOW-TO] [N7] [grouper+tilapia] BootUnlocker Script [Flashable Zip]

Search This thread

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
[TOOL][HOW-TO] [N7] [grouper+tilapia] BootUnlocker Script [Flashable Zip]

BootUnlocker Script for Nexus 7 (2012) -- Unlock your bootloader without fastboot.

Important Information


Those of you with any of the other recent flagship Nexus devices (Galaxy Nexus onward) may already be familiar with the brilliant work of segv11 in creating the BootUnlocker for Nexus Devices app. His app uses root to flip a byte on a device partition, allowing you to relock your bootloader for security and unlock it again any time you wish without the data loss that would come from unlocking via fastboot. I have also followed segv11's method and created a recovery flashable zip for the same devices available from my Odds & Ends thread.

Through the work of myself and several others in the GN BootUnlocker App thread it has been found that the data which controls the lockstate for the N7 '12 is stored in the mmcblk0boot0 partition. Unfortunately we also found this data cannot be simply altered to change the lockstate of the N7 '12 (like it can with the other Nexus devices) due to encryption on a per-device basis. The encrypted data also changes with each new version of the bootloader. The complicated nature of the key means that it's unlikely that the encryption could ever be cracked.

There is, however, still a working solution. Even though your mmcblk0boot0 partition is uniquely encrypted for your device, I found it also changes exactly the same way each time you lock or unlock your bootloader. This means if you back up your mmcblk0boot0 partition when your device is both unlocked and locked, you can simply flash these partition dumps whole to change the lockstate, with no data loss. That's where my script comes in.

In this How-To we are going to make dumps of your mmcblk0boot0 partition in both lockstates, then alter my included zip and updater-script using the dumps so that you have a fully functioning BootUnlocker Script recovery flashable zip tailored to your specific device. When flashed, this zip will lock or unlock your device (depending on what state it's currently in), whenever you want with no data loss.


Requirements

  • Nexus 7 (2012) grouper/WiFi or tilapia/GSM-HSPA+ (both use the exact same bootloader).
  • An UNLOCKED bootloader (if locked you'll need to fastboot oem unlock first which WILL factory reset your device).
  • Bootloader version 4.23 (if newer, then you'll also need to follow the steps to update the bootloader check, found in the 3rd post).
  • Custom recovery (CWM or TWRP) flashed to your device.
  • adb+fastboot binaries/executables, either from the Android SDK or you can get them standalone from here.
  • Universal Naked Driver for Android devices recommended installed for both adb+fastboot on Windows machines.
  • Notepad2, Notepad++, or another text editor capable of keeping the LF (linefeed) format required for Linux/Unix files like the updater-script.

Disclaimers / Warnings (READ)

I am in no way responsible for you somehow messing up these reasonably simple steps and damaging your device. DO NOT attempt this if you do not accept this risk. If you met the above requirements (in particular the unlocked bootloader), then the following instructions will not result in any data being lost in this process. DO NOT post your zips to this thread once you've followed the directions since the zips will not work on other peoples' devices and if another user somehow flashes your dumps by mistake, could damage their device. Each device must have its own specific BootUnlocker Script zip made using the unique dumps that belong to it.


It is critical that you have read all of the above before you move on.
 
Last edited:

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
Building Instructions

Instructions

Step 1 - Getting the dumps and their sha1sums:


Start by downloading the zip attached to this post to your PC. Save it for later.

Boot into your custom recovery on your device with it connected, open a command prompt on your PC where you have adb+fastboot.

Ensure the device is recognized by typing "adb devices".

Type "adb shell" in and then do the following, being sure to copy+paste the sha1sum for unlocked to Notepad for later.

Code:
dd if=/dev/block/mmcblk0boot0 of=/tmp/unlocked-mmcblk0boot0.img
sha1sum /tmp/unlocked-mmcblk0boot0.img
exit

adb pull /tmp/unlocked-mmcblk0boot0.img unlocked-mmcblk0boot0.img
adb reboot-bootloader

fastboot devices
fastboot oem lock

Boot to Recovery using the Bootloader menu then "adb shell" in and do the following, again copy+paste the sha1sum for later, this time for locked.

Code:
dd if=/dev/block/mmcblk0boot0 of=/tmp/locked-mmcblk0boot0.img
sha1sum /tmp/locked-mmcblk0boot0.img
exit

adb pull /tmp/locked-mmcblk0boot0.img locked-mmcblk0boot0.img

It's important that the dumps are named correctly according to the lockstate for the script, and equally important you have kept those sha1sums straight and you know which corresponds to unlocked and which is for locked.


Step 2 - Editing the updater-script:

Extract the updater-script (in /META-INF/com/google/android/) from the zip.

It appears as follows, and is written with safety checks for bootloader version and current lockstate to prevent flashing on the incorrect version or device, respectively. It is currently written for v4.23 ONLY of the bootloader. If you update the bootloader or have a newer version you must update all of these checks (instructions in next post).

Code:
ui_print("");
ui_print("Nexus 7 BootUnlocker Script");
ui_print("by osm0sis @ xda-developers");
ui_print("");

ui_print("For N7 bootloader 4.23 ONLY");
ui_print("and the device belonging to <yourname> ONLY");
show_progress(1.34, 0);

ui_print("");
ui_print("Verifying device...");
mount("ext4", "EMMC", "/dev/block/platform/sdhci-tegra.3/by-name/APP", "/system");
ui_print(getprop("ro.product.device"));
assert(getprop("ro.product.device") == "<devicename>" ||
       getprop("ro.build.product") == "<devicename>");
set_progress(0.2);

ui_print("");
ui_print("Verifying bootloader version...");
ui_print(getprop("ro.bootloader"));
assert(apply_patch_check("EMMC:/dev/block/platform/sdhci-tegra.3/by-name/USP:10485760:8c206a1a87599f532ce68675536f0b1546900d7a"),
       getprop("ro.bootloader") == "4.23" ||
       getprop("ro.boot.bootloader") == "4.23");
set_progress(0.5);

ui_print("");
ui_print("Checking bootloader status...");
run_program("/sbin/busybox", "dd", "if=/dev/block/mmcblk0boot0", "of=/tmp/current-mmcblk0boot0.img");
ifelse(sha1_check(read_file("/tmp/current-mmcblk0boot0.img")) == "<locked sha1sum>",
  (ui_print("Bootloader is locked.");
   ui_print("");
   ui_print("Unlocking...");
   package_extract_file("unlocked-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img");
  ),
  (ifelse(sha1_check(read_file("/tmp/current-mmcblk0boot0.img")) == "<unlocked sha1sum>",
     (ui_print("Bootloader is unlocked.");
      ui_print("");
      ui_print("Locking...");
      package_extract_file("locked-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img");
     ),
     (ui_print("Status does not match known values.");
      ui_print("This is not the intended specific device.");
      ui_print("");
      ui_print("Your system has not been changed.");
      ui_print("");
      ui_print("Script will now exit...");
      ui_print("");
      delete("/tmp/current-mmcblk0boot0.img");
      unmount("/system");
      abort();
     )
   );
  )
);
set_progress(0.9);

assert(run_program("/sbin/sh", "-c", "echo 0 > /sys/block/mmcblk0boot0/force_ro"),
       run_program("/sbin/busybox", "dd", "if=/tmp/mmcblk0boot0.img", "of=/dev/block/mmcblk0boot0"),
       run_program("/sbin/sh", "-c", "echo 1 > /sys/block/mmcblk0boot0/force_ro"),
       delete("/tmp/current-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img"));
set_progress(1.2);

unmount("/system");
ui_print("Done!");
set_progress(1.34);

Open Notepad 2/Notepad++ and ensure it is set so that it won't break the LF (Unix) formatting when it saves, then open the extracted updater-script.

Make sure the device check on lines 14+15 matches your device. ie. If you are running a tilapia then you should change them (quotes intact) to "tilapia", likewise for "grouper".

Replace <yourname> on line 7 with your username. eg. the device belonging to osm0sis ONLY

Replace <unlocked sha1sum> on line 35 with the sha1sum for the unlocked dump you saved from Step 1.

Replace <locked sha1sum> on line 29 with the sha1sum for the locked dump you also saved from Step 1.

The sha1sum replacements are the most important. They MUST match the dumps correctly. Also make sure you leave the quotes in the script surrounding the sha1sums intact, eg. "0000000000000000000000000000000000000000"

Save and exit Notepad.


Step 3 - Putting it all together:

Add both .img files to the zip. They should be in the root (top level) of the zip. Make sure they are located correctly.

Overwrite the updater-script in /META-INF/com/google/android/ of the zip with your new edited version. Double check that it has replaced the old one and has been added correctly.

Save and exit the zip.

It is now recommended you name the zip according to the following scheme: cwm-N7.<device>.BootUnlocker.v<bootloaderversion>-<username> to differentiate device, bootloader version and user. Mine is cwm-N7.grouper.BootUnlocker.v4.23-osm0sis.zip. This should help prevent confusion.


Done! You now have a BootUnlocker zip for your N7 '12 until the bootloader gets updated.
Flash it to unlock your device again. Flash it again to lock it.



Previous version download count: 131
 

Attachments

  • cwm-N7.BootUnlocker.v4.23.zip
    144.6 KB · Views: 1,242
Last edited:

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
Update Instructions

Updating When A New Bootloader Is Released

Once built for your device, the above script will work as long as the bootloader remains at v4.23 (as per the naming). The way I've scripted it, for safety it shouldn't work on any other bootloader version or on anyone else's device, but I'd still advise against trying. Since the encrypted data also changes based on the version of the bootloader, if/when you update the bootloader you MUST also get NEW dumps of the mmcblk0boot0 partition both unlocked and locked.


BEFORE you update your bootloader, if your device is locked, start by using the BootUnlocker Script zip you previously created to unlock.

Update your bootloader to the new version (usually done via OTA or fastboot flash of a Factory Image).

Follow the steps in the 2nd post again to update your zip, replacing the .img files with the new dumps, and altering the update-script with the new corresponding sha1sums.

Change the version number in the updater-script warning on line 6 and the version number check on lines 22+23 to that of the new bootloader, and be sure you have renamed the zip with the new version number as well to keep things straight.

"adb shell" in while booted to custom recovery and run the following, copy+paste the bytesize and sha1sum for the next step.
Code:
dd if=/dev/block/platform/sdhci-tegra.3/by-name/USP of=/tmp/USP.img 
sha1sum /tmp/USP.img
rm /tmp/USP.img

Enter the new bootloader's bytesize and sha1sum into the bootloader version check on line 21, in the following format USP:<bytesize>:<bootloader sha1sum>, eg. for v4.23 it is
Code:
USP:10485760:8c206a1a87599f532ce68675536f0b1546900d7a


Enjoy!
Questions, comments and feedback welcome.



Thanks to segv11 and efrant for all the fun in the GN BootUnlocker App thread, scary alien for the help with the bootloader check assert syntax in his OTA Verifier App thread, and thanks to trevd for the update-binary info/help in the GN EDIFY Scripting thread. Also a special thank you to Mach3.2, scary alien, partha and drose6102 for submitting dumps so all this could be figured out, and for basically being the Beta/RC testers for this script. Cheers!
 
Last edited:

Misledz

Senior Member
Jun 1, 2011
6,273
8,309
Cebu City, Philippines
You finally got it working! I ought to try this, of course after wrestling with the grizzly dad of mine. Awesome job there Chris!

Sent from my Galaxy Nexus using Tapatalk 2
 

lilstevie

Senior Recognized Developer
Apr 17, 2009
1,339
1,040
Since the encryption also changes based on the version of the bootloader

The encryption does not change, that is static for the life of the device, what changes is the data stored. Also boot0/1 are technically not partitions and are more analogous to mmcblk0 than mmcblk0px there are 3 partitions that start within this range, BCT, PT and the start of the bootloader. BCT takes up the entire boot0 and part of boot1.

The reason you cannot just flash back your backup copy is a hash of the bootloader is stored in the bct for verification and integrity checking purposes[1]. This changes the end result because all SBK encrypted data is done in AES-128-CBC meaning the previous blocks cipher text is the next blocks IV.

Because of this you should also be careful of any number of other conditions that cause writing to the BCT as they have the potential to cause the decryption to fail on the rest of the BCT which is in mmcblk0boot1. While this may not (and at this point should not) cause bricking, changes made by google in the future may alter this outcome.

[1] The hash stored in BCT not matching the bootloader hash causes the device to fall back into APX mode.
 
Last edited:

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
The encryption does not change, that is static for the life of the device, what changes is the data stored. Also boot0/1 are technically not partitions and are more analogous to mmcblk0 than mmcblk0px there are 3 partitions that start within this range, BCT, PT and the start of the bootloader. BCT takes up the entire boot0 and part of boot1.

The reason you cannot just flash back your backup copy is a hash of the bootloader is stored in the bct for verification and integrity checking purposes[1]. This changes the end result because all SBK encrypted data is done in AES-128-CBC meaning the previous blocks cipher text is the next blocks IV.

Because of this you should also be careful of any number of other conditions that cause writing to the BCT as they have the potential to cause the decryption to fail on the rest of the BCT which is in mmcblk0boot1. While this may not (and at this point should not) cause bricking, changes made by google in the future may alter this outcome.

[1] The hash stored in BCT not matching the bootloader hash causes the device to fall back into APX mode.

Hey great to finally get some more information about the encryption used and the contents of boot0-1. Very interesting stuff. :) How did you determine this? We couldn't find much documentation on the matter. Any ideas on how to decrypt it would also be greatly appreciated, since that might allow segv11 to still be able to include it in the BootUnlocker app.

So far the only time we've seen the md5hash of the boot0 block change on a particular device is with a bootloader version change, after which it continues to remain consistent depending on lockstate. I was merely guessing that was part of the encryption process but the data changing would of course also make perfect sense, so thank you for that information. What doesn't change when unlocking/locking the bootloader is boot1, so flipping between the two states for boot0 will still keep decryption of boot1 intact.

I definitely understand your concerns that it is a dangerous business writing to these blocks, and I agree, but as you've seen I haven't taken this lightly in either my posts or my script; the script has safeties built in to make sure it only writes to boot0 when it meets one of the two known states for that person's device (locked or unlocked). If somehow the boot0 did change randomly in the future without a bootloader update then the script wouldn't run, it would abort, questioning whether this was the intended device or not since it couldn't determine the lockstate from the stored sha1sums. :good:
 
Last edited:
  • Like
Reactions: deepdespair

lilstevie

Senior Recognized Developer
Apr 17, 2009
1,339
1,040
Hey great to finally get some more information about the encryption used and the content of boot0-1. Very interesting stuff. :) How did you determine this? We couldn't find much documentation on the matter. Any ideas on how to decrypt it would also be greatly appreciated, since that might allow segv11 to still be able to include it in the BootUnlocker app.

So far the only time we've seen the md5hash of the boot0 block change on a particular device is with bootloader version change, after which it continues to remains consistent depending on lockstate. I was merely guessing that was part of the encryption process but the data changing would of course also make perfect sense, so thank you for that information. What doesn't change when unlocking/locking the bootloader is boot1, so flipping between the two states for boot0 will still keep decryption of boot1 intact.

I definitely understand your concerns that it is a dangerous business writing to these blocks, and I agree, but as you've seen I haven't taken this lightly in either my posts or my script; the script has safeties built in to make sure it only writes to boot0 when it meets one of the two known states for that person's device (locked or unlocked). If somehow the boot0 did change randomly in the future without a bootloader update then the script wouldn't run, it would abort, questioning whether this was the intended device or not since it couldn't determine the lockstate from the stored md5hashes. :good:

it is off the shelf tegra security. As I said at this time changes shouldn't echo all the way through, but the BCT partition is usually ~3MB but only uses a fraction of that.

Decryption and Encryption of the data is not something easily available, it entirely defeats the purpose of it if you can do it yourself.
 

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
it is off the shelf tegra security. As I said at this time changes shouldn't echo all the way through, but the BCT partition is usually ~3MB but only uses a fraction of that.

Decryption and Encryption of the data is not something easily available, it entirely defeats the purpose of it if you can do it yourself.

Haha yeah of course it defeats the purpose, but in a way so does unlocking the bootloader with root. ;)
Either way, thanks for the help and your Tegra knowledge. :)
 
Last edited:

deepdespair

Member
Jul 26, 2011
40
10
Reno
Works perfect

Thanks a ton osm0sis. Just tested and it's flawless. Finally got rid of that unsightly unlock icon when you first boot and I still have full functionality. Locks and unlocks in an instant with the edited .zip file. Great work! :highfive:
 
  • Like
Reactions: osm0sis

slyb5

Member
Mar 15, 2010
20
1
46
Taipei
The encryption does not change, that is static for the life of the device,

I am very interested in unlocking the bootloader without rooting or fastboot oem unlock my device. I'd love to find that key and be able to write an encrypted bootloader via JTAG access for example (I guess can't do otherwise to write an encrypted image as the encryption is probably done by the bootloader while uploading an image through fastboot am I right?)

I foresee 2 possibilities, but might be very wrong: 1) key hardcoded (in the BIOS for ex), I am trying to see if I can JTAG access the processor next week (theoretically frist, as my N7 arrives after 2 weeks)
2) the key is computed based on the device serial number (which I think might very well be the case) at startup (I'd guess a logical operation like an XOR on the serial maybe with a master key hardcoded or just a crypto op on the serial) in this case it might not be required to search for it in a memory dump but aska crypto guy see if with the knowledge of cyphered data, the algorithm and the serial, a key could be diversified...


If some of you guys are interested to work on that...we could open a new thread?
Meanwhile any of you know where I can get more info on the memory map of the flash?
 
  • Like
Reactions: osm0sis

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
Just a reminder to everyone to unlock before you flash the OTA. Instructions for updating the script for new bootloader versions are in the 3rd post of this thread.

Happy OTA Day! :)
 
Last edited:

sebarkh

Senior Member
Oct 7, 2010
1,178
184
Warsaw
Apps & Games
What is strange USP.img sha1 did not change. It still is 8c206a1a87599f532ce68675536f0b1546900d7a

???

---------- Post added at 06:07 PM ---------- Previous post was at 05:58 PM ----------

Anyway....working ok with 4.2.2 after updating with post 2 instructions.
 
  • Like
Reactions: osm0sis

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
What is strange USP.img sha1 did not change. It still is 8c206a1a87599f532ce68675536f0b1546900d7a

???

---------- Post added at 06:07 PM ---------- Previous post was at 05:58 PM ----------

Anyway....working ok with 4.2.2 after updating with post 2 instructions.

You're right, interesting! My guess, based on what lilstevie said, is that when the OTA writes the new bootloader to /USP it actually writes it to multiple contiguous partitions starting with USP, including the mmcblk0boot ones we dump. So whatever changed in the bootloader didn't alter the actual USP part this time, and that's why it checksums the same. The mmcblk0boot blocks do change, so the method in post 3 should still be followed.
 
  • Like
Reactions: sebarkh

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,767
40,432
Halifax
GT-i9250
Google Nexus 4
Just noticed that having the mount /system in an assert will actually fail the assert if the system is already mounted. Not really a big deal, just means /system can't already be mounted when you go to run the BootUnlocker script or it won't make it past the device check. I haven't decided whether it matters enough to upload a new version of the script zip or not, since it's easy enough to go unmount /system before running it.

Also easy enough to fix it yourselves if you like:
Code:
assert(mount("ext4", "EMMC", "/dev/block/platform/sdhci-tegra.3/by-name/APP", "/system"),
       getprop("ro.product.device") == "grouper" ||
       getprop("ro.build.product") == "grouper");

should instead be:
Code:
mount("ext4", "EMMC", "/dev/block/platform/sdhci-tegra.3/by-name/APP", "/system");
assert(getprop("ro.product.device") == "grouper" ||
       getprop("ro.build.product") == "grouper");

Anyway, thought I'd give everyone the heads up even though nobody's apparently run into it or brought it to my attention before. ;):good:
 
Last edited:

pof

Retired Moderator
Mar 18, 2005
3,571
74
43
Barcelona
pof.eslack.org
Thanks for your tips! As I prefer to use the stock recovery I made a script to use your solution from the device itself, placing the partition backups in /system/usr/bootunlock. Here it is in case anyone else finds it useful:

Code:
#!/system/bin/sh

case $1 in
        "lock")
                echo "[x] Locking bootloader..."
                echo 0 > /sys/block/mmcblk0boot0/force_ro
                dd if=/system/usr/bootunlock/locked-mmcblk0boot0.img of=/dev/block/mmcblk0boot0
                echo 1 > /sys/block/mmcblk0boot0/force_ro
                echo "[x] Bootloader locked!"

        ;;
        "unlock")
                echo "[x] Unlocking bootloader..."
                echo 0 > /sys/block/mmcblk0boot0/force_ro
                dd if=/system/usr/bootunlock/unlocked-mmcblk0boot0.img of=/dev/block/mmcblk0boot0
                echo 1 > /sys/block/mmcblk0boot0/force_ro
                echo "[x] Bootloader unlocked!"
        ;;
        *)
                echo "Usage: $0 <lock|unlock>"
                exit 1
        ;;
esac
 

DIXES

Senior Member
Nov 22, 2010
335
34
Does it still work on the latest bootloader of Androud 4.3?
I just need to change the value in script and replace img files?

Thanks.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 26
    [TOOL][HOW-TO] [N7] [grouper+tilapia] BootUnlocker Script [Flashable Zip]

    BootUnlocker Script for Nexus 7 (2012) -- Unlock your bootloader without fastboot.

    Important Information


    Those of you with any of the other recent flagship Nexus devices (Galaxy Nexus onward) may already be familiar with the brilliant work of segv11 in creating the BootUnlocker for Nexus Devices app. His app uses root to flip a byte on a device partition, allowing you to relock your bootloader for security and unlock it again any time you wish without the data loss that would come from unlocking via fastboot. I have also followed segv11's method and created a recovery flashable zip for the same devices available from my Odds & Ends thread.

    Through the work of myself and several others in the GN BootUnlocker App thread it has been found that the data which controls the lockstate for the N7 '12 is stored in the mmcblk0boot0 partition. Unfortunately we also found this data cannot be simply altered to change the lockstate of the N7 '12 (like it can with the other Nexus devices) due to encryption on a per-device basis. The encrypted data also changes with each new version of the bootloader. The complicated nature of the key means that it's unlikely that the encryption could ever be cracked.

    There is, however, still a working solution. Even though your mmcblk0boot0 partition is uniquely encrypted for your device, I found it also changes exactly the same way each time you lock or unlock your bootloader. This means if you back up your mmcblk0boot0 partition when your device is both unlocked and locked, you can simply flash these partition dumps whole to change the lockstate, with no data loss. That's where my script comes in.

    In this How-To we are going to make dumps of your mmcblk0boot0 partition in both lockstates, then alter my included zip and updater-script using the dumps so that you have a fully functioning BootUnlocker Script recovery flashable zip tailored to your specific device. When flashed, this zip will lock or unlock your device (depending on what state it's currently in), whenever you want with no data loss.


    Requirements

    • Nexus 7 (2012) grouper/WiFi or tilapia/GSM-HSPA+ (both use the exact same bootloader).
    • An UNLOCKED bootloader (if locked you'll need to fastboot oem unlock first which WILL factory reset your device).
    • Bootloader version 4.23 (if newer, then you'll also need to follow the steps to update the bootloader check, found in the 3rd post).
    • Custom recovery (CWM or TWRP) flashed to your device.
    • adb+fastboot binaries/executables, either from the Android SDK or you can get them standalone from here.
    • Universal Naked Driver for Android devices recommended installed for both adb+fastboot on Windows machines.
    • Notepad2, Notepad++, or another text editor capable of keeping the LF (linefeed) format required for Linux/Unix files like the updater-script.

    Disclaimers / Warnings (READ)

    I am in no way responsible for you somehow messing up these reasonably simple steps and damaging your device. DO NOT attempt this if you do not accept this risk. If you met the above requirements (in particular the unlocked bootloader), then the following instructions will not result in any data being lost in this process. DO NOT post your zips to this thread once you've followed the directions since the zips will not work on other peoples' devices and if another user somehow flashes your dumps by mistake, could damage their device. Each device must have its own specific BootUnlocker Script zip made using the unique dumps that belong to it.


    It is critical that you have read all of the above before you move on.
    17
    Building Instructions

    Instructions

    Step 1 - Getting the dumps and their sha1sums:


    Start by downloading the zip attached to this post to your PC. Save it for later.

    Boot into your custom recovery on your device with it connected, open a command prompt on your PC where you have adb+fastboot.

    Ensure the device is recognized by typing "adb devices".

    Type "adb shell" in and then do the following, being sure to copy+paste the sha1sum for unlocked to Notepad for later.

    Code:
    dd if=/dev/block/mmcblk0boot0 of=/tmp/unlocked-mmcblk0boot0.img
    sha1sum /tmp/unlocked-mmcblk0boot0.img
    exit
    
    adb pull /tmp/unlocked-mmcblk0boot0.img unlocked-mmcblk0boot0.img
    adb reboot-bootloader
    
    fastboot devices
    fastboot oem lock

    Boot to Recovery using the Bootloader menu then "adb shell" in and do the following, again copy+paste the sha1sum for later, this time for locked.

    Code:
    dd if=/dev/block/mmcblk0boot0 of=/tmp/locked-mmcblk0boot0.img
    sha1sum /tmp/locked-mmcblk0boot0.img
    exit
    
    adb pull /tmp/locked-mmcblk0boot0.img locked-mmcblk0boot0.img

    It's important that the dumps are named correctly according to the lockstate for the script, and equally important you have kept those sha1sums straight and you know which corresponds to unlocked and which is for locked.


    Step 2 - Editing the updater-script:

    Extract the updater-script (in /META-INF/com/google/android/) from the zip.

    It appears as follows, and is written with safety checks for bootloader version and current lockstate to prevent flashing on the incorrect version or device, respectively. It is currently written for v4.23 ONLY of the bootloader. If you update the bootloader or have a newer version you must update all of these checks (instructions in next post).

    Code:
    ui_print("");
    ui_print("Nexus 7 BootUnlocker Script");
    ui_print("by osm0sis @ xda-developers");
    ui_print("");
    
    ui_print("For N7 bootloader 4.23 ONLY");
    ui_print("and the device belonging to <yourname> ONLY");
    show_progress(1.34, 0);
    
    ui_print("");
    ui_print("Verifying device...");
    mount("ext4", "EMMC", "/dev/block/platform/sdhci-tegra.3/by-name/APP", "/system");
    ui_print(getprop("ro.product.device"));
    assert(getprop("ro.product.device") == "<devicename>" ||
           getprop("ro.build.product") == "<devicename>");
    set_progress(0.2);
    
    ui_print("");
    ui_print("Verifying bootloader version...");
    ui_print(getprop("ro.bootloader"));
    assert(apply_patch_check("EMMC:/dev/block/platform/sdhci-tegra.3/by-name/USP:10485760:8c206a1a87599f532ce68675536f0b1546900d7a"),
           getprop("ro.bootloader") == "4.23" ||
           getprop("ro.boot.bootloader") == "4.23");
    set_progress(0.5);
    
    ui_print("");
    ui_print("Checking bootloader status...");
    run_program("/sbin/busybox", "dd", "if=/dev/block/mmcblk0boot0", "of=/tmp/current-mmcblk0boot0.img");
    ifelse(sha1_check(read_file("/tmp/current-mmcblk0boot0.img")) == "<locked sha1sum>",
      (ui_print("Bootloader is locked.");
       ui_print("");
       ui_print("Unlocking...");
       package_extract_file("unlocked-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img");
      ),
      (ifelse(sha1_check(read_file("/tmp/current-mmcblk0boot0.img")) == "<unlocked sha1sum>",
         (ui_print("Bootloader is unlocked.");
          ui_print("");
          ui_print("Locking...");
          package_extract_file("locked-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img");
         ),
         (ui_print("Status does not match known values.");
          ui_print("This is not the intended specific device.");
          ui_print("");
          ui_print("Your system has not been changed.");
          ui_print("");
          ui_print("Script will now exit...");
          ui_print("");
          delete("/tmp/current-mmcblk0boot0.img");
          unmount("/system");
          abort();
         )
       );
      )
    );
    set_progress(0.9);
    
    assert(run_program("/sbin/sh", "-c", "echo 0 > /sys/block/mmcblk0boot0/force_ro"),
           run_program("/sbin/busybox", "dd", "if=/tmp/mmcblk0boot0.img", "of=/dev/block/mmcblk0boot0"),
           run_program("/sbin/sh", "-c", "echo 1 > /sys/block/mmcblk0boot0/force_ro"),
           delete("/tmp/current-mmcblk0boot0.img", "/tmp/mmcblk0boot0.img"));
    set_progress(1.2);
    
    unmount("/system");
    ui_print("Done!");
    set_progress(1.34);

    Open Notepad 2/Notepad++ and ensure it is set so that it won't break the LF (Unix) formatting when it saves, then open the extracted updater-script.

    Make sure the device check on lines 14+15 matches your device. ie. If you are running a tilapia then you should change them (quotes intact) to "tilapia", likewise for "grouper".

    Replace <yourname> on line 7 with your username. eg. the device belonging to osm0sis ONLY

    Replace <unlocked sha1sum> on line 35 with the sha1sum for the unlocked dump you saved from Step 1.

    Replace <locked sha1sum> on line 29 with the sha1sum for the locked dump you also saved from Step 1.

    The sha1sum replacements are the most important. They MUST match the dumps correctly. Also make sure you leave the quotes in the script surrounding the sha1sums intact, eg. "0000000000000000000000000000000000000000"

    Save and exit Notepad.


    Step 3 - Putting it all together:

    Add both .img files to the zip. They should be in the root (top level) of the zip. Make sure they are located correctly.

    Overwrite the updater-script in /META-INF/com/google/android/ of the zip with your new edited version. Double check that it has replaced the old one and has been added correctly.

    Save and exit the zip.

    It is now recommended you name the zip according to the following scheme: cwm-N7.<device>.BootUnlocker.v<bootloaderversion>-<username> to differentiate device, bootloader version and user. Mine is cwm-N7.grouper.BootUnlocker.v4.23-osm0sis.zip. This should help prevent confusion.


    Done! You now have a BootUnlocker zip for your N7 '12 until the bootloader gets updated.
    Flash it to unlock your device again. Flash it again to lock it.



    Previous version download count: 131
    15
    Update Instructions

    Updating When A New Bootloader Is Released

    Once built for your device, the above script will work as long as the bootloader remains at v4.23 (as per the naming). The way I've scripted it, for safety it shouldn't work on any other bootloader version or on anyone else's device, but I'd still advise against trying. Since the encrypted data also changes based on the version of the bootloader, if/when you update the bootloader you MUST also get NEW dumps of the mmcblk0boot0 partition both unlocked and locked.


    BEFORE you update your bootloader, if your device is locked, start by using the BootUnlocker Script zip you previously created to unlock.

    Update your bootloader to the new version (usually done via OTA or fastboot flash of a Factory Image).

    Follow the steps in the 2nd post again to update your zip, replacing the .img files with the new dumps, and altering the update-script with the new corresponding sha1sums.

    Change the version number in the updater-script warning on line 6 and the version number check on lines 22+23 to that of the new bootloader, and be sure you have renamed the zip with the new version number as well to keep things straight.

    "adb shell" in while booted to custom recovery and run the following, copy+paste the bytesize and sha1sum for the next step.
    Code:
    dd if=/dev/block/platform/sdhci-tegra.3/by-name/USP of=/tmp/USP.img 
    sha1sum /tmp/USP.img
    rm /tmp/USP.img

    Enter the new bootloader's bytesize and sha1sum into the bootloader version check on line 21, in the following format USP:<bytesize>:<bootloader sha1sum>, eg. for v4.23 it is
    Code:
    USP:10485760:8c206a1a87599f532ce68675536f0b1546900d7a


    Enjoy!
    Questions, comments and feedback welcome.



    Thanks to segv11 and efrant for all the fun in the GN BootUnlocker App thread, scary alien for the help with the bootloader check assert syntax in his OTA Verifier App thread, and thanks to trevd for the update-binary info/help in the GN EDIFY Scripting thread. Also a special thank you to Mach3.2, scary alien, partha and drose6102 for submitting dumps so all this could be figured out, and for basically being the Beta/RC testers for this script. Cheers!
    4
    Since the encryption also changes based on the version of the bootloader

    The encryption does not change, that is static for the life of the device, what changes is the data stored. Also boot0/1 are technically not partitions and are more analogous to mmcblk0 than mmcblk0px there are 3 partitions that start within this range, BCT, PT and the start of the bootloader. BCT takes up the entire boot0 and part of boot1.

    The reason you cannot just flash back your backup copy is a hash of the bootloader is stored in the bct for verification and integrity checking purposes[1]. This changes the end result because all SBK encrypted data is done in AES-128-CBC meaning the previous blocks cipher text is the next blocks IV.

    Because of this you should also be careful of any number of other conditions that cause writing to the BCT as they have the potential to cause the decryption to fail on the rest of the BCT which is in mmcblk0boot1. While this may not (and at this point should not) cause bricking, changes made by google in the future may alter this outcome.

    [1] The hash stored in BCT not matching the bootloader hash causes the device to fall back into APX mode.
    2
    Hey great to finally get some more information about the encryption used and the content of boot0-1. Very interesting stuff. :) How did you determine this? We couldn't find much documentation on the matter. Any ideas on how to decrypt it would also be greatly appreciated, since that might allow segv11 to still be able to include it in the BootUnlocker app.

    So far the only time we've seen the md5hash of the boot0 block change on a particular device is with bootloader version change, after which it continues to remains consistent depending on lockstate. I was merely guessing that was part of the encryption process but the data changing would of course also make perfect sense, so thank you for that information. What doesn't change when unlocking/locking the bootloader is boot1, so flipping between the two states for boot0 will still keep decryption of boot1 intact.

    I definitely understand your concerns that it is a dangerous business writing to these blocks, and I agree, but as you've seen I haven't taken this lightly in either my posts or my script; the script has safeties built in to make sure it only writes to boot0 when it meets one of the two known states for that person's device (locked or unlocked). If somehow the boot0 did change randomly in the future without a bootloader update then the script wouldn't run, it would abort, questioning whether this was the intended device or not since it couldn't determine the lockstate from the stored md5hashes. :good:

    it is off the shelf tegra security. As I said at this time changes shouldn't echo all the way through, but the BCT partition is usually ~3MB but only uses a fraction of that.

    Decryption and Encryption of the data is not something easily available, it entirely defeats the purpose of it if you can do it yourself.