正如Android调用JNI本地方法经过有点改变章所说跟踪代码是可行的,但是跟踪某些代码会出现anr,点击取消,还是不好运,有提高办法吗?回答是有(gdb还没试过,本文只讨论ida)。

下面是我使用 0 * Message("%s = %d\n", GetString(Dword(R2+0x10),-1, ASCSTR_C), R2+0x20)打出的记录

"unlockCanvasAndPost"
"native_computeBounds"
"lockCanvasNative"
"nativeDraw"
"native_getClipBounds"
"native_drawText"
"nativeDraw"
"unlockCanvasAndPost"
"native_computeBounds"
"lockCanvasNative"
"nativeDraw"
"native_getClipBounds"
"native_drawText"
"nativeDraw"

....

反复调用然后anr了。

为了改善这种情况。经过仔细查阅IDA文档Edit breakpoint一章,发现

  Low level condition:
Evaluate the condition on the remote computer. Such conditions are
faster, especially during remote debugging, because there is no
network traffic between IDA and the remote computer on each
breakpoint hit. More details

低级条件,在远程计算机计算条件。这种条件运行更快,特别是在远程调试的时候。详细内容如下:

Low level breakpoint conditions

Low level breakpoint conditions can be used to speed up the debugger. They are evaluated like this:

  - for remote debugging, such a condition is evaluated on the remote
computer. The following actions are bypassed:
- copying the breakpoint event to the local computer
- switching from debthread to the main thread
- updating internal IDA structures and caches
- updating the screen
  - for local debugging, such a condition is evaluated at low level.
The following actions are bypassed:
- switching from debthread to the main thread
- updating internal IDA structures and caches
- updating the screen

In both cases, there is a significant speed up. This improvement imposes some limitations on the breakpoint condition:

  - only IDC expressions can be used for low level conditions
- only functions marked as 'thread-safe' may be called
- only entire registers can be accessed (e.g. EAX is ok but AL is not)

Essentially this means that the only available functions are:

  - read/write process registers
- read/write process memory
- file i/o
- auxiliary string and object functions
- Message() function (for debugging the breakpoint conditions)

Low level breakpoint conditions are available only for Win32, WinCE, Linux, Mac, Android debuggers.

从中看到对我有影响的就是使用的函数必须带有'thread-safe'字样提示。

诸如前文使用的

0 * print(GetString(DbgDword(R2+0x10),-1, ASCSTR_C))

"method" == GetString(DbgDword(R2+0x10),-1, ASCSTR_C)

0 * Message("%s = %d\n", GetString(DbgDword(R2+0x10),-1, ASCSTR_C), R2+0x20)

其中DbgDword就是线程安全的,而Dword就不是,如此

DbgDword

// Get value of program double word (4 bytes) using the debugger memory
// ea - linear address
// returns: the value of the double word. Throws an exception on failure.
// Thread-safe function (may be called only from the main thread and debthread)

long DbgDword (long ea);

表达式中另一个函数也不行

GetString

// Get string contents
// ea - linear address
// len - string length. -1 means to calculate the max string length
// type - the string type (one of ASCSTR_... constants)
// Returns: string contents or empty string

string GetString(long ea, long len, long type);

See also GetStringType function.

就没有

所以报错,不允许。

为了找到替代,找到一大圈无果。直到一个一个比较,先比较前几个吧如案例

可以在这个论坛下载2014攻防对抗挑战赛

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <string.h>
#include <errno.h> /*
package com.crackme;
public class MainActivity{
private native String crackme(String paramString1, String paramString2);
} Native的对应函数名要以“Java_”开头,后面依次跟上Java的“package名”、“class名”、“函数名”,中间以下划线“_” 分割,在package名中的“.”也要改为“_”。
此外,关于函数的参数和返回值也有相应的规则。对于Java中的基本类型如int 、double 、char等,在Native端都有相对应的类型来表示,如jint 、jdouble 、jchar 等;其他的对象类型则统统由jobject 来表示(String 是个例外,由于其使用广泛,故在Native代码中有 jstring 这个类型来表示,正如在上例中返回值String 对应到Native代码中的返回值jstring )。而对于Java中的数组,在Native中由jarray 对应,具体到基本类型和一般对象类型的数组则有jintArray 等和jobjectArray 分别对应(String 数组在这里没有例外,同样用jobjectArray 表示)。
还有一点需要注意的是,在JNI的Native函数中,其前两个参数JNIEnv *和jobject 是必需的——前者是一个JNIEnv 结构体的指针是JNI的核心数据,这个结构体中定义了很多JNI的接口函数指针,使开发者可以使用JNI所定义的接口功能;后者指代的是调用这个JNI函数的Java对象,有点类似于C++中的this 指针。在上述两个参数之后,还需要根据Java端的函数声明依次对应添加参数。 在上例中,Java中声明的JNI函数对应命名为: //Class: com_crackme_MainActivity
//Method: crackme
//Signature: (Ljava/lang/String;)Ljava/lang/String;
jstring Java_com_crackme_MainActivity_crackme(JNIEnv *,jobject,jstring,jstring); jstring (*crackme)(JNIEnv *,jobject,jstring, jstring) = NULL;
//事先把libcrackme.so放到root/system/lib/目录下
void *filehandle = dlopen("/system/lib/libcrackme.so", RTLD_LAZY);
//(jstring (*)(JNIEnv *,jobject, jstring, jstring))
if(filehandle)
{
crackme = (jstring (*)(JNIEnv *,jobject, jstring, jstring))dlsym(filehandle, "Java_com_crackme_MainActivity_crackme");
if(crackme){
jstring s = crackme(env, obj, a, b);
}
dlclose(filehandle);
filehandle = NULL;
}
*/ typedef void *CRACKME;
//typedef jstring *CRACKME(JNIEnv *,jobject, jstring, jstring); int main(int argc, char **argv)
{
CRACKME *crackme;
int i = ;
void *handle; handle = dlopen("/home/Sansan/a/libcrackme.so", RTLD_LAZY);
if (!handle) {
printf("%s, %d, NULL == handle. errno = %d, %s\n", __FUNCTION__, __LINE__, errno, strerror(errno));
return -;
}
crackme = dlsym(handle, "JNI_OnLoad");
if (!crackme) {
printf("%s, %d, NULL == crackme\n", __FUNCTION__, __LINE__);
return -;
}
printf("%s, %d, crackme = %p\n", __FUNCTION__, __LINE__, crackme);
dlclose(handle);
return ;
}

