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
faa13b1a
Commit
faa13b1a
authored
Jan 21, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
done trampoline manager
parent
6ab163a8
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
191 additions
and
317 deletions
+191
-317
build.gradle
app/build.gradle
+1
-1
art.h
app/src/main/cpp/casts/art/art.h
+50
-0
art_6_0.h
app/src/main/cpp/casts/art/art_6_0.h
+0
-211
cast_art_method.h
app/src/main/cpp/casts/cast_art_method.h
+13
-10
arch.h
app/src/main/cpp/includes/arch.h
+3
-2
cast.h
app/src/main/cpp/includes/cast.h
+5
-3
utils.h
app/src/main/cpp/includes/utils.h
+1
-64
native-lib.cpp
app/src/main/cpp/native-lib.cpp
+3
-2
trampoline.cpp
app/src/main/cpp/trampoline/trampoline.cpp
+5
-0
trampoline.h
app/src/main/cpp/trampoline/trampoline.h
+5
-5
trampoline_manager.cpp
app/src/main/cpp/trampoline/trampoline_manager.cpp
+82
-10
trampoline_manager.h
app/src/main/cpp/trampoline/trampoline_manager.h
+23
-9
No files found.
app/build.gradle
View file @
faa13b1a
...
@@ -11,7 +11,7 @@ android {
...
@@ -11,7 +11,7 @@ android {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild
{
externalNativeBuild
{
cmake
{
cmake
{
arguments
'-DBUILD_TESTING=OFF'
,
'-DANDROID_TOOLCHAIN=gcc'
arguments
'-DBUILD_TESTING=OFF'
cppFlags
"-frtti -fexceptions"
cppFlags
"-frtti -fexceptions"
abiFilters
'armeabi-v7a'
,
'arm64-v8a'
abiFilters
'armeabi-v7a'
,
'arm64-v8a'
}
}
...
...
app/src/main/cpp/casts/art/art.h
0 → 100755
View file @
faa13b1a
/*
*
* Copyright (c) 2011 The Android Open Source Project
* Copyright (c) 2015, alipay.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#ifndef ART_H
#define ART_H
namespace
art
{
namespace
mirror
{
class
Object
{
public
:
};
class
Class
:
public
Object
{
public
:
};
class
ArtField
{
public
:
};
class
ArtMethod
{
public
:
};
}
}
#endif //ART_H
app/src/main/cpp/casts/art/art_6_0.h
deleted
100755 → 0
View file @
6ab163a8
/*
*
* Copyright (c) 2011 The Android Open Source Project
* Copyright (c) 2015, alipay.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdint.h>
/* C99 */
namespace
art
{
namespace
mirror
{
class
Object
{
public
:
// The number of vtable entries in java.lang.Object.
static
constexpr
size_t
kVTableLength
=
11
;
static
uint32_t
hash_code_seed
;
uint32_t
klass_
;
uint32_t
monitor_
;
};
class
Class
:
public
Object
{
public
:
// A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when
// this is the value.
// [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by
// 2 ref instance fields.]
static
constexpr
uint32_t
kClassWalkSuper
=
0xC0000000
;
// Interface method table size. Increasing this value reduces the chance of two interface methods
// colliding in the interface method table but increases the size of classes that implement
// (non-marker) interfaces.
static
constexpr
size_t
kImtSize
=
0
;
//IMT_SIZE;
// Defining class loader, or null for the "bootstrap" system loader.
uint32_t
class_loader_
;
// For array classes, the component class object for instanceof/checkcast
// (for String[][][], this will be String[][]). null for non-array classes.
uint32_t
component_type_
;
// DexCache of resolved constant pool entries (will be null for classes generated by the
// runtime such as arrays and primitive classes).
uint32_t
dex_cache_
;
// Short cuts to dex_cache_ member for fast compiled code access.
uint32_t
dex_cache_strings_
;
// The interface table (iftable_) contains pairs of a interface class and an array of the
// interface methods. There is one pair per interface supported by this class. That means one
// pair for each interface we support directly, indirectly via superclass, or indirectly via a
// superinterface. This will be null if neither we nor our superclass implement any interfaces.
//
// Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
// Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
// single vtable.
//
// For every interface a concrete class implements, we create an array of the concrete vtable_
// methods for the methods in the interface.
uint32_t
iftable_
;
// Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
uint32_t
name_
;
// The superclass, or null if this is java.lang.Object or a primitive type.
//
// Note that interfaces have java.lang.Object as their
// superclass. This doesn't match the expectations in JNI
// GetSuperClass or java.lang.Class.getSuperClass() which need to
// check for interfaces and return null.
uint32_t
super_class_
;
// If class verify fails, we must return same error on subsequent tries.
uint32_t
verify_error_class_
;
// Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
// copied in, and virtual methods from our class either replace those from the super or are
// appended. For abstract classes, methods may be created in the vtable that aren't in
// virtual_ methods_ for miranda methods.
uint32_t
vtable_
;
// Access flags; low 16 bits are defined by VM spec.
// Note: Shuffled back.
uint32_t
access_flags_
;
// static, private, and <init> methods. Pointer to an ArtMethod length-prefixed array.
uint64_t
direct_methods_
;
// instance fields
//
// These describe the layout of the contents of an Object.
// Note that only the fields directly declared by this class are
// listed in ifields; fields declared by a superclass are listed in
// the superclass's Class.ifields.
//
// ArtFields are allocated as a length prefixed ArtField array, and not an array of pointers to
// ArtFields.
uint64_t
ifields_
;
// Static fields length-prefixed array.
uint64_t
sfields_
;
// Virtual methods defined in this class; invoked through vtable. Pointer to an ArtMethod
// length-prefixed array.
uint64_t
virtual_methods_
;
// Total size of the Class instance; used when allocating storage on gc heap.
// See also object_size_.
uint32_t
class_size_
;
// Tid used to check for recursive <clinit> invocation.
pid_t
clinit_thread_id_
;
// ClassDef index in dex file, -1 if no class definition such as an array.
// TODO: really 16bits
int32_t
dex_class_def_idx_
;
// Type index in dex file.
// TODO: really 16bits
int32_t
dex_type_idx_
;
// Number of direct fields.
uint32_t
num_direct_methods_
;
// Number of instance fields.
uint32_t
num_instance_fields_
;
// Number of instance fields that are object refs.
uint32_t
num_reference_instance_fields_
;
// Number of static fields that are object refs,
uint32_t
num_reference_static_fields_
;
// Number of static fields.
uint32_t
num_static_fields_
;
// Number of virtual methods.
uint32_t
num_virtual_methods_
;
// Total object size; used when allocating storage on gc heap.
// (For interfaces and abstract classes this will be zero.)
// See also class_size_.
uint32_t
object_size_
;
// The lower 16 bits contains a Primitive::Type value. The upper 16
// bits contains the size shift of the primitive type.
uint32_t
primitive_type_
;
// Bitmap of offsets of ifields.
uint32_t
reference_instance_offsets_
;
// State of class initialization.
uint32_t
status_
;
// TODO: ?
// initiating class loader list
// NOTE: for classes with low serialNumber, these are unused, and the
// values are kept in a table in gDvm.
// InitiatingLoaderList initiating_loader_list_;
// The following data exist in real class objects.
// Embedded Imtable, for class object that's not an interface, fixed size.
// ImTableEntry embedded_imtable_[0];
// Embedded Vtable, for class object that's not an interface, variable size.
// VTableEntry embedded_vtable_[0];
// Static fields, variable size.
// uint32_t fields_[0];
// java.lang.Class
static
uint32_t
java_lang_Class_
;
};
class
ArtField
{
public
:
uint32_t
declaring_class_
;
uint32_t
access_flags_
;
uint32_t
field_dex_idx_
;
uint32_t
offset_
;
};
class
ArtMethod
{
public
:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of.
uint32_t
declaring_class_
;
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
uint32_t
dex_cache_resolved_methods_
;
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
uint32_t
dex_cache_resolved_types_
;
// Access flags; low 16 bits are defined by spec.
uint32_t
access_flags_
;
/* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
// Offset to the CodeItem.
uint32_t
dex_code_item_offset_
;
// Index into method_ids of the dex file associated with this method.
uint32_t
dex_method_index_
;
/* End of dex file fields. */
// Entry within a dispatch table for this method. For static/direct methods the index is into
// the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
// ifTable.
uint32_t
method_index_
;
// Fake padding field gets inserted here.
// Must be the last fields in the method.
// PACKED(4) is necessary for the correctness of
// RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size).
struct
PtrSizedFields
{
// Method dispatch from the interpreter invokes this pointer which may cause a bridge into
// compiled code.
void
*
entry_point_from_interpreter_
;
// Pointer to JNI function registered to this method, or a function to resolve the JNI function.
void
*
entry_point_from_jni_
;
// Method dispatch from quick compiled code invokes this pointer which may cause bridging into
// the interpreter.
void
*
entry_point_from_quick_compiled_code_
;
}
ptr_sized_fields_
;
};
}
}
app/src/main/cpp/casts/cast_art_method.h
View file @
faa13b1a
//
//
// Created by 甘尧 on 2019/1/12.
// Created by 甘尧 on 2019/1/12.
//
//
#ifndef SANDHOOK_CAST_ART_METHOD_H
#define SANDHOOK_CAST_ART_METHOD_H
#include "../includes/cast.h"
#include "../includes/cast.h"
#include "art/art_6_0.h"
namespace
SandHook
{
namespace
SandHook
{
...
@@ -94,7 +97,7 @@ namespace SandHook {
...
@@ -94,7 +97,7 @@ namespace SandHook {
class
cast_art_m
ethod
{
class
CastArtM
ethod
{
public
:
public
:
static
Size
size
;
static
Size
size
;
static
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
entryPointQuickCompiled
;
static
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
entryPointQuickCompiled
;
...
@@ -143,15 +146,15 @@ namespace SandHook {
...
@@ -143,15 +146,15 @@ namespace SandHook {
};
};
Size
cast_art_method
::
size
=
0
;
Size
CastArtMethod
::
size
=
0
;
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
cast_art_method
::
entryPointQuickCompiled
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
CastArtMethod
::
entryPointQuickCompiled
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
cast_art_method
::
entryPointFormInterpreter
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
void
*>*
CastArtMethod
::
entryPointFormInterpreter
=
nullptr
;
ArrayMember
<
art
::
mirror
::
ArtMethod
>*
cast_art_method
::
dexCacheResolvedMethods
=
nullptr
;
ArrayMember
<
art
::
mirror
::
ArtMethod
>*
CastArtMethod
::
dexCacheResolvedMethods
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>*
cast_art_method
::
dexMethodIndex
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>*
CastArtMethod
::
dexMethodIndex
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>*
cast_art_method
::
accessFlag
=
nullptr
;
IMember
<
art
::
mirror
::
ArtMethod
,
uint32_t
>*
CastArtMethod
::
accessFlag
=
nullptr
;
}
}
#endif //SANDHOOK_CAST_ART_METHOD_H
app/src/main/cpp/includes/arch.h
View file @
faa13b1a
...
@@ -5,8 +5,6 @@
...
@@ -5,8 +5,6 @@
#ifndef SANDHOOK_ARCH_H
#ifndef SANDHOOK_ARCH_H
#define SANDHOOK_ARCH_H
#define SANDHOOK_ARCH_H
#endif //SANDHOOK_ARCH_H
namespace
SandHook
{
namespace
SandHook
{
#define BYTE_POINT sizeof(void*)
#define BYTE_POINT sizeof(void*)
...
@@ -24,4 +22,7 @@ namespace SandHook {
...
@@ -24,4 +22,7 @@ namespace SandHook {
#else
#else
#endif
#endif
}
}
#endif //SANDHOOK_ARCH_H
\ No newline at end of file
app/src/main/cpp/includes/cast.h
View file @
faa13b1a
...
@@ -2,11 +2,16 @@
...
@@ -2,11 +2,16 @@
// Created by 甘尧 on 2019/1/12.
// Created by 甘尧 on 2019/1/12.
//
//
#ifndef SANDHOOK_ICAST_H
#define SANDHOOK_ICAST_H
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
#include <jni.h>
#include <jni.h>
#include "arch.h"
#include "arch.h"
#include "utils.h"
#include "utils.h"
#include "../casts/art/art.h"
#define ANDROID_L 21
#define ANDROID_L 21
#define ANDROID_L2 22
#define ANDROID_L2 22
...
@@ -17,9 +22,6 @@
...
@@ -17,9 +22,6 @@
#define ANDROID_O2 27
#define ANDROID_O2 27
#define ANDROID_P 28
#define ANDROID_P 28
#ifndef SANDHOOK_ICAST_H
#define SANDHOOK_ICAST_H
namespace
SandHook
{
namespace
SandHook
{
static
int
SDK_INT
=
0
;
static
int
SDK_INT
=
0
;
...
...
app/src/main/cpp/includes/utils.h
View file @
faa13b1a
...
@@ -5,20 +5,8 @@
...
@@ -5,20 +5,8 @@
#ifndef SANDHOOK_UTILS_H
#ifndef SANDHOOK_UTILS_H
#define SANDHOOK_UTILS_H
#define SANDHOOK_UTILS_H
#if defined(__MACH__) && defined(__FreeBSD__) && defined(__NetBSD__) && defined(__OpenBSD__)\
&& defined(__DragonFly__)
#define ERROR_SIGNAL SIGBUS
#else
#define ERROR_SIGNAL SIGSEGV
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <signal.h>
#include "jni.h"
#include <setjmp.h>
#include <unistd.h>
#include <cwchar>
template
<
typename
T
>
template
<
typename
T
>
int
findOffset
(
void
*
start
,
size_t
len
,
size_t
step
,
T
value
)
{
int
findOffset
(
void
*
start
,
size_t
len
,
size_t
step
,
T
value
)
{
...
@@ -70,57 +58,6 @@ int findOffsetWithCB2(void *start1, void *start2, size_t len,size_t step, bool f
...
@@ -70,57 +58,6 @@ int findOffsetWithCB2(void *start1, void *start2, size_t len,size_t step, bool f
return
-
1
;
return
-
1
;
}
}
static
sigjmp_buf
badreadjmpbuf
;
static
void
badreadfunc
(
int
signo
)
{
/*write(STDOUT_FILENO, "catch\n", 6);*/
siglongjmp
(
badreadjmpbuf
,
1
);
}
bool
isBadReadPtr
(
void
*
ptr
,
int
length
)
{
struct
sigaction
sa
,
osa
;
bool
ret
=
false
;
/*init new handler struct*/
sa
.
sa_handler
=
badreadfunc
;
sigemptyset
(
&
sa
.
sa_mask
);
sa
.
sa_flags
=
0
;
/*retrieve old and set new handlers*/
if
(
sigaction
(
ERROR_SIGNAL
,
&
sa
,
&
osa
)
<
0
)
return
true
;
if
(
sigsetjmp
(
badreadjmpbuf
,
1
)
==
0
)
{
int
i
,
hi
=
length
/
sizeof
(
int
),
remain
=
length
%
sizeof
(
int
);
int
*
pi
=
static_cast
<
int
*>
(
ptr
);
char
*
pc
=
(
char
*
)
ptr
+
hi
;
for
(
i
=
0
;
i
<
hi
;
i
++
)
{
int
tmp
=
*
(
pi
+
i
);
}
for
(
i
=
0
;
i
<
remain
;
i
++
)
{
char
tmp
=
*
(
pc
+
i
);
}
}
else
{
ret
=
true
;
}
/*restore prevouis signal actions*/
if
(
sigaction
(
ERROR_SIGNAL
,
&
osa
,
NULL
)
<
0
)
return
true
;
return
ret
;
}
Size
getAddressFromJava
(
JNIEnv
*
env
,
char
*
className
,
char
*
fieldName
)
{
Size
getAddressFromJava
(
JNIEnv
*
env
,
char
*
className
,
char
*
fieldName
)
{
jclass
clazz
=
env
->
FindClass
(
className
);
jclass
clazz
=
env
->
FindClass
(
className
);
...
...
app/src/main/cpp/native-lib.cpp
View file @
faa13b1a
#include <jni.h>
#include <jni.h>
#include <string>
#include <string>
#include "casts/cast_art_method.h"
#include "casts/cast_art_method.h"
#include "./trampoline/arch/base.h"
#include "./trampoline/trampoline_manager.h"
extern
"C"
JNIEXPORT
jstring
extern
"C"
JNIEXPORT
jstring
...
@@ -40,6 +41,6 @@ Java_com_swift_sandhook_MainActivity_initHook(JNIEnv *env, jobject instance) {
...
@@ -40,6 +41,6 @@ Java_com_swift_sandhook_MainActivity_initHook(JNIEnv *env, jobject instance) {
INLINE_HOOK_TRAMPOLINE
();
INLINE_HOOK_TRAMPOLINE
();
SandHook
::
cast_art_m
ethod
::
init
(
env
);
SandHook
::
CastArtM
ethod
::
init
(
env
);
}
}
\ No newline at end of file
app/src/main/cpp/trampoline/trampoline.cpp
View file @
faa13b1a
//
//
// Created by SwiftGan on 2019/1/17.
// Created by SwiftGan on 2019/1/17.
//
//
#ifndef SANDHOOK_TRAMPOLINE_CPP
#define SANDHOOK_TRAMPOLINE_CPP
#include "trampoline.h"
#include "trampoline.h"
namespace
SandHook
{
namespace
SandHook
{
...
@@ -76,3 +80,4 @@ namespace SandHook {
...
@@ -76,3 +80,4 @@ namespace SandHook {
}
}
#endif //SANDHOOK_TRAMPOLINE_CPP
app/src/main/cpp/trampoline/trampoline.h
View file @
faa13b1a
...
@@ -83,20 +83,20 @@ namespace SandHook {
...
@@ -83,20 +83,20 @@ namespace SandHook {
codeLen
=
codeLength
();
codeLen
=
codeLength
();
tempCode
=
templateCode
();
tempCode
=
templateCode
();
}
}
const
void
setExecuteSpace
(
Code
start
)
{
void
setExecuteSpace
(
Code
start
)
{
code
=
start
;
code
=
start
;
memcpy
(
code
,
tempCode
,
codeLen
);
memcpy
(
code
,
tempCode
,
codeLen
);
}
}
const
void
codeCopy
(
Code
src
,
Size
targetOffset
,
Size
len
)
{
void
codeCopy
(
Code
src
,
Size
targetOffset
,
Size
len
)
{
memcpy
(
code
+
targetOffset
,
src
,
len
);
memcpy
(
code
+
targetOffset
,
src
,
len
);
}
}
const
void
clone
(
Code
dest
)
{
void
clone
(
Code
dest
)
{
memcpy
(
dest
,
code
,
codeLen
);
memcpy
(
dest
,
code
,
codeLen
);
}
}
const
Code
getCode
()
{
Code
getCode
()
{
return
code
;
return
code
;
}
}
const
Size
getCodeLen
()
{
Size
getCodeLen
()
{
return
codeLen
;
return
codeLen
;
}
}
protected
:
protected
:
...
...
app/src/main/cpp/trampoline/trampoline_manager.cpp
View file @
faa13b1a
...
@@ -5,10 +5,6 @@
...
@@ -5,10 +5,6 @@
namespace
SandHook
{
namespace
SandHook
{
void
TrampolineManager
::
init
()
{
}
Code
TrampolineManager
::
allocExecuteSpace
(
Size
size
)
{
Code
TrampolineManager
::
allocExecuteSpace
(
Size
size
)
{
if
(
size
>
MMAP_PAGE_SIZE
)
if
(
size
>
MMAP_PAGE_SIZE
)
return
0
;
return
0
;
...
@@ -37,23 +33,99 @@ namespace SandHook {
...
@@ -37,23 +33,99 @@ namespace SandHook {
return
exeSpace
;
return
exeSpace
;
}
}
HookTrampoline
*
TrampolineManager
::
installReplacementTrampoline
(
void
*
originMethod
,
HookTrampoline
*
TrampolineManager
::
installReplacementTrampoline
(
mirror
::
ArtMethod
*
originMethod
,
void
*
hookMethod
,
mirror
::
ArtMethod
*
hookMethod
,
void
*
backupMethod
)
{
mirror
::
ArtMethod
*
backupMethod
)
{
AutoLock
autoLock
(
installLock
);
if
(
trampolines
.
count
(
originMethod
)
!=
0
)
if
(
trampolines
.
count
(
originMethod
)
!=
0
)
return
getHookTrampoline
(
originMethod
);
return
getHookTrampoline
(
originMethod
);
HookTrampoline
*
hookTrampoline
=
new
HookTrampoline
();
HookTrampoline
*
hookTrampoline
=
new
HookTrampoline
();
ReplacementHookTrampoline
*
replacementHookTrampoline
=
nullptr
;
Code
replacementHookTrampolineSpace
;
replacementHookTrampoline
=
new
ReplacementHookTrampoline
();
replacementHookTrampoline
->
init
();
replacementHookTrampolineSpace
=
allocExecuteSpace
(
replacementHookTrampoline
->
getCodeLen
());
if
(
replacementHookTrampolineSpace
==
0
)
goto
label_error
;
replacementHookTrampoline
->
setExecuteSpace
(
replacementHookTrampolineSpace
);
replacementHookTrampoline
->
setEntryCodeOffset
(
quickCompileOffset
);
replacementHookTrampoline
->
setHookMethod
(
reinterpret_cast
<
Code
>
(
hookMethod
));
hookTrampoline
->
replacement
=
replacementHookTrampoline
;
trampolines
[
originMethod
]
=
hookTrampoline
;
return
hookTrampoline
;
label_error
:
delete
hookTrampoline
;
delete
replacementHookTrampoline
;
return
nullptr
;
}
}
HookTrampoline
*
TrampolineManager
::
installInlineTrampoline
(
void
*
originMethod
,
void
*
hookMethod
,
HookTrampoline
*
TrampolineManager
::
installInlineTrampoline
(
mirror
::
ArtMethod
*
originMethod
,
void
*
backupMethod
)
{
mirror
::
ArtMethod
*
hookMethod
,
mirror
::
ArtMethod
*
backupMethod
)
{
AutoLock
autoLock
(
installLock
);
if
(
trampolines
.
count
(
originMethod
)
!=
0
)
if
(
trampolines
.
count
(
originMethod
)
!=
0
)
return
getHookTrampoline
(
originMethod
);
return
getHookTrampoline
(
originMethod
);
HookTrampoline
*
hookTrampoline
=
new
HookTrampoline
();
HookTrampoline
*
hookTrampoline
=
new
HookTrampoline
();
InlineHookTrampoline
*
inlineHookTrampoline
=
nullptr
;
DirectJumpTrampoline
*
directJumpTrampoline
=
nullptr
;
ReplacementHookTrampoline
*
callOriginTrampoline
=
nullptr
;
Code
inlineHookTrampolineSpace
;
Code
callOriginTrampolineSpace
;
//生成二段跳板
inlineHookTrampoline
=
new
InlineHookTrampoline
;
inlineHookTrampoline
->
init
();
inlineHookTrampolineSpace
=
allocExecuteSpace
(
inlineHookTrampoline
->
getCodeLen
());
if
(
inlineHookTrampolineSpace
==
0
)
goto
label_error
;
inlineHookTrampoline
->
setExecuteSpace
(
inlineHookTrampolineSpace
);
inlineHookTrampoline
->
setOriginMethod
(
reinterpret_cast
<
Code
>
(
originMethod
));
inlineHookTrampoline
->
setHookMethod
(
reinterpret_cast
<
Code
>
(
hookMethod
));
inlineHookTrampoline
->
setEntryCodeOffset
(
quickCompileOffset
);
inlineHookTrampoline
->
setOriginCode
(
getEntryCode
(
originMethod
));
hookTrampoline
->
inlineSecondory
=
inlineHookTrampoline
;
DirectJumpTrampoline
*
directJumpTrampoline
=
new
DirectJumpTrampoline
();
//注入 EntryCode
directJumpTrampoline
=
new
DirectJumpTrampoline
();
directJumpTrampoline
->
init
();
directJumpTrampoline
->
setExecuteSpace
(
getEntryCode
(
originMethod
));
directJumpTrampoline
->
setJumpTarget
(
inlineHookTrampoline
->
getCode
());
hookTrampoline
->
inlineJump
=
directJumpTrampoline
;
//备份原始方法
if
(
backupMethod
)
{
callOriginTrampoline
=
new
ReplacementHookTrampoline
();
callOriginTrampoline
->
init
();
callOriginTrampolineSpace
=
allocExecuteSpace
(
callOriginTrampoline
->
getCodeLen
());
if
(
callOriginTrampolineSpace
==
0
)
goto
label_error
;
callOriginTrampoline
->
setExecuteSpace
(
callOriginTrampolineSpace
);
callOriginTrampoline
->
setHookMethod
(
reinterpret_cast
<
Code
>
(
originMethod
));
callOriginTrampoline
->
setEntryCodeOffset
(
quickCompileOffset
);
hookTrampoline
->
callOrigin
=
callOriginTrampoline
;
}
trampolines
[
originMethod
]
=
hookTrampoline
;
return
hookTrampoline
;
label_error
:
delete
hookTrampoline
;
if
(
inlineHookTrampoline
!=
nullptr
)
{
delete
inlineHookTrampoline
;
}
if
(
directJumpTrampoline
!=
nullptr
)
{
delete
directJumpTrampoline
;
}
if
(
callOriginTrampoline
!=
nullptr
)
{
delete
callOriginTrampoline
;
}
return
nullptr
;
}
}
}
}
app/src/main/cpp/trampoline/trampoline_manager.h
View file @
faa13b1a
...
@@ -10,39 +10,53 @@
...
@@ -10,39 +10,53 @@
#include "trampoline.cpp"
#include "trampoline.cpp"
#include "../utils/lock.h"
#include "../utils/lock.h"
#include <sys/mman.h>
#include <sys/mman.h>
#include "../casts/art/art.h"
namespace
SandHook
{
namespace
SandHook
{
#define MMAP_PAGE_SIZE 4 * 1024
#define MMAP_PAGE_SIZE 4 * 1024
using
namespace
art
;
class
HookTrampoline
{
class
HookTrampoline
{
public
:
public
:
HookTrampoline
()
=
default
;
HookTrampoline
()
=
default
;
Trampoline
*
replacement
;
Trampoline
*
replacement
=
nullptr
;
Trampoline
*
inlineJump
;
Trampoline
*
inlineJump
=
nullptr
;
Trampoline
*
inlineSecondory
;
Trampoline
*
inlineSecondory
=
nullptr
;
Trampoline
*
callOrigin
;
Trampoline
*
callOrigin
=
nullptr
;
};
};
class
TrampolineManager
{
class
TrampolineManager
{
public
:
public
:
TrampolineManager
()
=
default
;
TrampolineManager
()
=
default
;
void
init
();
void
init
(
Size
quickCompileOffset
)
{
this
->
quickCompileOffset
=
quickCompileOffset
;
}
Code
allocExecuteSpace
(
Size
size
);
Code
allocExecuteSpace
(
Size
size
);
HookTrampoline
*
installReplacementTrampoline
(
void
*
originMethod
,
void
*
hookMethod
,
voi
d
*
backupMethod
);
HookTrampoline
*
installReplacementTrampoline
(
mirror
::
ArtMethod
*
originMethod
,
mirror
::
ArtMethod
*
hookMethod
,
mirror
::
ArtMetho
d
*
backupMethod
);
HookTrampoline
*
installInlineTrampoline
(
void
*
originMethod
,
void
*
hookMethod
,
voi
d
*
backupMethod
);
HookTrampoline
*
installInlineTrampoline
(
mirror
::
ArtMethod
*
originMethod
,
mirror
::
ArtMethod
*
hookMethod
,
mirror
::
ArtMetho
d
*
backupMethod
);
HookTrampoline
*
getHookTrampoline
(
voi
d
*
method
)
{
HookTrampoline
*
getHookTrampoline
(
mirror
::
ArtMetho
d
*
method
)
{
return
trampolines
[
method
];
return
trampolines
[
method
];
}
}
Code
getEntryCode
(
mirror
::
ArtMethod
*
method
)
{
Size
*
pEntryAddress
=
reinterpret_cast
<
Size
*>
(
method
+
quickCompileOffset
);
Code
entryCode
=
reinterpret_cast
<
Code
>
(
*
pEntryAddress
);
}
private
:
private
:
std
::
map
<
void
*
,
HookTrampoline
*>
trampolines
=
{};
Size
quickCompileOffset
;
std
::
map
<
mirror
::
ArtMethod
*
,
HookTrampoline
*>
trampolines
=
{};
std
::
list
<
Code
>
executeSpaceList
=
std
::
list
<
Code
>
();
std
::
list
<
Code
>
executeSpaceList
=
std
::
list
<
Code
>
();
std
::
mutex
allocSpaceLock
;
std
::
mutex
allocSpaceLock
;
std
::
mutex
installLock
;
std
::
mutex
installLock
;
...
...
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