Add Int and Buffer primitives.

This commit is contained in:
Andy Nguyen 2021-11-06 11:16:02 +01:00
parent 8f0fc0d578
commit c1ec81b377
10 changed files with 377 additions and 27 deletions

View File

@ -11,6 +11,12 @@ CLASSES = \
$(SRC)/com/bdjb/JIT.java \
$(SRC)/com/bdjb/Screen.java \
$(SRC)/com/bdjb/api/API.java \
$(SRC)/com/bdjb/api/Buffer.java \
$(SRC)/com/bdjb/api/IntBase.java \
$(SRC)/com/bdjb/api/Int8.java \
$(SRC)/com/bdjb/api/Int16.java \
$(SRC)/com/bdjb/api/Int32.java \
$(SRC)/com/bdjb/api/Int64.java \
$(SRC)/com/bdjb/api/UnsafeInterface.java \
$(SRC)/com/bdjb/api/UnsafeJdkImpl.java \
$(SRC)/com/bdjb/api/UnsafeSunImpl.java \

View File

@ -20,18 +20,16 @@ import java.net.ServerSocket;
import java.net.Socket;
class Exploit implements Runnable {
private static final Class[] sandboxExploits =
new Class[] {
ExploitDefaultImpl.class, ExploitUserPrefsImpl.class, ExploitServiceProxyImpl.class
};
private static final Class[] kernelExploits = new Class[] {};
static void init() {
Screen.println("[+] bd-jb by theflow");
Screen.println("[*] Escaping Java Sandbox...");
Class[] sandboxExploits =
new Class[] {
ExploitDefaultImpl.class, ExploitUserPrefsImpl.class, ExploitServiceProxyImpl.class
};
for (int i = 0; i < sandboxExploits.length; i++) {
try {
ExploitSandboxInterface exploit =
@ -60,6 +58,8 @@ class Exploit implements Runnable {
Screen.println("[*] Exploiting kernel...");
Class[] kernelExploits = new Class[] {};
for (int i = 0; i < kernelExploits.length; i++) {
try {
ExploitKernelInterface exploit = (ExploitKernelInterface) kernelExploits[i].newInstance();

View File

@ -8,6 +8,8 @@
package com.bdjb;
import com.bdjb.api.API;
import com.bdjb.api.Buffer;
import com.bdjb.api.Int8;
import java.io.RandomAccessFile;
/**
@ -97,17 +99,15 @@ public final class JIT {
}
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);
if (api.call(sceKernelGetModuleInfo, BDJ_MODULE_HANDLE, modinfo) != 0) {
Buffer modinfo = new Buffer(SCE_KERNEL_MODULE_INFO_SIZE);
modinfo.fill((byte) 0);
modinfo.putLong(0x00, SCE_KERNEL_MODULE_INFO_SIZE);
if (api.call(sceKernelGetModuleInfo, BDJ_MODULE_HANDLE, modinfo.address()) != 0) {
throw new IllegalStateException("sceKernelGetModuleInfo failed.");
}
long bdjBase = api.read64(modinfo + 0x108);
long bdjSize = api.read32(modinfo + 0x110);
api.free(modinfo);
long bdjBase = modinfo.getLong(0x108);
int bdjSize = modinfo.getInt(0x110);
int i = 0;
while (i < bdjSize
@ -141,10 +141,9 @@ public final class JIT {
}
public long jitMap(long size, long alignment) {
long name = api.malloc(4);
api.strcpy(name, "jit");
long blob = api.call(BufferBlob__create, name, size);
api.free(name);
Buffer name = new Buffer(4);
api.strcpy(name.address(), "jit");
long blob = api.call(BufferBlob__create, name.address(), size);
if (blob == 0) {
throw new IllegalStateException("Could not map JIT memory.");
}
@ -154,7 +153,7 @@ public final class JIT {
public void jitCopy(long dest, byte[] src, long n) {
long req = api.malloc(COMPILER_AGENT_REQUEST_SIZE);
long resp = api.malloc(API.INT8_SIZE);
long resp = api.malloc(Int8.SIZE);
for (long i = 0; i < n; i += CHUNK_SIZE) {
byte[] chunk = new byte[CHUNK_SIZE];
@ -167,7 +166,7 @@ public final class JIT {
api.call(write, compilerAgentSocket, req, COMPILER_AGENT_REQUEST_SIZE);
api.write8(resp, (byte) 0);
api.call(read, compilerAgentSocket, resp, API.INT8_SIZE);
api.call(read, compilerAgentSocket, resp, Int8.SIZE);
if (api.read8(resp) != ACK_MAGIC_NUMBER) {
throw new IllegalStateException("Wrong compiler resp.");

View File

@ -15,11 +15,6 @@ import java.lang.reflect.Method;
/** API class to access native data and execute native code. */
public final class API {
public static final int INT8_SIZE = 1;
public static final int INT16_SIZE = 2;
public static final int INT32_SIZE = 4;
public static final int INT64_SIZE = 8;
public static final int RTLD_DEFAULT = -2;
public static final int LIBC_MODULE_HANDLE = 0x2;
@ -280,7 +275,7 @@ public final class API {
}
public long call(long func, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
long fakeClassOop = malloc(INT64_SIZE);
long fakeClassOop = malloc(Int64.SIZE);
long fakeClass = malloc(0x100);
long fakeKlass = malloc(0x200);
long fakeKlassVtable = malloc(0x400);

View File

@ -0,0 +1,91 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
public class Buffer {
private static final API api;
static {
try {
api = API.getInstance();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
private final long address;
private final int size;
public Buffer(int size) {
this.address = api.malloc(size);
this.size = size;
}
public void finalize() {
api.free(address);
}
public long address() {
return address;
}
public int size() {
return size;
}
public byte getByte(int offset) {
checkOffset(offset);
return api.read8(address + offset);
}
public short getShort(int offset) {
checkOffset(offset);
return api.read16(address + offset);
}
public int getInt(int offset) {
checkOffset(offset);
return api.read32(address + offset);
}
public long getLong(int offset) {
checkOffset(offset);
return api.read64(address + offset);
}
public void putByte(int offset, byte value) {
checkOffset(offset);
api.write8(address + offset, value);
}
public void putShort(int offset, short value) {
checkOffset(offset);
api.write16(address + offset, value);
}
public void putInt(int offset, int value) {
checkOffset(offset);
api.write32(address + offset, value);
}
public void putLong(int offset, long value) {
checkOffset(offset);
api.write64(address + offset, value);
}
public void fill(byte value) {
api.memset(address, value, size);
}
private void checkOffset(int offset) {
if (offset < 0 || offset >= size) {
throw new IndexOutOfBoundsException();
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
public final class Int16 extends IntBase {
public static final int SIZE = 2;
public Int16(int[] dimensions) {
super(dimensions);
}
public Int16() {
super();
}
public Int16(short value) {
this();
this.set(value);
}
int elementSize() {
return SIZE;
}
public short get() {
return api.read16(address);
}
public void set(short value) {
api.write16(address, value);
}
public short get(int[] indices) {
return api.read16(address + offset(indices));
}
public void set(int[] indices, short value) {
api.write16(address + offset(indices), value);
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
public final class Int32 extends IntBase {
public static final int SIZE = 4;
public Int32(int[] dimensions) {
super(dimensions);
}
public Int32() {
super();
}
public Int32(int value) {
this();
this.set(value);
}
int elementSize() {
return SIZE;
}
public int get() {
return api.read32(address);
}
public void set(int value) {
api.write32(address, value);
}
public int get(int[] indices) {
return api.read32(address + offset(indices));
}
public void set(int[] indices, int value) {
api.write32(address + offset(indices), value);
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
public final class Int64 extends IntBase {
public static final int SIZE = 8;
public Int64(int[] dimensions) {
super(dimensions);
}
public Int64() {
super();
}
public Int64(long value) {
this();
this.set(value);
}
int elementSize() {
return SIZE;
}
public long get() {
return api.read64(address);
}
public void set(long value) {
api.write64(address, value);
}
public long get(int[] indices) {
return api.read64(address + offset(indices));
}
public void set(int[] indices, long value) {
api.write64(address + offset(indices), value);
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
public final class Int8 extends IntBase {
public static final int SIZE = 1;
public Int8(int[] dimensions) {
super(dimensions);
}
public Int8() {
super();
}
public Int8(byte value) {
this();
this.set(value);
}
int elementSize() {
return SIZE;
}
public byte get() {
return api.read8(address);
}
public void set(byte value) {
api.write8(address, value);
}
public byte get(int[] indices) {
return api.read8(address + offset(indices));
}
public void set(int[] indices, byte value) {
api.write8(address + offset(indices), value);
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb.api;
abstract class IntBase {
static final API api;
static {
try {
api = API.getInstance();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
final long address;
final int size;
final int[] dimensions;
IntBase(int[] dimensions) {
this.dimensions = dimensions;
this.size = size(dimensions);
this.address = api.malloc(size);
}
IntBase() {
this(new int[] {1});
}
abstract int elementSize();
public void finalize() {
api.free(address);
}
public long address() {
return address;
}
public int size() {
return size;
}
public int size(int[] dimensions) {
assert (dimensions.length > 0);
int size = 1;
for (int i = 0; i < dimensions.length; i++) {
size *= dimensions[i];
}
size *= elementSize();
return size;
}
public int offset(int[] indices) {
assert (indices.length == dimensions.length);
int offset = 0;
int stride = 1;
for (int i = indices.length - 1; i >= 0; i--) {
offset += stride * indices[i];
stride *= dimensions[i];
}
offset *= elementSize();
checkOffset(offset);
return offset;
}
private void checkOffset(int offset) {
if (offset < 0 || offset >= size) {
throw new IndexOutOfBoundsException();
}
}
}