SM-S367VL support #3

Open
opened 2025-12-28 16:46:14 -05:00 by chipmunkmc · 12 comments
Owner

This is the third bootloader-locked Exynos device I own. Mine is currently borrowed and has been for quite a few months, but supposedly I'll get it back at some point in January.

This is the third bootloader-locked Exynos device I own. Mine is currently borrowed and has been for quite a few months, but supposedly I'll get it back at some point in January.
Author
Owner

Well um... You see I live in the United States, and the borrower moved to a state other than mine, and I don't think I'm crazy enough to go on a road trip to get back the device or anything... It's a shame, I really became interested in this specific phone once I learned it had an exynos7885 (or exynos7884a which is just an underclocked one)...

I have a relative in Canada with the exact same phone, though. Maybe I can get it from him (maybe my family will visit him again?), especially if I trade the SM-J327VPP I got from him for it Still, I haven't really looked into rooting that phone yet...

So since I probably won't have testing hardware soon (if ever) I'll just try to port the phone using its bootloader image; I can't just use upload mode to figure out where the PIT chunk will be and whatnot, but I suppose I can guess using other phones' addresses. I already can find the load address using a previous upload mode dump, fortunately. Maybe someone else will test it...

Well um... You see I live in the United States, and the borrower moved to a state other than mine, and I don't think I'm crazy enough to go on a road trip to get back the device or anything... It's a shame, I really became interested in this specific phone once I learned it had an exynos7885 (or exynos7884a which is just an underclocked one)... I have a relative in Canada with the exact same phone, though. Maybe I can get it from him (maybe my family will visit him again?), especially if I trade the SM-J327VPP I got from him for it Still, I haven't really looked into rooting that phone yet... So since I probably won't have testing hardware soon (if ever) I'll just try to port the phone using its bootloader image; I can't just use upload mode to figure out where the PIT chunk will be and whatnot, but I suppose I can guess using other phones' addresses. I already can find the load address using a previous upload mode dump, fortunately. Maybe someone else will test it...
Author
Owner

After looking around in Ghidra and finding some addresses, I made some untested info in ee332c3097.

Notes: the bootloader is at offset 0x61800 in sboot.bin, loaded to address 0x8f000000 in memory, and its uncached heap begins at 0x90500000 not counting the root chunk.

After looking around in Ghidra and finding some addresses, I made some untested info in ee332c3097a52e3defbb283f3644c174b29dab04. Notes: the bootloader is at offset `0x61800` in `sboot.bin`, loaded to address `0x8f000000` in memory, and its uncached heap begins at `0x90500000` not counting the root chunk.
Author
Owner

Well I asked said relative about testing it, and he ended up deciding to just mail me the phone! Let's just hope this phone has revision <= 9 (otherwise I won't be able to downgrade the bootloader to run this exploit)

Well I asked said relative about testing it, and he ended up deciding to just mail me the phone! Let's just hope this phone has revision <= 9 (otherwise I won't be able to downgrade the bootloader to run this exploit)
Author
Owner

Well I received it, and it's on revision 4, which fits my needs! Except I decided to test fastory binary first, and flashed its sboot.bin while forgetting I won't be able to get back into download mode...
Well since I've already went this far, it would be foolish to surrender. I will try to get a download mode jig, force the phone into exynos usbdl mode, etc until it works; this will cause a delay though.

Edit: I forgot to say, this older revision seems to be used by two (normal, non-factory) firmware versions which are both vulnerable. When I unbrick the device (hopefully not never!) I will at the very least try porting the latest one.
And no, factory sboot.bin won't boot Pie except for recovery.

Well I received it, and it's on revision 4, which fits my needs! Except I decided to test fastory binary first, and flashed its `sboot.bin` while forgetting I won't be able to get back into download mode... Well since I've already went this far, it would be foolish to surrender. I will try to get a download mode jig, force the phone into exynos usbdl mode, etc until it works; this will cause a delay though. Edit: I forgot to say, this older revision seems to be used by two (normal, non-factory) firmware versions which are both vulnerable. When I unbrick the device (hopefully not never!) I will at the very least try porting the latest one. And no, factory `sboot.bin` won't boot Pie except for recovery.
Author
Owner

