struct
str
{
const char
*
s;
int
len
;
};
/
/
struct
str
global_name
=
{.s
=
"ed8b9244350d3644"
, .
len
=
16
};
/
/
struct
str
global_serial
=
{.s
=
"7C9815255BFE832D3F93140B"
, .
len
=
24
};
struct
str
global_name
=
{.s
=
"KCTF"
, .
len
=
4
};
struct
str
global_serial
=
{.s
=
"17726331DA0FE737149C8202"
, .
len
=
24
};
/
/
struct
str
global_serial
=
{.s
=
"17726331da0fe737149c8202"
, .
len
=
24
};
struct JNINativeInterface_ {
unsigned
int
f[
0x1000
/
4
];
};
typedef struct JNIEnv_ {
struct JNINativeInterface_
*
functions;
} JNIEnv;
void JNICALL_FindClass(JNIEnv
*
env, const char
*
name) {
printf(
"JNICALL_FindClass %s\n"
, name);
}
void JNICALL_NewStringUTF(JNIEnv
*
env, const char
*
utf) {
printf(
"%s %s\n"
, __func__, utf);
}
int
JNICALL_GetMethodID(JNIEnv
*
env, void
*
clazz, const char
*
name, const char
*
sig) {
printf(
"%s %p %s %s\n"
, __func__, clazz, name, sig);
return
0x55555501
;
}
void
*
JNICALL_CallObjectMethod(JNIEnv
*
env, void
*
obj,
int
methodID) {
assert
(methodID
=
=
0x55555501
);
printf(
"%s %p %x\n"
, __func__, obj, methodID);
return
obj;
}
int
JNICALL_GetArrayLength(JNIEnv
*
env, struct
str
*
array) {
printf(
"%s %p\n"
, __func__, array);
return
array
-
>
len
;
}
unsigned char
*
JNICALL_GetByteArrayElements(JNIEnv
*
env, struct
str
*
array,
int
isCopy) {
printf(
"%s %p %d\n"
, __func__, array, isCopy);
return
array
-
>s;
}
void JNICALL_ReleaseByteArrayElements(JNIEnv
*
env, void
*
array, void
*
elems,
int
mode) {
printf(
"%s %p %p %d\n"
, __func__, array, elems, mode);
}
void
*
got_malloc(
int
size) {
void
*
r
=
malloc(size);
printf(
"%s %d %p\n"
, __func__, size, r);
return
r;
}
void got_free(void
*
p) {
printf(
"%s\n"
, __func__);
free(p);
}
void got_memset(char
*
p,
int
n,
int
count) {
printf(
"%s %p %d %d\n"
, __func__, p, n, count);
memset(p, n, count);
}
void bp(void) {
;
}
void stack_chk_guard(void) {
printf(
"%s\n"
, __func__);
}
void imp___gnu_Unwind_Find_exidx(void) {
printf(
"%s\n"
, __func__);
}
void cxa_call_unexpected(void) {
printf(
"%s\n"
, __func__);
}
int
main(void) {
int
fd
=
open
(
"libhello-jni.so"
, O_RDONLY);
unsigned char
*
fmem
=
mmap(NULL,
0x7000
, PROT_READ, MAP_PRIVATE, fd,
0
);
unsigned char
*
mem
=
mmap(
0xdead0000
,
0x8000
, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS,
-
1
,
0
);
memcpy(mem, fmem,
0x2b13
);
memcpy(mem
+
0x3e8c
, fmem
+
0x2e8c
,
0x1a8
);
memcpy(mem
+
0x5000
, fmem
+
0x4000
,
0x26bc
);
munmap(fmem,
0x7000
);
close(fd);
*
(unsigned
int
*
)(mem
+
0x3f98
)
=
mem
+
0x1034
+
1
;
/
/
xxxxxxxxxx2
+
1
*
(unsigned
int
*
)(mem
+
0x3f9c
)
=
stack_chk_guard;
*
(unsigned
int
*
)(mem
+
0x3fb8
)
=
imp___gnu_Unwind_Find_exidx;
*
(unsigned
int
*
)(mem
+
0x3fc4
)
=
cxa_call_unexpected;
*
(unsigned
int
*
)(mem
+
0x3fc8
)
=
mem
+
0x3f98
;
/
/
_GLOBAL_OFFSET_TABLE_@got
*
(unsigned
int
*
)(mem
+
0x3fa0
)
=
mem
+
0x10e4
+
1
;
/
/
Java_com_example_hellojni_HelloJni_stringFromJNI_ptr
+
1
*
(unsigned
int
*
)(mem
+
0x3fa4
)
=
mem
+
0x4004
;
/
/
f_data_key_dllink
*
(unsigned
int
*
)(mem
+
0x3fa8
)
=
mem
+
0x401c
;
/
/
f_sucess
*
(unsigned
int
*
)(mem
+
0x3fdc
)
=
got_malloc;
/
/
malloc@got
*
(unsigned
int
*
)(mem
+
0x3fe0
)
=
got_memset;
/
/
memset@got
*
(unsigned
int
*
)(mem
+
0x3fe4
)
=
got_free;
/
/
free@got
for
(
int
i
=
0x3f98
; i <
0x4000
; i
+
=
4
) {
if
(
*
(unsigned
int
*
)(mem
+
i)
=
=
0
) {
/
/
*
(unsigned
int
*
)(
0x77770000
+
i)
=
i;
}
}
struct JNINativeInterface_ jnii
=
{.f
=
{
0
}};
for
(
int
i
=
0
; i <
0x100
; i
+
+
) {
jnii.f[i]
=
0x11110000
+
i
*
4
;
}
jnii.f[
0x18
/
4
]
=
JNICALL_FindClass;
jnii.f[
0x29c
/
4
]
=
JNICALL_NewStringUTF;
jnii.f[
0x84
/
4
]
=
JNICALL_GetMethodID;
jnii.f[
0x88
/
4
]
=
JNICALL_CallObjectMethod;
jnii.f[
0x2ac
/
4
]
=
JNICALL_GetArrayLength;
jnii.f[
0x2e0
/
4
]
=
JNICALL_GetByteArrayElements;
jnii.f[
0x300
/
4
]
=
JNICALL_ReleaseByteArrayElements;
JNIEnv env;
env.functions
=
&jnii;
printf(
"&global_name: %p, &global_serial: %p\n"
, &global_name, &global_serial);
bp();
((void (
*
)(
int
,
int
,
int
,
int
,
int
))(mem
+
0x10e4
+
1
))(&env,
0xaaaa
, &global_name, &global_serial,
0xdddd
);
return
0
;
}