条件语句类似这样

'c' == DbgByte(DbgDword(R2+0x10)) && 'r' == DbgByte(1+DbgDword(R2+0x10)) && 'a' == DbgByte(2+DbgDword(R2+0x10)) && 'c' == DbgByte(3+DbgDword(R2+0x10)) && 'k' == DbgByte(4+DbgDword(R2+0x10))

char *crac = "crac" 是4字节可以计算成一个4字节的整数,可能更好,类似这样计算出它在内存中的值0x63617263。

    ;int crac = *(int*)"crackme我啊h";
011EF305 mov eax,dword ptr ds:[011F46BCh]
011EF30A mov dword ptr [crac],eax

跳到目标,如果F5不行需要弄一下。

最后F5结果,有神奇F5就是容易点啊,虽说君子善假于物也,依靠工具会产生惰性,分析汇编能力会下降。

int __fastcall sub_80905D1C(int a1, int a2, int a3, int a4)
{
int v4; // r6@1
int v5; // r4@1
int v6; // r7@1
int v7; // r0@1 v4 = a4;
v5 = a1;
v6 = (*(int (**)(void))(*(_DWORD *)a1 + ))();
v7 = (*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)v5 + ))(v5, v4, );
((void (__fastcall *)(_UNKNOWN *, int, int))sub_809055F8)(&"Failure", v6, v7);
((void (__fastcall *)(_UNKNOWN *))sub_80905C44)(&"Failure");
return (*(int (__fastcall **)(int, _UNKNOWN *))(*(_DWORD *)v5 + ))(v5, &"Failure");
}
int __fastcall sub_809055F8(int a1, int a2, int a3)
{
int v3; // r6@1
int v4; // r4@1
int v5; // r5@1
int result; // r0@1
int v7; // r0@3
int v8; // r7@3
int v9; // r0@3
int v10; // r7@3
int v11; // r3@3
int v12; // [sp+4h] [bp-24h]@3
int v13; // [sp+8h] [bp-20h]@3
int v14; // [sp+Ch] [bp-1Ch]@3 v3 = a3;
v4 = a1;
v5 = a2;
result = ((int (*)(void))unk_809055B4)();
if ( v3 )
{
if ( v5 )
{
v7 = ((int (__fastcall *)(int))strlen_0)(v5);
v13 = v7;
v8 = v7;
v9 = ((int (__fastcall *)(int))strlen_0)(v3);
v10 = v8 + ;
v14 = v9;
v12 = v9 + ;
*(_DWORD *)(v4 + ) = ((int (__fastcall *)(int))malloc_0)(v10);
result = ((int (__fastcall *)(int))malloc_0)(v12);
v11 = *(_DWORD *)(v4 + );
*(_DWORD *)(v4 + ) = result;
if ( v11 )
{
if ( result )
{
((void (__fastcall *)(int, _DWORD, int))memset_0)(v11, , v10);
((void (__fastcall *)(_DWORD, _DWORD, int))memset_0)(*(_DWORD *)(v4 + ), , v12);
((void (__fastcall *)(_DWORD, int, int))memcpy_0)(*(_DWORD *)(v4 + ), v5, v13);
result = ((int (__fastcall *)(_DWORD, int, int))memcpy_0)(*(_DWORD *)(v4 + ), v3, v14);
}
}
}
}
return result;
}
int __fastcall sub_809055B4(int a1)
{
int v1; // r4@1 v1 = a1;
if ( *(_DWORD *)(a1 + ) )
{
((void (*)(void))free)();
*(_DWORD *)(v1 + ) = ;
}
if ( *(_DWORD *)(v1 + ) )
{
((void (*)(void))free)();
*(_DWORD *)(v1 + ) = ;
}
memset_0(v1 + , , );
return memset_0(v1, , );
}

接下来的工作分析吧,很常规了。。。

附两个头可以直接导入,使用其中的结构体,但是对于C++方式结构体,即类的不知道怎么导入,记住先倒入依赖的头stddarg.h(jni依赖它)

