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
60fd35cd
Commit
60fd35cd
authored
Feb 21, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix param parser
parent
f65fd71c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
54 additions
and
59 deletions
+54
-59
SandHook.java
hooklib/src/main/java/com/swift/sandhook/SandHook.java
+4
-0
ParamWrapper.java
.../src/main/java/com/swift/sandhook/utils/ParamWrapper.java
+4
-4
Unsafe.java
hooklib/src/main/java/com/swift/sandhook/utils/Unsafe.java
+26
-40
HookStubManager.java
...swift/sandhook/xposedcompat/hookstub/HookStubManager.java
+8
-3
DynamicBridge.java
.../swift/sandhook/xposedcompat/methodgen/DynamicBridge.java
+10
-10
XposedBridge.java
...at/src/main/java/de/robv/android/xposed/XposedBridge.java
+2
-2
No files found.
hooklib/src/main/java/com/swift/sandhook/SandHook.java
View file @
60fd35cd
...
...
@@ -204,6 +204,10 @@ public class SandHook {
return
getObjectNative
(
threadSelf
,
address
);
}
public
static
boolean
canGetObjectAddress
()
{
return
Unsafe
.
support
();
}
public
static
long
getObjectAddress
(
Object
object
)
{
return
Unsafe
.
getObjectAddress
(
object
);
}
...
...
hooklib/src/main/java/com/swift/sandhook/utils/ParamWrapper.java
View file @
60fd35cd
...
...
@@ -35,7 +35,7 @@ public class ParamWrapper {
}
else
if
(
objectType
==
char
.
class
)
{
return
(
char
)
address
;
}
else
if
(
objectType
==
boolean
.
class
)
{
return
address
=
=
0
;
return
address
!
=
0
;
}
else
{
throw
new
RuntimeException
(
"unknown type: "
+
objectType
.
toString
());
}
...
...
@@ -57,7 +57,7 @@ public class ParamWrapper {
}
else
if
(
objectType
==
char
.
class
)
{
return
(
char
)
address
;
}
else
if
(
objectType
==
boolean
.
class
)
{
return
address
=
=
0
;
return
address
!
=
0
;
}
else
{
throw
new
RuntimeException
(
"unknown type: "
+
objectType
.
toString
());
}
...
...
@@ -87,7 +87,7 @@ public class ParamWrapper {
}
else
if
(
objectType
==
char
.
class
)
{
return
(
char
)
object
;
}
else
if
(
objectType
==
boolean
.
class
)
{
return
object
==
Boolean
.
TRUE
?
0
:
1
;
return
object
==
Boolean
.
TRUE
?
1
:
0
;
}
else
{
throw
new
RuntimeException
(
"unknown type: "
+
objectType
.
toString
());
}
...
...
@@ -111,7 +111,7 @@ public class ParamWrapper {
}
else
if
(
objectType
==
char
.
class
)
{
return
(
char
)
object
;
}
else
if
(
objectType
==
boolean
.
class
)
{
return
object
==
Boolean
.
TRUE
?
0
:
1
;
return
object
==
Boolean
.
TRUE
?
1
:
0
;
}
else
{
throw
new
RuntimeException
(
"unknown type: "
+
objectType
.
toString
());
}
...
...
hooklib/src/main/java/com/swift/sandhook/utils/Unsafe.java
View file @
60fd35cd
...
...
@@ -19,6 +19,7 @@ package com.swift.sandhook.utils;
import
android.util.Log
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
public
final
class
Unsafe
{
private
static
final
String
TAG
=
"Unsafe"
;
...
...
@@ -26,6 +27,13 @@ public final class Unsafe {
private
static
Object
unsafe
;
private
static
Class
unsafeClass
;
private
static
Method
arrayBaseOffsetMethod
,
arrayIndexScaleMethod
,
getIntMethod
,
getLongMethod
;
private
volatile
static
boolean
supported
=
false
;
static
{
try
{
unsafeClass
=
Class
.
forName
(
"sun.misc.Unsafe"
);
...
...
@@ -41,6 +49,20 @@ public final class Unsafe {
Log
.
w
(
TAG
,
"Unsafe not found o.O"
);
}
}
if
(
unsafe
!=
null
)
{
try
{
arrayBaseOffsetMethod
=
unsafeClass
.
getDeclaredMethod
(
"arrayBaseOffset"
,
Class
.
class
);
arrayIndexScaleMethod
=
unsafeClass
.
getDeclaredMethod
(
"arrayIndexScale"
,
Class
.
class
);
getIntMethod
=
unsafeClass
.
getDeclaredMethod
(
"getInt"
,
Object
.
class
,
long
.
class
);
getLongMethod
=
unsafeClass
.
getDeclaredMethod
(
"getLong"
,
Object
.
class
,
long
.
class
);
supported
=
true
;
}
catch
(
Exception
e
)
{
}
}
}
public
static
boolean
support
()
{
return
supported
;
}
private
Unsafe
()
{
...
...
@@ -49,7 +71,7 @@ public final class Unsafe {
@SuppressWarnings
(
"unchecked"
)
public
static
int
arrayBaseOffset
(
Class
cls
)
{
try
{
return
(
int
)
unsafeClass
.
getDeclaredMethod
(
"arrayBaseOffset"
,
Class
.
class
)
.
invoke
(
unsafe
,
cls
);
return
(
int
)
arrayBaseOffsetMethod
.
invoke
(
unsafe
,
cls
);
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
e
);
return
0
;
...
...
@@ -59,17 +81,7 @@ public final class Unsafe {
@SuppressWarnings
(
"unchecked"
)
public
static
int
arrayIndexScale
(
Class
cls
)
{
try
{
return
(
int
)
unsafeClass
.
getDeclaredMethod
(
"arrayIndexScale"
,
Class
.
class
).
invoke
(
unsafe
,
cls
);
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
e
);
return
0
;
}
}
@SuppressWarnings
(
"unchecked"
)
public
static
long
objectFieldOffset
(
Field
field
)
{
try
{
return
(
long
)
unsafeClass
.
getDeclaredMethod
(
"objectFieldOffset"
,
Field
.
class
).
invoke
(
unsafe
,
field
);
return
(
int
)
arrayIndexScaleMethod
.
invoke
(
unsafe
,
cls
);
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
e
);
return
0
;
...
...
@@ -79,7 +91,7 @@ public final class Unsafe {
@SuppressWarnings
(
"unchecked"
)
public
static
int
getInt
(
Object
array
,
long
offset
)
{
try
{
return
(
int
)
unsafeClass
.
getDeclaredMethod
(
"getInt"
,
Object
.
class
,
long
.
class
)
.
invoke
(
unsafe
,
array
,
offset
);
return
(
int
)
getIntMethod
.
invoke
(
unsafe
,
array
,
offset
);
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
e
);
return
0
;
...
...
@@ -89,39 +101,13 @@ public final class Unsafe {
@SuppressWarnings
(
"unchecked"
)
public
static
long
getLong
(
Object
array
,
long
offset
)
{
try
{
return
(
long
)
unsafeClass
.
getDeclaredMethod
(
"getLong"
,
Object
.
class
,
long
.
class
)
.
invoke
(
unsafe
,
array
,
offset
);
return
(
long
)
getLongMethod
.
invoke
(
unsafe
,
array
,
offset
);
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
e
);
return
0
;
}
}
@SuppressWarnings
(
"unchecked"
)
public
static
void
putLong
(
Object
array
,
long
offset
,
long
value
)
{
try
{
unsafeClass
.
getDeclaredMethod
(
"putLongVolatile"
,
Object
.
class
,
long
.
class
,
long
.
class
).
invoke
(
unsafe
,
array
,
offset
,
value
);
}
catch
(
Exception
e
)
{
try
{
unsafeClass
.
getDeclaredMethod
(
"putLong"
,
Object
.
class
,
long
.
class
,
long
.
class
).
invoke
(
unsafe
,
array
,
offset
,
value
);
}
catch
(
Exception
e1
)
{
Log
.
w
(
TAG
,
e
);
}
}
}
@SuppressWarnings
(
"unchecked"
)
public
static
void
putInt
(
Object
array
,
long
offset
,
int
value
)
{
try
{
unsafeClass
.
getDeclaredMethod
(
"putIntVolatile"
,
Object
.
class
,
long
.
class
,
int
.
class
).
invoke
(
unsafe
,
array
,
offset
,
value
);
}
catch
(
Exception
e
)
{
try
{
unsafeClass
.
getDeclaredMethod
(
"putIntVolatile"
,
Object
.
class
,
long
.
class
,
int
.
class
).
invoke
(
unsafe
,
array
,
offset
,
value
);
}
catch
(
Exception
e1
)
{
Log
.
w
(
TAG
,
e
);
}
}
}
public
static
long
getObjectAddress
(
Object
obj
)
{
try
{
Object
[]
array
=
new
Object
[]{
obj
};
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java
View file @
60fd35cd
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
import
android.util.Pair
;
import
com.swift.sandhook.SandHook
;
import
com.swift.sandhook.utils.ParamWrapper
;
...
...
@@ -9,7 +7,6 @@ import java.lang.reflect.Constructor;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicInteger
;
...
...
@@ -49,6 +46,10 @@ public class HookStubManager {
public
static
HookMethodEntity
getHookMethodEntity
(
Member
origin
)
{
if
(!
support
())
{
return
null
;
}
Class
[]
parType
;
Class
retType
;
boolean
isStatic
=
Modifier
.
isStatic
(
origin
.
getModifiers
());
...
...
@@ -284,4 +285,8 @@ public class HookStubManager {
return
args
!=
null
&&
args
.
length
>
0
;
}
public
static
boolean
support
()
{
return
SandHook
.
canGetObject
()
&&
SandHook
.
canGetObjectAddress
();
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java
View file @
60fd35cd
...
...
@@ -12,11 +12,11 @@ import com.swift.sandhook.xposedcompat.utils.FileUtils;
import
java.io.File
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
de.robv.android.xposed.XposedBridge
;
...
...
@@ -28,6 +28,8 @@ public final class DynamicBridge {
private
static
final
AtomicBoolean
dexPathInited
=
new
AtomicBoolean
(
false
);
private
static
File
dexDir
;
public
static
Map
<
Member
,
HookMethodEntity
>
entityMap
=
new
HashMap
<>();
public
static
void
onForkPost
()
{
dexPathInited
.
set
(
false
);
}
...
...
@@ -38,17 +40,13 @@ public final class DynamicBridge {
return
;
}
if
(
hookedInfo
.
containsKey
(
hookMethod
))
{
if
(
hookedInfo
.
containsKey
(
hookMethod
)
||
entityMap
.
containsKey
(
hookMethod
)
)
{
DexLog
.
w
(
"already hook method:"
+
hookMethod
.
toString
());
return
;
}
DexLog
.
d
(
"start to generate class for: "
+
hookMethod
);
try
{
// using file based DexClassLoader
if
(
dexPathInited
.
compareAndSet
(
false
,
true
))
{
// delete previous compiled dex to prevent potential crashing
// TODO find a way to reuse them in consideration of performance
try
{
String
fixedAppDataDir
=
XposedCompat
.
cacheDir
.
getAbsolutePath
();
dexDir
=
new
File
(
fixedAppDataDir
,
"/sandxposed/"
);
...
...
@@ -63,15 +61,16 @@ public final class DynamicBridge {
HookMethodEntity
stub
=
HookStubManager
.
getHookMethodEntity
(
hookMethod
);
if
(
stub
!=
null
)
{
SandHook
.
hook
(
new
HookWrapper
.
HookEntity
(
hookMethod
,
stub
.
hook
,
stub
.
backup
));
entityMap
.
put
(
hookMethod
,
stub
);
}
else
{
dexMaker
.
start
(
hookMethod
,
additionalHookInfo
,
XposedCompat
.
classLoader
,
dexDir
==
null
?
null
:
dexDir
.
getAbsolutePath
());
hookedInfo
.
put
(
hookMethod
,
dexMaker
.
getCallBackupMethod
());
}
DexLog
.
d
(
"hook method <"
+
hookMethod
.
toString
()
+
">
use "
+
(
System
.
currentTimeMillis
()
-
timeStart
)
+
" ms."
);
DexLog
.
d
(
"hook method <"
+
hookMethod
.
toString
()
+
">
cost "
+
(
System
.
currentTimeMillis
()
-
timeStart
)
+
" ms, by "
+
(
stub
!=
null
?
"internal stub."
:
"dex maker"
)
);
Trace
.
endSection
();
}
catch
(
Exception
e
)
{
DexLog
.
e
(
"error occur when
generating dex. dexDir="
+
dexDir
,
e
);
DexLog
.
e
(
"error occur when
hook method <"
+
hookMethod
.
toString
()
+
">"
,
e
);
}
}
...
...
@@ -106,10 +105,11 @@ public final class DynamicBridge {
}
public
static
Object
invokeOriginalMethod
(
Member
method
,
Object
thisObject
,
Object
[]
args
)
throws
InvocationTargetException
,
IllegalAccessException
{
throws
Throwable
{
Method
callBackup
=
hookedInfo
.
get
(
method
);
if
(
callBackup
==
null
)
{
throw
new
IllegalStateException
(
"method not hooked, cannot call original method."
);
//method hook use internal stub
return
SandHook
.
callOriginMethod
(
method
,
thisObject
,
args
);
}
if
(!
Modifier
.
isStatic
(
callBackup
.
getModifiers
()))
{
throw
new
IllegalStateException
(
"original method is not static, something must be wrong!"
);
...
...
xposedcompat/src/main/java/de/robv/android/xposed/XposedBridge.java
View file @
60fd35cd
...
...
@@ -391,7 +391,7 @@ public final class XposedBridge {
Class
<?>[]
parameterTypes
,
Class
<?>
returnType
,
Object
thisObject
,
Object
[]
args
)
throws
IllegalAccessException
,
IllegalArgumentException
,
InvocationTargetException
{
throws
Throwable
{
return
DynamicBridge
.
invokeOriginalMethod
(
method
,
thisObject
,
args
);
}
...
...
@@ -421,7 +421,7 @@ public final class XposedBridge {
* if an exception was thrown by the invoked method
*/
public
static
Object
invokeOriginalMethod
(
Member
method
,
Object
thisObject
,
Object
[]
args
)
throws
NullPointerException
,
IllegalAccessException
,
IllegalArgumentException
,
InvocationTargetException
{
throws
Throwable
{
if
(
args
==
null
)
{
args
=
EMPTY_ARRAY
;
}
...
...
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