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
786ed74f
Commit
786ed74f
authored
Feb 14, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tweak xposed loadModule
parent
87f376ea
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
540 additions
and
315 deletions
+540
-315
XposedCompat.java
...in/java/com/swift/sandhook/xposedcompat/XposedCompat.java
+66
-1
ComposeClassLoader.java
...andhook/xposedcompat/classloaders/ComposeClassLoader.java
+34
-0
XposedClassLoader.java
...sandhook/xposedcompat/classloaders/XposedClassLoader.java
+21
-0
DynamicBridge.java
.../swift/sandhook/xposedcompat/methodgen/DynamicBridge.java
+2
-0
HookerDexMaker.java
...swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java
+5
-5
ProcessUtils.java
...m/swift/sandhook/xposedcompat/methodgen/ProcessUtils.java
+0
-82
ApplicationUtils.java
...m/swift/sandhook/xposedcompat/utils/ApplicationUtils.java
+34
-0
ClassLoaderUtils.java
...m/swift/sandhook/xposedcompat/utils/ClassLoaderUtils.java
+106
-0
DexLog.java
...in/java/com/swift/sandhook/xposedcompat/utils/DexLog.java
+1
-1
DexMakerUtils.java
.../com/swift/sandhook/xposedcompat/utils/DexMakerUtils.java
+1
-1
DexUtils.java
.../java/com/swift/sandhook/xposedcompat/utils/DexUtils.java
+66
-0
FileUtils.java
...java/com/swift/sandhook/xposedcompat/utils/FileUtils.java
+1
-1
ProcessUtils.java
...a/com/swift/sandhook/xposedcompat/utils/ProcessUtils.java
+1
-1
XposedInit.java
...mpat/src/main/java/de/robv/android/xposed/XposedInit.java
+201
-222
XC_LoadPackage.java
...java/de/robv/android/xposed/callbacks/XC_LoadPackage.java
+1
-1
No files found.
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/XposedCompat.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
;
import
android.app.Application
;
import
android.content.Context
;
import
android.content.pm.ApplicationInfo
;
import
com.swift.sandhook.xposedcompat.classloaders.ComposeClassLoader
;
import
com.swift.sandhook.xposedcompat.classloaders.XposedClassLoader
;
import
com.swift.sandhook.xposedcompat.utils.ApplicationUtils
;
import
com.swift.sandhook.xposedcompat.utils.ProcessUtils
;
import
java.io.File
;
import
de.robv.android.xposed.IXposedHookLoadPackage
;
import
de.robv.android.xposed.XposedBridge
;
import
de.robv.android.xposed.XposedInit
;
import
de.robv.android.xposed.callbacks.XC_LoadPackage
;
public
class
XposedCompat
{
public
static
File
cacheDir
;
public
static
Context
context
;
public
static
ClassLoader
classLoader
;
public
static
boolean
isFirstApplication
;
private
static
ClassLoader
sandHookXposedClassLoader
;
public
static
void
loadModule
(
String
apkPath
,
ClassLoader
classLoader
)
{
XposedInit
.
loadModule
(
apkPath
,
classLoader
);
}
public
static
void
addXposedModuleCallback
(
IXposedHookLoadPackage
module
)
{
XposedBridge
.
hookLoadPackage
(
new
IXposedHookLoadPackage
.
Wrapper
(
module
));
}
public
static
void
callXposedModuleInit
()
throws
Throwable
{
//prepare LoadPackageParam
XC_LoadPackage
.
LoadPackageParam
packageParam
=
new
XC_LoadPackage
.
LoadPackageParam
(
XposedBridge
.
sLoadedPackageCallbacks
);
Application
application
=
ApplicationUtils
.
currentApplication
();
if
(
application
!=
null
)
{
if
(
packageParam
.
processName
==
null
)
{
packageParam
.
processName
=
ProcessUtils
.
getProcessName
(
application
);
}
if
(
packageParam
.
classLoader
==
null
)
{
packageParam
.
classLoader
=
application
.
getClassLoader
();
}
if
(
packageParam
.
appInfo
==
null
)
{
packageParam
.
appInfo
=
application
.
getApplicationInfo
();
}
if
(
cacheDir
==
null
)
{
application
.
getCacheDir
();
}
}
XC_LoadPackage
.
callAll
(
packageParam
);
}
public
static
ClassLoader
getSandHookXposedClassLoader
(
ClassLoader
appOriginClassLoader
,
ClassLoader
sandBoxHostClassLoader
)
{
if
(
sandHookXposedClassLoader
!=
null
)
{
return
sandHookXposedClassLoader
;
}
else
{
ClassLoader
xposedClassLoader
=
getXposedClassLoader
(
sandBoxHostClassLoader
);
sandHookXposedClassLoader
=
new
ComposeClassLoader
(
xposedClassLoader
,
appOriginClassLoader
);
return
sandHookXposedClassLoader
;
}
}
private
static
XposedClassLoader
xposedClassLoader
;
public
static
synchronized
ClassLoader
getXposedClassLoader
(
ClassLoader
hostClassLoader
)
{
if
(
xposedClassLoader
==
null
)
{
xposedClassLoader
=
new
XposedClassLoader
(
hostClassLoader
);
}
return
xposedClassLoader
;
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/ComposeClassLoader.java
0 → 100644
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
classloaders
;
/**
* Created by weishu on 17/11/30.
*/
public
class
ComposeClassLoader
extends
ClassLoader
{
private
final
ClassLoader
mAppClassLoader
;
public
ComposeClassLoader
(
ClassLoader
parent
,
ClassLoader
appClassLoader
)
{
super
(
parent
);
mAppClassLoader
=
appClassLoader
;
}
@Override
protected
Class
<?>
loadClass
(
String
name
,
boolean
resolve
)
throws
ClassNotFoundException
{
Class
clazz
=
null
;
try
{
clazz
=
mAppClassLoader
.
loadClass
(
name
);
}
catch
(
ClassNotFoundException
e
)
{
// IGNORE.
}
if
(
clazz
==
null
)
{
clazz
=
super
.
loadClass
(
name
,
resolve
);
}
if
(
clazz
==
null
)
{
throw
new
ClassNotFoundException
();
}
return
clazz
;
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/XposedClassLoader.java
0 → 100644
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
classloaders
;
/**
* XposedClassLoader: make sure load xposed class in sandhook
*/
public
class
XposedClassLoader
extends
ClassLoader
{
private
ClassLoader
mHostClassLoader
;
public
XposedClassLoader
(
ClassLoader
hostClassLoader
)
{
super
(
ClassLoader
.
getSystemClassLoader
());
// parent is BootClassLoader
mHostClassLoader
=
hostClassLoader
;
}
@Override
protected
Class
<?>
loadClass
(
String
name
,
boolean
resolve
)
throws
ClassNotFoundException
{
if
(
name
.
startsWith
(
"de.robv.android.xposed"
)
||
name
.
startsWith
(
"android"
))
{
return
mHostClassLoader
.
loadClass
(
name
);
}
return
super
.
loadClass
(
name
,
resolve
);
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
import
com.swift.sandhook.xposedcompat.XposedCompat
;
import
com.swift.sandhook.xposedcompat.utils.DexLog
;
import
com.swift.sandhook.xposedcompat.utils.FileUtils
;
import
java.io.File
;
import
java.lang.reflect.Constructor
;
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java
View file @
786ed74f
...
...
@@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicLong;
import
de.robv.android.xposed.XC_MethodHook
;
import
de.robv.android.xposed.XposedBridge
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
autoBoxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
autoUnboxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
createResultLocals
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
getObjTypeIdIfPrimitive
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
moveException
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
autoBoxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
autoUnboxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
createResultLocals
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
getObjTypeIdIfPrimitive
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
moveException
;
public
class
HookerDexMaker
{
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/ProcessUtils.java
deleted
100644 → 0
View file @
87f376ea
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
import
android.os.Process
;
import
android.text.TextUtils
;
//import com.elderdrivers.riru.xposed.Main;
import
java.io.BufferedReader
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.InputStreamReader
;
public
class
ProcessUtils
{
public
static
String
getCurrentProcessName
()
{
String
prettyName
=
null
;
//Main.sAppProcessName;
if
(!
TextUtils
.
isEmpty
(
prettyName
))
{
return
prettyName
;
}
return
getProcessName
(
Process
.
myPid
());
}
/**
* a common solution from https://stackoverflow.com/a/21389402
* <p>
* use {@link com.elderdrivers.riru.xposed.Main#sAppProcessName} to get current process name
*/
public
static
String
getProcessName
(
int
pid
)
{
BufferedReader
cmdlineReader
=
null
;
try
{
cmdlineReader
=
new
BufferedReader
(
new
InputStreamReader
(
new
FileInputStream
(
"/proc/"
+
pid
+
"/cmdline"
),
"iso-8859-1"
));
int
c
;
StringBuilder
processName
=
new
StringBuilder
();
while
((
c
=
cmdlineReader
.
read
())
>
0
)
{
processName
.
append
((
char
)
c
);
}
return
processName
.
toString
();
}
catch
(
Throwable
throwable
)
{
DexLog
.
w
(
"getProcessName: "
+
throwable
.
getMessage
());
}
finally
{
try
{
if
(
cmdlineReader
!=
null
)
{
cmdlineReader
.
close
();
}
}
catch
(
Throwable
throwable
)
{
DexLog
.
e
(
"getProcessName: "
+
throwable
.
getMessage
());
}
}
return
""
;
}
public
static
boolean
isLastPidAlive
(
File
lastPidFile
)
{
String
lastPidInfo
=
FileUtils
.
readLine
(
lastPidFile
);
try
{
String
[]
split
=
lastPidInfo
.
split
(
":"
,
2
);
return
checkProcessAlive
(
Integer
.
parseInt
(
split
[
0
]),
split
[
1
]);
}
catch
(
Throwable
throwable
)
{
DexLog
.
w
(
"error when check last pid "
+
lastPidFile
+
": "
+
throwable
.
getMessage
());
return
false
;
}
}
public
static
void
saveLastPidInfo
(
File
lastPidFile
,
int
pid
,
String
processName
)
{
try
{
if
(!
lastPidFile
.
exists
())
{
lastPidFile
.
getParentFile
().
mkdirs
();
lastPidFile
.
createNewFile
();
}
}
catch
(
Throwable
throwable
)
{
}
FileUtils
.
writeLine
(
lastPidFile
,
pid
+
":"
+
processName
);
}
public
static
boolean
checkProcessAlive
(
int
pid
,
String
processName
)
{
String
existsPrcName
=
getProcessName
(
pid
);
DexLog
.
w
(
"checking pid alive: "
+
pid
+
", "
+
processName
+
", processName="
+
existsPrcName
);
return
existsPrcName
.
equals
(
processName
);
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/utils/ApplicationUtils.java
0 → 100644
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.app.Application
;
import
java.lang.reflect.Method
;
public
class
ApplicationUtils
{
private
static
Class
classActivityThread
;
private
static
Method
currentApplicationMethod
;
static
Application
application
;
public
static
Application
currentApplication
()
{
if
(
application
!=
null
)
return
application
;
if
(
currentApplicationMethod
==
null
)
{
try
{
classActivityThread
=
Class
.
forName
(
"android.app.ActivityThread"
);
currentApplicationMethod
=
classActivityThread
.
getDeclaredMethod
(
"currentApplication"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
if
(
currentApplicationMethod
==
null
)
return
null
;
try
{
application
=
(
Application
)
currentApplicationMethod
.
invoke
(
null
);
}
catch
(
Exception
e
)
{
}
return
application
;
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/utils/ClassLoaderUtils.java
0 → 100644
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.os.Build
;
import
android.util.ArrayMap
;
import
com.swift.sandhook.xposedcompat.BuildConfig
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
dalvik.system.PathClassLoader
;
public
class
ClassLoaderUtils
{
public
static
final
String
DEXPATH
=
"/system/framework/edxposed.dex:/system/framework/eddalvikdx.dex:/system/framework/eddexmaker.dex"
;
public
static
void
replaceParentClassLoader
(
ClassLoader
appClassLoader
)
{
if
(
appClassLoader
==
null
)
{
DexLog
.
e
(
"appClassLoader is null, you might be kidding me?"
);
return
;
}
try
{
ClassLoader
curCL
=
ClassLoaderUtils
.
class
.
getClassLoader
();
ClassLoader
parent
=
appClassLoader
;
ClassLoader
lastChild
=
appClassLoader
;
while
(
parent
!=
null
)
{
ClassLoader
tmp
=
parent
.
getParent
();
if
(
tmp
==
curCL
)
{
DexLog
.
d
(
"replacing has been done before, skip."
);
return
;
}
if
(
tmp
==
null
)
{
DexLog
.
d
(
"before replacing =========================================>"
);
dumpClassLoaders
(
appClassLoader
);
Field
parentField
=
ClassLoader
.
class
.
getDeclaredField
(
"parent"
);
parentField
.
setAccessible
(
true
);
parentField
.
set
(
curCL
,
parent
);
parentField
.
set
(
lastChild
,
curCL
);
DexLog
.
d
(
"after replacing ==========================================>"
);
dumpClassLoaders
(
appClassLoader
);
}
lastChild
=
parent
;
parent
=
tmp
;
}
}
catch
(
Throwable
throwable
)
{
DexLog
.
e
(
"error when replacing class loader."
,
throwable
);
}
}
private
static
void
dumpClassLoaders
(
ClassLoader
classLoader
)
{
if
(
BuildConfig
.
DEBUG
)
{
while
(
classLoader
!=
null
)
{
DexLog
.
d
(
classLoader
+
" =>"
);
classLoader
=
classLoader
.
getParent
();
}
}
}
public
static
List
<
ClassLoader
>
getAppClassLoader
()
{
List
<
ClassLoader
>
cacheLoaders
=
new
ArrayList
<>(
0
);
try
{
DexLog
.
d
(
"start getting app classloader"
);
Class
appLoadersClass
=
Class
.
forName
(
"android.app.ApplicationLoaders"
);
Field
loadersField
=
appLoadersClass
.
getDeclaredField
(
"gApplicationLoaders"
);
loadersField
.
setAccessible
(
true
);
Object
loaders
=
loadersField
.
get
(
null
);
Field
mLoaderMapField
=
loaders
.
getClass
().
getDeclaredField
(
"mLoaders"
);
mLoaderMapField
.
setAccessible
(
true
);
ArrayMap
<
String
,
ClassLoader
>
mLoaderMap
=
(
ArrayMap
<
String
,
ClassLoader
>)
mLoaderMapField
.
get
(
loaders
);
DexLog
.
d
(
"mLoaders size = "
+
mLoaderMap
.
size
());
cacheLoaders
=
new
ArrayList
<>(
mLoaderMap
.
values
());
}
catch
(
Exception
ex
)
{
DexLog
.
e
(
"error get app class loader."
,
ex
);
}
return
cacheLoaders
;
}
private
static
HashSet
<
ClassLoader
>
classLoaders
=
new
HashSet
<>();
public
static
boolean
addPathToClassLoader
(
ClassLoader
classLoader
)
{
if
(!(
classLoader
instanceof
PathClassLoader
))
{
DexLog
.
w
(
classLoader
+
" is not a BaseDexClassLoader!!!"
);
return
false
;
}
if
(
classLoaders
.
contains
(
classLoader
))
{
DexLog
.
d
(
classLoader
+
" has been hooked before"
);
return
true
;
}
try
{
PathClassLoader
baseDexClassLoader
=
(
PathClassLoader
)
classLoader
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
N
)
{
//baseDexClassLoader.addDexPath(DEXPATH);
}
else
{
DexUtils
.
injectDexAtFirst
(
DEXPATH
,
baseDexClassLoader
);
}
classLoaders
.
add
(
classLoader
);
return
true
;
}
catch
(
Throwable
throwable
)
{
DexLog
.
e
(
"error when addPath to ClassLoader: "
+
classLoader
,
throwable
);
}
return
false
;
}
}
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
methodgen
/DexLog.java
→
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
utils
/DexLog.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.util.Log
;
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
methodgen
/DexMakerUtils.java
→
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
utils
/DexMakerUtils.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
com.android.dx.Code
;
import
com.android.dx.Local
;
import
com.android.dx.TypeId
;
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/utils/DexUtils.java
0 → 100644
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.annotation.TargetApi
;
import
android.os.Build
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Field
;
import
dalvik.system.BaseDexClassLoader
;
import
dalvik.system.DexClassLoader
;
/**
* For 6.0 only.
*/
@TargetApi
(
Build
.
VERSION_CODES
.
M
)
public
class
DexUtils
{
public
static
void
injectDexAtFirst
(
String
dexPath
,
BaseDexClassLoader
classLoader
)
throws
NoSuchFieldException
,
IllegalAccessException
,
ClassNotFoundException
{
DexClassLoader
dexClassLoader
=
new
DexClassLoader
(
dexPath
,
null
,
dexPath
,
classLoader
);
Object
baseDexElements
=
getDexElements
(
getPathList
(
classLoader
));
Object
newDexElements
=
getDexElements
(
getPathList
(
dexClassLoader
));
Object
allDexElements
=
combineArray
(
newDexElements
,
baseDexElements
);
Object
pathList
=
getPathList
(
classLoader
);
setField
(
pathList
,
pathList
.
getClass
(),
"dexElements"
,
allDexElements
);
}
private
static
Object
getDexElements
(
Object
paramObject
)
throws
IllegalArgumentException
,
NoSuchFieldException
,
IllegalAccessException
{
return
getField
(
paramObject
,
paramObject
.
getClass
(),
"dexElements"
);
}
private
static
Object
getPathList
(
Object
baseDexClassLoader
)
throws
IllegalArgumentException
,
NoSuchFieldException
,
IllegalAccessException
,
ClassNotFoundException
{
return
getField
(
baseDexClassLoader
,
Class
.
forName
(
"dalvik.system.BaseDexClassLoader"
),
"pathList"
);
}
private
static
Object
combineArray
(
Object
firstArray
,
Object
secondArray
)
{
Class
<?>
localClass
=
firstArray
.
getClass
().
getComponentType
();
int
firstArrayLength
=
Array
.
getLength
(
firstArray
);
int
allLength
=
firstArrayLength
+
Array
.
getLength
(
secondArray
);
Object
result
=
Array
.
newInstance
(
localClass
,
allLength
);
for
(
int
k
=
0
;
k
<
allLength
;
++
k
)
{
if
(
k
<
firstArrayLength
)
{
Array
.
set
(
result
,
k
,
Array
.
get
(
firstArray
,
k
));
}
else
{
Array
.
set
(
result
,
k
,
Array
.
get
(
secondArray
,
k
-
firstArrayLength
));
}
}
return
result
;
}
public
static
Object
getField
(
Object
obj
,
Class
<?>
cl
,
String
field
)
throws
NoSuchFieldException
,
IllegalArgumentException
,
IllegalAccessException
{
Field
localField
=
cl
.
getDeclaredField
(
field
);
localField
.
setAccessible
(
true
);
return
localField
.
get
(
obj
);
}
public
static
void
setField
(
Object
obj
,
Class
<?>
cl
,
String
field
,
Object
value
)
throws
NoSuchFieldException
,
IllegalArgumentException
,
IllegalAccessException
{
Field
localField
=
cl
.
getDeclaredField
(
field
);
localField
.
setAccessible
(
true
);
localField
.
set
(
obj
,
value
);
}
}
\ No newline at end of file
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
methodgen
/FileUtils.java
→
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
utils
/FileUtils.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.os.Build
;
import
android.text.TextUtils
;
...
...
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/ProcessUtils.java
→
xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/
utils/
ProcessUtils.java
View file @
786ed74f
package
com
.
swift
.
sandhook
.
xposedcompat
;
package
com
.
swift
.
sandhook
.
xposedcompat
.
utils
;
import
android.app.ActivityManager
;
import
android.content.Context
;
...
...
xposedcompat/src/main/java/de/robv/android/xposed/XposedInit.java
View file @
786ed74f
This diff is collapsed.
Click to expand it.
xposedcompat/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java
View file @
786ed74f
...
...
@@ -2,7 +2,7 @@ package de.robv.android.xposed.callbacks;
import
android.content.pm.ApplicationInfo
;
import
com.swift.sandhook.xposedcompat.ProcessUtils
;
import
com.swift.sandhook.xposedcompat.
utils.
ProcessUtils
;
import
com.swift.sandhook.xposedcompat.XposedCompat
;
import
de.robv.android.xposed.IXposedHookLoadPackage
;
...
...
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