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
8775fed6
Commit
8775fed6
authored
Jan 14, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ResolveMethod]add resolve method in java
parent
a2623a31
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
229 additions
and
12 deletions
+229
-12
CastArtMethod.h
app/src/main/cpp/casts/CastArtMethod.h
+15
-8
IMethodResolver.h
app/src/main/cpp/includes/IMethodResolver.h
+8
-0
MainActivity.java
app/src/main/java/com/swift/sandhook/MainActivity.java
+36
-1
SandHook.java
app/src/main/java/com/swift/sandhook/SandHook.java
+91
-3
SandHookMethodResolver.java
.../main/java/com/swift/sandhook/SandHookMethodResolver.java
+79
-0
No files found.
app/src/main/cpp/casts/CastArtMethod.h
View file @
8775fed6
...
@@ -12,15 +12,16 @@ namespace SandHook {
...
@@ -12,15 +12,16 @@ namespace SandHook {
if
(
SDK_INT
>=
ANDROID_P
)
if
(
SDK_INT
>=
ANDROID_P
)
return
getParentSize
()
+
1
;
return
getParentSize
()
+
1
;
auto
filter
=
[](
int
offset
,
void
*
ptr
)
->
bool
{
auto
filter
=
[](
int
offset
,
void
*
ptr
)
->
bool
{
if
(
isBadReadPtr
(
ptr
,
BYTE_POINT
))
//
if (isBadReadPtr(ptr, BYTE_POINT))
return
false
;
//
return false;
Size
addr
=
ADDR
(
ptr
);
//
Size addr = ADDR(ptr);
if
(
isBadReadPtr
(
reinterpret_cast
<
void
*>
(
addr
+
offset
),
BYTE_POINT
))
//
if (isBadReadPtr(reinterpret_cast<void *>(addr + offset), BYTE_POINT))
return
false
;
//
return false;
Size
subAddr
=
ADDR
(
addr
+
offset
);
//
Size subAddr = ADDR(addr + offset);
return
addr
==
subAddr
;
//
return addr == subAddr;
};
};
int
offset
=
findOffsetWithCB1
(
&
p
,
getParentSize
(),
4
,
*
filter
);
int
offset
=
findOffsetWithCB1
(
&
p
,
getParentSize
(),
4
,
*
filter
);
return
offset
;
}
}
};
};
...
@@ -85,7 +86,13 @@ namespace SandHook {
...
@@ -85,7 +86,13 @@ namespace SandHook {
entryPointFormInterpreter
->
init
(
m1
,
size
);
entryPointFormInterpreter
->
init
(
m1
,
size
);
dexCacheResolvedMethods
=
new
CastDexCacheResolvedMethods
();
dexCacheResolvedMethods
=
new
CastDexCacheResolvedMethods
();
dexCacheResolvedMethods
->
init
(
m1
,
size
);
// dexCacheResolvedMethods->init(m1, size);
//test
art
::
mirror
::
ArtMethod
**
mArray
=
reinterpret_cast
<
art
::
mirror
::
ArtMethod
**>
(
m1
.
dex_cache_resolved_methods_
);
art
::
mirror
::
ArtMethod
m1B
=
*
(
mArray
+
8
)[
m1
.
dex_method_index_
];
art
::
mirror
::
ArtMethod
m1C
=
*
(
mArray
+
8
)[
m2
.
dex_method_index_
];
}
}
...
...
app/src/main/cpp/includes/IMethodResolver.h
0 → 100644
View file @
8775fed6
//
// Created by SwiftGan on 2019/1/14.
//
#ifndef SANDHOOK_IMETHODRESOLVER_H
#define SANDHOOK_IMETHODRESOLVER_H
#endif //SANDHOOK_IMETHODRESOLVER_H
app/src/main/java/com/swift/sandhook/MainActivity.java
View file @
8775fed6
...
@@ -10,6 +10,7 @@ import android.view.View;
...
@@ -10,6 +10,7 @@ import android.view.View;
import
android.view.Menu
;
import
android.view.Menu
;
import
android.view.MenuItem
;
import
android.view.MenuItem
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
public
class
MainActivity
extends
AppCompatActivity
{
public
class
MainActivity
extends
AppCompatActivity
{
...
@@ -40,11 +41,45 @@ public class MainActivity extends AppCompatActivity {
...
@@ -40,11 +41,45 @@ public class MainActivity extends AppCompatActivity {
try
{
try
{
Method
method1
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method1"
);
Method
method1
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method1"
);
Method
method2
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method2"
);
Method
method2
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method2"
);
tv
.
setText
(
""
+
calArtSize
(
method1
,
method2
));
Field
field
=
Class
.
class
.
getDeclaredField
(
"dexCache"
);
field
.
setAccessible
(
true
);
Object
dexCache
=
field
.
get
(
ArtMethodSizeTest
.
class
);
Field
resolvedMethodsField
=
dexCache
.
getClass
().
getDeclaredField
(
"resolvedMethods"
);
resolvedMethodsField
.
setAccessible
(
true
);
long
[]
methods
=
(
long
[])
resolvedMethodsField
.
get
(
dexCache
);
Field
dexMethodIndexField
=
getField
(
Method
.
class
,
"dexMethodIndex"
);
dexMethodIndexField
.
setAccessible
(
true
);
int
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
method1
);
Field
artMethodField
=
getField
(
Method
.
class
,
"artMethod"
);
artMethodField
.
setAccessible
(
true
);
long
artMethod
=
(
long
)
artMethodField
.
get
(
method1
);
// methods[dexMethodIndex] = artMethod;
initHook
();
initHook
();
// SandHook.init();
tv
.
setText
(
""
+
calArtSize
(
method1
,
method2
));
}
catch
(
NoSuchMethodException
e
)
{
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
}
catch
(
NoSuchFieldException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
}
public
static
Field
getField
(
Class
topClass
,
String
fieldName
)
throws
NoSuchFieldException
{
while
(
topClass
!=
null
&&
topClass
!=
Object
.
class
)
{
try
{
return
topClass
.
getDeclaredField
(
fieldName
);
}
catch
(
Exception
e
)
{
}
topClass
=
topClass
.
getSuperclass
();
}
}
throw
new
NoSuchFieldException
(
fieldName
);
}
}
@Override
@Override
...
...
app/src/main/java/com/swift/sandhook/SandHook.java
View file @
8775fed6
package
com
.
swift
.
sandhook
;
package
com
.
swift
.
sandhook
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
public
class
SandHook
{
public
class
SandHook
{
public
final
static
boolean
init
()
{
// make sure resolved!
public
static
Class
artMethodClass
;
public
static
Method
testOffsetMethod1
;
public
static
Method
testOffsetMethod2
;
public
static
Object
testOffsetArtMethod1
;
public
static
Object
testOffsetArtMethod2
;
public
static
int
testAccessFlag
;
public
static
int
methodOffset
;
public
static
boolean
init
()
{
initTestOffset
();
return
true
;
}
private
static
void
initTestOffset
()
{
// make test methods sure resolved!
ArtMethodSizeTest
.
method1
();
ArtMethodSizeTest
.
method1
();
ArtMethodSizeTest
.
method2
();
ArtMethodSizeTest
.
method2
();
// get test methods
try
{
testOffsetMethod1
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method1"
);
testOffsetMethod2
=
ArtMethodSizeTest
.
class
.
getDeclaredMethod
(
"method2"
);
}
catch
(
NoSuchMethodException
e
)
{
throw
new
RuntimeException
(
"SandHook init error"
,
e
);
}
//
initTestAccessFlag
();
}
private
static
void
initTestAccessFlag
()
{
if
(
hasJavaArtMethod
())
{
try
{
loadArtMethod
();
Field
fieldAccessFlags
=
getField
(
artMethodClass
,
"accessFlags"
);
fieldAccessFlags
.
setAccessible
(
true
);
testAccessFlag
=
(
int
)
fieldAccessFlags
.
get
(
testOffsetArtMethod1
);
}
catch
(
Exception
e
)
{
}
}
else
{
try
{
Field
fieldAccessFlags
=
getField
(
Method
.
class
,
"accessFlags"
);
fieldAccessFlags
.
setAccessible
(
true
);
testAccessFlag
=
(
int
)
fieldAccessFlags
.
get
(
testOffsetMethod1
);
}
catch
(
Exception
e
)
{
}
}
}
private
static
void
loadArtMethod
()
{
try
{
Field
fieldArtMethod
=
getField
(
Method
.
class
,
"artMethod"
);
fieldArtMethod
.
setAccessible
(
true
);
testOffsetArtMethod1
=
fieldArtMethod
.
get
(
testOffsetMethod1
);
testOffsetArtMethod2
=
fieldArtMethod
.
get
(
testOffsetMethod2
);
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchFieldException
e
)
{
e
.
printStackTrace
();
}
}
public
static
boolean
hasJavaArtMethod
()
{
if
(
artMethodClass
!=
null
)
return
true
;
try
{
artMethodClass
=
Class
.
forName
(
"java.lang.reflect.ArtMethod"
);
return
true
;
return
true
;
}
catch
(
ClassNotFoundException
e
)
{
return
false
;
}
}
}
public
static
Field
getField
(
Class
topClass
,
String
fieldName
)
throws
NoSuchFieldException
{
while
(
topClass
!=
null
&&
topClass
!=
Object
.
class
)
{
try
{
Field
field
=
topClass
.
getDeclaredField
(
fieldName
);
field
.
setAccessible
(
true
);
return
field
;
}
catch
(
Exception
e
)
{
}
topClass
=
topClass
.
getSuperclass
();
}
throw
new
NoSuchFieldException
(
fieldName
);
}
}
}
app/src/main/java/com/swift/sandhook/SandHookMethodResolver.java
0 → 100644
View file @
8775fed6
package
com
.
swift
.
sandhook
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
public
class
SandHookMethodResolver
{
public
static
Field
resolvedMethodsField
;
public
static
Field
dexCacheField
;
public
static
Field
dexMethodIndexField
;
public
static
Field
artMethodField
;
public
static
boolean
canResolvedInJava
=
false
;
public
static
long
resolvedMethodsAddress
=
0
;
public
static
int
dexMethodIndex
=
0
;
public
static
void
init
()
{
checkSupport
();
}
private
static
void
checkSupport
()
{
try
{
dexMethodIndexField
=
SandHook
.
getField
(
Method
.
class
,
"dexMethodIndex"
);
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
SandHook
.
testOffsetMethod1
);
dexCacheField
=
SandHook
.
getField
(
Class
.
class
,
"dexCache"
);
dexCacheField
.
setAccessible
(
true
);
Object
dexCache
=
dexCacheField
.
get
(
ArtMethodSizeTest
.
class
);
resolvedMethodsField
=
SandHook
.
getField
(
dexCache
.
getClass
(),
"resolvedMethods"
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
if
(
resolvedMethods
instanceof
Long
)
{
canResolvedInJava
=
false
;
resolvedMethodsAddress
=
(
long
)
resolvedMethods
;
}
else
if
(
resolvedMethods
instanceof
long
[])
{
canResolvedInJava
=
true
;
}
else
if
(
SandHook
.
hasJavaArtMethod
()
&&
resolvedMethods
instanceof
Object
[])
{
canResolvedInJava
=
true
;
}
else
{
canResolvedInJava
=
false
;
}
if
(
canResolvedInJava
)
{
artMethodField
=
SandHook
.
getField
(
Method
.
class
,
"artMethod"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
resolveMethod
(
Method
method
)
{
if
(
canResolvedInJava
&&
artMethodField
!=
null
)
{
// in java
try
{
resolveInJava
(
method
);
}
catch
(
Exception
e
)
{
// in native
}
}
else
{
// in native
}
}
private
static
void
resolveInJava
(
Method
method
)
throws
Exception
{
Object
dexCache
=
dexCacheField
.
get
(
method
.
getDeclaringClass
());
resolvedMethodsField
.
setAccessible
(
true
);
int
dexMethodIndex
=
(
int
)
dexMethodIndexField
.
get
(
method
);
Object
resolvedMethods
=
resolvedMethodsField
.
get
(
dexCache
);
if
(
resolvedMethods
instanceof
long
[])
{
long
artMethod
=
(
long
)
artMethodField
.
get
(
method
);
((
long
[])
resolvedMethods
)[
dexMethodIndex
]
=
artMethod
;
}
else
if
(
resolvedMethods
instanceof
Object
[])
{
Object
artMethod
=
artMethodField
.
get
(
method
);
((
Object
[])
resolvedMethods
)[
dexMethodIndex
]
=
artMethod
;
}
else
{
throw
new
UnsupportedOperationException
(
"unsupport"
);
}
}
}
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