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
935457ea
Commit
935457ea
authored
Sep 02, 2019
by
swift_gan
Committed by
swift_gan
Sep 02, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add SingleInstBreakPoint
parent
d714cd48
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
188 additions
and
16 deletions
+188
-16
README.md
README.md
+1
-1
hook_arm32.cpp
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
+64
-5
hook_arm32.h
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h
+2
-0
hook_arm64.cpp
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
+56
-7
hook_arm64.h
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h
+3
-0
hook.h
nativehook/src/main/cpp/includes/hook.h
+7
-0
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 @
935457ea
...
...
@@ -233,7 +233,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 @
935457ea
...
...
@@ -4,6 +4,7 @@
#include <log.h>
#include <cstdlib>
#include <cassert>
#include "code_relocate_arm32.h"
#include "hook_arm32.h"
#include "code_buffer.h"
...
...
@@ -75,6 +76,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 +132,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 +171,76 @@ 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
);
}
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
;
}
void
InlineHookArm32Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
assert
(
num
==
SIGILL
);
InstT32
*
code
=
reinterpret_cast
<
InstT32
*>
(
context
->
arm_pc
);
if
(
!
IS_OPCODE_T32
(
*
code
,
HVC
))
{
abort
();
}
assert
(
IS_OPCODE_T32
(
*
code
,
HVC
));
INST_T32
(
HVC
)
hvc
(
code
);
hvc
.
Disassemble
();
if
(
hvc
.
imme
>=
hook_infos
.
size
())
return
;
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
.
replace
);
}
else
{
context
->
arm_pc
+=
4
;
}
}
}
nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h
View file @
935457ea
...
...
@@ -16,6 +16,8 @@ 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
;
...
...
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
View file @
935457ea
...
...
@@ -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,67 @@ 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
;
}
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
;
}
void
InlineHookArm64Android
::
ExceptionHandler
(
int
num
,
sigcontext
*
context
)
{
assert
(
num
==
SIGILL
);
InstA64
*
code
=
reinterpret_cast
<
InstA64
*>
(
context
->
pc
);
if
(
!
IS_OPCODE_A64
(
*
code
,
EXCEPTION_GEN
))
{
abort
();
}
assert
(
IS_OPCODE_A64
(
*
code
,
EXCEPTION_GEN
));
INST_A64
(
EXCEPTION_GEN
)
hvc
(
code
);
hvc
.
Disassemble
();
if
(
hvc
.
imme
>=
hook_infos
.
size
())
return
;
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
.
replace
);
}
else
{
context
->
pc
+=
4
;
}
}
}
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h
View file @
935457ea
...
...
@@ -12,8 +12,11 @@ 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
;
...
...
nativehook/src/main/cpp/includes/hook.h
View file @
935457ea
...
...
@@ -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,6 +34,9 @@ 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
;
};
...
...
nativehook/src/main/cpp/sandhook_native.cpp
View file @
935457ea
...
...
@@ -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 @
935457ea
...
...
@@ -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