Samsung S6 FACTORY Bootloader Unlocker apk and source

Search This thread

The.Jericho.Initiative

Senior Member
Jan 3, 2009
123
104
Texas
Got a hold of the Samsung CROM Service apk that unlocks the S6 SM-G9250 bootloader and I've decompiled it, I'll be honest, it's been years since I've looked at this stuff. The file is distributed by Samsung for the Chinese market It's been verified to install on American Devices but force closes immediately. I figure it's failing a version check or something along those lines.

I can pass it along if anyone wants to take a crack at it. I'll be muddling along on my end but my primary interest is in the results - not the credit.

Anyone interested?

Edit: I have TWO versions of the file,version 1.04 android:versionCode="20150408" and
version 1.01 android:versionCode="20141126", which I've attached below.
-----
Contents of S6 CROM Android Manifest xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest android:sharedUserId="android.uid.system" android:versionCode="20150408" android:versionName="1.0.4" package="com.sec.android.app.kwb"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> />
<uses-library android:name="kwb" />
<application android:theme="@style/SettingsTheme" android:label="@string/app_name" android:icon="@drawable/custom_rom" android:allowBackup="true">
<activity android:theme="@style/SettingsTheme" android:label="@string/app_name" android:name="com.sec.android.app.kwb.KwbLaunchActivity" android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="SPDE.build.signature" android:value="424919/737923/release" />
<meta-data android:name="SPDE.env.version" android:value="0.12.2/19.1.8/19.2.12" />
</application>
</manifest>
 

Attachments

  • s6-CROM.apk
    1.3 MB · Views: 40,506
Last edited:

juancollado2003

Senior Member
Mar 1, 2011
598
176
Santo Domingo
Got a hold of the Samsung CROM Service apk that unlocks the S6 SM-G9250 bootloader and I've decompiled it, I'll be honest, it's been years since I've looked at this stuff. The file is distributed by Samsung for the Chinese market It's been verified to install on American Devices but force closes immediately. I figure it's failing a version check or something along those lines.

I can pass it along if anyone wants to take a crack at it. I'll be muddling along on my end but my primary interest is in the results - not the credit.

Anyone interested?

Edit:
-----
Contents of Android Manifest xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest android:sharedUserId="android.uid.system" android:versionCode="20150408" android:versionName="1.0.4" package="com.sec.android.app.kwb"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> />
<uses-library android:name="kwb" />
<application android:theme="@style/SettingsTheme" android:label="@string/app_name" android:icon="@drawable/custom_rom" android:allowBackup="true">
<activity android:theme="@style/SettingsTheme" android:label="@string/app_name" android:name="com.sec.android.app.kwb.KwbLaunchActivity" android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="SPDE.build.signature" android:value="424919/737923/release" />
<meta-data android:name="SPDE.env.version" android:value="0.12.2/19.1.8/19.2.12" />
</application>
</manifest>

You can post the apk and wait for anyone crack it, you will receive the proper credit
 

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
Interestingly I came across a second version. The manifest of the first I posted said version 1.04 android:versionCode="20150408"
The manifest of the second reads version 1.01 android:versionCode="20141126" I've attached the second apk to this message

odd. on my galaxy tab s 10.5 (T807v) it opens up to the message that talks about unlocking device then fcs.. on my vzw s6 edge it fcs right away

Sent from my SM-G925V using XDA Free mobile app

---------- Post added at 06:57 PM ---------- Previous post was at 06:51 PM ----------

odd. on my galaxy tab s 10.5 (T807v) it opens up to the message that talks about unlocking device then fcs.. on my vzw s6 edge it fcs right away

Sent from my SM-G925V using XDA Free mobile app

also, the second apk has a lib file.. libkwb.so

Sent from my SM-G925V using XDA Free mobile app
 

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
heres where i get on my tablet...



Sent from my SM-T807V using XDA Free mobile app
 

Attachments

  • 1429409294171.jpg
    1429409294171.jpg
    101 KB · Views: 8,818
  • 1429409301818.jpg
    1429409301818.jpg
    105.4 KB · Views: 8,735

