mirror of
https://github.com/TheOfficialFloW/bd-jb
synced 2024-11-21 16:35:05 -05:00
Support data section in payload and implement errno.
This commit is contained in:
parent
3020b3476d
commit
560014c17d
@ -34,6 +34,7 @@ public final class API {
|
||||
private static final String JVM_NATIVE_PATH_SYMBOL = "JVM_NativePath";
|
||||
private static final String SETJMP_SYMBOL = "setjmp";
|
||||
private static final String UX86_64_SETCONTEXT_SYMBOL = "__Ux86_64_setcontext";
|
||||
private static final String ERROR_SYMBOL = "__error";
|
||||
|
||||
private static final String MULTI_NEW_ARRAY_METHOD_NAME = "multiNewArray";
|
||||
private static final String MULTI_NEW_ARRAY_METHOD_SIGNATURE = "(Ljava/lang/Class;[I)J";
|
||||
@ -65,6 +66,7 @@ public final class API {
|
||||
private long JVM_NativePath;
|
||||
private long setjmp;
|
||||
private long __Ux86_64_setcontext;
|
||||
private long __error;
|
||||
|
||||
private boolean jdk11;
|
||||
|
||||
@ -127,7 +129,7 @@ public final class API {
|
||||
private void initSymbols() {
|
||||
JVM_NativePath = dlsym(RTLD_DEFAULT, JVM_NATIVE_PATH_SYMBOL);
|
||||
if (JVM_NativePath == 0) {
|
||||
throw new IllegalStateException("JVM_NativePath symbol could not be found.");
|
||||
throw new IllegalStateException("Could not find JVM_NativePath.");
|
||||
}
|
||||
|
||||
__Ux86_64_setcontext = dlsym(LIBKERNEL_MODULE_HANDLE, UX86_64_SETCONTEXT_SYMBOL);
|
||||
@ -145,7 +147,7 @@ public final class API {
|
||||
}
|
||||
|
||||
if (__Ux86_64_setcontext == 0) {
|
||||
throw new IllegalStateException("__Ux86_64_setcontext symbol could not be found.");
|
||||
throw new IllegalStateException("Could not find __Ux86_64_setcontext.");
|
||||
}
|
||||
|
||||
if (jdk11) {
|
||||
@ -156,13 +158,17 @@ public final class API {
|
||||
dlsym(RTLD_DEFAULT, JAVA_JAVA_LANG_REFLECT_ARRAY_MULTI_NEW_ARRAY_SYMBOL);
|
||||
}
|
||||
if (Java_java_lang_reflect_Array_multiNewArray == 0) {
|
||||
throw new IllegalStateException(
|
||||
"Java_java_lang_reflect_Array_multiNewArray symbol could not be found.");
|
||||
throw new IllegalStateException("Could not find Java_java_lang_reflect_Array_multiNewArray.");
|
||||
}
|
||||
|
||||
setjmp = dlsym(LIBC_MODULE_HANDLE, SETJMP_SYMBOL);
|
||||
if (setjmp == 0) {
|
||||
throw new IllegalStateException("setjmp symbol could not be found.");
|
||||
throw new IllegalStateException("Could not find setjmp.");
|
||||
}
|
||||
|
||||
__error = dlsym(LIBKERNEL_MODULE_HANDLE, ERROR_SYMBOL);
|
||||
if (__error == 0) {
|
||||
throw new IllegalStateException("Could not find __error.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,7 +224,7 @@ public final class API {
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Native method could not be installed.");
|
||||
throw new IllegalStateException("Could not install native method.");
|
||||
}
|
||||
|
||||
private void buildContext(
|
||||
@ -345,6 +351,10 @@ public final class API {
|
||||
return call(func, (long) 0);
|
||||
}
|
||||
|
||||
public int errno() {
|
||||
return read32(call(__error));
|
||||
}
|
||||
|
||||
public long dlsym(long handle, String symbol) {
|
||||
int oldHandle = (int) RTLD_DEFAULT;
|
||||
try {
|
||||
|
@ -80,7 +80,7 @@ class Exploit implements Runnable {
|
||||
socket.close();
|
||||
|
||||
Screen.println("[*] Executing payload...");
|
||||
long payload = jit.mapPayload("/OS/HDD/download0/mnt_ada/payload.bin");
|
||||
long payload = jit.mapPayload("/OS/HDD/download0/mnt_ada/payload.bin", 0x4000);
|
||||
int ret = (int) api.call(payload, api.dlsym(API.LIBKERNEL_MODULE_HANDLE, "sceKernelDlsym"));
|
||||
Screen.println("[+] Result: " + ret);
|
||||
} catch (Exception e) {
|
||||
|
@ -19,6 +19,18 @@ public final class JIT {
|
||||
public static final int PAGE_SIZE = 0x4000;
|
||||
public static final int ALIGNMENT = 0x100000;
|
||||
|
||||
public static final int PROT_NONE = 0x0;
|
||||
public static final int PROT_READ = 0x1;
|
||||
public static final int PROT_WRITE = 0x2;
|
||||
public static final int PROT_EXEC = 0x4;
|
||||
|
||||
public static final int MAP_SHARED = 0x1;
|
||||
public static final int MAP_PRIVATE = 0x2;
|
||||
public static final int MAP_FIXED = 0x10;
|
||||
public static final int MAP_ANONYMOUS = 0x1000;
|
||||
|
||||
public static final long MAP_FAILED = -1;
|
||||
|
||||
private static final int CHUNK_SIZE = 0x30;
|
||||
|
||||
private static final int SCE_KERNEL_MODULE_INFO_SIZE = 0x160;
|
||||
@ -46,6 +58,7 @@ public final class JIT {
|
||||
private final API api;
|
||||
|
||||
private long sceKernelGetModuleInfo;
|
||||
private long mmap;
|
||||
private long read;
|
||||
private long write;
|
||||
private long BufferBlob__create;
|
||||
@ -65,15 +78,23 @@ public final class JIT {
|
||||
}
|
||||
|
||||
private void init() {
|
||||
initSymbols();
|
||||
initJitHelpers();
|
||||
}
|
||||
|
||||
private void initSymbols() {
|
||||
sceKernelGetModuleInfo =
|
||||
api.dlsym(API.LIBKERNEL_MODULE_HANDLE, SCE_KERNEL_GET_MODULE_INFO_SYMBOL);
|
||||
mmap = api.dlsym(API.LIBKERNEL_MODULE_HANDLE, "mmap");
|
||||
read = api.dlsym(API.LIBKERNEL_MODULE_HANDLE, READ_SYMBOL);
|
||||
write = api.dlsym(API.LIBKERNEL_MODULE_HANDLE, WRITE_SYMBOL);
|
||||
|
||||
if (sceKernelGetModuleInfo == 0 || read == 0 || write == 0) {
|
||||
throw new IllegalStateException("Symbols could not be found.");
|
||||
throw new IllegalStateException("Could not find symbols.");
|
||||
}
|
||||
}
|
||||
|
||||
private void initJitHelpers() {
|
||||
long modinfo = api.malloc(SCE_KERNEL_MODULE_INFO_SIZE);
|
||||
api.memset(modinfo, 0, SCE_KERNEL_MODULE_INFO_SIZE);
|
||||
api.write64(modinfo + 0x00, SCE_KERNEL_MODULE_INFO_SIZE);
|
||||
@ -92,7 +113,7 @@ public final class JIT {
|
||||
i++;
|
||||
}
|
||||
if (i == bdjSize) {
|
||||
throw new IllegalStateException("BufferBlob::create function could not be found.");
|
||||
throw new IllegalStateException("Could not find BufferBlob::create.");
|
||||
}
|
||||
BufferBlob__create = bdjBase + i - 0x21;
|
||||
|
||||
@ -106,16 +127,28 @@ public final class JIT {
|
||||
i++;
|
||||
}
|
||||
if (i == bdjSize) {
|
||||
throw new IllegalStateException("Compiler agent socket could not be found.");
|
||||
throw new IllegalStateException("Could not find compiler agent socket.");
|
||||
}
|
||||
long compilerAgentSocketOpcode = bdjBase + i - 0x10;
|
||||
compilerAgentSocket =
|
||||
api.read32(compilerAgentSocketOpcode + api.read32(compilerAgentSocketOpcode + 0x3) + 0x7);
|
||||
}
|
||||
|
||||
public long mapPayload(String path) throws Exception {
|
||||
private long align(long x, long align) {
|
||||
return (x + align - 1) & ~(align - 1);
|
||||
}
|
||||
|
||||
public long mapPayload(String path, long dataSectionOffset) throws Exception {
|
||||
RandomAccessFile file = new RandomAccessFile(path, "r");
|
||||
|
||||
if ((dataSectionOffset & (PAGE_SIZE - 1)) != 0) {
|
||||
throw new IllegalArgumentException("Ddata section offset is not page aligned.");
|
||||
}
|
||||
|
||||
if (dataSectionOffset > file.length()) {
|
||||
throw new IllegalArgumentException("Data section offset is too big.");
|
||||
}
|
||||
|
||||
// TODO: Currently we just use maximum size so that the address is predictable.
|
||||
long size = MAX_CODE_SIZE;
|
||||
// long size = file.length() + 0x88 + ALIGNMENT - 1;
|
||||
@ -123,22 +156,27 @@ public final class JIT {
|
||||
// throw new IllegalArgumentException("Payload is too big.");
|
||||
// }
|
||||
|
||||
// Allocate JIT memory.
|
||||
long name = api.malloc(4);
|
||||
api.strcpy(name, "jit");
|
||||
long blob = api.call(BufferBlob__create, name, size);
|
||||
long code = blob + api.read32(blob + 0x20);
|
||||
api.free(name);
|
||||
if (blob == 0) {
|
||||
throw new IllegalStateException("Could not allocate JIT memory.");
|
||||
}
|
||||
long code = blob + api.read32(blob + 0x20);
|
||||
|
||||
long address = (code + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
|
||||
long address = align(code, ALIGNMENT);
|
||||
|
||||
long request = api.malloc(COMPILER_AGENT_REQUEST_SIZE);
|
||||
long response = api.malloc(API.INT8_SIZE);
|
||||
|
||||
for (long i = 0; i < file.length(); i += CHUNK_SIZE) {
|
||||
// Copy .text section.
|
||||
for (long i = 0; i < dataSectionOffset; i += CHUNK_SIZE) {
|
||||
byte[] chunk = new byte[CHUNK_SIZE];
|
||||
|
||||
file.seek(i);
|
||||
file.read(chunk, 0, (int) Math.min(file.length() - i, CHUNK_SIZE));
|
||||
file.read(chunk, 0, (int) Math.min(dataSectionOffset - i, CHUNK_SIZE));
|
||||
|
||||
api.memset(request, 0, COMPILER_AGENT_REQUEST_SIZE);
|
||||
api.memcpy(request + 0x00, chunk, CHUNK_SIZE);
|
||||
@ -156,6 +194,29 @@ public final class JIT {
|
||||
api.free(response);
|
||||
api.free(request);
|
||||
|
||||
// Map the .data section as RW.
|
||||
if (api.call(
|
||||
mmap,
|
||||
address + dataSectionOffset,
|
||||
align(file.length() - dataSectionOffset, PAGE_SIZE),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS,
|
||||
-1,
|
||||
0)
|
||||
== MAP_FAILED) {
|
||||
throw new IllegalStateException("Could not map data section.");
|
||||
}
|
||||
|
||||
// Copy .data section.
|
||||
for (long i = dataSectionOffset; i < file.length(); i += CHUNK_SIZE) {
|
||||
byte[] chunk = new byte[CHUNK_SIZE];
|
||||
|
||||
file.seek(dataSectionOffset);
|
||||
int read = file.read(chunk, 0, (int) Math.min(file.length() - i, CHUNK_SIZE));
|
||||
|
||||
api.memcpy(address + i, chunk, read);
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
@ -6,4 +6,7 @@ ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x916300000;
|
||||
.text : { *(.text) }
|
||||
. = 0x916304000;
|
||||
.data : { *(.data) }
|
||||
}
|
||||
|
@ -4,6 +4,9 @@
|
||||
|
||||
typedef int32_t SceKernelModule;
|
||||
|
||||
int payload(int (* sceKernelDlsym)(SceKernelModule handle, const char *symbol, void **addrp)) {
|
||||
return 1337;
|
||||
int x = 1337;
|
||||
|
||||
int payload(int (*sceKernelDlsym)(SceKernelModule handle, const char *symbol,
|
||||
void **addrp)) {
|
||||
return x;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user