Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SandHook
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
SandHook
Commits
13f17d10
Commit
13f17d10
authored
Jan 16, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync code
parent
3d7db2a9
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
106 additions
and
57 deletions
+106
-57
CastArtMethod.h
app/src/main/cpp/casts/CastArtMethod.h
+27
-24
ICast.h
app/src/main/cpp/includes/ICast.h
+3
-3
utils.h
app/src/main/cpp/includes/utils.h
+15
-0
SandHook.java
app/src/main/java/com/swift/sandhook/SandHook.java
+1
-5
SandHookMethodResolver.java
.../main/java/com/swift/sandhook/SandHookMethodResolver.java
+60
-25
No files found.
app/src/main/cpp/casts/CastArtMethod.h
View file @
13f17d10
...
...
@@ -8,26 +8,27 @@ namespace SandHook {
class
CastDexCacheResolvedMethods
:
public
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>
{
protected
:
Size
calOffset
(
art
::
mirror
::
ArtMethod
p
)
override
{
Size
calOffset
(
JNIEnv
*
jniEnv
,
art
::
mirror
::
ArtMethod
p
)
override
{
if
(
SDK_INT
>=
ANDROID_P
)
return
getParentSize
()
+
1
;
auto
filter
=
[](
int
offset
,
void
*
ptr
)
->
bool
{
// if (isBadReadPtr(ptr, BYTE_POINT))
// return false;
// Size addr = ADDR(ptr);
// if (isBadReadPtr(reinterpret_cast<void *>(addr + offset), BYTE_POINT))
// return false;
// Size subAddr = ADDR(addr + offset);
// return addr == subAddr;
};
int
offset
=
findOffsetWithCB1
(
&
p
,
getParentSize
(),
4
,
*
filter
);
return
offset
;
int
offset
=
0
;
Size
addr
=
getAddressFromJava
(
jniEnv
,
"com/swift/sandhook/SandHookMethodResolver"
,
"resolvedMethodsAddress"
);
if
(
addr
!=
0
)
{
offset
=
findOffset
(
&
p
,
getParentSize
(),
2
,
reinterpret_cast
<
void
*>
(
addr
));
if
(
offset
>=
0
)
{
return
static_cast
<
Size
>
(
offset
);
}
}
switch
(
SDK_INT
)
{
}
return
getParentSize
()
+
1
;
}
};
class
CastEntryPointFormInterpreter
:
public
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>
{
protected
:
Size
calOffset
(
art
::
mirror
::
ArtMethod
p
)
override
{
Size
calOffset
(
JNIEnv
*
jniEnv
,
art
::
mirror
::
ArtMethod
p
)
override
{
if
(
SDK_INT
<=
ANDROID_M
)
return
getParentSize
()
-
3
*
BYTE_POINT
;
else
...
...
@@ -37,7 +38,7 @@ namespace SandHook {
class
CastEntryPointQuickCompiled
:
public
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>
{
protected
:
Size
calOffset
(
art
::
mirror
::
ArtMethod
p
)
override
{
Size
calOffset
(
JNIEnv
*
jniEnv
,
art
::
mirror
::
ArtMethod
p
)
override
{
return
getParentSize
()
-
BYTE_POINT
;
}
};
...
...
@@ -45,7 +46,7 @@ namespace SandHook {
class
CastAccessFlag
:
public
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>
{
protected
:
Size
calOffset
(
art
::
mirror
::
ArtMethod
p
)
override
{
Size
calOffset
(
JNIEnv
*
jniEnv
,
art
::
mirror
::
ArtMethod
p
)
override
{
int
offset
=
findOffset
(
&
p
,
getParentSize
(),
sizeof
(
uint32_t
),
524313
);
if
(
offset
<
0
)
throw
getParentSize
()
+
1
;
...
...
@@ -77,22 +78,22 @@ namespace SandHook {
//init Members
entryPointQuickCompiled
=
new
CastEntryPointQuickCompiled
();
entryPointQuickCompiled
->
init
(
m1
,
size
);
entryPointQuickCompiled
->
init
(
env
,
m1
,
size
);
accessFlag
=
new
CastAccessFlag
();
accessFlag
->
init
(
m1
,
size
);
accessFlag
->
init
(
env
,
m1
,
size
);
entryPointFormInterpreter
=
new
CastEntryPointFormInterpreter
();
entryPointFormInterpreter
->
init
(
m1
,
size
);
entryPointFormInterpreter
->
init
(
env
,
m1
,
size
);
dexCacheResolvedMethods
=
new
CastDexCacheResolvedMethods
();
// dexCacheResolvedMethods->init(
m1, size);
dexCacheResolvedMethods
->
init
(
env
,
m1
,
size
);
//test
art
::
mirror
::
ArtMethod
**
mArray
=
reinterpret_cast
<
art
::
mirror
::
ArtMethod
**>
(
m1
.
dex_cache_resolved_methods_
);
art
::
mirror
::
ArtMethod
m1B
=
*
mArray
[
m1
.
dex_method_index_
];
art
::
mirror
::
ArtMethod
m1C
=
*
mArray
[
m2
.
dex_method_index_
];
//
//test
//
art::mirror::ArtMethod** mArray = reinterpret_cast<art::mirror::ArtMethod**>(m1.dex_cache_resolved_methods_);
//
//
art::mirror::ArtMethod m1B = *mArray[m1.dex_method_index_];
//
art::mirror::ArtMethod m1C = *mArray[m2.dex_method_index_];
}
...
...
@@ -108,6 +109,8 @@ namespace SandHook {
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
CastArtMethod
::
dexCacheResolvedMethods
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>*
CastArtMethod
::
accessFlag
=
nullptr
;
}
app/src/main/cpp/includes/ICast.h
View file @
13f17d10
...
...
@@ -40,9 +40,9 @@ namespace SandHook {
class
IMember
{
public
:
virtual
void
init
(
PType
p
,
Size
size
)
{
virtual
void
init
(
JNIEnv
*
jniEnv
,
PType
p
,
Size
size
)
{
this
->
parentSize
=
size
;
offset
=
calOffset
(
p
);
offset
=
calOffset
(
jniEnv
,
p
);
}
virtual
Size
getOffset
()
{
...
...
@@ -69,7 +69,7 @@ namespace SandHook {
Size
offset
=
0
;
protected
:
Size
parentSize
=
0
;
virtual
Size
calOffset
(
PType
p
)
=
0
;
virtual
Size
calOffset
(
JNIEnv
*
jniEnv
,
PType
p
)
=
0
;
};
...
...
app/src/main/cpp/includes/utils.h
View file @
13f17d10
...
...
@@ -122,5 +122,20 @@ bool isBadReadPtr(void *ptr, int length)
}
Size
getAddressFromJava
(
JNIEnv
*
env
,
char
*
className
,
char
*
fieldName
)
{
jclass
clazz
=
env
->
FindClass
(
className
);
if
(
clazz
==
NULL
){
printf
(
"find class error !"
);
return
0
;
}
jfieldID
id
=
env
->
GetStaticFieldID
(
clazz
,
fieldName
,
"Ljava/lang/Long;"
);
if
(
id
==
NULL
){
printf
(
"find field error !"
);
return
0
;
}
return
env
->
GetStaticLongField
(
clazz
,
id
);
}
#endif //SANDHOOK_UTILS_H
app/src/main/java/com/swift/sandhook/SandHook.java
View file @
13f17d10
...
...
@@ -13,11 +13,11 @@ public class SandHook {
public
static
Object
testOffsetArtMethod2
;
public
static
int
testAccessFlag
;
public
static
int
methodOffset
;
public
static
boolean
init
()
{
initTestOffset
();
SandHookMethodResolver
.
init
();
return
true
;
}
...
...
@@ -33,7 +33,6 @@ public class SandHook {
}
catch
(
NoSuchMethodException
e
)
{
throw
new
RuntimeException
(
"SandHook init error"
,
e
);
}
//
initTestAccessFlag
();
}
...
...
@@ -42,14 +41,12 @@ public class SandHook {
try
{
loadArtMethod
();
Field
fieldAccessFlags
=
getField
(
artMethodClass
,
"accessFlags"
);
fieldAccessFlags
.
setAccessible
(
true
);
testAccessFlag
=
(
int
)
fieldAccessFlags
.
get
(
testOffsetArtMethod1
);
}
catch
(
Exception
e
)
{
}
}
else
{
try
{
Field
fieldAccessFlags
=
getField
(
Method
.
class
,
"accessFlags"
);
fieldAccessFlags
.
setAccessible
(
true
);
testAccessFlag
=
(
int
)
fieldAccessFlags
.
get
(
testOffsetMethod1
);
}
catch
(
Exception
e
)
{
}
...
...
@@ -59,7 +56,6 @@ public class SandHook {
private
static
void
loadArtMethod
()
{
try
{
Field
fieldArtMethod
=
getField
(
Method
.
class
,
"artMethod"
);
fieldArtMethod
.
setAccessible
(
true
);
testOffsetArtMethod1
=
fieldArtMethod
.
get
(
testOffsetMethod1
);
testOffsetArtMethod2
=
fieldArtMethod
.
get
(
testOffsetMethod2
);
}
catch
(
IllegalAccessException
e
)
{
...
...
app/src/main/java/com/swift/sandhook/SandHookMethodResolver.java
View file @
13f17d10
...
...
@@ -3,6 +3,10 @@ package com.swift.sandhook;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
static
com
.
swift
.
sandhook
.
SandHook
.
artMethodClass
;
import
static
com
.
swift
.
sandhook
.
SandHook
.
getField
;
import
static
com
.
swift
.
sandhook
.
SandHook
.
hasJavaArtMethod
;
public
class
SandHookMethodResolver
{
public
static
Field
resolvedMethodsField
;
...
...
@@ -11,41 +15,67 @@ public class SandHookMethodResolver {
public
static
Field
artMethodField
;
public
static
boolean
canResolvedInJava
=
false
;
public
static
boolean
isArtMethod
=
false
;
public
static
long
resolvedMethodsAddress
=
0
;
public
static
int
dexMethodIndex
=
0
;
public
static
Method
testMethod
;
public
static
Object
testArtMethod
;
public
static
void
init
()
{
testMethod
=
SandHook
.
testOffsetMethod1
;
checkSupport
();
}
private
static
void
checkSupport
()
{
try
{
dexMethodIndexField
=
SandHook
.
getField
(
Method
.
class
,
"dexMethodIndex"
);
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
SandHook
.
testOffsetMethod1
);
dexCacheField
=
SandHook
.
getField
(
Class
.
class
,
"dexCache"
);
dexCacheField
.
setAccessible
(
true
);
Object
dexCache
=
dexCacheField
.
get
(
ArtMethodSizeTest
.
class
);
resolvedMethodsField
=
SandHook
.
getField
(
dexCache
.
getClass
(),
"resolvedMethods"
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
if
(
resolvedMethods
instanceof
Long
)
{
canResolvedInJava
=
false
;
resolvedMethodsAddress
=
(
long
)
resolvedMethods
;
}
else
if
(
resolvedMethods
instanceof
long
[])
{
canResolvedInJava
=
true
;
}
else
if
(
SandHook
.
hasJavaArtMethod
()
&&
resolvedMethods
instanceof
Object
[])
{
canResolvedInJava
=
true
;
artMethodField
=
getField
(
Method
.
class
,
"artMethod"
);
testArtMethod
=
artMethodField
.
get
(
testMethod
);
if
(
hasJavaArtMethod
()
&&
testArtMethod
.
getClass
()
==
artMethodClass
)
{
checkSupportForArtMethod
();
isArtMethod
=
true
;
}
else
if
(
testArtMethod
instanceof
Long
)
{
checkSupportForArtMethodId
();
isArtMethod
=
false
;
}
else
{
canResolvedInJava
=
false
;
}
if
(
canResolvedInJava
)
{
artMethodField
=
SandHook
.
getField
(
Method
.
class
,
"artMethod"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
// may 5.0
private
static
void
checkSupportForArtMethod
()
throws
Exception
{
dexMethodIndexField
=
getField
(
artMethodClass
,
"dexMethodIndex"
);
dexCacheField
=
getField
(
Class
.
class
,
"dexCache"
);
Object
dexCache
=
dexCacheField
.
get
(
testMethod
.
getDeclaringClass
());
resolvedMethodsField
=
getField
(
dexCache
.
getClass
(),
"resolvedMethods"
);
if
(
resolvedMethodsField
.
get
(
dexCache
)
instanceof
Object
[])
{
canResolvedInJava
=
true
;
}
}
// may 6.0
private
static
void
checkSupportForArtMethodId
()
throws
Exception
{
dexMethodIndexField
=
getField
(
Method
.
class
,
"dexMethodIndex"
);
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
testMethod
);
dexCacheField
=
getField
(
Class
.
class
,
"dexCache"
);
Object
dexCache
=
dexCacheField
.
get
(
testMethod
.
getDeclaringClass
());
resolvedMethodsField
=
getField
(
dexCache
.
getClass
(),
"resolvedMethods"
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
if
(
resolvedMethods
instanceof
Long
)
{
canResolvedInJava
=
false
;
resolvedMethodsAddress
=
(
long
)
resolvedMethods
;
}
else
if
(
resolvedMethods
instanceof
long
[])
{
canResolvedInJava
=
true
;
}
}
public
static
void
resolveMethod
(
Method
hook
,
Method
backup
)
{
if
(
canResolvedInJava
&&
artMethodField
!=
null
)
{
// in java
...
...
@@ -53,26 +83,31 @@ public class SandHookMethodResolver {
resolveInJava
(
hook
,
backup
);
}
catch
(
Exception
e
)
{
// in native
resolveInNative
(
hook
,
backup
);
}
}
else
{
// in native
resolveInNative
(
hook
,
backup
);
}
}
private
static
void
resolveInJava
(
Method
hook
,
Method
backup
)
throws
Exception
{
Object
dexCache
=
dexCacheField
.
get
(
hook
.
getDeclaringClass
());
int
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
backup
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
if
(
resolvedMethods
instanceof
long
[])
{
long
artMethod
=
(
long
)
artMethodField
.
get
(
backup
);
((
long
[])
resolvedMethods
)[
dexMethodIndex
]
=
artMethod
;
}
else
if
(
resolvedMethods
instanceof
Object
[])
{
if
(
isArtMethod
)
{
Object
artMethod
=
artMethodField
.
get
(
backup
);
int
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
artMethod
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
((
Object
[])
resolvedMethods
)[
dexMethodIndex
]
=
artMethod
;
}
else
{
throw
new
UnsupportedOperationException
(
"unsupport"
);
int
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
backup
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
long
artMethod
=
(
long
)
artMethodField
.
get
(
backup
);
((
long
[])
resolvedMethods
)[
dexMethodIndex
]
=
artMethod
;
}
}
private
static
void
resolveInNative
(
Method
hook
,
Method
backup
)
{
// HookMain.ensureMethodCached(hook, backup);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment