implement missing APIs (uc_query, uc_mem_map_ptr, uc_mem_regions) in java binding
This commit is contained in:
parent
6986fa3947
commit
aa1657006b
37
bindings/java/unicorn/MemRegion.java
Executable file
37
bindings/java/unicorn/MemRegion.java
Executable file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
|
||||
Java bindings for the Unicorn Emulator Engine
|
||||
|
||||
Copyright(c) 2016 Chris Eagle
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
package unicorn;
|
||||
|
||||
public class MemRegion {
|
||||
|
||||
public long begin;
|
||||
public long end;
|
||||
public int perms;
|
||||
|
||||
public MemRegion(long begin, long end, int perms) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
this.perms = perms;
|
||||
}
|
||||
|
||||
}
|
||||
|
40
bindings/java/unicorn/Unicorn.java
Normal file → Executable file
40
bindings/java/unicorn/Unicorn.java
Normal file → Executable file
@ -288,7 +288,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*
|
||||
* @param arch Architecture type (UC_ARCH_*)
|
||||
* @param mode Hardware mode. This is combined of UC_MODE_*
|
||||
* @see unicorn.UnicornArchs, unicorn.UnicornModes
|
||||
* @see unicorn.UnicornConst
|
||||
*
|
||||
*/
|
||||
public Unicorn(int arch, int mode) throws UnicornException {
|
||||
@ -327,7 +327,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*
|
||||
* @param arch Architecture type (UC_ARCH_*)
|
||||
* @return true if this library supports the given arch.
|
||||
* @see unicorn.UnicornArchs
|
||||
* @see unicorn.UnicornConst
|
||||
*/
|
||||
public native static boolean arch_supported(int arch);
|
||||
|
||||
@ -337,12 +337,23 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*/
|
||||
public native void close() throws UnicornException;
|
||||
|
||||
/**
|
||||
* Query internal status of engine.
|
||||
*
|
||||
* @param type query type. See UC_QUERY_*
|
||||
* @param result save the internal status queried
|
||||
*
|
||||
* @return: error code. see UC_ERR_*
|
||||
* @see unicorn.UnicornConst
|
||||
*/
|
||||
public native int query(int type) throws UnicornException;
|
||||
|
||||
/**
|
||||
* Report the last error number when some API function fail.
|
||||
* Like glibc's errno, uc_errno might not retain its old value once accessed.
|
||||
*
|
||||
* @return Error code of uc_err enum type (UC_ERR_*, see above)
|
||||
* @see unicorn.UnicornErrors
|
||||
* @see unicorn.UnicornConst
|
||||
*/
|
||||
public native int errno();
|
||||
|
||||
@ -351,7 +362,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*
|
||||
* @param code Error code (see UC_ERR_* above)
|
||||
* @return Returns a String that describes the error code
|
||||
* @see unicorn.UnicornErrors
|
||||
* @see unicorn.UnicornConst
|
||||
*/
|
||||
public native static String strerror(int code);
|
||||
|
||||
@ -625,6 +636,19 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*/
|
||||
public native void mem_map(long address, long size, int perms) throws UnicornException;
|
||||
|
||||
/**
|
||||
* Map existing host memory in for emulation.
|
||||
* This API adds a memory region that can be used by emulation.
|
||||
*
|
||||
* @param address Base address of the memory range
|
||||
* @param size Size of the memory block.
|
||||
* @param perms Permissions on the memory block. A combination of UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC
|
||||
* @param ptr Block of host memory backing the newly mapped memory. This block is
|
||||
* expected to be an equal or larger size than provided, and be mapped with at
|
||||
* least PROT_READ | PROT_WRITE. If it is not, the resulting behavior is undefined.
|
||||
*/
|
||||
public native void mem_map_ptr(long address, long size, int perms, byte[] block) throws UnicornException;
|
||||
|
||||
/**
|
||||
* Unmap a range of memory.
|
||||
*
|
||||
@ -642,5 +666,13 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||
*/
|
||||
public native void mem_protect(long address, long size, int perms) throws UnicornException;
|
||||
|
||||
/**
|
||||
* Retrieve all memory regions mapped by mem_map() and mem_map_ptr()
|
||||
* NOTE: memory regions may be split by mem_unmap()
|
||||
*
|
||||
* @return list of mapped regions.
|
||||
*/
|
||||
public native MemRegion[] mem_regions() throws UnicornException;
|
||||
|
||||
}
|
||||
|
||||
|
76
bindings/java/unicorn_Unicorn.c
Normal file → Executable file
76
bindings/java/unicorn_Unicorn.c
Normal file → Executable file
@ -244,7 +244,28 @@ JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported
|
||||
JNIEXPORT void JNICALL Java_unicorn_Unicorn_close
|
||||
(JNIEnv *env, jobject self) {
|
||||
uc_engine *eng = getEngine(env, self);
|
||||
uc_close(eng);
|
||||
uc_err err = uc_close(eng);
|
||||
if (err != UC_ERR_OK) {
|
||||
throwException(env, err);
|
||||
}
|
||||
//We also need to ReleaseByteArrayElements for any regions that
|
||||
//were mapped with uc_mem_map_ptr
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: unicorn_Unicorn
|
||||
* Method: query
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_unicorn_Unicorn_query
|
||||
(JNIEnv *env, jobject self, jint type) {
|
||||
uc_engine *eng = getEngine(env, self);
|
||||
size_t result;
|
||||
uc_err err = uc_query(eng, type, &result);
|
||||
if (err != UC_ERR_OK) {
|
||||
throwException(env, err);
|
||||
}
|
||||
return (jint)result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -508,6 +529,24 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: unicorn_Unicorn
|
||||
* Method: mem_map_ptr
|
||||
* Signature: (JJI[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map_1ptr
|
||||
(JNIEnv *env, jobject self, jlong address, jlong size, jint perms, jbyteArray block) {
|
||||
uc_engine *eng = getEngine(env, self);
|
||||
jbyte *array = (*env)->GetByteArrayElements(env, block, NULL);
|
||||
uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, (uint32_t)perms, (void*)array);
|
||||
if (err != UC_ERR_OK) {
|
||||
throwException(env, err);
|
||||
}
|
||||
//Need to track address/block/array so that we can ReleaseByteArrayElements when the
|
||||
//block gets unmapped or when uc_close gets called
|
||||
//(*env)->ReleaseByteArrayElements(env, block, array, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: unicorn_Unicorn
|
||||
* Method: mem_unmap
|
||||
@ -521,6 +560,9 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap
|
||||
if (err != UC_ERR_OK) {
|
||||
throwException(env, err);
|
||||
}
|
||||
|
||||
//If a region was mapped using uc_mem_map_ptr, we also need to
|
||||
//ReleaseByteArrayElements for that region
|
||||
}
|
||||
|
||||
/*
|
||||
@ -537,3 +579,35 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect
|
||||
throwException(env, err);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: unicorn_Unicorn
|
||||
* Method: mem_regions
|
||||
* Signature: ()[Lunicorn/MemRegion;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions
|
||||
(JNIEnv *env, jobject self) {
|
||||
uc_engine *eng = getEngine(env, self);
|
||||
|
||||
uc_mem_region *regions = NULL;
|
||||
uint32_t count = 0;
|
||||
uint32_t i;
|
||||
|
||||
uc_err err = uc_mem_regions(eng, ®ions, &count);
|
||||
if (err != UC_ERR_OK) {
|
||||
throwException(env, err);
|
||||
}
|
||||
jclass clz = (*env)->FindClass(env, "unicorn/MemRegion");
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
return NULL;
|
||||
}
|
||||
jobjectArray result = (*env)->NewObjectArray(env, (jsize)count, clz, NULL);
|
||||
jmethodID cons = (*env)->GetMethodID(env, clz, "<init>", "(JJI)V");
|
||||
for (i = 0; i < count; i++) {
|
||||
jobject mr = (*env)->NewObject(env, clz, cons, regions[i].begin, regions[i].end, regions[i].perms);
|
||||
(*env)->SetObjectArrayElement(env, result, (jsize)i, mr);
|
||||
}
|
||||
free(regions);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user