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
17d05f69
Unverified
Commit
17d05f69
authored
Sep 03, 2019
by
ganyao114
Committed by
GitHub
Sep 03, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #33 from ganyao114/single_inst_brk
Single inst brk
parents
12178791
ca6e273c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
237 additions
and
34 deletions
+237
-34
README.md
README.md
+1
-1
hook_arm32.cpp
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
+68
-7
hook_arm32.h
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h
+3
-1
hook_arm64.cpp
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
+59
-9
hook_arm64.h
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h
+4
-1
hook.cpp
nativehook/src/main/cpp/hook/hook.cpp
+32
-11
hook.h
nativehook/src/main/cpp/includes/hook.h
+15
-1
sandhook_native.cpp
nativehook/src/main/cpp/sandhook_native.cpp
+36
-2
sandhook_native.h
nativehook/src/main/cpp/sandhook_native.h
+19
-1
No files found.
README.md
View file @
17d05f69
...
...
@@ -235,7 +235,7 @@ return is backup method
you can insert a break point in body of method(not only start of method), so you can read/write registers in break point.
bool SandBreak
p
oint(void
* origin, void (*
callback)(REG
[]
));
bool SandBreak
P
oint(void
* origin, void (*
callback)(REG
[]
));
## short method
...
...
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
View file @
17d05f69
...
...
@@ -4,6 +4,8 @@
#include <log.h>
#include <cstdlib>
#include <cassert>
#include <signal.h>
#include "code_relocate_arm32.h"
#include "hook_arm32.h"
#include "code_buffer.h"
...
...
@@ -75,6 +77,8 @@ IMPORT_SHELLCODE(BP_SHELLCODE)
IMPORT_LABEL
(
callback_addr_s
,
Addr
)
IMPORT_LABEL
(
origin_addr_s
,
Addr
)
bool
InlineHookArm32Android
::
BreakPoint
(
void
*
origin
,
void
(
*
callback
)(
REG
*
))
{
if
(
origin
==
nullptr
||
callback
==
nullptr
)
return
false
;
AutoLock
lock
(
hook_lock
);
void
*
origin_code
;
...
...
@@ -129,6 +133,8 @@ bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) {
}
void
*
InlineHookArm32Android
::
SingleInstHook
(
void
*
origin
,
void
*
replace
)
{
if
(
origin
==
nullptr
||
replace
==
nullptr
)
return
nullptr
;
if
(
!
InitForSingleInstHook
())
{
return
nullptr
;
}
...
...
@@ -166,22 +172,77 @@ void *InlineHookArm32Android::SingleInstHook(void *origin, void *replace) {
__
Finish
();
#undef __
hook_infos
.
push_back
({
origin
,
replace
,
GetThumbPC
(
backup
)});
hook_infos
.
push_back
({
false
,
nullptr
,
origin
,
replace
,
GetThumbPC
(
backup
)});
//commit inline trampoline
assembler_inline
.
Finish
();
return
GetThumbPC
(
backup
);
}
void
InlineHookArm32Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
InstT32
*
code
=
reinterpret_cast
<
InstT32
*>
(
context
->
arm_pc
);
if
(
!
IS_OPCODE_T32
(
*
code
,
HVC
))
{
abort
();
bool
InlineHookArm32Android
::
SingleBreakPoint
(
void
*
point
,
BreakCallback
callback
,
void
*
data
)
{
if
(
point
==
nullptr
||
callback
==
nullptr
)
return
false
;
if
(
!
InitForSingleInstHook
())
return
false
;
AutoLock
lock
(
hook_lock
);
void
*
origin_code
;
if
(
IsThumbCode
((
Addr
)
point
))
{
origin_code
=
GetThumbCodeAddress
(
point
);
}
else
{
LOGE
(
"hook %d error!, only support thumb2 now!"
,
point
);
return
nullptr
;
}
void
*
backup
=
nullptr
;
AssemblerA32
assembler_backup
(
backup_buffer
);
StaticCodeBuffer
inline_buffer
=
StaticCodeBuffer
(
reinterpret_cast
<
Addr
>
(
origin_code
));
AssemblerA32
assembler_inline
(
&
inline_buffer
);
CodeContainer
*
code_container_inline
=
&
assembler_inline
.
code_container
;
//build inline trampoline
#define __ assembler_inline.
__
Hvc
(
static_cast
<
U16
>
(
hook_infos
.
size
()));
#undef __
//build backup method
CodeRelocateA32
relocate
=
CodeRelocateA32
(
assembler_backup
);
backup
=
relocate
.
Relocate
(
point
,
code_container_inline
->
Size
(),
nullptr
);
#define __ assembler_backup.
Label
*
origin_addr_label
=
new
Label
();
ALIGN_FOR_LDR
__
Ldr
(
PC
,
origin_addr_label
);
__
Emit
(
origin_addr_label
);
__
Emit
((
Addr
)
GetThumbPC
(
reinterpret_cast
<
void
*>
(
reinterpret_cast
<
Addr
>
(
origin_code
)
+
relocate
.
cur_offset
)));
__
Finish
();
#undef __
hook_infos
.
push_back
({
true
,
data
,
point
,
(
void
*
)
callback
,
GetThumbPC
(
backup
)});
//commit inline trampoline
assembler_inline
.
Finish
();
return
true
;
}
bool
InlineHookArm32Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
InstT32
*
code
=
reinterpret_cast
<
InstT32
*>
(
context
->
arm_pc
);
if
(
!
IS_OPCODE_T32
(
*
code
,
HVC
))
return
false
;
INST_T32
(
HVC
)
hvc
(
code
);
hvc
.
Disassemble
();
if
(
hvc
.
imme
>=
hook_infos
.
size
())
return
;
return
false
;
HookInfo
&
hook_info
=
hook_infos
[
hvc
.
imme
];
context
->
arm_pc
=
reinterpret_cast
<
U32
>
(
hook_info
.
replace
);
if
(
!
hook_info
.
is_break_point
)
{
context
->
arm_pc
=
reinterpret_cast
<
U32
>
(
hook_info
.
replace
);
}
else
{
BreakCallback
callback
=
reinterpret_cast
<
BreakCallback
>
(
hook_info
.
replace
);
if
(
callback
(
context
,
hook_info
.
user_data
))
{
context
->
arm_pc
=
reinterpret_cast
<
U32
>
(
hook_info
.
backup
);
}
else
{
context
->
arm_pc
+=
4
;
}
}
return
true
;
}
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h
View file @
17d05f69
...
...
@@ -16,9 +16,11 @@ namespace SandHook {
bool
BreakPoint
(
void
*
point
,
void
(
*
callback
)(
REG
*
))
override
;
bool
SingleBreakPoint
(
void
*
point
,
BreakCallback
callback
,
void
*
data
)
override
;
void
*
SingleInstHook
(
void
*
origin
,
void
*
replace
)
override
;
void
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
override
;
bool
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
override
;
private
:
std
::
vector
<
HookInfo
>
hook_infos
;
...
...
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
View file @
17d05f69
...
...
@@ -3,6 +3,7 @@
//
#include <cstdlib>
#include <cassert>
#include "hook_arm64.h"
#include "code_buffer.h"
#include "lock.h"
...
...
@@ -53,6 +54,8 @@ void *InlineHookArm64Android::Hook(void *origin, void *replace) {
}
bool
InlineHookArm64Android
::
BreakPoint
(
void
*
point
,
void
(
*
callback
)(
REG
regs
[]))
{
if
(
point
==
nullptr
||
callback
==
nullptr
)
return
false
;
AutoLock
lock
(
hook_lock
);
void
*
backup
=
nullptr
;
...
...
@@ -135,9 +138,10 @@ bool InlineHookArm64Android::BreakPoint(void *point, void (*callback)(REG regs[]
void
*
InlineHookArm64Android
::
SingleInstHook
(
void
*
origin
,
void
*
replace
)
{
if
(
!
InitForSingleInstHook
())
{
if
(
origin
==
nullptr
||
replace
==
nullptr
)
return
nullptr
;
if
(
!
InitForSingleInstHook
())
return
nullptr
;
}
AutoLock
lock
(
hook_lock
);
void
*
backup
=
nullptr
;
AssemblerA64
assembler_backup
(
backup_buffer
);
...
...
@@ -163,22 +167,68 @@ void *InlineHookArm64Android::SingleInstHook(void *origin, void *replace) {
__
Finish
();
#undef __
hook_infos
.
push_back
({
origin
,
replace
,
backup
});
hook_infos
.
push_back
({
false
,
nullptr
,
origin
,
replace
,
backup
});
//commit inline trampoline
assembler_inline
.
Finish
();
return
backup
;
}
void
InlineHookArm64Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
bool
InlineHookArm64Android
::
SingleBreakPoint
(
void
*
point
,
BreakCallback
callback
,
void
*
data
)
{
if
(
point
==
nullptr
||
callback
==
nullptr
)
return
false
;
if
(
!
InitForSingleInstHook
())
return
false
;
AutoLock
lock
(
hook_lock
);
void
*
backup
=
nullptr
;
AssemblerA64
assembler_backup
(
backup_buffer
);
StaticCodeBuffer
inline_buffer
=
StaticCodeBuffer
(
reinterpret_cast
<
Addr
>
(
point
));
AssemblerA64
assembler_inline
(
&
inline_buffer
);
CodeContainer
*
code_container_inline
=
&
assembler_inline
.
code_container
;
//build inline trampoline
#define __ assembler_inline.
__
Hvc
(
static_cast
<
U16
>
(
hook_infos
.
size
()));
#undef __
//build backup method
CodeRelocateA64
relocate
=
CodeRelocateA64
(
assembler_backup
);
backup
=
relocate
.
Relocate
(
point
,
code_container_inline
->
Size
(),
nullptr
);
#define __ assembler_backup.
Label
*
origin_addr_label
=
new
Label
();
__
Ldr
(
IP1
,
origin_addr_label
);
__
Br
(
IP1
);
__
Emit
(
origin_addr_label
);
__
Emit
((
Addr
)
point
+
code_container_inline
->
Size
());
__
Finish
();
#undef __
hook_infos
.
push_back
({
true
,
data
,
point
,
(
void
*
)
callback
,
backup
});
//commit inline trampoline
assembler_inline
.
Finish
();
return
true
;
}
bool
InlineHookArm64Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
InstA64
*
code
=
reinterpret_cast
<
InstA64
*>
(
context
->
pc
);
if
(
!
IS_OPCODE_A64
(
*
code
,
EXCEPTION_GEN
))
{
abort
();
}
if
(
!
IS_OPCODE_A64
(
*
code
,
EXCEPTION_GEN
))
return
false
;
INST_A64
(
EXCEPTION_GEN
)
hvc
(
code
);
hvc
.
Disassemble
();
if
(
hvc
.
imme
>=
hook_infos
.
size
())
return
;
return
false
;
HookInfo
&
hook_info
=
hook_infos
[
hvc
.
imme
];
context
->
pc
=
reinterpret_cast
<
U64
>
(
hook_info
.
replace
);
if
(
!
hook_info
.
is_break_point
)
{
context
->
pc
=
reinterpret_cast
<
U64
>
(
hook_info
.
replace
);
}
else
{
BreakCallback
callback
=
reinterpret_cast
<
BreakCallback
>
(
hook_info
.
replace
);
if
(
callback
(
context
,
hook_info
.
user_data
))
{
context
->
pc
=
reinterpret_cast
<
U64
>
(
hook_info
.
backup
);
}
else
{
context
->
pc
+=
4
;
}
}
return
true
;
}
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h
View file @
17d05f69
...
...
@@ -12,11 +12,14 @@ namespace SandHook {
class
InlineHookArm64Android
:
public
InlineHook
{
public
:
void
*
Hook
(
void
*
origin
,
void
*
replace
)
override
;
bool
BreakPoint
(
void
*
point
,
void
(
*
callback
)(
REG
[]))
override
;
bool
SingleBreakPoint
(
void
*
point
,
BreakCallback
callback
,
void
*
data
)
override
;
void
*
SingleInstHook
(
void
*
origin
,
void
*
replace
)
override
;
void
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
override
;
bool
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
override
;
private
:
std
::
vector
<
HookInfo
>
hook_infos
;
...
...
nativehook/src/main/cpp/hook/hook.cpp
View file @
17d05f69
...
...
@@ -25,20 +25,41 @@ void InterruptHandler(int signum, siginfo_t* siginfo, void* uc) {
if
(
signum
!=
SIGILL
)
return
;
sigcontext
&
context
=
reinterpret_cast
<
ucontext_t
*>
(
uc
)
->
uc_mcontext
;
InlineHook
::
instance
->
ExceptionHandler
(
signum
,
&
context
);
if
(
!
InlineHook
::
instance
->
ExceptionHandler
(
signum
,
&
context
))
{
if
(
InlineHook
::
instance
->
old_sig_act
.
sa_sigaction
)
{
InlineHook
::
instance
->
old_sig_act
.
sa_sigaction
(
signum
,
siginfo
,
uc
);
}
}
}
bool
InlineHook
::
InitForSingleInstHook
()
{
AutoLock
lock
(
hook_lock
);
if
(
inited
)
return
true
;
struct
sigaction
sig
{};
sigemptyset
(
&
sig
.
sa_mask
);
// Notice: remove this flag if needed.
sig
.
sa_flags
=
SA_SIGINFO
;
sig
.
sa_sigaction
=
InterruptHandler
;
if
(
sigaction
(
SIGILL
,
&
sig
,
nullptr
)
!=
-
1
)
{
inited
=
true
;
bool
do_init
=
false
;
{
AutoLock
lock
(
hook_lock
);
if
(
inited
)
return
true
;
struct
sigaction
sig
{};
sigemptyset
(
&
sig
.
sa_mask
);
// Notice: remove this flag if needed.
sig
.
sa_flags
=
SA_SIGINFO
;
sig
.
sa_sigaction
=
InterruptHandler
;
if
(
sigaction
(
SIGILL
,
&
sig
,
&
old_sig_act
)
!=
-
1
)
{
inited
=
true
;
do_init
=
true
;
}
}
//protect sigaction
if
(
do_init
)
{
int
(
*
replace
)(
int
,
struct
sigaction
*
,
struct
sigaction
*
)
=
[](
int
sig
,
struct
sigaction
*
new_sa
,
struct
sigaction
*
old_sa
)
->
int
{
if
(
sig
!=
SIGILL
)
{
return
InlineHook
::
instance
->
sigaction_backup
(
sig
,
new_sa
,
old_sa
);
}
else
{
*
old_sa
=
InlineHook
::
instance
->
old_sig_act
;
InlineHook
::
instance
->
old_sig_act
=
*
new_sa
;
return
0
;
}
};
sigaction_backup
=
reinterpret_cast
<
SigAct
>
(
SingleInstHook
((
void
*
)
sigaction
,
(
void
*
)
replace
));
}
return
inited
;
}
\ No newline at end of file
nativehook/src/main/cpp/includes/hook.h
View file @
17d05f69
...
...
@@ -18,11 +18,15 @@ namespace SandHook {
namespace
Hook
{
struct
HookInfo
{
bool
is_break_point
;
void
*
user_data
;
void
*
origin
;
void
*
replace
;
void
*
backup
;
};
using
BreakCallback
=
bool
(
*
)(
sigcontext
*
,
void
*
);
class
InlineHook
{
public
:
//return == backup method
...
...
@@ -30,10 +34,15 @@ namespace SandHook {
virtual
bool
BreakPoint
(
void
*
point
,
void
(
*
callback
)(
REG
[]))
{
return
false
;
};
virtual
bool
SingleBreakPoint
(
void
*
point
,
BreakCallback
callback
,
void
*
data
=
nullptr
)
{
return
false
;
};
virtual
void
*
SingleInstHook
(
void
*
origin
,
void
*
replace
)
{
return
nullptr
;
};
virtual
void
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{};
virtual
bool
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
return
false
;
};
protected
:
virtual
bool
InitForSingleInstHook
();
...
...
@@ -41,8 +50,13 @@ namespace SandHook {
bool
inited
=
false
;
static
CodeBuffer
*
backup_buffer
;
std
::
mutex
hook_lock
;
private
:
using
SigAct
=
int
(
*
)(
int
,
struct
sigaction
*
,
struct
sigaction
*
);
SigAct
sigaction_backup
=
nullptr
;
public
:
static
InlineHook
*
instance
;
struct
sigaction
old_sig_act
{};
};
}
...
...
nativehook/src/main/cpp/sandhook_native.cpp
View file @
17d05f69
...
...
@@ -3,6 +3,8 @@
//
#include <jni.h>
#include <cassert>
#include <cstdlib>
#include "sandhook_native.h"
#include "hook.h"
#include "elf.h"
...
...
@@ -10,6 +12,11 @@
using
namespace
SandHook
::
Hook
;
using
namespace
SandHook
::
Elf
;
extern
"C"
EXPORT
void
*
SandGetModuleBase
(
const
char
*
so
)
{
return
ElfImg
::
GetModuleBase
(
so
);
}
extern
"C"
EXPORT
void
*
SandGetSym
(
const
char
*
so
,
const
char
*
symb
)
{
ElfImg
elfImg
(
so
);
...
...
@@ -47,6 +54,33 @@ EXPORT void* SandSingleInstHookSym(const char* so, const char* symb, void* repla
}
extern
"C"
EXPORT
bool
SandBreak
point
(
void
*
origin
,
void
(
*
callback
)(
REG
[]))
{
EXPORT
bool
SandBreak
Point
(
void
*
origin
,
void
(
*
callback
)(
REG
[]))
{
return
InlineHook
::
instance
->
BreakPoint
(
origin
,
callback
);
}
\ No newline at end of file
}
extern
"C"
EXPORT
bool
SandSingleInstBreakPoint
(
void
*
origin
,
BreakCallback
(
callback
))
{
return
InlineHook
::
instance
->
SingleBreakPoint
(
origin
,
callback
);
}
#if defined(__aarch64__)
fpsimd_context
*
GetSimdContext
(
sigcontext
*
mcontext
)
{
size_t
size
=
0
;
do
{
fpsimd_context
*
fp
=
reinterpret_cast
<
fpsimd_context
*>
(
&
mcontext
->
__reserved
[
size
]);
if
(
fp
->
head
.
magic
==
FPSIMD_MAGIC
)
{
assert
(
fp
->
head
.
size
>=
sizeof
(
fpsimd_context
));
assert
(
size
+
fp
->
head
.
size
<=
sizeof
(
mcontext
->
__reserved
));
return
fp
;
}
if
(
fp
->
head
.
size
==
0
)
{
break
;
}
size
+=
fp
->
head
.
size
;
}
while
(
size
+
sizeof
(
fpsimd_context
)
<=
sizeof
(
mcontext
->
__reserved
));
abort
();
return
nullptr
;
}
#endif
\ No newline at end of file
nativehook/src/main/cpp/sandhook_native.h
View file @
17d05f69
...
...
@@ -4,10 +4,17 @@
#pragma once
#include <signal.h>
typedef
size_t
REG
;
#define EXPORT __attribute__ ((visibility ("default")))
#define BreakCallback(callback) bool(*callback)(sigcontext*, void*)
extern
"C"
EXPORT
void
*
SandGetModuleBase
(
const
char
*
so
);
extern
"C"
EXPORT
void
*
SandGetSym
(
const
char
*
so
,
const
char
*
sym
);
...
...
@@ -24,4 +31,15 @@ extern "C"
EXPORT
void
*
SandSingleInstHookSym
(
const
char
*
so
,
const
char
*
symb
,
void
*
replace
);
extern
"C"
EXPORT
bool
SandBreakpoint
(
void
*
origin
,
void
(
*
callback
)(
REG
[]));
\ No newline at end of file
EXPORT
bool
SandBreakPoint
(
void
*
origin
,
void
(
*
callback
)(
REG
[]));
extern
"C"
EXPORT
bool
SandSingleInstBreakPoint
(
void
*
origin
,
BreakCallback
(
callback
));
#if defined(__aarch64__)
#include <asm/sigcontext.h>
extern
"C"
EXPORT
fpsimd_context
*
GetSimdContext
(
sigcontext
*
mcontext
);
#endif
\ No newline at end of file
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