designgears

Inactive Recognized Developer
Feb 9, 2010
5,399
8,909
SLC
s6-CROM.apk is missing /libs/libkwb.so

Code:
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.471: D/Activity(19562): performCreate Call Injection manager
04-20 10:40:09.481: I/InjectionManager(19562): dispatchOnViewCreated > Target : com.sec.android.app.kwb.KwbLaunchActivity isFragment :false
04-20 10:40:09.481: D/KwbLaunchActivity(19562): onResume called
04-20 10:40:09.481: D/LibKwb(19562): WARNING: Could not load /libs/libkwb.so
04-20 10:40:09.481: D/LibKwb(19562): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libkwb.so"
04-20 10:40:09.481: E/art(19562): No implementation found for int com.sec.android.lib.kwb.LibKwb.getCustomBinStatusFlag() (tried Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag and Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag__)

edit:

Added the that in, now it has unmet dependencies

Code:
04-20 11:32:14.231: E/art(24783): dlopen("/data/app/com.sec.android.app.kwb-1/lib/arm/libkwb.so", RTLD_LAZY) failed: dlopen failed: could not load library "libQSEEComAPI.so" needed by "libkwb.so"; caused by library "libQSEEComAPI.so" not found

edit:

Added in libQSEEComAPI.so and the app fires up and you can get thru all of the prompts, but then it crashes because I had to remove the shareduser so it would install, basically it has no permissions. We need to be able to load the two dependencies without modifying the apk because we can't resign the apk with the same signing key that it was originally signed with.

If someone could test this on an S6 that has root and load the two .so files we could do some more testing.
 
Last edited:

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
s6-CROM.apk is missing /libs/libkwb.so

Code:
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.471: D/Activity(19562): performCreate Call Injection manager
04-20 10:40:09.481: I/InjectionManager(19562): dispatchOnViewCreated > Target : com.sec.android.app.kwb.KwbLaunchActivity isFragment :false
04-20 10:40:09.481: D/KwbLaunchActivity(19562): onResume called
04-20 10:40:09.481: D/LibKwb(19562): WARNING: Could not load /libs/libkwb.so
04-20 10:40:09.481: D/LibKwb(19562): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libkwb.so"
04-20 10:40:09.481: E/art(19562): No implementation found for int com.sec.android.lib.kwb.LibKwb.getCustomBinStatusFlag() (tried Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag and Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag__)

edit:

Added the that in, now it has unmet dependencies

Code:
04-20 11:32:14.231: E/art(24783): dlopen("/data/app/com.sec.android.app.kwb-1/lib/arm/libkwb.so", RTLD_LAZY) failed: dlopen failed: could not load library "libQSEEComAPI.so" needed by "libkwb.so"; caused by library "libQSEEComAPI.so" not found

edit:

Added in libQSEEComAPI.so and the app fires up and you can get thru all of the prompts, but then it crashes because I had to remove the shareduser so it would install, basically it has no permissions. We need to be able to load the two dependencies without modifying the apk because we can't resign the apk with the same signing key that it was originally signed with.

If someone could test this on an S6 that has root and load the two .so files we could do some more testing.

do you have the two files? i am not sure where to locate the libqsee file.. i know it doesnt work but i am trying to learn and would like to see what you did lol

Sent from my SM-T807V using XDA Free mobile app
 

The.Jericho.Initiative

Senior Member
Jan 3, 2009
123
104
Texas
s6-CROM.apk is missing /libs/libkwb.so

Code:
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
04-20 10:40:09.471: D/Activity(19562): performCreate Call Injection manager
04-20 10:40:09.481: I/InjectionManager(19562): dispatchOnViewCreated > Target : com.sec.android.app.kwb.KwbLaunchActivity isFragment :false
04-20 10:40:09.481: D/KwbLaunchActivity(19562): onResume called
04-20 10:40:09.481: D/LibKwb(19562): WARNING: Could not load /libs/libkwb.so
04-20 10:40:09.481: D/LibKwb(19562): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libkwb.so"
04-20 10:40:09.481: E/art(19562): No implementation found for int com.sec.android.lib.kwb.LibKwb.getCustomBinStatusFlag() (tried Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag and Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag__)