/*
* stdarg.h
*
* Provides facilities for stepping through a list of function arguments of
* an unknown number and type.
*
* NOTE: Gcc should provide stdarg.h, and I believe their version will work
* with crtdll. If necessary I think you can replace this with the GCC
* stdarg.h.
*
* Note that the type used in va_arg is supposed to match the actual type
* *after default promotions*. Thus, va_arg (..., short) is not valid.
*
* This file is part of the Mingw32 package.
*
* Contributors:
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.2 $
* $Author: noer $
* $Date: 1998/10/10 00:51:16 $
*
*/ #ifndef _STDARG_H_
#define _STDARG_H_ /*
* Don't do any of this stuff for the resource compiler.
*/
#ifndef RC_INVOKED /*
* I was told that Win NT likes this.
*/
#ifndef _VA_LIST_DEFINED
#define _VA_LIST_DEFINED
#endif #ifndef _VA_LIST
#define _VA_LIST
typedef char* va_list;
#endif /*
* Amount of space required in an argument list (ie. the stack) for an
* argument of type t.
*/
#define __va_argsiz(t) \
(((sizeof(t) + sizeof(int) - ) / sizeof(int)) * sizeof(int)) /*
* Start variable argument list processing by setting AP to point to the
* argument after pN.
*/
#ifdef __GNUC__
/*
* In GNU the stack is not necessarily arranged very neatly in order to
* pack shorts and such into a smaller argument list. Fortunately a
* neatly arranged version is available through the use of __builtin_next_arg.
*/
#define va_start(ap, pN) \
((ap) = ((va_list) __builtin_next_arg(pN)))
#else
/*
* For a simple minded compiler this should work (it works in GNU too for
* vararg lists that don't follow shorts and such).
*/
#define va_start(ap, pN) \
((ap) = ((va_list) (&pN) + __va_argsiz(pN)))
#endif /*
* End processing of variable argument list. In this case we do nothing.
*/
#define va_end(ap) ((void)0) /*
* Increment ap to the next argument in the list while returing a
* pointer to what ap pointed to first, which is of type t.
*
* We cast to void* and then to t* because this avoids a warning about
* increasing the alignment requirement.
*/ #define va_arg(ap, t) \
(((ap) = (ap) + __va_argsiz(t)), \
*((t*) (void*) ((ap) - __va_argsiz(t)))) #endif /* Not RC_INVOKED */ #endif /* not _STDARG_H_ */ stdarg.h

stdarg.h

