struct Method {
ClassObject
*
clazz;
/
*
method所属的类 public、native等
*
/
u4 accessFlags;
/
*
访问标记
*
/
u2 methodIndex;
/
/
method索引
/
/
三个size为边界值,对于native函数,这
3
个size均等于参数列表的size
u2 registersSize;
/
*
ins
+
locals
*
/
u2 outsSize;
u2 insSize;
const char
*
name;
/
/
函数名称
/
*
*
Method prototype descriptor string (
return
and
argument types)
*
/
DexProto prototype;
/
*
short
-
form method descriptor string
*
/
const char
*
shorty;
/
*
*
The remaining items are
not
used
for
abstract
or
native methods.
*
(JNI
is
currently hijacking
"insns"
as a function pointer,
set
*
after the first call. For internal
-
native this stays null.)
*
/
/
*
the actual code
*
/
const u2
*
insns;
/
*
instructions,
in
memory
-
mapped .dex
*
/
/
*
cached JNI argument
and
return
-
type
hints
*
/
int
jniArgInfo;
/
*
*
Native method ptr; could be actual function
or
a JNI bridge. We
*
don't currently discriminate between DalvikBridgeFunc
and
*
DalvikNativeFunc; the former takes an argument superset (i.e. two
*
extra args) which will be ignored. If necessary we can use
*
insns
=
=
NULL to detect JNI bridge vs. internal native.
*
/
DalvikBridgeFunc nativeFunc;
/
*
*
Register
map
data,
if
available. This will point into the DEX
file
*
if
the data was computed during pre
-
verification,
or
into the
*
linear alloc area
if
not
.
*
/
const RegisterMap
*
registerMap;
};
…
…
…
function replaceDalvikImplementation (fn) {
if
(fn
=
=
=
null && dalvikOriginalMethod
=
=
=
null) {
return
;
}
/
/
备份原来的method,
if
(dalvikOriginalMethod
=
=
=
null) {
dalvikOriginalMethod
=
Memory.dup(methodId, DVM_METHOD_SIZE);
dalvikTargetMethodId
=
Memory.dup(methodId, DVM_METHOD_SIZE);
}
if
(fn !
=
=
null) {
/
/
自定的代码
implementation
=
implement(f, fn);
let argsSize
=
argTypes.
reduce
((acc, t)
=
> (acc
+
t.size),
0
);
if
(
type
=
=
=
INSTANCE_METHOD) {
argsSize
+
+
;
}
/
/
把method变成native函数
/
*
*
make method native (with kAccNative)
*
insSize
and
registersSize are
set
to arguments size
*
/
const accessFlags
=
(Memory.readU32(methodId.add(DVM_METHOD_OFFSET_ACCESS_FLAGS)) | kAccNative) >>>
0
;
const registersSize
=
argsSize;
const outsSize
=
0
;
const insSize
=
argsSize;
Memory.writeU32(methodId.add(DVM_METHOD_OFFSET_ACCESS_FLAGS), accessFlags);
Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_REGISTERS_SIZE), registersSize);
Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_OUTS_SIZE), outsSize);
Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_INS_SIZE), insSize);
Memory.writeU32(methodId.add(DVM_METHOD_OFFSET_JNI_ARG_INFO), computeDalvikJniArgInfo(methodId));
/
/
调用dvmUseJNIBridge为这个Method设置一个Bridge,本质上是修改结构体中的nativeFunc为自定义的implementation函数
api.dvmUseJNIBridge(methodId, implementation);
patchedMethods.add(f);
}
else
{
patchedMethods.delete(f);
Memory.copy(methodId, dalvikOriginalMethod, DVM_METHOD_SIZE);
implementation
=
null;
}
}