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 arch Architecture type (UC_ARCH_*)
|
||||||
* @param mode Hardware mode. This is combined of UC_MODE_*
|
* @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 {
|
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_*)
|
* @param arch Architecture type (UC_ARCH_*)
|
||||||
* @return true if this library supports the given arch.
|
* @return true if this library supports the given arch.
|
||||||
* @see unicorn.UnicornArchs
|
* @see unicorn.UnicornConst
|
||||||
*/
|
*/
|
||||||
public native static boolean arch_supported(int arch);
|
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;
|
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.
|
* Report the last error number when some API function fail.
|
||||||
* Like glibc's errno, uc_errno might not retain its old value once accessed.
|
* 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)
|
* @return Error code of uc_err enum type (UC_ERR_*, see above)
|
||||||
* @see unicorn.UnicornErrors
|
* @see unicorn.UnicornConst
|
||||||
*/
|
*/
|
||||||
public native int errno();
|
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)
|
* @param code Error code (see UC_ERR_* above)
|
||||||
* @return Returns a String that describes the error code
|
* @return Returns a String that describes the error code
|
||||||
* @see unicorn.UnicornErrors
|
* @see unicorn.UnicornConst
|
||||||
*/
|
*/
|
||||||
public native static String strerror(int code);
|
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;
|
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.
|
* 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;
|
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
|
JNIEXPORT void JNICALL Java_unicorn_Unicorn_close
|
||||||
(JNIEnv *env, jobject self) {
|
(JNIEnv *env, jobject self) {
|
||||||
uc_engine *eng = getEngine(env, 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
|
* Class: unicorn_Unicorn
|
||||||
* Method: mem_unmap
|
* Method: mem_unmap
|
||||||
@ -521,6 +560,9 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap
|
|||||||
if (err != UC_ERR_OK) {
|
if (err != UC_ERR_OK) {
|
||||||
throwException(env, err);
|
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);
|
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