//xref: /development/ndk/platforms/android-3/include/jni.h
//http://androidxref.com/2.3.6/xref/development/ndk/platforms/android-3/include/jni.h /*
* Copyright 2006 The Android Open Source Project
*
* JNI specification, as defined by Sun:
* http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
*
* Everything here is expected to be VM-neutral.
*/
#ifndef _JNI_H
#define _JNI_H //#include <stdarg.h> /*
* Primitive types that match up with Java equivalents.
*/
#ifdef HAVE_INTTYPES_H
//@@@@@@@@@ # include <inttypes.h> /* C99 */
typedef uint8_t jboolean; /* unsigned 8 bits */
typedef int8_t jbyte; /* signed 8 bits */
typedef uint16_t jchar; /* unsigned 16 bits */
typedef int16_t jshort; /* signed 16 bits */
typedef int32_t jint; /* signed 32 bits */
typedef int64_t jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#else
typedef unsigned char jboolean; /* unsigned 8 bits */
typedef signed char jbyte; /* signed 8 bits */
typedef unsigned short jchar; /* unsigned 16 bits */
typedef short jshort; /* signed 16 bits */
typedef int jint; /* signed 32 bits */
typedef long long jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#endif /* "cardinal indices and sizes" */
typedef jint jsize; #ifdef __cplusplus
/*
* Reference types, in C++
*/
class _jobject {};
class _jclass : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarray {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jthrowable : public _jobject {}; typedef _jobject* jobject;
typedef _jclass* jclass;
typedef _jstring* jstring;
typedef _jarray* jarray;
typedef _jobjectArray* jobjectArray;
typedef _jbooleanArray* jbooleanArray;
typedef _jbyteArray* jbyteArray;
typedef _jcharArray* jcharArray;
typedef _jshortArray* jshortArray;
typedef _jintArray* jintArray;
typedef _jlongArray* jlongArray;
typedef _jfloatArray* jfloatArray;
typedef _jdoubleArray* jdoubleArray;
typedef _jthrowable* jthrowable;
typedef _jobject* jweak; #else /* not __cplusplus */ /*
* Reference types, in C.
*/
typedef void* jobject;
typedef jobject jclass;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jobjectArray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jobject jthrowable;
typedef jobject jweak; #endif /* not __cplusplus */ struct _jfieldID; /* opaque structure */
typedef struct _jfieldID* jfieldID; /* field IDs */ struct _jmethodID; /* opaque structure */
typedef struct _jmethodID* jmethodID; /* method IDs */ struct JNIInvokeInterface; typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue; typedef enum jobjectRefType {
JNIInvalidRefType = ,
JNILocalRefType = ,
JNIGlobalRefType = ,
JNIWeakGlobalRefType =
} jobjectRefType; typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod; struct _JNIEnv;
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIEnv; #if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif /*
* Table of interface function pointers.
*/
struct JNINativeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3; jint (*GetVersion)(JNIEnv *); jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
jsize);
jclass (*FindClass)(JNIEnv*, const char*); jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);
jfieldID (*FromReflectedField)(JNIEnv*, jobject);
/* spec doesn't show jboolean parameter */
jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); jclass (*GetSuperclass)(JNIEnv*, jclass);
jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); /* spec doesn't show jboolean parameter */
jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); jint (*Throw)(JNIEnv*, jthrowable);
jint (*ThrowNew)(JNIEnv *, jclass, const char *);
jthrowable (*ExceptionOccurred)(JNIEnv*);
void (*ExceptionDescribe)(JNIEnv*);
void (*ExceptionClear)(JNIEnv*);
void (*FatalError)(JNIEnv*, const char*); jint (*PushLocalFrame)(JNIEnv*, jint);
jobject (*PopLocalFrame)(JNIEnv*, jobject); jobject (*NewGlobalRef)(JNIEnv*, jobject);
void (*DeleteGlobalRef)(JNIEnv*, jobject);
void (*DeleteLocalRef)(JNIEnv*, jobject);
jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); jobject (*NewLocalRef)(JNIEnv*, jobject);
jint (*EnsureLocalCapacity)(JNIEnv*, jint); jobject (*AllocObject)(JNIEnv*, jclass);
jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); jclass (*GetObjectClass)(JNIEnv*, jobject);
jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);
jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*); jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID);
jchar (*GetCharField)(JNIEnv*, jobject, jfieldID);
jshort (*GetShortField)(JNIEnv*, jobject, jfieldID);
jint (*GetIntField)(JNIEnv*, jobject, jfieldID);
jlong (*GetLongField)(JNIEnv*, jobject, jfieldID);
jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID);
jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
va_list);
jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
jvalue*);
jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*,
const char*); jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); jstring (*NewString)(JNIEnv*, const jchar*, jsize);
jsize (*GetStringLength)(JNIEnv*, jstring);
const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
jstring (*NewStringUTF)(JNIEnv*, const char*);
jsize (*GetStringUTFLength)(JNIEnv*, jstring);
/* JNI spec says this returns const jbyte*, but that's inconsistent */
const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
jsize (*GetArrayLength)(JNIEnv*, jarray);
jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
jbyteArray (*NewByteArray)(JNIEnv*, jsize);
jcharArray (*NewCharArray)(JNIEnv*, jsize);
jshortArray (*NewShortArray)(JNIEnv*, jsize);
jintArray (*NewIntArray)(JNIEnv*, jsize);
jlongArray (*NewLongArray)(JNIEnv*, jsize);
jfloatArray (*NewFloatArray)(JNIEnv*, jsize);
jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,
jboolean*, jint);
void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,
jbyte*, jint);
void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,
jchar*, jint);
void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,
jshort*, jint);
void (*ReleaseIntArrayElements)(JNIEnv*, jintArray,
jint*, jint);
void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,
jlong*, jint);
void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,
jfloat*, jint);
void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,
jdouble*, jint); void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
jsize, jsize, jboolean*);
void (*GetByteArrayRegion)(JNIEnv*, jbyteArray,
jsize, jsize, jbyte*);
void (*GetCharArrayRegion)(JNIEnv*, jcharArray,
jsize, jsize, jchar*);
void (*GetShortArrayRegion)(JNIEnv*, jshortArray,
jsize, jsize, jshort*);
void (*GetIntArrayRegion)(JNIEnv*, jintArray,
jsize, jsize, jint*);
void (*GetLongArrayRegion)(JNIEnv*, jlongArray,
jsize, jsize, jlong*);
void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray,
jsize, jsize, jfloat*);
void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
jsize, jsize, jdouble*); /* spec shows these without const; some jni.h do, some don't */
void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
jsize, jsize, const jboolean*);
void (*SetByteArrayRegion)(JNIEnv*, jbyteArray,
jsize, jsize, const jbyte*);
void (*SetCharArrayRegion)(JNIEnv*, jcharArray,
jsize, jsize, const jchar*);
void (*SetShortArrayRegion)(JNIEnv*, jshortArray,
jsize, jsize, const jshort*);
void (*SetIntArrayRegion)(JNIEnv*, jintArray,
jsize, jsize, const jint*);
void (*SetLongArrayRegion)(JNIEnv*, jlongArray,
jsize, jsize, const jlong*);
void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,
jsize, jsize, const jfloat*);
void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
jsize, jsize, const jdouble*); jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,
jint);
jint (*UnregisterNatives)(JNIEnv*, jclass);
jint (*MonitorEnter)(JNIEnv*, jobject);
jint (*MonitorExit)(JNIEnv*, jobject);
jint (*GetJavaVM)(JNIEnv*, JavaVM**); void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); jweak (*NewWeakGlobalRef)(JNIEnv*, jobject);
void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); jboolean (*ExceptionCheck)(JNIEnv*); jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
void* (*GetDirectBufferAddress)(JNIEnv*, jobject);
jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); /* added in JNI 1.6 */
jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
}; /*
* C++ object wrapper.
*
* This is usually overlaid on a C struct whose first element is a
* JNINativeInterface*. We rely somewhat on compiler behavior.
*/
struct _JNIEnv {
/* do not rename this; it does not seem to be entirely opaque */
const struct JNINativeInterface* functions; #if defined(__cplusplus) jint GetVersion()
{ return functions->GetVersion(this); } jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
jsize bufLen)
{ return functions->DefineClass(this, name, loader, buf, bufLen); } jclass FindClass(const char* name)
{ return functions->FindClass(this, name); } jmethodID FromReflectedMethod(jobject method)
{ return functions->FromReflectedMethod(this, method); } jfieldID FromReflectedField(jobject field)
{ return functions->FromReflectedField(this, field); } jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
{ return functions->ToReflectedMethod(this, cls, methodID, isStatic); } jclass GetSuperclass(jclass clazz)
{ return functions->GetSuperclass(this, clazz); } jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
{ return functions->IsAssignableFrom(this, clazz1, clazz2); } jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
{ return functions->ToReflectedField(this, cls, fieldID, isStatic); } jint Throw(jthrowable obj)
{ return functions->Throw(this, obj); } jint ThrowNew(jclass clazz, const char* message)
{ return functions->ThrowNew(this, clazz, message); } jthrowable ExceptionOccurred()
{ return functions->ExceptionOccurred(this); } void ExceptionDescribe()
{ functions->ExceptionDescribe(this); } void ExceptionClear()
{ functions->ExceptionClear(this); } void FatalError(const char* msg)
{ functions->FatalError(this, msg); } jint PushLocalFrame(jint capacity)
{ return functions->PushLocalFrame(this, capacity); } jobject PopLocalFrame(jobject result)
{ return functions->PopLocalFrame(this, result); } jobject NewGlobalRef(jobject obj)
{ return functions->NewGlobalRef(this, obj); } void DeleteGlobalRef(jobject globalRef)
{ functions->DeleteGlobalRef(this, globalRef); } void DeleteLocalRef(jobject localRef)
{ functions->DeleteLocalRef(this, localRef); } jboolean IsSameObject(jobject ref1, jobject ref2)
{ return functions->IsSameObject(this, ref1, ref2); } jobject NewLocalRef(jobject ref)
{ return functions->NewLocalRef(this, ref); } jint EnsureLocalCapacity(jint capacity)
{ return functions->EnsureLocalCapacity(this, capacity); } jobject AllocObject(jclass clazz)
{ return functions->AllocObject(this, clazz); } jobject NewObject(jclass clazz, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
jobject result = functions->NewObjectV(this, clazz, methodID, args);
va_end(args);
return result;
} jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
{ return functions->NewObjectV(this, clazz, methodID, args); } jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
{ return functions->NewObjectA(this, clazz, methodID, args); } jclass GetObjectClass(jobject obj)
{ return functions->GetObjectClass(this, obj); } jboolean IsInstanceOf(jobject obj, jclass clazz)
{ return functions->IsInstanceOf(this, obj, clazz); } jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
{ return functions->GetMethodID(this, clazz, name, sig); } #define CALL_TYPE_METHOD(_jtype, _jname) \
_jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->Call##_jname##MethodV(this, obj, methodID, \
args); \
va_end(args); \
return result; \
}
#define CALL_TYPE_METHODV(_jtype, _jname) \
_jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \
va_list args) \
{ return functions->Call##_jname##MethodV(this, obj, methodID, args); }
#define CALL_TYPE_METHODA(_jtype, _jname) \
_jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \
jvalue* args) \
{ return functions->Call##_jname##MethodA(this, obj, methodID, args); } #define CALL_TYPE(_jtype, _jname) \
CALL_TYPE_METHOD(_jtype, _jname) \
CALL_TYPE_METHODV(_jtype, _jname) \
CALL_TYPE_METHODA(_jtype, _jname) CALL_TYPE(jobject, Object)
CALL_TYPE(jboolean, Boolean)
CALL_TYPE(jbyte, Byte)
CALL_TYPE(jchar, Char)
CALL_TYPE(jshort, Short)
CALL_TYPE(jint, Int)
CALL_TYPE(jlong, Long)
CALL_TYPE(jfloat, Float)
CALL_TYPE(jdouble, Double) void CallVoidMethod(jobject obj, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallVoidMethodV(this, obj, methodID, args);
va_end(args);
}
void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
{ functions->CallVoidMethodV(this, obj, methodID, args); }
void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
{ functions->CallVoidMethodA(this, obj, methodID, args); } #define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
_jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \
jmethodID methodID, ...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->CallNonvirtual##_jname##MethodV(this, obj, \
clazz, methodID, args); \
va_end(args); \
return result; \
}
#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
_jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \
jmethodID methodID, va_list args) \
{ return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \
methodID, args); }
#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \
_jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \
jmethodID methodID, jvalue* args) \
{ return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \
methodID, args); } #define CALL_NONVIRT_TYPE(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) CALL_NONVIRT_TYPE(jobject, Object)
CALL_NONVIRT_TYPE(jboolean, Boolean)
CALL_NONVIRT_TYPE(jbyte, Byte)
CALL_NONVIRT_TYPE(jchar, Char)
CALL_NONVIRT_TYPE(jshort, Short)
CALL_NONVIRT_TYPE(jint, Int)
CALL_NONVIRT_TYPE(jlong, Long)
CALL_NONVIRT_TYPE(jfloat, Float)
CALL_NONVIRT_TYPE(jdouble, Double) void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
va_end(args);
}
void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
jmethodID methodID, va_list args)
{ functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
jmethodID methodID, jvalue* args)
{ functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
{ return functions->GetFieldID(this, clazz, name, sig); } jobject GetObjectField(jobject obj, jfieldID fieldID)
{ return functions->GetObjectField(this, obj, fieldID); }
jboolean GetBooleanField(jobject obj, jfieldID fieldID)
{ return functions->GetBooleanField(this, obj, fieldID); }
jbyte GetByteField(jobject obj, jfieldID fieldID)
{ return functions->GetByteField(this, obj, fieldID); }
jchar GetCharField(jobject obj, jfieldID fieldID)
{ return functions->GetCharField(this, obj, fieldID); }
jshort GetShortField(jobject obj, jfieldID fieldID)
{ return functions->GetShortField(this, obj, fieldID); }
jint GetIntField(jobject obj, jfieldID fieldID)
{ return functions->GetIntField(this, obj, fieldID); }
jlong GetLongField(jobject obj, jfieldID fieldID)
{ return functions->GetLongField(this, obj, fieldID); }
jfloat GetFloatField(jobject obj, jfieldID fieldID)
{ return functions->GetFloatField(this, obj, fieldID); }
jdouble GetDoubleField(jobject obj, jfieldID fieldID)
{ return functions->GetDoubleField(this, obj, fieldID); } void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
{ functions->SetObjectField(this, obj, fieldID, value); }
void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
{ functions->SetBooleanField(this, obj, fieldID, value); }
void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
{ functions->SetByteField(this, obj, fieldID, value); }
void SetCharField(jobject obj, jfieldID fieldID, jchar value)
{ functions->SetCharField(this, obj, fieldID, value); }
void SetShortField(jobject obj, jfieldID fieldID, jshort value)
{ functions->SetShortField(this, obj, fieldID, value); }
void SetIntField(jobject obj, jfieldID fieldID, jint value)
{ functions->SetIntField(this, obj, fieldID, value); }
void SetLongField(jobject obj, jfieldID fieldID, jlong value)
{ functions->SetLongField(this, obj, fieldID, value); }
void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
{ functions->SetFloatField(this, obj, fieldID, value); }
void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
{ functions->SetDoubleField(this, obj, fieldID, value); } jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
{ return functions->GetStaticMethodID(this, clazz, name, sig); } #define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
_jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \
...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->CallStatic##_jname##MethodV(this, clazz, \
methodID, args); \
va_end(args); \
return result; \
}
#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
_jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \
va_list args) \
{ return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \
args); }
#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \
_jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \
jvalue* args) \
{ return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \
args); } #define CALL_STATIC_TYPE(_jtype, _jname) \
CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
CALL_STATIC_TYPE_METHODA(_jtype, _jname) CALL_STATIC_TYPE(jobject, Object)
CALL_STATIC_TYPE(jboolean, Boolean)
CALL_STATIC_TYPE(jbyte, Byte)
CALL_STATIC_TYPE(jchar, Char)
CALL_STATIC_TYPE(jshort, Short)
CALL_STATIC_TYPE(jint, Int)
CALL_STATIC_TYPE(jlong, Long)
CALL_STATIC_TYPE(jfloat, Float)
CALL_STATIC_TYPE(jdouble, Double) void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallStaticVoidMethodV(this, clazz, methodID, args);
va_end(args);
}
void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
{ functions->CallStaticVoidMethodV(this, clazz, methodID, args); }
void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
{ functions->CallStaticVoidMethodA(this, clazz, methodID, args); } jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
{ return functions->GetStaticFieldID(this, clazz, name, sig); } jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticObjectField(this, clazz, fieldID); }
jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticBooleanField(this, clazz, fieldID); }
jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticByteField(this, clazz, fieldID); }
jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticCharField(this, clazz, fieldID); }
jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticShortField(this, clazz, fieldID); }
jint GetStaticIntField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticIntField(this, clazz, fieldID); }
jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticLongField(this, clazz, fieldID); }
jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticFloatField(this, clazz, fieldID); }
jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticDoubleField(this, clazz, fieldID); } void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
{ functions->SetStaticObjectField(this, clazz, fieldID, value); }
void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
{ functions->SetStaticBooleanField(this, clazz, fieldID, value); }
void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
{ functions->SetStaticByteField(this, clazz, fieldID, value); }
void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
{ functions->SetStaticCharField(this, clazz, fieldID, value); }
void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
{ functions->SetStaticShortField(this, clazz, fieldID, value); }
void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
{ functions->SetStaticIntField(this, clazz, fieldID, value); }
void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
{ functions->SetStaticLongField(this, clazz, fieldID, value); }
void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
{ functions->SetStaticFloatField(this, clazz, fieldID, value); }
void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
{ functions->SetStaticDoubleField(this, clazz, fieldID, value); } jstring NewString(const jchar* unicodeChars, jsize len)
{ return functions->NewString(this, unicodeChars, len); } jsize GetStringLength(jstring string)
{ return functions->GetStringLength(this, string); } const jchar* GetStringChars(jstring string, jboolean* isCopy)
{ return functions->GetStringChars(this, string, isCopy); } void ReleaseStringChars(jstring string, const jchar* chars)
{ functions->ReleaseStringChars(this, string, chars); } jstring NewStringUTF(const char* bytes)
{ return functions->NewStringUTF(this, bytes); } jsize GetStringUTFLength(jstring string)
{ return functions->GetStringUTFLength(this, string); } const char* GetStringUTFChars(jstring string, jboolean* isCopy)
{ return functions->GetStringUTFChars(this, string, isCopy); } void ReleaseStringUTFChars(jstring string, const char* utf)
{ functions->ReleaseStringUTFChars(this, string, utf); } jsize GetArrayLength(jarray array)
{ return functions->GetArrayLength(this, array); } jobjectArray NewObjectArray(jsize length, jclass elementClass,
jobject initialElement)
{ return functions->NewObjectArray(this, length, elementClass,
initialElement); } jobject GetObjectArrayElement(jobjectArray array, jsize index)
{ return functions->GetObjectArrayElement(this, array, index); } void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
{ functions->SetObjectArrayElement(this, array, index, value); } jbooleanArray NewBooleanArray(jsize length)
{ return functions->NewBooleanArray(this, length); }
jbyteArray NewByteArray(jsize length)
{ return functions->NewByteArray(this, length); }
jcharArray NewCharArray(jsize length)
{ return functions->NewCharArray(this, length); }
jshortArray NewShortArray(jsize length)
{ return functions->NewShortArray(this, length); }
jintArray NewIntArray(jsize length)
{ return functions->NewIntArray(this, length); }
jlongArray NewLongArray(jsize length)
{ return functions->NewLongArray(this, length); }
jfloatArray NewFloatArray(jsize length)
{ return functions->NewFloatArray(this, length); }
jdoubleArray NewDoubleArray(jsize length)
{ return functions->NewDoubleArray(this, length); } jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
{ return functions->GetBooleanArrayElements(this, array, isCopy); }
jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
{ return functions->GetByteArrayElements(this, array, isCopy); }
jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
{ return functions->GetCharArrayElements(this, array, isCopy); }
jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
{ return functions->GetShortArrayElements(this, array, isCopy); }
jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
{ return functions->GetIntArrayElements(this, array, isCopy); }
jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
{ return functions->GetLongArrayElements(this, array, isCopy); }
jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
{ return functions->GetFloatArrayElements(this, array, isCopy); }
jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
{ return functions->GetDoubleArrayElements(this, array, isCopy); } void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
jint mode)
{ functions->ReleaseBooleanArrayElements(this, array, elems, mode); }
void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
jint mode)
{ functions->ReleaseByteArrayElements(this, array, elems, mode); }
void ReleaseCharArrayElements(jcharArray array, jchar* elems,
jint mode)
{ functions->ReleaseCharArrayElements(this, array, elems, mode); }
void ReleaseShortArrayElements(jshortArray array, jshort* elems,
jint mode)
{ functions->ReleaseShortArrayElements(this, array, elems, mode); }
void ReleaseIntArrayElements(jintArray array, jint* elems,
jint mode)
{ functions->ReleaseIntArrayElements(this, array, elems, mode); }
void ReleaseLongArrayElements(jlongArray array, jlong* elems,
jint mode)
{ functions->ReleaseLongArrayElements(this, array, elems, mode); }
void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
jint mode)
{ functions->ReleaseFloatArrayElements(this, array, elems, mode); }
void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
jint mode)
{ functions->ReleaseDoubleArrayElements(this, array, elems, mode); } void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
jboolean* buf)
{ functions->GetBooleanArrayRegion(this, array, start, len, buf); }
void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
jbyte* buf)
{ functions->GetByteArrayRegion(this, array, start, len, buf); }
void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
jchar* buf)
{ functions->GetCharArrayRegion(this, array, start, len, buf); }
void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
jshort* buf)
{ functions->GetShortArrayRegion(this, array, start, len, buf); }
void GetIntArrayRegion(jintArray array, jsize start, jsize len,
jint* buf)
{ functions->GetIntArrayRegion(this, array, start, len, buf); }
void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
jlong* buf)
{ functions->GetLongArrayRegion(this, array, start, len, buf); }
void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
jfloat* buf)
{ functions->GetFloatArrayRegion(this, array, start, len, buf); }
void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
jdouble* buf)
{ functions->GetDoubleArrayRegion(this, array, start, len, buf); } void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
const jboolean* buf)
{ functions->SetBooleanArrayRegion(this, array, start, len, buf); }
void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
const jbyte* buf)
{ functions->SetByteArrayRegion(this, array, start, len, buf); }
void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
const jchar* buf)
{ functions->SetCharArrayRegion(this, array, start, len, buf); }
void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
const jshort* buf)
{ functions->SetShortArrayRegion(this, array, start, len, buf); }
void SetIntArrayRegion(jintArray array, jsize start, jsize len,
const jint* buf)
{ functions->SetIntArrayRegion(this, array, start, len, buf); }
void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
const jlong* buf)
{ functions->SetLongArrayRegion(this, array, start, len, buf); }
void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
const jfloat* buf)
{ functions->SetFloatArrayRegion(this, array, start, len, buf); }
void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
const jdouble* buf)
{ functions->SetDoubleArrayRegion(this, array, start, len, buf); } jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
jint nMethods)
{ return functions->RegisterNatives(this, clazz, methods, nMethods); } jint UnregisterNatives(jclass clazz)
{ return functions->UnregisterNatives(this, clazz); } jint MonitorEnter(jobject obj)
{ return functions->MonitorEnter(this, obj); } jint MonitorExit(jobject obj)
{ return functions->MonitorExit(this, obj); } jint GetJavaVM(JavaVM** vm)
{ return functions->GetJavaVM(this, vm); } void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
{ functions->GetStringRegion(this, str, start, len, buf); } void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
{ return functions->GetStringUTFRegion(this, str, start, len, buf); } void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
{ return functions->GetPrimitiveArrayCritical(this, array, isCopy); } void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
{ functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } const jchar* GetStringCritical(jstring string, jboolean* isCopy)
{ return functions->GetStringCritical(this, string, isCopy); } void ReleaseStringCritical(jstring string, const jchar* carray)
{ functions->ReleaseStringCritical(this, string, carray); } jweak NewWeakGlobalRef(jobject obj)
{ return functions->NewWeakGlobalRef(this, obj); } void DeleteWeakGlobalRef(jweak obj)
{ functions->DeleteWeakGlobalRef(this, obj); } jboolean ExceptionCheck()
{ return functions->ExceptionCheck(this); } jobject NewDirectByteBuffer(void* address, jlong capacity)
{ return functions->NewDirectByteBuffer(this, address, capacity); } void* GetDirectBufferAddress(jobject buf)
{ return functions->GetDirectBufferAddress(this, buf); } jlong GetDirectBufferCapacity(jobject buf)
{ return functions->GetDirectBufferCapacity(this, buf); } /* added in JNI 1.6 */
jobjectRefType GetObjectRefType(jobject obj)
{ return functions->GetObjectRefType(this, obj); }
#endif /*__cplusplus*/
}; /*
* JNI invocation interface.
*/
struct JNIInvokeInterface {
void* reserved0;
void* reserved1;
void* reserved2; jint (*DestroyJavaVM)(JavaVM*);
jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
jint (*DetachCurrentThread)(JavaVM*);
jint (*GetEnv)(JavaVM*, void**, jint);
jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
}; /*
* C++ version.
*/
struct _JavaVM {
const struct JNIInvokeInterface* functions; #if defined(__cplusplus)
jint DestroyJavaVM()
{ return functions->DestroyJavaVM(this); }
jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
{ return functions->AttachCurrentThread(this, p_env, thr_args); }
jint DetachCurrentThread()
{ return functions->DetachCurrentThread(this); }
jint GetEnv(void** env, jint version)
{ return functions->GetEnv(this, env, version); }
jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)
{ return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }
#endif /*__cplusplus*/
}; struct JavaVMAttachArgs {
jint version; /* must be >= JNI_VERSION_1_2 */
const char* name; /* NULL or name of thread as modified UTF-8 str */
jobject group; /* global ref of a ThreadGroup object, or NULL */
};
typedef struct JavaVMAttachArgs JavaVMAttachArgs; /*
* JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no
* longer supported.)
*/
typedef struct JavaVMOption {
const char* optionString;
void* extraInfo;
} JavaVMOption; typedef struct JavaVMInitArgs {
jint version; /* use JNI_VERSION_1_2 or later */ jint nOptions;
JavaVMOption* options;
jboolean ignoreUnrecognized;
} JavaVMInitArgs; #ifdef __cplusplus
extern "C" {
#endif
/*
* VM initialization functions.
*
* Note these are the only symbols exported for JNI by the VM.
*/
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); /*
* Prototypes for functions exported by loadable shared libs. These are
* called by JNI, not provided by JNI.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved);
void JNI_OnUnload(JavaVM* vm, void* reserved); #ifdef __cplusplus
}
#endif /*
* Manifest constants.
*/
#define JNI_FALSE 0
#define JNI_TRUE 1 #define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006 #define JNI_OK (0) /* no error */
#define JNI_ERR (-1) /* generic error */
#define JNI_EDETACHED (-2) /* thread detached from the VM */
#define JNI_EVERSION (-3) /* JNI version error */ #define JNI_COMMIT 1 /* copy content, do not free buffer */
#define JNI_ABORT 2 /* free buffer w/o copying back */ /* need these for Windows-aware headers */
#define JNIIMPORT
#define JNIEXPORT
#define JNICALL #endif /*_JNI_H*/ jni.h