edit:

Added the that in, now it has unmet dependencies

Code:
04-20 11:32:14.231: E/art(24783): dlopen("/data/app/com.sec.android.app.kwb-1/lib/arm/libkwb.so", RTLD_LAZY) failed: dlopen failed: could not load library "libQSEEComAPI.so" needed by "libkwb.so"; caused by library "libQSEEComAPI.so" not found

edit:

Added in libQSEEComAPI.so and the app fires up and you can get thru all of the prompts, but then it crashes because I had to remove the shareduser so it would install, basically it has no permissions. We need to be able to load the two dependencies without modifying the apk because we can't resign the apk with the same signing key that it was originally signed with.

If someone could test this on an S6 that has root and load the two .so files we could do some more testing.

I know CROM Service does have the library, what results, if any, did you see running that app?
 

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
I know CROM Service does have the library, what results, if any, did you see running that app?

i was not able to locate the libqseecomapi.so within the apk once i decompiled it.. when i tried to add it and recompile with original signature it failed to install as he stated due to signature..

i would assume if a rooted device was able to load the lib files to the right area, the apk would not need the original signature to function..

i have no idea if thats what he meant bcuz he is beyond my skill ha!

maybe we can get someone with root to help us out.

Sent from my SM-G925V using XDA Free mobile app
 

BMc08GT

Senior Member
Oct 26, 2012
232
1,758
Metro Detroit
Post the libs and ill put them together tomorrow at the office. Will also be posting docs on how to deodex Android 5.0+ apks tomorrow as well :)
 

designgears

Inactive Recognized Developer
Feb 9, 2010
5,399
8,909
SLC
i was not able to locate the libqseecomapi.so within the apk once i decompiled it.. when i tried to add it and recompile with original signature it failed to install as he stated due to signature..

i would assume if a rooted device was able to load the lib files to the right area, the apk would not need the original signature to function..

i have no idea if thats what he meant bcuz he is beyond my skill ha!

maybe we can get someone with root to help us out.

Sent from my SM-G925V using XDA Free mobile app

If you can load the 2 files into the lib folder of the device there is no need to modify the apk and lose the signature and permissions. Even then the app checks the CID, IMEI, and serial which it then sends to a server to validate that you are using an unlockable device, which the AT&T variant isn't.

The only chance I see of this working is if we get root we could modify the app to have root permissions which would make modifying it not a problem. Might be possible to spoof the info being sent to the server but then there is a pretty good chance what it returned wouldn't work anyways because it doesn't match the phone.

Might be worth checking out, but I am pretty sure it's a dead end.
 
Last edited:

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
If you can load the 2 files into the lib folder of the device there is no need to modify the apk and lose the signature and permissions. Even then the app checks the CID, IMEI, and serial which it then sends to a server to validate that you are using an unlockable device, which the AT&T variant isn't.

The only chance I see of this working is if we get root we could modify the app to have root permissions which would make modifying it not a problem. Might be possible to spoof the info being sent to the server but then there is a pretty good chance what it returns wouldn't work anyways because it doesn't match the phone.

Might be worth checking out, but I am pretty sure it's a dead end.

Thanks for the clarification! so we need root in order to manually push the apk/libs as well as try to modify it so it will work on other devices..

i knew it wasnt that easy! thanks for looking into it! hopefully it can provide insight at a bl unlock later down the road if and when root is attained.

Thanks again!

Sent from my SM-G925V using XDA Free mobile app
 

Pure+

Senior Member
May 28, 2013
1,317
515
Att has root. Time to revive this thread?

Sent from My Samsung Galaxy S6 "Pure" Black
 

Wiseor

Senior Member
Apr 14, 2015
62
17
Is there any hope for this at all because I feal like we have the tool we just need to get past the checks
 

elliwigy

Retired Forum Moderator / Recognized Developer
XDA App Taskforce
Is there any hope for this at all because I feal like we have the tool we just need to get past the checks