I'd like to mention this brick (assuming I can revert it!) might as well be a good thing since remembering this event will make me even more careful when working with factory binary bootloaders, and more importantly, instructing people to do the same (and yes it's safe on SM-J327T and SM-J727T).

I'd like to mention this brick (assuming I can revert it!) might as well be a good thing since remembering this event will make me even more careful when working with factory binary bootloaders, and more importantly, instructing people to do the same (and yes it's safe on SM-J327T and SM-J727T).
Author
Owner

Said that too soon, turns out I can just hold Volume Down + Home while plugging in a USB cable (found this trick at https://xdaforums.com/t/solved-problem-enter-downloading-mode-factory-binary-in-samsung-galaxy-j3-sm-s367vl.3916357/).
Anyway the TI2 bootloader was either incorrectly ported or is not binary compatible with SG1, I'll wait till tomorrow at least to actually start porting.
Note: it seems to be freezing about when malloc() is called (after the version request response) judging from the verbose output; this implies a heap chunk's address is wrong.

Said that too soon, turns out I can just hold Volume Down + Home while plugging in a USB cable (found this trick at https://xdaforums.com/t/solved-problem-enter-downloading-mode-factory-binary-in-samsung-galaxy-j3-sm-s367vl.3916357/). Anyway the TI2 bootloader was either incorrectly ported or is not binary compatible with SG1, I'll wait till tomorrow at least to actually start porting. _Note: it seems to be freezing about when `malloc()` is called (after the version request response) judging from the verbose output; this implies a heap chunk's address is wrong._
Author
Owner

The PIT chunk address was wrong and I can't be bothered to guess it, so I tried using the packer buffer w/ a25e8bfb6e (calculated as 0x8f148140 - 0x20 - 0x80 - 0x30 - 0x20 - 0x60 - 0x450 - 0x400).
The phone entered upload mode, and according to the ESR there was an alignment error (see https://esr.arm64.dev/#0x96000061). I suppose the current exploitation method is not as universal as I hoped, I might want to support using multiple methods.

The PIT chunk address was wrong and I can't be bothered to guess it, so I tried using the packer buffer w/ a25e8bfb6ecb46b731c584eb214cfc80d3fac32f (calculated as `0x8f148140 - 0x20 - 0x80 - 0x30 - 0x20 - 0x60 - 0x450 - 0x400`). The phone entered upload mode, and according to the ESR there was an alignment error (see https://esr.arm64.dev/#0x96000061). I suppose the current exploitation method is not as universal as I hoped, I might want to support using multiple methods.
Author
Owner

So I used the exploitation method which targets the pointers right after the packet buffer on Oreo and newer bootloaders, to avoid alignment issues.
I ran this code:

_start:
	mov w0, #10
	ldr w2, color
	ldr w3, bg
	adr x4, fmt
	ldr x5, pit_buf_ptr_ptr
	ldr x5, [x5]
	ldr x6, scr_printf_ptr
	blr x6

loop:
	b loop

color:
	.word 0x9eff9e
bg:
	.word 0x001144
.align 8
pit_buf_ptr_ptr:
	.quad 0x8f349538
scr_printf_ptr:
	.quad 0x8f040ad4
fmt:
	.asciz "pwned! pit buffer: %p"

And it turns out the PIT buffer is at 0x906fb338, so my guess wasn't too far off (it was based on the J3/J7 Prime ones which are both Nougat).
Also the actual shellcode (patched for alignment ofc) crashes from an invalid instruction when ran from the stack, seemingly also with parallel download code removed (perhaps I cannot reliably execute a program more than one page long from it for some reason? or are there moar bugs?)

So I used the exploitation method which targets the pointers right after the packet buffer on Oreo and newer bootloaders, to avoid alignment issues. I ran this code: ```armasm _start: mov w0, #10 ldr w2, color ldr w3, bg adr x4, fmt ldr x5, pit_buf_ptr_ptr ldr x5, [x5] ldr x6, scr_printf_ptr blr x6 loop: b loop color: .word 0x9eff9e bg: .word 0x001144 .align 8 pit_buf_ptr_ptr: .quad 0x8f349538 scr_printf_ptr: .quad 0x8f040ad4 fmt: .asciz "pwned! pit buffer: %p" ``` And it turns out the PIT buffer is at `0x906fb338`, so my guess wasn't *too* far off (it was based on the J3/J7 Prime ones which are both Nougat). Also the actual shellcode (patched for alignment ofc) crashes from an invalid instruction when ran from the stack, seemingly also with parallel download code removed (perhaps I cannot reliably execute a program more than one page long from it for some reason? or are there moar bugs?)
Author
Owner

And with even more patching, and running the shellcode from the PIT buffer, I can boot into the stock recovery from the factory binary bootloader (again, Android Pie refuses to boot).
I'll take that as a victory for now, and go to bed since it's getting quite late.

And with even more patching, and running the shellcode from the PIT buffer, I can boot into the stock recovery from the factory binary bootloader (again, Android Pie refuses to boot). I'll take that as a victory for now, and go to bed since it's getting quite late.
Author
Owner

So I could successfully exploit the SJ1 sboot and boot rooted Android, however with both it and the factory binary sboot, it seems CPU1 never comes online, which implies the PSCI call to turn it off never works...
Also, encryption on this device is a little different; a /data encrypted on the stock image won't be read on the custom one, and vice versa(!)
Anyway I will push the needed changes soon(TM)

So I could successfully exploit the SJ1 sboot and boot rooted Android, however with both it and the factory binary sboot, it seems CPU1 never comes online, which implies the PSCI call to turn it off never works... Also, encryption on this device is a little different; a /data encrypted on the stock image won't be read on the custom one, and vice versa(!) Anyway I will push the needed changes soon(TM)
Author
Owner

So the PSCI call works on CPU0 it seems, as a program that tries to print the return value seemingly does nothing. Will test CPU1 (through the v3 smp trick) later.

So the PSCI call works on CPU0 it seems, as a program that tries to print the return value seemingly does nothing. Will test CPU1 (through the v3 smp trick) later.
Author
Owner

Well after testing I am under the suspicion that I'm not managing to run anything on CPU1 in the first place (and yet somehow the next CPU check passes). I'm not sure of course, I tested this on factory binary firmware, and I could have gotten the addresses for it wrong, but it's still possible.
Perhaps I should stop using my current method of hijacking CPU1? According to another writeup I read I might be able to trigger an exception on the core (forgot how... I'm still new to low-level stuff sorry).
Finding the exception handler should be a matter of adding an offset to VBAR_EL1, and doesn't require looking for addresses used by the parallel download feature.
Of course if this is the case I would also need to use something other than the next core value to track whether or not CPU1 shut down, as the check already passes, even though that's one of the two values that can pass the running core check on SM-J327T(1), the other involving weird pointer math to find...

Well after testing I am under the suspicion that I'm not managing to run anything on CPU1 in the first place (and yet somehow the next CPU check passes). I'm not sure of course, I tested this on factory binary firmware, and I could have gotten the addresses for it wrong, but it's still possible. Perhaps I should stop using my current method of hijacking CPU1? According to another writeup I read I might be able to trigger an exception on the core (forgot how... I'm still new to low-level stuff sorry). Finding the exception handler should be a matter of adding an offset to `VBAR_EL1`, and doesn't require looking for addresses used by the parallel download feature. Of course if this is the case I would also need to use something other than the next core value to track whether or not CPU1 shut down, as the check already passes, even though that's one of the two values that can pass the running core check on SM-J327T(1), the other involving weird pointer math to find...
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
chipmunkmc/osmium#3
No description provided.