jni.h

然后可以使用其中的结构体了。

有人曾搞成excel但是不知道地址了,临时下载,当时看到下来看是不能传出去的。

Android调用JNI本地方法跟踪目标代码的更多相关文章

  1. Android调用JNI本地方法经过有点改变

    方法注册好后要经过哪些路 Android一个异常捕获项目 https://github.com/xroche/coffeecatch coffeecatch CoffeeCatch, a tiny n ...

  2. Android Java访问本地方法(JNI)

    当功能需要本地代码实现的时候,Java 代码就需要调用本地代码. 在调用本地代码时,首先要保证本地代码被加载到 Java 执行环境中并与 Java 代码连接在一起,这样 Java 代码在调用本地方法时 ...

  3. 【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法

    错误描述 今天使用第三方的so库时候,调用JNI方法时出现了错误.报错如下所示: 11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/a ...

  4. WebView js 调用Java本地方法

    webView = (WebView) this.findViewById(R.id.webview); WebSettings webSettings = webView.getSettings() ...

  5. JNI学习2:android 调用C语言方法与C语言调用android方法

    #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <jni.h> #in ...

  6. Android之——jni通用工具方法

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47002207 1.将java字符串转化为c++字符串 /** *工具方法 *将ja ...

  7. Android调用Jni,非常简单的一个Demo

    step1:创建一个android项目       Project Name:jnitest       Build Target: Android 1.6       Application Nam ...

  8. Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码

    以前写过两个Android开发配置文档,使用NDK进行JNI开发,这样能够利用以前已经写好的C++代码. 前两篇博客地址: http://blog.csdn.net/watkinsong/articl ...

  9. [转][android][利用JNI技术在Android中调用、调试C++代码]

    在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux). 没写过 ...

随机推荐

  1. 集合篇 —— Collection(1):JDK 中的重复实现问题

    1.      问题的提出 在 Java 的集合体系当中,无论是 List(列表)还是 Set(集),在设计的时候都存在一个很奇怪的现象:这两种集合的接口,Java 都为其设计了抽象类 Abstrac ...

  2. ubuntu安装jdk<服务器>

    服务器 阿里云服务器Ubuntu安装jdk7 2014-08-25 16:44 |  coding云 |  5825次阅读 | 6条评论   一.下载jdk 可以先下载到本地,然后ftp到服务器 官方 ...

  3. webpack错误Chunk.entry was removed. Use hasRuntime()

    这个错误在从webpack1升级webpack2或webpack3时候都遇到了,起初查到的都是extract-text-webpack-plugin版本的问题,升级了还是不管用.搜索引擎上查不到其他的 ...

  4. 【CF696B】Puzzles(树形DP,期望)

    题意:n 个节点的树,初始位置为 1 号节点,初始时间为 1.每次随机地走向任何一个没有走过的子树并且令时间 +1求问走到每一个点时的时间的期望值 思路:比较少见的一道自顶向下的树形DP dp[i]表 ...

  5. vue.js源码学习分享(三)

    /** * Mix properties into target object.//把多个属性插入目标的对象 */ function extend (to, _from) { for (var key ...

  6. Nginx没有启动文件、nginx服务不支持chkconfig、nginx无法自启

    Nginx没有启动文件.nginx服务不支持chkconfig.nginx无法自启 问题描述: Nginx安装后,当想要设置Ngixn为开机启动时, 就需要把nginx的启动命令路径放到/etc/rc ...

  7. Codeforces 403D: Beautiful Pairs of Numbers(DP)

    题意:转换模型之后,就是1~n个数中选k个,放到一个容量为n的背包中,这个背包还特别神奇,相同的物品摆放的位置不同时,算不同的放法(想象背包空间就是一个长度为n的数组,然后容量为1的物体放一个格子,容 ...

  8. js-jquery 中$.ajax -浅显接触

    工作了将近2年,终于开始自己写ajax了!!!真紧张的! 当年培训时就没有学ajax,就让我们自己看看,我是那种主动学习的人吗?不是!!!所以搞不懂ajax!!!!! 在工作中,数据的绑定我们之前都是 ...

  9. js-className修改class属性

    1.修改className 1)修改class类名为p-a-0 2)在保留class="p1"的基础上再添加一个类名为p-a-0 2.删除className 1).结果需删除cla ...

  10. 浅谈DPCHookSSDT和RemoveDPC

    最近学了DPC这一对,把Win7 32位和64位都做了,查阅了大量的资料,并且进行了大量调试,理一下思路,为了后面更好的学习. 转载请注明出处:http://www.cnblogs.com/littl ...