you need to manually push the libqseecom and libkwn files if you can find them then need to spoof device so it thinks its an unlockable variant when it contacts the server in order to have a chance at it working..

i am unable to locate the necessary files and when i installed both versions of the apk (also tried manually pushing and setting perms) they just fcd immediately.. i think this is due to me not having the required libs

Sent from my SM-G925V using XDA Free mobile app
 
  • Like
Reactions: Pure+

Top Liked Posts

  • There are no posts matching your filters.
  • 14
    Got a hold of the Samsung CROM Service apk that unlocks the S6 SM-G9250 bootloader and I've decompiled it, I'll be honest, it's been years since I've looked at this stuff. The file is distributed by Samsung for the Chinese market It's been verified to install on American Devices but force closes immediately. I figure it's failing a version check or something along those lines.

    I can pass it along if anyone wants to take a crack at it. I'll be muddling along on my end but my primary interest is in the results - not the credit.

    Anyone interested?

    Edit: I have TWO versions of the file,version 1.04 android:versionCode="20150408" and
    version 1.01 android:versionCode="20141126", which I've attached below.
    -----
    Contents of S6 CROM Android Manifest xml file:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest android:sharedUserId="android.uid.system" android:versionCode="20150408" android:versionName="1.0.4" package="com.sec.android.app.kwb"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> />
    <uses-library android:name="kwb" />
    <application android:theme="@style/SettingsTheme" android:label="@string/app_name" android:icon="@drawable/custom_rom" android:allowBackup="true">
    <activity android:theme="@style/SettingsTheme" android:label="@string/app_name" android:name="com.sec.android.app.kwb.KwbLaunchActivity" android:configChanges="keyboardHidden|orientation">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    <meta-data android:name="SPDE.build.signature" android:value="424919/737923/release" />
    <meta-data android:name="SPDE.env.version" android:value="0.12.2/19.1.8/19.2.12" />
    </application>
    </manifest>
    11
    so for us less intelligent folks, what does this mean? lol more promising or less? what does it check for if not a CID?

    We all for the most part should have root so if anything can be done or tested let us know

    Sent from my SM-G925V using XDA Free mobile app

    Well, it's more promising in the fact I had been wasting my time with the wrong version of the files (all my previous posts can be ignored - that info is not for the S6). S6's uses ro.serialno instead of CID.

    However, even after a preliminary overview of the correct files, it doesn't look so promising.

    From my brief look, the actual unlock is stupidly easy. All it does is set a flag with the string "KIWIBIRD" (libkwb being short for kiwibird) written to the STEADY partition. All that stuff that gets sent to server is not even needed at all. In fact, I don't even believe Samsung are checking ID's to ensure they are eligible to unlock. They are probably just collecting the ID's for counting purposes.

    The server just signs the data you upload, the app then verifies the signature and if correct sets the KIWIBIRD flag. You could probably upload rubbish data and it'll still get signed by the server. But anyway, none of that is needed.

    The real magic actually lies in the Chinese bootloader. It is different to all others. The CROM lock is actually an extra lock on top of the usual locks. On boot, it looks for the KIWIBIRD flag in the STEADY partition and if found, then allows custom binaries.

    However, this CROM lock doesn't exist on non-Chinese bootloaders. So Chinese bootloaders have in fact 3 locks, the normal carrier lock, the CROM lock, and the reactivation lock (that new feature in lollipop where it needs the password of the Samsung account before you can reflash). So far, it doesn't seem the carrier lock is used at all on Chinese models, just the CROM lock.

    All other bootloaders just have the 2 locks, the normal carrier one and the reactivation one. So there's no check for KIWIBIRD on other bootloaders so this CROM app will actually achieve nothing since there's no CROM lock to even unlock.

    If your bootloader is carrier locked, this app won't unlock it. If it says "CROM Service" in download mode, then you can use this app, otherwise it'll do nothing (other than write the string KIWIBIRD into STEADY partition which your bootloader will just completely ignore).

    You can check the error it gives when you try install custom ROM, it'll either say:
    "Custom binary blocked by C-ROM."
    "Custom binary blocked by CC Mode."
    "Custom binary blocked by Reactivation Lock."

    So if your bootloader happens to have a CROM lock you might be in luck. Or you can check your PARAM partition where all those ODIN pics are stored for this pic "kiwiBird_warning_L.jpg".

    Note: this is all just from a preliminary observation, more research might yield some more info especially stuff inside the Chinese bootloader and comparing it to other bootloaders, but it's not likely at this point.
    8
    s6-CROM.apk is missing /libs/libkwb.so

    Code:
    04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
    04-20 10:40:09.461: I/LoadedApk(19562): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
    04-20 10:40:09.471: D/Activity(19562): performCreate Call Injection manager
    04-20 10:40:09.481: I/InjectionManager(19562): dispatchOnViewCreated > Target : com.sec.android.app.kwb.KwbLaunchActivity isFragment :false
    04-20 10:40:09.481: D/KwbLaunchActivity(19562): onResume called
    04-20 10:40:09.481: D/LibKwb(19562): WARNING: Could not load /libs/libkwb.so
    04-20 10:40:09.481: D/LibKwb(19562): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sec.android.app.kwb-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libkwb.so"
    04-20 10:40:09.481: E/art(19562): No implementation found for int com.sec.android.lib.kwb.LibKwb.getCustomBinStatusFlag() (tried Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag and Java_com_sec_android_lib_kwb_LibKwb_getCustomBinStatusFlag__)

    edit:

    Added the that in, now it has unmet dependencies

    Code:
    04-20 11:32:14.231: E/art(24783): dlopen("/data/app/com.sec.android.app.kwb-1/lib/arm/libkwb.so", RTLD_LAZY) failed: dlopen failed: could not load library "libQSEEComAPI.so" needed by "libkwb.so"; caused by library "libQSEEComAPI.so" not found

    edit:

    Added in libQSEEComAPI.so and the app fires up and you can get thru all of the prompts, but then it crashes because I had to remove the shareduser so it would install, basically it has no permissions. We need to be able to load the two dependencies without modifying the apk because we can't resign the apk with the same signing key that it was originally signed with.

    If someone could test this on an S6 that has root and load the two .so files we could do some more testing.
    7
    Eeek, I think they might've banned me cause I spammed their server too much. The server is now returning 500 - Internal Server Error.
    I think I'll stop now. In case anyone else wants to play around here's quick sample I wrote up:

    Basically, it RSA encrypts the ID's (dummied with 0's) with the Samsung Public Key (grabbed from libkwb.so) attaches a SHA256HMAC to it and uploads to the server, then prints out the response. It was working previously and giving a valid response but now seems to just give 500 error html page.

    Excuse the messy code, most of it was reversed from libkwb.so. Just reimplemented in C using libopenssl for the crypto and libcurl for the uploading to the server.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #include <openssl/crypto.h>
    #include <openssl/rand.h>
    #include <openssl/rsa.h>
    #include <openssl/bn.h>
    #include <openssl/err.h>
    #include <openssl/hmac.h>
    #include <openssl/evp.h>
    
    #include <curl/curl.h>
    
    
    typedef struct
    {
    	char cmd;
    	char hmacKey[0x20]; /* meant to be random */
    	char rand[0x20]; /* meant to be random */
    	char model[0x20];
    	char imei[0x20];
    	char cid[0x20];
    
    } request_msg_t; /* sizeof == 0xA1 */
    
    typedef struct
    {
    	char encText[0x100]; /* encrypted request_msg_t */
    	char hmac[0x20]; /* hmacSHA256 of KWBREQ0001+encText */
    
    } request_token_t; /* sizeof == 0x120 */
    
    
    
    /* Samsung Server RSA Public Key Modulus */
    static const unsigned char g_pub_mod[0x100] =
    {
    	0xC3, 0x8F, 0x89, 0x63, 0x1C, 0x32, 0x6B, 0x6E, 0x49, 0xF2, 0x12, 0xDB, 0x60, 0x00, 0x81, 0xB2,
    	0x9C, 0xE4, 0x37, 0x54, 0xFE, 0xF4, 0x85, 0xDC, 0xF1, 0xC5, 0x14, 0x30, 0x9C, 0x4C, 0x6A, 0xFB,
    	0x35, 0x61, 0xED, 0x5E, 0xC2, 0x76, 0xFE, 0x24, 0x4F, 0xAF, 0x34, 0x15, 0xB3, 0xB2, 0xE4, 0xEE,
    	0xB4, 0x11, 0x52, 0xCD, 0xB9, 0x62, 0xEA, 0x1A, 0x41, 0xC4, 0x07, 0xEF, 0x5B, 0x0F, 0x3E, 0x08,
    	0x14, 0x94, 0x63, 0xDC, 0xFE, 0x26, 0xAF, 0x63, 0x06, 0x0D, 0x26, 0xEE, 0x5A, 0xB6, 0x4B, 0x30,
    	0xEE, 0x6A, 0x8A, 0xC4, 0xB6, 0x90, 0x6D, 0x1F, 0x6F, 0x5D, 0x70, 0x70, 0xA6, 0x1C, 0x3D, 0x73,
    	0xC1, 0xF3, 0x56, 0x13, 0xB2, 0x32, 0x75, 0xB7, 0x04, 0xA5, 0x92, 0x91, 0x6C, 0xDE, 0x53, 0x40,
    	0x2D, 0xDC, 0x47, 0x9E, 0xF6, 0x93, 0x4F, 0xF8, 0x6C, 0x8F, 0x53, 0x14, 0x61, 0x58, 0x59, 0xB2,
    	0x2F, 0x89, 0x00, 0x30, 0x71, 0xEC, 0x48, 0x4D, 0x44, 0x83, 0x4F, 0x8F, 0x35, 0x14, 0x10, 0x57,
    	0x80, 0x97, 0x74, 0x00, 0x90, 0x65, 0xF3, 0x30, 0x08, 0x35, 0x37, 0xF6, 0xAB, 0xC2, 0xE6, 0x2A,
    	0x0B, 0xF2, 0xA0, 0x52, 0xC5, 0x35, 0x1F, 0x4A, 0x1A, 0x4B, 0xC1, 0x38, 0xE8, 0x23, 0xAF, 0x65,
    	0x82, 0x7E, 0x9E, 0xED, 0x7E, 0x0F, 0x40, 0x52, 0xD5, 0x32, 0x85, 0xBC, 0xCE, 0x84, 0x0A, 0x71,
    	0x4F, 0x81, 0x9F, 0x52, 0xD5, 0xCA, 0x2A, 0xEA, 0x20, 0xDF, 0xD5, 0x7F, 0x39, 0x45, 0x65, 0x2F,
    	0xD7, 0x83, 0x2C, 0x2B, 0xCD, 0xB3, 0xA8, 0x63, 0xD6, 0x4D, 0xF2, 0xEA, 0x77, 0xEA, 0x01, 0xCD,
    	0xC7, 0xEA, 0xC9, 0x61, 0x0A, 0xD2, 0x8B, 0xE0, 0x00, 0x3A, 0xF5, 0xFD, 0x8A, 0x93, 0xBA, 0x49,
    	0x25, 0xEF, 0x94, 0xCB, 0x52, 0xAB, 0x97, 0x23, 0xC9, 0xBB, 0x2C, 0xF5, 0x09, 0x77, 0x38, 0x1B,
    };
    
    /* RSA Public Key Exponent */
    static const unsigned char g_pub_exp[3] = { 0x01, 0x00, 0x01 };  
    
    
    static inline int unknown_padding(void)
    {
    	unsigned long l;
    	while ((l = ERR_get_error()) != 0)
    	{
    		if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE)
    			return 1;
    	}
    
    	return 0;
    }
    
    /* copied straight from openssl rsa_test, they didn't even bother to change the string */
    static const char seed[] = "string to make the random number generator think it has entropy";
    
    /* .text:00001E30 */
    size_t pubKeyEncMsg(void *inBuf, size_t size, void *outBuf)
    {
    	int ret;
    
    	unsigned char *encMsg = outBuf; /* sp+0xC */
    
    	unsigned char ptext[0x100];	/* sp+0x14  */
    	unsigned char ctext[0x100];	/* sp+0x114 */
    	unsigned char utext[0x100];	/* sp+0x214 */
    	char errStr[0x100];		/* sp+0x314 */
    
    	memset(ptext, 0, sizeof(ptext));
    	memset(ctext, 0, sizeof(ctext));
    	memset(utext, 0, sizeof(utext));
    
    	memcpy(ptext, inBuf, size);
    
    	CRYPTO_set_mem_debug_functions(	&CRYPTO_dbg_malloc, 
    					&CRYPTO_dbg_realloc, 
    					&CRYPTO_dbg_free, 
    					&CRYPTO_dbg_set_options, 
    					&CRYPTO_dbg_get_options);
    
    	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL /*3*/);
    	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON /*1*/);
    
    	RAND_seed(seed, sizeof(seed)); /* apparently needed otherwise OAEP fails */
    
    	RSA *key = RSA_new();
    
    	key->n = BN_bin2bn(g_pub_mod, sizeof(g_pub_mod), key->n);
    	key->e = BN_bin2bn(g_pub_exp, sizeof(g_pub_exp), key->e);
    
    	if (RSA_check_key(key) == -1)
    	{
    		ERR_load_crypto_strings();
    		ERR_error_string(ERR_get_error(), errStr);
    		printf("key is invaild : %s", errStr);
    		ret = 0;
    		goto exit;
    	}
    
    	int num = RSA_public_encrypt(size, ptext, ctext, key, RSA_PKCS1_OAEP_PADDING /*4*/);
    
    	if ((num == -1) && unknown_padding())
    	{
    		ERR_load_crypto_strings();
    		ERR_error_string(ERR_get_error(), errStr);
    		printf("No OAEP support : %s", errStr);
    		ret = -1;
    		goto exit;
    	}
    
    	memcpy(encMsg, ctext, num);
    	ret = num;
    
    exit:
    	RSA_free(key);
    	CRYPTO_cleanup_all_ex_data();
    	ERR_remove_thread_state(NULL);
    	CRYPTO_mem_leaks_fp(stderr);
    
    	return(ret);
    }
    
    void show(void *ptr, size_t size, size_t nmemb, void *stream)
    {
    	unsigned char *data = ptr;
    	int i;
    
    	printf("\nsize:0x%lX\n", size*nmemb);
    
    	for(i=0; i<size*nmemb; i++)
    	{
    		printf("%02X ", data[i]);
    		if ((i+1)%16 == 0)
    			printf("\n");
    	}
    }
    
    int main(void)
    {
    	unsigned char hmac_input[0x10A];
    	memset(hmac_input, 0, sizeof(hmac_input));
    	memcpy(hmac_input, "KWBREQ0001", 0xA);
    
    	unsigned int hmacLen = 0;
    	unsigned char hmac[0x20];
    	memset(hmac, 0, sizeof(hmac));
    
    	unsigned char enc[0x100];
    	memset(enc, 0, sizeof(enc));
    
    	request_msg_t msg;
    	memset(&msg, 0, sizeof(msg));
    	msg.cmd = 1;
    
    	int ret = pubKeyEncMsg(&msg, sizeof(msg), enc);
    	memcpy(&hmac_input[0xA], enc, ret);
    
    	HMAC(EVP_sha256(), msg.hmacKey, sizeof(msg.hmacKey), hmac_input, sizeof(hmac_input), hmac, &hmacLen);
    
    	request_token_t tok;
    	memset(&tok, 0, sizeof(tok));
    	memcpy(&tok.encText, enc, ret);
    	memcpy(&tok.hmac, hmac, hmacLen);
    
    	CURL *curl;
    	CURLcode res;
     
    	struct curl_httppost *formpost = NULL;
    	struct curl_httppost *lastptr = NULL;
     
    	curl_global_init(CURL_GLOBAL_ALL);
     
    	curl_formadd(&formpost, &lastptr,
    		CURLFORM_COPYNAME, "tokenreq",
    		CURLFORM_COPYCONTENTS, tok,
    		CURLFORM_END);
     	
    	curl = curl_easy_init();
    	if (!curl) 
    	{
    		printf("Failed init\n");
    		return -1;
    	}
    
    	curl_easy_setopt(curl, CURLOPT_URL, "https://kwb.secmobilesvc.com:7788/requestToken.kwb");
    	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, show);
    	curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
     
    	res = curl_easy_perform(curl);
    	if(res != CURLE_OK)
    	{
    		printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    	}
    
    	curl_easy_cleanup(curl);
    	curl_formfree(formpost);
    
    	return 0;
    }

    Compiled in cygwin on Windows 8.1:
    Code:
    gcc -Wall -o main main.c -lcrypto -lcurl
    6
    This is the code to do the unlock:

    The token is returned from the server, it's the sig of the message body (includes your imei etc). The app verifies the signature and unlocks. The send_command function is posted earlier.

    Basically, if we can sign ourselves (in such a way that it verifies correctly) then we can unlock.

    Code:
    typedef struct 
    {
    	char header[0xA];
    	char cmd;
    	char sig[0x100];
    
    } token_t; 
    
    typedef struct
    {
    	char header[0xA];
    	char cid[0x20];
    	char imei[0x20];
    	char model[0x20];
    	char random[0x20];
    	char cmd;
    
    } plain_msg_t; 
    
    /* .text:00001B10 */
    int verifyTokenToUnlock(token_t *token, plain_msg_t *msg) 
    {
    	char cid[0x20]; 
    	char buf[0x320];
    
    	memset(buf, 0, sizeof(buf));
    
    	ALOGI("v%s %s: %s ", "0.0.1", __progname, __FUNCTION__);
    
    	if ((!token) || (!msg))
    	{
    		ALOGI("%s: %s wrong data input", __progname, __FUNCTION__);
    		return -1;
    	}
    
    	memcpy(buf, token, sizeof(token_t)); 
    	memcpy(&buf[sizeof(token_t)], msg, sizeof(plain_msg_t));
    
    	FILE *fileptr = fopen("/sys/block/mmcblk0/device/cid", "rb");
    	if (!fileptr)
    	{
    		ALOGE("%s: %s: failed to open device unique ID (%d)", __progname, __FUNCTION__, f);
    	}
    
    	size_t result = fread(cid, 1, sizeof(cid), fileptr);
    	if (result != sizeof(cid))
    	{
    		ALOGE("%s: %s: failed to read device unique ID (%d)", __progname, __FUNCTION__, result);
    	}
    
    	fclose(fileptr);
    
    	memcpy(&buf[0x115], cid, 0x20);
    
    	if (load_trustlet_app() != 0)
    		return -1;
    
    	int ret = send_command(0x11, 0, buf, sizeof(token_t) + sizeof(plain_msg_t));
    
    	unload_trustlet_app();
    
    	if (ret < 0)
    	{
    		ALOGE("%s: %s: failed to verify token (%d)", __progname, __FUNCTION__, ret);
    		return -1;
    	}
    
    	return 0;
    }

    However, ever though this is from the libkwb.so inside the apk I no longer believe that library is correct. As in, the library is not for the S6. I'm waiting to get a hold of the correct S6 version of libkwb.so. But since this one is still used for other Samsung models I'll keep this here for documentation purposes for other models. Plus, this part of the code at least should be the same on the S6. It'd be needed to code our own unlocker.

    EDIT: The bootloader on the Chinese models look completely different. They explicitly have the CROM Service lock indicator in Download mode that tells you if Custom ROM is enabled or not. This doesn't appear on other S6's in download mode (definitely doesn't appear on mine).

    Does anyone elses S6 show "CROM Service" in download mode (hold vol-down + home button + power when powering on then press vol-up at the prompt)?