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
Show 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
;
package
com
.
swift
.
sandhook
.
xposedcompat
;
import
android.app.Application
;
import
android.content.Context
;
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
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
class
XposedCompat
{
public
static
File
cacheDir
;
public
static
File
cacheDir
;
public
static
Context
context
;
public
static
Context
context
;
public
static
ClassLoader
classLoader
;
public
static
ClassLoader
classLoader
;
public
static
boolean
isFirstApplication
;
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
;
package
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
;
import
com.swift.sandhook.xposedcompat.XposedCompat
;
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.io.File
;
import
java.lang.reflect.Constructor
;
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;
...
@@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicLong;
import
de.robv.android.xposed.XC_MethodHook
;
import
de.robv.android.xposed.XC_MethodHook
;
import
de.robv.android.xposed.XposedBridge
;
import
de.robv.android.xposed.XposedBridge
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
autoBoxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
autoBoxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
autoUnboxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
autoUnboxIfNecessary
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
createResultLocals
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
createResultLocals
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
getObjTypeIdIfPrimitive
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
getObjTypeIdIfPrimitive
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
methodgen
.
DexMakerUtils
.
moveException
;
import
static
com
.
swift
.
sandhook
.
xposedcompat
.
utils
.
DexMakerUtils
.
moveException
;
public
class
HookerDexMaker
{
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
;
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.Code
;
import
com.android.dx.Local
;
import
com.android.dx.Local
;
import
com.android.dx.TypeId
;
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.os.Build
;
import
android.text.TextUtils
;
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.app.ActivityManager
;
import
android.content.Context
;
import
android.content.Context
;
...
...
xposedcompat/src/main/java/de/robv/android/xposed/XposedInit.java
View file @
786ed74f
package
de
.
robv
.
android
.
xposed
;
package
de
.
robv
.
android
.
xposed
;
//import android.annotation.SuppressLint;
import
android.annotation.SuppressLint
;
//import android.app.AndroidAppHelper;
import
android.os.Build
;
//import android.os.Build;
import
android.util.Log
;
//import android.text.TextUtils;
//import android.util.Log;
import
java.io.BufferedReader
;
//
import
java.io.File
;
//import com.android.internal.os.ZygoteInit;
import
java.io.IOException
;
//import com.elderdrivers.riru.xposed.BuildConfig;
import
java.io.InputStream
;
//import com.elderdrivers.riru.xposed.entry.Router;
import
java.io.InputStreamReader
;
//import com.elderdrivers.riru.xposed.util.Utils;
import
java.util.HashSet
;
//
import
java.util.concurrent.atomic.AtomicBoolean
;
//import java.io.BufferedReader;
import
java.util.zip.ZipEntry
;
//import java.io.File;
import
java.util.zip.ZipFile
;
//import java.io.IOException;
//import java.io.InputStream;
import
dalvik.system.DexFile
;
//import java.io.InputStreamReader;
import
dalvik.system.PathClassLoader
;
//import java.util.HashSet;
import
de.robv.android.xposed.services.BaseService
;
//import java.util.concurrent.atomic.AtomicBoolean;
//import java.util.zip.ZipEntry;
import
static
de
.
robv
.
android
.
xposed
.
XposedHelpers
.
closeSilently
;
//import java.util.zip.ZipFile;
//
//import dalvik.system.DexFile;
//import dalvik.system.PathClassLoader;
//import de.robv.android.xposed.services.BaseService;
//
//import static com.elderdrivers.riru.xposed.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
//import static de.robv.android.xposed.XposedHelpers.closeSilently;
//import static de.robv.android.xposed.XposedHelpers.findClass;
//import static de.robv.android.xposed.XposedHelpers.findFieldIfExists;
//import static de.robv.android.xposed.XposedHelpers.setStaticBooleanField;
//import static de.robv.android.xposed.XposedHelpers.setStaticLongField;
public
final
class
XposedInit
{
public
final
class
XposedInit
{
//
private static final String TAG = XposedBridge.TAG;
private
static
final
String
TAG
=
XposedBridge
.
TAG
;
//
private static boolean startsSystemServer = false;
private
static
boolean
startsSystemServer
=
false
;
//
private static final String startClassName = ""; // ed: no support for tool process anymore
private
static
final
String
startClassName
=
""
;
// ed: no support for tool process anymore
//
//
public static final String INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager";
public
static
final
String
INSTALLER_PACKAGE_NAME
=
"com.solohsu.android.edxp.manager"
;
//
public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer";
public
static
final
String
INSTALLER_LEGACY_PACKAGE_NAME
=
"de.robv.android.xposed.installer"
;
//
@SuppressLint("SdCardPath")
@SuppressLint
(
"SdCardPath"
)
//
public static final String INSTALLER_DATA_BASE_DIR = Build.VERSION.SDK_INT >= 24
public
static
final
String
INSTALLER_DATA_BASE_DIR
=
Build
.
VERSION
.
SDK_INT
>=
24
//
? "/data/user_de/0/" + INSTALLER_PACKAGE_NAME + "/"
?
"/data/user_de/0/"
+
INSTALLER_PACKAGE_NAME
+
"/"
//
: "/data/data/" + INSTALLER_PACKAGE_NAME + "/";
:
"/data/data/"
+
INSTALLER_PACKAGE_NAME
+
"/"
;
//
private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication";
private
static
final
String
INSTANT_RUN_CLASS
=
"com.android.tools.fd.runtime.BootstrapApplication"
;
//
// TODO not supported yet
// TODO not supported yet
//
private static boolean disableResources = true;
private
static
boolean
disableResources
=
true
;
//
private static final String[] XRESOURCES_CONFLICTING_PACKAGES = {"com.sygic.aura"};
private
static
final
String
[]
XRESOURCES_CONFLICTING_PACKAGES
=
{
"com.sygic.aura"
};
//
//
private XposedInit() {
private
XposedInit
()
{
//
}
}
//
//
private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);
private
static
volatile
AtomicBoolean
bootstrapHooked
=
new
AtomicBoolean
(
false
);
//
//
/**
/**
//
* Hook some methods which we want to create an easier interface for developers.
* Hook some methods which we want to create an easier interface for developers.
//
*/
*/
//
/*package*/
/*package*/
// public static void initForZygote(boolean isSystem) throws Throwable {
// public static void initForZygote(boolean isSystem) throws Throwable {
// if (!bootstrapHooked.compareAndSet(false, true)) {
// if (!bootstrapHooked.compareAndSet(false, true)) {
// return;
// return;
...
@@ -77,175 +65,166 @@ public final class XposedInit {
...
@@ -77,175 +65,166 @@ public final class XposedInit {
// }
// }
// }
// }
// }
// }
//
// /*package*/
/*package*/
// static void hookResources() throws Throwable {
static
void
hookResources
()
throws
Throwable
{
// // ed: not for now
// ed: not for now
// }
}
//
// private static boolean needsToCloseFilesForFork() {
private
static
boolean
needsToCloseFilesForFork
()
{
// // ed: we always start to do our work after forking finishes
// ed: we always start to do our work after forking finishes
// return false;
return
false
;
// }
}
//
// /**
/**
// * Try to load all modules defined in <code>INSTALLER_DATA_BASE_DIR/conf/modules.list</code>
* Try to load all modules defined in <code>INSTALLER_DATA_BASE_DIR/conf/modules.list</code>
// */
*/
// private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
private
static
volatile
AtomicBoolean
modulesLoaded
=
new
AtomicBoolean
(
false
);
//
// public static void loadModules() throws IOException {
public
static
void
loadModules
()
throws
IOException
{
// if (!modulesLoaded.compareAndSet(false, true)) {
if
(!
modulesLoaded
.
compareAndSet
(
false
,
true
))
{
// return;
return
;
// }
}
// final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list";
final
String
filename
=
INSTALLER_DATA_BASE_DIR
+
"conf/modules.list"
;
// BaseService service = SELinuxHelper.getAppDataFileService();
BaseService
service
=
SELinuxHelper
.
getAppDataFileService
();
// if (!service.checkFileExists(filename)) {
if
(!
service
.
checkFileExists
(
filename
))
{
// Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
Log
.
e
(
TAG
,
"Cannot load any modules because "
+
filename
+
" was not found"
);
// return;
return
;
// }
}
//
// ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
ClassLoader
topClassLoader
=
XposedBridge
.
BOOTCLASSLOADER
;
// ClassLoader parent;
ClassLoader
parent
;
// while ((parent = topClassLoader.getParent()) != null) {
while
((
parent
=
topClassLoader
.
getParent
())
!=
null
)
{
// topClassLoader = parent;
topClassLoader
=
parent
;
// }
}
//
// InputStream stream = service.getFileInputStream(filename);
InputStream
stream
=
service
.
getFileInputStream
(
filename
);
// BufferedReader apks = new BufferedReader(new InputStreamReader(stream));
BufferedReader
apks
=
new
BufferedReader
(
new
InputStreamReader
(
stream
));
// String apk;
String
apk
;
// while ((apk = apks.readLine()) != null) {
while
((
apk
=
apks
.
readLine
())
!=
null
)
{
// loadModule(apk, topClassLoader);
loadModule
(
apk
,
topClassLoader
);
// }
}
// apks.close();
apks
.
close
();
// }
}
//
//
// /**
/**
// * Load a module from an APK by calling the init(String) method for all classes defined
* Load a module from an APK by calling the init(String) method for all classes defined
// * in <code>assets/xposed_init</code>.
* in <code>assets/xposed_init</code>.
// */
*/
// private static void loadModule(String apk, ClassLoader topClassLoader) {
public
static
void
loadModule
(
String
apk
,
ClassLoader
topClassLoader
)
{
// if (BuildConfig.DEBUG)
// Log.i(TAG, "Loading modules from " + apk);
if
(!
new
File
(
apk
).
exists
())
{
//
Log
.
e
(
TAG
,
" File does not exist"
);
// if (!TextUtils.isEmpty(apk) && apk.contains(BLACK_LIST_PACKAGE_NAME)) {
return
;
// if (BuildConfig.DEBUG)
}
// Log.i(TAG, "We are going to take over black list's job...");
// return;
DexFile
dexFile
;
// }
try
{
//
dexFile
=
new
DexFile
(
apk
);
// if (!new File(apk).exists()) {
}
catch
(
IOException
e
)
{
// Log.e(TAG, " File does not exist");
Log
.
e
(
TAG
,
" Cannot load module"
,
e
);
// return;
return
;
// }
}
//
// DexFile dexFile;
if
(
dexFile
.
loadClass
(
INSTANT_RUN_CLASS
,
topClassLoader
)
!=
null
)
{
// try {
Log
.
e
(
TAG
,
" Cannot load module, please disable \"Instant Run\" in Android Studio."
);
// dexFile = new DexFile(apk);
closeSilently
(
dexFile
);
// } catch (IOException e) {
return
;
// Log.e(TAG, " Cannot load module", e);
}
// return;
// }
if
(
dexFile
.
loadClass
(
XposedBridge
.
class
.
getName
(),
topClassLoader
)
!=
null
)
{
//
Log
.
e
(
TAG
,
" Cannot load module:"
);
// if (dexFile.loadClass(INSTANT_RUN_CLASS, topClassLoader) != null) {
Log
.
e
(
TAG
,
" The Xposed API classes are compiled into the module's APK."
);
// Log.e(TAG, " Cannot load module, please disable \"Instant Run\" in Android Studio.");
Log
.
e
(
TAG
,
" This may cause strange issues and must be fixed by the module developer."
);
// closeSilently(dexFile);
Log
.
e
(
TAG
,
" For details, see: http://api.xposed.info/using.html"
);
// return;
closeSilently
(
dexFile
);
// }
return
;
//
}
// if (dexFile.loadClass(XposedBridge.class.getName(), topClassLoader) != null) {
// Log.e(TAG, " Cannot load module:");
closeSilently
(
dexFile
);
// Log.e(TAG, " The Xposed API classes are compiled into the module's APK.");
// Log.e(TAG, " This may cause strange issues and must be fixed by the module developer.");
ZipFile
zipFile
=
null
;
// Log.e(TAG, " For details, see: http://api.xposed.info/using.html");
InputStream
is
;
// closeSilently(dexFile);
try
{
// return;
zipFile
=
new
ZipFile
(
apk
);
// }
ZipEntry
zipEntry
=
zipFile
.
getEntry
(
"assets/xposed_init"
);
//
if
(
zipEntry
==
null
)
{
// closeSilently(dexFile);
Log
.
e
(
TAG
,
" assets/xposed_init not found in the APK"
);
//
closeSilently
(
zipFile
);
// ZipFile zipFile = null;
return
;
// InputStream is;
}
// try {
is
=
zipFile
.
getInputStream
(
zipEntry
);
// zipFile = new ZipFile(apk);
}
catch
(
IOException
e
)
{
// ZipEntry zipEntry = zipFile.getEntry("assets/xposed_init");
Log
.
e
(
TAG
,
" Cannot read assets/xposed_init in the APK"
,
e
);
// if (zipEntry == null) {
closeSilently
(
zipFile
);
// Log.e(TAG, " assets/xposed_init not found in the APK");
return
;
// closeSilently(zipFile);
}
// return;
// }
ClassLoader
mcl
=
new
PathClassLoader
(
apk
,
XposedInit
.
class
.
getClassLoader
());
// is = zipFile.getInputStream(zipEntry);
BufferedReader
moduleClassesReader
=
new
BufferedReader
(
new
InputStreamReader
(
is
));
// } catch (IOException e) {
try
{
// Log.e(TAG, " Cannot read assets/xposed_init in the APK", e);
String
moduleClassName
;
// closeSilently(zipFile);
while
((
moduleClassName
=
moduleClassesReader
.
readLine
())
!=
null
)
{
// return;
moduleClassName
=
moduleClassName
.
trim
();
// }
if
(
moduleClassName
.
isEmpty
()
||
moduleClassName
.
startsWith
(
"#"
))
//
continue
;
// ClassLoader mcl = new PathClassLoader(apk, XposedInit.class.getClassLoader());
// BufferedReader moduleClassesReader = new BufferedReader(new InputStreamReader(is));
try
{
// try {
Log
.
i
(
TAG
,
" Loading class "
+
moduleClassName
);
// String moduleClassName;
Class
<?>
moduleClass
=
mcl
.
loadClass
(
moduleClassName
);
// while ((moduleClassName = moduleClassesReader.readLine()) != null) {
// moduleClassName = moduleClassName.trim();
if
(!
IXposedMod
.
class
.
isAssignableFrom
(
moduleClass
))
{
// if (moduleClassName.isEmpty() || moduleClassName.startsWith("#"))
Log
.
e
(
TAG
,
" This class doesn't implement any sub-interface of IXposedMod, skipping it"
);
// continue;
continue
;
//
}
else
if
(
disableResources
&&
IXposedHookInitPackageResources
.
class
.
isAssignableFrom
(
moduleClass
))
{
// try {
Log
.
e
(
TAG
,
" This class requires resource-related hooks (which are disabled), skipping it."
);
// if (BuildConfig.DEBUG)
continue
;
// Log.i(TAG, " Loading class " + moduleClassName);
}
// Class<?> moduleClass = mcl.loadClass(moduleClassName);
//
final
Object
moduleInstance
=
moduleClass
.
newInstance
();
// if (!IXposedMod.class.isAssignableFrom(moduleClass)) {
// Log.e(TAG, " This class doesn't implement any sub-interface of IXposedMod, skipping it");
if
(
true
)
{
// continue;
// } else if (disableResources && IXposedHookInitPackageResources.class.isAssignableFrom(moduleClass)) {
//fake
// Log.e(TAG, " This class requires resource-related hooks (which are disabled), skipping it.");
if
(
moduleInstance
instanceof
IXposedHookZygoteInit
)
{
// continue;
IXposedHookZygoteInit
.
StartupParam
param
=
new
IXposedHookZygoteInit
.
StartupParam
();
// }
param
.
modulePath
=
apk
;
//
param
.
startsSystemServer
=
false
;
// final Object moduleInstance = moduleClass.newInstance();
((
IXposedHookZygoteInit
)
moduleInstance
).
initZygote
(
param
);
// if (XposedBridge.isZygote) {
}
// if (moduleInstance instanceof IXposedHookZygoteInit) {
// IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
if
(
moduleInstance
instanceof
IXposedHookLoadPackage
)
// param.modulePath = apk;
XposedBridge
.
hookLoadPackage
(
new
IXposedHookLoadPackage
.
Wrapper
((
IXposedHookLoadPackage
)
moduleInstance
));
// param.startsSystemServer = startsSystemServer;
// ((IXposedHookZygoteInit) moduleInstance).initZygote(param);
//not support now
// }
//so off
//
if
(
moduleInstance
instanceof
IXposedHookInitPackageResources
)
{
// if (moduleInstance instanceof IXposedHookLoadPackage)
throw
new
UnsupportedOperationException
(
"can not hook resource!"
);
// XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper((IXposedHookLoadPackage) moduleInstance));
//XposedBridge.hookInitPackageResources(new IXposedHookInitPackageResources.Wrapper((IXposedHookInitPackageResources) moduleInstance));
//
}
// if (moduleInstance instanceof IXposedHookInitPackageResources)
}
else
{
// XposedBridge.hookInitPackageResources(new IXposedHookInitPackageResources.Wrapper((IXposedHookInitPackageResources) moduleInstance));
//not support now
// } else {
//so off
// if (moduleInstance instanceof IXposedHookCmdInit) {
if
(
moduleInstance
instanceof
IXposedHookCmdInit
)
{
throw
new
UnsupportedOperationException
(
"can not hook cmd!"
);
// IXposedHookCmdInit.StartupParam param = new IXposedHookCmdInit.StartupParam();
// IXposedHookCmdInit.StartupParam param = new IXposedHookCmdInit.StartupParam();
// param.modulePath = apk;
// param.modulePath = apk;
// param.startClassName = startClassName;
// param.startClassName = startClassName;
// ((IXposedHookCmdInit) moduleInstance).initCmdApp(param);
// ((IXposedHookCmdInit) moduleInstance).initCmdApp(param);
// }
}
// }
}
// } catch (Throwable t) {
}
catch
(
Throwable
t
)
{
// Log.e(TAG, " Failed to load class " + moduleClassName, t);
Log
.
e
(
TAG
,
" Failed to load class "
+
moduleClassName
,
t
);
// }
}
// }
}
// } catch (IOException e) {
}
catch
(
IOException
e
)
{
// Log.e(TAG, " Failed to load module from " + apk, e);
Log
.
e
(
TAG
,
" Failed to load module from "
+
apk
,
e
);
// } finally {
}
finally
{
// closeSilently(is);
closeSilently
(
is
);
// closeSilently(zipFile);
closeSilently
(
zipFile
);
// }
}
// }
}
//
// public final static HashSet<String> loadedPackagesInProcess = new HashSet<>(1);
public
final
static
HashSet
<
String
>
loadedPackagesInProcess
=
new
HashSet
<>(
1
);
//
// public static void logD(String prefix) {
// Utils.logD(String.format("%s: pkg=%s, prc=%s", prefix, AndroidAppHelper.currentPackageName(),
// AndroidAppHelper.currentProcessName()));
// }
//
// public static void logE(String prefix, Throwable throwable) {
// Utils.logE(String.format("%s: pkg=%s, prc=%s", prefix, AndroidAppHelper.currentPackageName(),
// AndroidAppHelper.currentProcessName()), throwable);
// }
}
}
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;
...
@@ -2,7 +2,7 @@ package de.robv.android.xposed.callbacks;
import
android.content.pm.ApplicationInfo
;
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
com.swift.sandhook.xposedcompat.XposedCompat
;
import
de.robv.android.xposed.IXposedHookLoadPackage
;
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