Commit 2c5124f5 authored by swift_gan's avatar swift_gan Committed by swift_gan

add armv8

parent 372876e9
...@@ -18,8 +18,19 @@ add_library( # Sets the name of the library. ...@@ -18,8 +18,19 @@ add_library( # Sets the name of the library.
# Provides a relative path to your source file(s). # Provides a relative path to your source file(s).
src/main/cpp/sandhook_native.cpp src/main/cpp/sandhook_native.cpp
src/main/cpp/decoder/decoder.cpp
src/main/cpp/archs/arm64/inst_arm64.cpp
src/main/cpp/archs/arm64/decoder_arm64.cpp
) )
include_directories(
src/main/cpp/asm
src/main/cpp/decoder
src/main/cpp/elf
src/main/cpp/includes
)
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by # variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library # default, you only need to specify the name of the public NDK library
......
...@@ -15,8 +15,8 @@ android { ...@@ -15,8 +15,8 @@ android {
externalNativeBuild { externalNativeBuild {
cmake { cmake {
arguments '-DBUILD_TESTING=OFF', '-DANDROID_TOOLCHAIN=gcc' arguments '-DBUILD_TESTING=OFF'
cppFlags "-frtti -fexceptions" cppFlags "-frtti -fexceptions -Wpointer-arith"
abiFilters 'armeabi-v7a', 'arm64-v8a' abiFilters 'armeabi-v7a', 'arm64-v8a'
} }
} }
......
//
// Created by swift on 2019/5/6.
//
#include "decoder_arm64.h"
//
// Created by swift on 2019/5/6.
//
#ifndef SANDHOOK_NH_DECODER_ARM64_H
#define SANDHOOK_NH_DECODER_ARM64_H
#include "decoder.h"
namespace SandHook {
namespace Decoder {
class Arm64Decoder {
};
}
}
#endif //SANDHOOK_NH_DECODER_ARM64_H
//
// Created by swift on 2019/5/6.
//
#include "inst_arm64.h"
using namespace SandHook::Asm;
//PC Rel Inst
int A64_INST_PC_REL::getImmPCRel() {
U32 hi = static_cast<U32>(get().immhi);
U32 lo = get().immlo;
U32 offset = (hi << IMM_LO_W) | lo;
int width = IMM_HI_W + IMM_LO_W;
return ExtractSignedBitfield32(width - 1, 0, offset);
}
ADDR A64_INST_PC_REL::getImmPCOffset() {
return static_cast<ADDR>(getImmBranch() * size());
}
ADDR A64_INST_PC_REL::getImmPCOffsetTarget() {
return reinterpret_cast<ADDR>(getImmPCOffset() + (ADDR) getPC());
}
//ADR ADRP
ADDR A64_ADR_ADRP::getImmPCOffset() {
ADDR offset = static_cast<ADDR>(getImmPCRel());
if (isADRP()) {
offset *= PAGE_SIZE;
}
return offset;
}
ADDR A64_ADR_ADRP::getImmPCOffsetTarget() {
Instruction* base = AlignDown(this, PAGE_SIZE);
return reinterpret_cast<ADDR>(getImmPCOffset() + (ADDR) base);
}
int A64_ADR_ADRP::getImm() {
return getImmPCRel();
}
\ No newline at end of file
//
// Created by swift on 2019/5/6.
//
#ifndef SANDHOOK_NH_INST_ARM64_H
#define SANDHOOK_NH_INST_ARM64_H
#include "inst_struct_aarch64.h"
#include "../../asm/instruction.h"
#include "../../includes/base.h"
namespace SandHook {
namespace Asm {
template<typename InstStruct>
class InstructionA64 : public Instruction<InstStruct> {
public:
InstStruct mask(InstStruct raw) {
return raw & (InstStruct) *this;
}
bool IsPCRelAddressing() {
return mask(PCRelAddressingFMask) == PCRelAddressingFixed;
}
int getImmBranch() {
//TODO
return 0;
}
};
class A64_INST_PC_REL : public InstructionA64<aarch64_pcrel_insts> {
public:
int getImmPCRel();
ADDR getImmPCOffset();
ADDR getImmPCOffsetTarget();
};
class A64_ADR_ADRP : public A64_INST_PC_REL {
public:
bool isADRP() {
return get().op == 1;
}
ADDR getImmPCOffset();
ADDR getImmPCOffsetTarget();
int getImm();
};
}
}
#endif //SANDHOOK_NH_INST_ARM64_H
//
// Created by swift on 2019/5/5.
//
#ifndef SANDHOOK_NH_INST_AARCH64_H
#define SANDHOOK_NH_INST_AARCH64_H
#include "../../asm/instruction.h"
enum PCRelAddressingOp {
PCRelAddressingFixed = 0x10000000,
PCRelAddressingFMask = 0x1F000000,
PCRelAddressingMask = 0x9F000000,
ADR = PCRelAddressingFixed | 0x00000000,
ADRP = PCRelAddressingFixed | 0x80000000
};
enum ImmBranchType {
UnknownBranchType = 0,
CondBranchType = 1,
UncondBranchType = 2,
CompareBranchType = 3,
TestBranchType = 4
};
#define IMM_LO_W 2
#define IMM_HI_W 19
struct aarch64_pcrel_insts {
InstA64 op:1;
InstA64 immlo:IMM_LO_W;
InstA64 opcode:5;
InstA64 immhi:IMM_HI_W;
InstA64 rd:5;
};
struct aarch64_adr_adrp : public aarch64_pcrel_insts {};
#endif //SANDHOOK_NH_INST_AARCH64_H
...@@ -5,11 +5,59 @@ ...@@ -5,11 +5,59 @@
#ifndef SANDHOOK_INSTRUCTION_H #ifndef SANDHOOK_INSTRUCTION_H
#define SANDHOOK_INSTRUCTION_H #define SANDHOOK_INSTRUCTION_H
#include "../includes/base.h"
typedef U32 InstA64;
typedef U32 InstA32;
typedef U16 InstT16;
typedef U32 InstT32;
#if defined(__aarch64__)
typedef U32 InstRaw;
#endif
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename Raw>
class Instruction { class Instruction {
public:
inline void* getPC() const {
return (void *) this;
}
bool pcRelate() {
return false;
}
Raw get() {
return *reinterpret_cast<Raw*>(this);
}
void set(Raw raw) {
*this = raw;
}
U8 size() {
return sizeof(Raw);
}
bool operator&(const Instruction &rhs) {
return rhs == *this;
}
bool operator==(const Instruction &rhs) {
return rhs == *this;
}
bool operator!=(const Instruction &rhs) {
return !(rhs == *this);
}
virtual ~Instruction() {
}
}; };
} }
......
//
// Created by swift on 2019/5/6.
//
#include "decoder.h"
using namespace SandHook::Decoder;
InstDecoder* Decoder::get(Arch arch) {
switch (arch) {
case arm32:
break;
case arm64:
break;
default:
return nullptr;
}
return nullptr;
}
\ No newline at end of file
//
// Created by swift on 2019/5/6.
//
#ifndef SANDHOOK_NH_DECODER_H
#define SANDHOOK_NH_DECODER_H
#include "../includes/base.h"
#include "../asm/instruction.h"
namespace SandHook {
namespace Decoder {
using namespace Asm;
class InstVisitor {
public:
virtual bool visit(Instruction<void>* inst, ADDR offset, ADDR length) = 0;
};
class InstDecoder {
public:
virtual void decode(void* codeStart, ADDR codeLen, InstVisitor* visitor) = 0;
};
class Decoder {
static InstDecoder* get(Arch arch);
};
}
}
#endif //SANDHOOK_NH_DECODER_H
...@@ -6,29 +6,160 @@ ...@@ -6,29 +6,160 @@
#define SANDHOOK_BASE_H #define SANDHOOK_BASE_H
#include <cstdint> #include <cstdint>
#include <cstring>
#include "compiler.h"
typedef uint8_t U8; typedef uint8_t U8;
typedef uint16_t U16; typedef uint16_t U16;
typedef uint32_t U32; typedef uint32_t U32;
typedef uint64_t U64; typedef uint64_t U64;
typedef size_t Address; typedef size_t ADDR;
const int PTR_BYTE = sizeof(void*);
#define PAGE_OFFSET 12
const int BITS_OF_BYTE = 8;
const ADDR PAGE_SIZE = 2 << PAGE_OFFSET;
enum Arch { enum Arch {
arm32, arm32,
arm64, arm64
x86,
x64,
mips
}; };
enum InstType { enum InstType {
arm32, A32,
thumb16, thumb16,
thumb32, thumb32,
aarch64, A64
x86, };
x64
template <int SizeInBits>
struct Unsigned;
template <>
struct Unsigned<16> {
typedef U16 type;
};
template <>
struct Unsigned<32> {
typedef U32 type;
}; };
template <>
struct Unsigned<64> {
typedef U64 type;
};
template <typename T>
T AlignDown(T pointer,
typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type alignment) {
// Use C-style casts to get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types.
typename Unsigned<sizeof(T)* BITS_OF_BYTE>::type pointer_raw =
(typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type)pointer;
size_t mask = alignment - 1;
return (T)(pointer_raw & ~mask);
}
#define OFFSET(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
//data covert
// Macros for compile-time format checking.
#if GCC_VERSION_OR_NEWER(4, 4, 0)
#define PRINTF_CHECK(format_index, varargs_index) \
__attribute__((format(gnu_printf, format_index, varargs_index)))
#else
#define PRINTF_CHECK(format_index, varargs_index)
#endif
#ifdef __GNUC__
#define VIXL_HAS_DEPRECATED_WITH_MSG
#elif defined(__clang__)
#ifdef __has_extension(attribute_deprecated_with_message)
#define VIXL_HAS_DEPRECATED_WITH_MSG
#endif
#endif
#ifdef VIXL_HAS_DEPRECATED_WITH_MSG
#define VIXL_DEPRECATED(replaced_by, declarator) \
__attribute__((deprecated("Use \"" replaced_by "\" instead"))) declarator
#else
#define VIXL_DEPRECATED(replaced_by, declarator) declarator
#endif
inline uint64_t TruncateToUintN(unsigned n, uint64_t x) {
return static_cast<uint64_t>(x) & ((UINT64_C(1) << n) - 1);
}
VIXL_DEPRECATED("TruncateToUintN",
inline uint64_t truncate_to_intn(unsigned n, int64_t x)) {
return TruncateToUintN(n, x);
}
// clang-format off
#define INT_1_TO_32_LIST(V) \
V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \
V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \
V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) \
V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32)
#define INT_33_TO_63_LIST(V) \
V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \
V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \
V(49) V(50) V(51) V(52) V(53) V(54) V(55) V(56) \
V(57) V(58) V(59) V(60) V(61) V(62) V(63)
#define INT_1_TO_63_LIST(V) INT_1_TO_32_LIST(V) INT_33_TO_63_LIST(V)
#define DECLARE_TRUNCATE_TO_UINT_32(N) \
inline uint32_t TruncateToUint##N(uint64_t x) { \
return static_cast<uint32_t>(TruncateToUintN(N, x)); \
} \
VIXL_DEPRECATED("TruncateToUint" #N, \
inline uint32_t truncate_to_int##N(int64_t x)) { \
return TruncateToUint##N(x); \
}
INT_1_TO_32_LIST(DECLARE_TRUNCATE_TO_UINT_32)
#undef DECLARE_TRUNCATE_TO_INT_N
// Bit field extraction.
inline uint64_t ExtractUnsignedBitfield64(int msb, int lsb, uint64_t x) {
if ((msb == 63) && (lsb == 0)) return x;
return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1);
}
inline int64_t ExtractSignedBitfield64(int msb, int lsb, int64_t x) {
uint64_t temp = ExtractUnsignedBitfield64(msb, lsb, x);
// If the highest extracted bit is set, sign extend.
if ((temp >> (msb - lsb)) == 1) {
temp |= ~UINT64_C(0) << (msb - lsb);
}
int64_t result;
memcpy(&result, &temp, sizeof(result));
return result;
}
inline int32_t ExtractSignedBitfield32(int msb, int lsb, int32_t x) {
uint32_t temp = TruncateToUint32(ExtractSignedBitfield64(msb, lsb, x));
int32_t result;
memcpy(&result, &temp, sizeof(result));
return result;
}
#endif //SANDHOOK_BASE_H #endif //SANDHOOK_BASE_H
//
// Created by swift on 2019/5/6.
//
#ifndef SANDHOOK_NH_COMPILER_H
#define SANDHOOK_NH_COMPILER_H
// Helper to check whether the version of GCC used is greater than the specified
// requirement.
#define MAJOR 1000000
#define MINOR 1000
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * (MAJOR) + __GNUC_MINOR__ * (MINOR) + __GNUC_PATCHLEVEL__) >= \
((major) * (MAJOR) + ((minor)) * (MINOR) + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * (MAJOR) + __GNUC_MINOR__ * (MINOR)) >= \
((major) * (MAJOR) + ((minor)) * (MINOR) + (patchlevel)))
#else
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) 0
#endif
#if defined(__clang__) && !defined(VIXL_NO_COMPILER_BUILTINS)
// clang-format off
#define COMPILER_HAS_BUILTIN_CLRSB (__has_builtin(__builtin_clrsb))
#define COMPILER_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
#define COMPILER_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
#define COMPILER_HAS_BUILTIN_FFS (__has_builtin(__builtin_ffs))
#define COMPILER_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
// clang-format on
#elif defined(__GNUC__) && !defined(VIXL_NO_COMPILER_BUILTINS)
// The documentation for these builtins is available at:
// https://gcc.gnu.org/onlinedocs/gcc-$MAJOR.$MINOR.$PATCHLEVEL/gcc//Other-Builtins.html
// clang-format off
# define COMPILER_HAS_BUILTIN_CLRSB (GCC_VERSION_OR_NEWER(4, 7, 0))
# define COMPILER_HAS_BUILTIN_CLZ (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_CTZ (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_FFS (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_POPCOUNT (GCC_VERSION_OR_NEWER(3, 4, 0))
// clang-format on
#else
// One can define VIXL_NO_COMPILER_BUILTINS to force using the manually
// implemented C++ methods.
// clang-format off
#define COMPILER_HAS_BUILTIN_BSWAP false
#define COMPILER_HAS_BUILTIN_CLRSB false
#define COMPILER_HAS_BUILTIN_CLZ false
#define COMPILER_HAS_BUILTIN_CTZ false
#define COMPILER_HAS_BUILTIN_FFS false
#define COMPILER_HAS_BUILTIN_POPCOUNT false
// clang-format on
#endif
#endif //SANDHOOK_NH_COMPILER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment