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
31b1326a
Commit
31b1326a
authored
Jan 23, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix
parent
da81d7bd
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
102 additions
and
6 deletions
+102
-6
native-lib.cpp
app/src/main/cpp/native-lib.cpp
+8
-1
MainActivity.java
app/src/main/java/com/swift/sandhook/MainActivity.java
+2
-1
SandHook.java
app/src/main/java/com/swift/sandhook/SandHook.java
+7
-1
CustmizeHooker.java
...src/main/java/com/swift/sandhook/test/CustmizeHooker.java
+6
-0
HookMethodBackup.java
...ain/java/com/swift/sandhook/wrapper/HookMethodBackup.java
+1
-1
HookWrapper.java
...src/main/java/com/swift/sandhook/wrapper/HookWrapper.java
+76
-0
MethodParams.java
...rc/main/java/com/swift/sandhook/wrapper/MethodParams.java
+1
-1
MethodReflectParams.java
.../java/com/swift/sandhook/wrapper/MethodReflectParams.java
+1
-1
No files found.
app/src/main/cpp/native-lib.cpp
View file @
31b1326a
...
...
@@ -32,6 +32,13 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
SandHook
::
CastArtMethod
::
accessFlag
->
set
(
method
,
accessFlag
);
}
void
setPrivate
(
art
::
mirror
::
ArtMethod
*
method
)
{
uint32_t
accessFlag
=
SandHook
::
CastArtMethod
::
accessFlag
->
get
(
method
);
accessFlag
&=
~
0x1
;
accessFlag
|=
0x2
;
SandHook
::
CastArtMethod
::
accessFlag
->
set
(
method
,
accessFlag
);
}
void
ensureMethodCached
(
art
::
mirror
::
ArtMethod
*
hookMethod
,
art
::
mirror
::
ArtMethod
*
backupMethod
)
{
if
(
SDK_INT
>=
ANDROID_P
)
return
;
...
...
@@ -120,7 +127,7 @@ bool doHookWithInline(JNIEnv* env,
if
(
SDK_INT
>=
ANDROID_O
)
{
disableInterpreterForO
(
backupMethod
);
}
//setPrivate(backupMethod);
hookTrampoline
->
callOrigin
->
flushCache
(
reinterpret_cast
<
Size
>
(
backupMethod
),
SandHook
::
CastArtMethod
::
size
);
}
return
true
;
...
...
app/src/main/java/com/swift/sandhook/MainActivity.java
View file @
31b1326a
...
...
@@ -10,6 +10,7 @@ import android.support.v7.widget.Toolbar;
import
android.view.View
;
import
android.view.Menu
;
import
android.view.MenuItem
;
import
android.widget.Toast
;
import
com.swift.sandhook.wrapper.HookErrorException
;
import
com.swift.sandhook.wrapper.HookWrapper
;
...
...
@@ -76,7 +77,7 @@ public class MainActivity extends AppCompatActivity {
public
static
int
methodBeHooked
(
int
a
,
int
b
)
{
a
=
a
+
1
+
2
;
b
=
b
+
a
+
3
;
Log
.
e
(
"MainActivity"
,
"methodBeHooked called"
);
//Toast.makeText(MyApp.context, "call origin!", Toast.LENGTH_SHORT).show(
);
return
a
+
b
;
}
...
...
app/src/main/java/com/swift/sandhook/SandHook.java
View file @
31b1326a
...
...
@@ -59,15 +59,21 @@ public class SandHook {
if
(
target
instanceof
Method
)
{
((
Method
)
target
).
setAccessible
(
true
);
}
return
hookMethod
(
target
,
hook
,
backup
);
boolean
res
=
hookMethod
(
target
,
hook
,
backup
);
if
(
res
&&
backup
!=
null
)
{
backup
.
setAccessible
(
true
);
}
return
res
;
}
private
static
void
resolveStaticMethod
(
Member
method
)
{
//ignore result, just call to trigger resolve
try
{
if
(
method
instanceof
Method
)
{
((
Method
)
method
).
setAccessible
(
true
);
((
Method
)
method
).
invoke
(
null
);
}
else
if
(
method
instanceof
Constructor
){
((
Constructor
)
method
).
setAccessible
(
true
);
((
Constructor
)
method
).
newInstance
(
null
);
}
}
catch
(
Exception
e
)
{
...
...
app/src/main/java/com/swift/sandhook/test/CustmizeHooker.java
View file @
31b1326a
...
...
@@ -8,9 +8,15 @@ import com.swift.sandhook.wrapper.HookMethod;
import
com.swift.sandhook.wrapper.HookMethodBackup
;
import
com.swift.sandhook.wrapper.MethodParams
;
import
java.lang.reflect.Method
;
@HookClass
(
MainActivity
.
class
)
public
class
CustmizeHooker
{
@HookMethodBackup
(
"methodBeHooked"
)
@MethodParams
({
int
.
class
,
int
.
class
})
static
Method
backup
;
@HookMethod
(
"methodBeHooked"
)
@MethodParams
({
int
.
class
,
int
.
class
})
public
static
int
staticMethodHooked
(
int
a
,
int
b
)
{
...
...
app/src/main/java/com/swift/sandhook/wrapper/HookMethodBackup.java
View file @
31b1326a
...
...
@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Target
({
ElementType
.
METHOD
})
@Target
({
ElementType
.
METHOD
,
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
HookMethodBackup
{
String
value
()
default
"<init>"
;
...
...
app/src/main/java/com/swift/sandhook/wrapper/HookWrapper.java
View file @
31b1326a
package
com
.
swift
.
sandhook
.
wrapper
;
import
android.text.TextUtils
;
import
com.swift.sandhook.SandHook
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
...
...
@@ -25,6 +28,7 @@ public class HookWrapper {
if
(
targetHookClass
==
null
)
throw
new
HookErrorException
(
"error hook wrapper class :"
+
clazz
.
getName
());
Map
<
Member
,
HookEntity
>
hookEntityMap
=
getHookMethods
(
targetHookClass
,
clazz
);
fillBackupMethod
(
clazz
,
hookEntityMap
);
for
(
HookEntity
entity:
hookEntityMap
.
values
())
{
if
(
entity
.
target
!=
null
&&
entity
.
hook
!=
null
)
{
SandHook
.
hook
(
entity
.
target
,
entity
.
hook
,
entity
.
backup
);
...
...
@@ -33,6 +37,33 @@ public class HookWrapper {
}
}
private
static
void
fillBackupMethod
(
Class
<?>
clazz
,
Map
<
Member
,
HookEntity
>
hookEntityMap
)
{
Field
[]
fields
=
clazz
.
getDeclaredFields
();
if
(
fields
==
null
||
fields
.
length
==
0
)
return
;
if
(
hookEntityMap
.
isEmpty
())
return
;
for
(
Field
field:
fields
)
{
if
(!
field
.
getType
().
equals
(
Method
.
class
))
continue
;
if
(!
Modifier
.
isStatic
(
field
.
getModifiers
()))
continue
;
HookMethodBackup
hookMethodBackup
=
field
.
getAnnotation
(
HookMethodBackup
.
class
);
if
(
hookMethodBackup
==
null
)
continue
;
for
(
HookEntity
hookEntity:
hookEntityMap
.
values
())
{
if
(
TextUtils
.
equals
(
hookEntity
.
target
.
getName
(),
hookMethodBackup
.
value
())
&&
hookEntity
.
backup
!=
null
&&
samePars
(
field
,
hookEntity
.
pars
))
{
field
.
setAccessible
(
true
);
try
{
field
.
set
(
null
,
hookEntity
.
backup
);
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
}
}
}
}
private
static
Map
<
Member
,
HookEntity
>
getHookMethods
(
Class
targetHookClass
,
Class
<?>
hookWrapperClass
)
throws
HookErrorException
{
Map
<
Member
,
HookEntity
>
hookEntityMap
=
new
HashMap
<>();
Method
[]
methods
=
hookWrapperClass
.
getDeclaredMethods
();
...
...
@@ -81,6 +112,7 @@ public class HookWrapper {
entity
=
new
HookEntity
(
foundMethod
);
hookEntityMap
.
put
(
foundMethod
,
entity
);
}
entity
.
pars
=
pars
;
entity
.
backup
=
method
;
}
else
{
continue
;
...
...
@@ -111,6 +143,48 @@ public class HookWrapper {
}
}
private
static
Class
[]
parseMethodPars
(
Field
field
)
throws
HookErrorException
{
MethodParams
methodParams
=
field
.
getAnnotation
(
MethodParams
.
class
);
MethodReflectParams
methodReflectParams
=
field
.
getAnnotation
(
MethodReflectParams
.
class
);
if
(
methodParams
!=
null
)
{
return
methodParams
.
value
();
}
else
if
(
methodReflectParams
!=
null
)
{
if
(
methodReflectParams
.
value
().
length
==
0
)
return
null
;
Class
[]
pars
=
new
Class
[
methodReflectParams
.
value
().
length
];
for
(
int
i
=
0
;
i
<
methodReflectParams
.
value
().
length
;
i
++)
{
try
{
pars
[
i
]
=
Class
.
forName
(
methodReflectParams
.
value
()[
i
]);
}
catch
(
ClassNotFoundException
e
)
{
throw
new
HookErrorException
(
"hook method pars error: "
+
field
.
getName
(),
e
);
}
}
return
pars
;
}
else
{
return
null
;
}
}
private
static
boolean
samePars
(
Field
field
,
Class
[]
par
)
{
try
{
Class
[]
parsOnField
=
parseMethodPars
(
field
);
if
(
par
==
null
)
par
=
new
Class
[
0
];
if
(
parsOnField
==
null
)
parsOnField
=
new
Class
[
0
];
if
(
par
.
length
!=
parsOnField
.
length
)
return
false
;
for
(
int
i
=
0
;
i
<
par
.
length
;
i
++)
{
if
(
par
[
i
]
!=
parsOnField
[
i
])
return
false
;
}
return
true
;
}
catch
(
HookErrorException
e
)
{
return
false
;
}
}
...
...
@@ -173,6 +247,8 @@ public class HookWrapper {
public
Method
hook
;
public
Method
backup
;
public
Class
[]
pars
;
public
HookEntity
(
Member
target
)
{
this
.
target
=
target
;
}
...
...
app/src/main/java/com/swift/sandhook/wrapper/MethodParams.java
View file @
31b1326a
...
...
@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Target
({
ElementType
.
METHOD
})
@Target
({
ElementType
.
METHOD
,
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodParams
{
Class
<?>[]
value
();
...
...
app/src/main/java/com/swift/sandhook/wrapper/MethodReflectParams.java
View file @
31b1326a
...
...
@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Target
({
ElementType
.
METHOD
})
@Target
({
ElementType
.
METHOD
,
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodReflectParams
{
String
[]
value
();
...
...
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