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
3b15f9e6
Commit
3b15f9e6
authored
Feb 20, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
done stub manager
parent
ff09c694
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
282 additions
and
28 deletions
+282
-28
SandHook.java
hooklib/src/main/java/com/swift/sandhook/SandHook.java
+1
-1
HookMethodEntity.java
...wift/sandhook/xposedcompat/hookstub/HookMethodEntity.java
+77
-0
HookMethodInfo.java
.../swift/sandhook/xposedcompat/hookstub/HookMethodInfo.java
+0
-19
HookStubManager.java
...swift/sandhook/xposedcompat/hookstub/HookStubManager.java
+198
-5
MethodHookerStubs32.java
...t/sandhook/xposedcompat/hookstub/MethodHookerStubs32.java
+1
-3
MethodHookerStubs64.java
...t/sandhook/xposedcompat/hookstub/MethodHookerStubs64.java
+5
-0
No files found.
hooklib/src/main/java/com/swift/sandhook/SandHook.java
View file @
3b15f9e6
...
...
@@ -199,7 +199,7 @@ public class SandHook {
public
static
Object
getObject
(
long
address
)
{
long
threadSelf
=
getThreadId
();
if
(
threadSelf
==
0
)
if
(
address
==
0
||
threadSelf
==
0
)
return
null
;
return
getObjectNative
(
threadSelf
,
address
);
}
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookMethodEntity.java
0 → 100644
View file @
3b15f9e6
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
import
com.swift.sandhook.utils.ParamWrapper
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
public
class
HookMethodEntity
{
public
Member
origin
;
public
Method
hook
;
public
Member
bacup
;
public
Class
[]
parType
;
public
Class
retType
;
public
HookMethodEntity
(
Member
origin
,
Method
hook
,
Member
bacup
)
{
this
.
origin
=
origin
;
this
.
hook
=
hook
;
this
.
bacup
=
bacup
;
}
public
Object
[]
getArgs
(
long
...
addresses
)
{
if
(
addresses
==
null
||
addresses
.
length
==
0
)
return
new
Object
[
0
];
if
(
parType
==
null
||
parType
.
length
==
0
)
return
new
Object
[
0
];
int
argStart
=
0
;
if
(!
isStatic
())
{
argStart
=
1
;
}
Object
[]
args
=
new
Object
[
parType
.
length
];
for
(
int
i
=
argStart
;
i
<
addresses
.
length
;
i
++)
{
args
[
i
-
argStart
]
=
getArg
(
i
-
argStart
,
addresses
[
i
]);
}
return
args
;
}
public
long
[]
getArgsAddress
(
long
[]
oldAddress
,
Object
...
args
)
{
if
(
oldAddress
==
null
||
oldAddress
.
length
==
0
)
return
new
long
[
0
];
long
[]
addresses
=
new
long
[
oldAddress
.
length
];
int
argStart
=
0
;
if
(!
isStatic
())
{
argStart
=
1
;
addresses
[
0
]
=
oldAddress
[
0
];
}
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
addresses
[
i
+
argStart
]
=
ParamWrapper
.
objectToAddress
(
args
[
i
]);
}
return
addresses
;
}
public
Object
getThis
(
long
address
)
{
if
(
isStatic
())
return
null
;
return
getArg
(
0
,
address
);
}
public
Object
getArg
(
int
index
,
long
address
)
{
return
ParamWrapper
.
addressToObject
(
parType
[
index
],
address
);
}
public
boolean
isVoid
()
{
return
retType
==
null
||
Void
.
TYPE
.
equals
(
retType
);
}
public
boolean
isConstructor
()
{
return
origin
instanceof
Constructor
;
}
public
boolean
isStatic
()
{
return
Modifier
.
isStatic
(
origin
.
getModifiers
());
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookMethodInfo.java
deleted
100644 → 0
View file @
ff09c694
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
import
com.swift.sandhook.utils.ParamWrapper
;
public
class
HookMethodInfo
{
public
Class
[]
parType
;
public
Class
retType
;
public
Object
getArg
(
int
index
,
long
address
)
{
return
ParamWrapper
.
addressToObject
(
parType
[
index
],
address
);
}
public
boolean
isVoid
()
{
return
Void
.
TYPE
.
equals
(
retType
);
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java
View file @
3b15f9e6
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
import
android.util.Pair
;
import
com.swift.sandhook.SandHook
;
import
com.swift.sandhook.utils.ParamWrapper
;
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
;
import
de.robv.android.xposed.XC_MethodHook
;
import
de.robv.android.xposed.XposedBridge
;
public
class
HookStubManager
{
public
final
static
int
MAX_STUB_COUNT
=
100
;
public
final
static
int
MAX_STUB_ARGS
=
4
;
public
final
static
int
MAX_PER_STUB
=
5
;
public
final
static
int
MAX_STUB_COUNT
=
MAX_PER_STUB
*
(
MAX_STUB_ARGS
+
1
);
public
final
static
AtomicInteger
[]
curUseStubIndexes
=
new
AtomicInteger
[
MAX_STUB_ARGS
+
1
];
public
static
Member
[]
originMethods
=
new
Member
[
MAX_STUB_COUNT
];
public
static
HookMethodEntity
[]
hookMethodEntities
=
new
HookMethodEntity
[
MAX_STUB_COUNT
];
private
static
final
Map
<
Member
,
XposedBridge
.
CopyOnWriteSortedSet
<
XC_MethodHook
>>
hookCallbacks
=
new
HashMap
<>();
static
{
for
(
int
i
=
0
;
i
<
curUseStubIndexes
.
length
;
i
++)
{
curUseStubIndexes
[
i
]
=
new
AtomicInteger
(
0
);
}
}
public
static
HookMethodEntity
getHookMethodEntity
(
Member
origin
)
{
Class
[]
parType
;
Class
retType
;
boolean
isStatic
=
Modifier
.
isStatic
(
origin
.
getModifiers
());
if
(
origin
instanceof
Method
)
{
Method
method
=
(
Method
)
origin
;
retType
=
method
.
getReturnType
();
parType
=
method
.
getParameterTypes
();
}
else
if
(
origin
instanceof
Constructor
)
{
Constructor
constructor
=
(
Constructor
)
origin
;
retType
=
Void
.
TYPE
;
parType
=
constructor
.
getParameterTypes
();
}
else
{
return
null
;
}
if
(!
ParamWrapper
.
support
(
retType
))
return
null
;
int
needStubArgCount
=
isStatic
?
0
:
1
;
if
(
parType
!=
null
)
{
needStubArgCount
+=
parType
.
length
;
if
(
needStubArgCount
>
MAX_STUB_ARGS
)
return
null
;
for
(
Class
par:
parType
)
{
if
(!
ParamWrapper
.
support
(
par
))
return
null
;
}
}
synchronized
(
HookStubManager
.
class
)
{
Pair
<
Method
,
Method
>
methodPair
=
getStubMethodPair
(
SandHook
.
is64Bit
(),
needStubArgCount
);
if
(
methodPair
==
null
)
return
null
;
HookMethodEntity
entity
=
new
HookMethodEntity
(
origin
,
methodPair
.
first
,
methodPair
.
second
);
entity
.
retType
=
retType
;
entity
.
parType
=
parType
;
return
entity
;
}
}
public
static
int
getMethodId
(
int
args
,
int
index
)
{
return
args
*
MAX_PER_STUB
+
index
;
}
public
static
String
getHookMethodName
(
int
index
)
{
return
"stub_hook_"
+
index
;
}
public
static
String
get
b
ackupMethodName
(
int
index
)
{
public
static
String
get
B
ackupMethodName
(
int
index
)
{
return
"stub_backup_"
+
index
;
}
public
static
Object
hookBridge
(
int
index
,
CallOriginCallBack
callOrigin
,
long
...
stubArgs
)
throws
Throwable
{
Member
originMethod
=
originMethods
[
index
];
return
null
;
private
static
synchronized
Pair
<
Method
,
Method
>
getStubMethodPair
(
boolean
is64Bit
,
int
stubArgs
)
{
int
curUseStubIndex
=
curUseStubIndexes
[
stubArgs
].
getAndIncrement
();
if
(
curUseStubIndex
>=
MAX_PER_STUB
)
return
null
;
Class
[]
pars
=
getFindMethodParTypes
(
is64Bit
,
stubArgs
);
try
{
if
(
is64Bit
)
{
Method
hook
=
MethodHookerStubs64
.
class
.
getDeclaredMethod
(
getHookMethodName
(
curUseStubIndex
),
pars
);
Method
backup
=
MethodHookerStubs64
.
class
.
getDeclaredMethod
(
getBackupMethodName
(
curUseStubIndex
),
pars
);
if
(
hook
==
null
||
backup
==
null
)
return
null
;
return
new
Pair
<>(
hook
,
backup
);
}
else
{
Method
hook
=
MethodHookerStubs32
.
class
.
getDeclaredMethod
(
getHookMethodName
(
curUseStubIndex
),
pars
);
Method
backup
=
MethodHookerStubs32
.
class
.
getDeclaredMethod
(
getBackupMethodName
(
curUseStubIndex
),
pars
);
if
(
hook
==
null
||
backup
==
null
)
return
null
;
return
new
Pair
<>(
hook
,
backup
);
}
}
catch
(
Exception
e
)
{
return
null
;
}
}
public
static
Class
[]
getFindMethodParTypes
(
boolean
is64Bit
,
int
stubArgs
)
{
if
(
stubArgs
==
0
)
return
null
;
Class
[]
args
=
new
Class
[
stubArgs
];
if
(
is64Bit
)
{
for
(
int
i
=
0
;
i
<
stubArgs
;
i
++)
{
args
[
i
]
=
long
.
class
;
}
}
else
{
for
(
int
i
=
0
;
i
<
stubArgs
;
i
++)
{
args
[
i
]
=
int
.
class
;
}
}
return
args
;
}
public
static
Object
hookBridge
(
int
id
,
CallOriginCallBack
callOrigin
,
long
...
stubArgs
)
throws
Throwable
{
if
(
XposedBridge
.
disableHooks
)
return
callOrigin
.
call
(
stubArgs
);
Member
originMethod
=
originMethods
[
id
];
HookMethodEntity
entity
=
hookMethodEntities
[
id
];
Object
[]
snapshot
=
hookCallbacks
.
get
(
originMethod
).
getSnapshot
();
if
(
snapshot
==
null
||
snapshot
.
length
==
0
)
return
callOrigin
.
call
(
stubArgs
);
XC_MethodHook
.
MethodHookParam
param
=
new
XC_MethodHook
.
MethodHookParam
();
param
.
method
=
originMethod
;
if
(
hasArgs
(
stubArgs
))
{
param
.
thisObject
=
entity
.
getThis
(
stubArgs
[
0
]);
param
.
args
=
entity
.
getArgs
(
stubArgs
);
}
int
beforeIdx
=
0
;
do
{
try
{
((
XC_MethodHook
)
snapshot
[
beforeIdx
]).
callBeforeHookedMethod
(
param
);
}
catch
(
Throwable
t
)
{
// reset result (ignoring what the unexpectedly exiting callback did)
param
.
setResult
(
null
);
param
.
returnEarly
=
false
;
continue
;
}
if
(
param
.
returnEarly
)
{
// skip remaining "before" callbacks and corresponding "after" callbacks
beforeIdx
++;
break
;
}
}
while
(++
beforeIdx
<
snapshot
.
length
);
// call original method if not requested otherwise
if
(!
param
.
returnEarly
)
{
try
{
//prepare new args
long
[]
newArgs
=
entity
.
getArgsAddress
(
stubArgs
,
param
.
args
);
param
.
setResult
(
callOrigin
.
call
(
newArgs
));
}
catch
(
Exception
e
)
{
XposedBridge
.
log
(
e
);
param
.
setThrowable
(
e
);
}
}
// call "after method" callbacks
int
afterIdx
=
beforeIdx
-
1
;
do
{
Object
lastResult
=
param
.
getResult
();
Throwable
lastThrowable
=
param
.
getThrowable
();
try
{
((
XC_MethodHook
)
snapshot
[
afterIdx
]).
callAfterHookedMethod
(
param
);
}
catch
(
Throwable
t
)
{
XposedBridge
.
log
(
t
);
if
(
lastThrowable
==
null
)
param
.
setResult
(
lastResult
);
else
param
.
setThrowable
(
lastThrowable
);
}
}
while
(--
afterIdx
>=
0
);
if
(
param
.
hasThrowable
())
{
return
param
.
getResult
();
}
else
{
final
Object
result
=
param
.
getResult
();
return
result
;
}
}
private
static
boolean
hasArgs
(
long
...
args
)
{
return
args
!=
null
&&
args
.
length
>
0
;
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/MethodHookerStubs.java
→
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/MethodHookerStubs
32
.java
View file @
3b15f9e6
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
public
class
MethodHookerStubs
{
public
class
MethodHookerStubs32
{
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/hookstub/MethodHookerStubs64.java
0 → 100644
View file @
3b15f9e6
package
com
.
swift
.
sandhook
.
xposedcompat
.
hookstub
;
public
class
MethodHookerStubs64
{
}
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