Commit 45832ece authored by swift_gan's avatar swift_gan Committed by swift_gan

add arm32 & tweak code

parent 6a4150d7
......@@ -11,28 +11,31 @@ cmake_minimum_required(VERSION 3.4.1)
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
sandhook-native
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/sandhook_native.cpp
src/main/cpp/decoder/decoder.cpp
src/main/cpp/archs/arm64/assembler/assembler_a64.cpp
src/main/cpp/archs/arm64/inst/inst_arm64.cpp
src/main/cpp/archs/arm64/register/register_a64.cpp
src/main/cpp/archs/arm64/register/register_list_a64.cpp
src/main/cpp/archs/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm64/relocate/code_relocate_a64.cpp
src/main/cpp/archs/arm32/inst/inst_arm32.cpp
src/main/cpp/archs/arm32/register/register_a32.cpp
src/main/cpp/relocate/code_relocate.cpp
src/main/cpp/elf/elf.cpp
src/main/cpp/assembler/assembler.cpp
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp
src/main/cpp/hook/hook.cpp
sandhook-native
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/sandhook_native.cpp
src/main/cpp/decoder/decoder.cpp
src/main/cpp/archs/arm/arm64/assembler/assembler_a64.cpp
src/main/cpp/archs/arm/arm64/inst/inst_arm64.cpp
src/main/cpp/archs/arm/arm64/register/register_a64.cpp
src/main/cpp/archs/arm/arm64/register/register_list_a64.cpp
src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm/arm64/relocate/code_relocate_a64.cpp
src/main/cpp/archs/arm/arm32/inst/inst_arm32.cpp
src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp
src/main/cpp/archs/arm/arm32/inst/inst_t16.cpp
src/main/cpp/archs/arm/arm32/register/register_a32.cpp
src/main/cpp/archs/arm/arm32/register/register_list_a32.cpp
src/main/cpp/relocate/code_relocate.cpp
src/main/cpp/elf/elf.cpp
src/main/cpp/assembler/assembler.cpp
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp
src/main/cpp/hook/hook.cpp
)
......@@ -43,13 +46,14 @@ include_directories(
src/main/cpp/utils
src/main/cpp/includes
src/main/cpp/buffer
src/main/cpp/archs/arm64/inst
src/main/cpp/archs/arm64/register
src/main/cpp/archs/arm64/decoder
src/main/cpp/archs/arm64/assembler
src/main/cpp/archs/arm64/relocate
src/main/cpp/archs/arm32/inst
src/main/cpp/archs/arm32/register
src/main/cpp/archs/arm
src/main/cpp/archs/arm/arm64/inst
src/main/cpp/archs/arm/arm64/register
src/main/cpp/archs/arm/arm64/decoder
src/main/cpp/archs/arm/arm64/assembler
src/main/cpp/archs/arm/arm64/relocate
src/main/cpp/archs/arm/arm32/inst
src/main/cpp/archs/arm/arm32/register
)
# Searches for a specified prebuilt library and stores the path as a
......@@ -59,22 +63,22 @@ include_directories(
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
sandhook-native
sandhook-native
# Links the target library to the log library
# included in the NDK.
${log-lib} )
# Links the target library to the log library
# included in the NDK.
${log-lib})
add_definitions(-std=c++11)
......
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_ARM32_BASE_H
#define SANDHOOK_ARM32_BASE_H
#include "arm_base.h"
#include "register_list_a32.h"
#define DECODE_OFFSET(bits, ext) signExtend32(bits + ext, COMBINE(get()->imm##bits, 0, ext))
#define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext)
using namespace SandHook::RegistersA32;
namespace SandHook {
namespace AsmA32 {
enum Sign { Plus, Minus };
class MemOperand {
public:
explicit MemOperand(RegisterA32* rn, S32 offset = 0, AddrMode am = Offset)
: rn(rn), rm(&UnknowRegiser), offset(offset), addr_mode(am) {}
explicit MemOperand(RegisterA32* rn, RegisterA32* rm, AddrMode am = Offset)
: rn(rn), rm(rm), shift(LSL), shift_imm(0), addr_mode(am) {
}
explicit MemOperand(RegisterA32* rn, RegisterA32* rm, Shift shift, int shift_imm, AddrMode am = Offset)
: rn(rn), rm(rm), shift(shift), shift_imm(shift_imm & 31), addr_mode(am) {
}
// =====
bool IsImmediateOffset() const { return (addr_mode == Offset); }
bool IsRegisterOffset() const { return (addr_mode == Offset); }
bool IsPreIndex() const { return addr_mode == PreIndex; }
bool IsPostIndex() const { return addr_mode == PostIndex; }
public:
RegisterA32* rn; // base
RegisterA32* rm; // register offset
S32 offset; // valid if rm_ == no_reg
Shift shift;
Sign sign;
int shift_imm; // valid if rm_ != no_reg && rs_ == no_reg
AddrMode addr_mode; // bits P, U, and W
};
}
}
#endif //SANDHOOK_ARM32_BASE_H
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_INST_CODE_ARM32_H
#define SANDHOOK_INST_CODE_ARM32_H
enum InstCodeA32 {
};
enum InstCodeT16 {
B,
B_COND,
BX_BLX
};
enum InstCodeT32 {
};
#endif //SANDHOOK_INST_CODE_ARM32_H
......@@ -2,11 +2,11 @@
// Created by swift on 2019/5/12.
//
#ifndef SANDHOOK_NH_INST_STRCUT_ARM32_H
#define SANDHOOK_NH_INST_STRCUT_ARM32_H
#ifndef SANDHOOK_NH_INST_STRUCT_ARM32_H
#define SANDHOOK_NH_INST_STRUCT_ARM32_H
#include "../../../asm/instruction.h"
#include "instruction.h"
#define STRUCT_A32(X) A32_STRUCT_##X
#define OPCODE_A32(X) A32_OPCODE_##X
......
//
// Created by swift on 2019/5/12.
//
#ifndef SANDHOOK_NH_INST_STRUCT_T16_H
#define SANDHOOK_NH_INST_STRUCT_T16_H
#include "instruction.h"
#include "inst_code_arm32.h"
#define STRUCT_T16(X) T16_STRUCT_##X
#define OPCODE_T16(X) T16_OPCODE_##X
#define DEFINE_OPCODE_T16(X, V) const U32 OPCODE_T16(X) = V;
#define DEFINE_STRUCT_T16(X) struct STRUCT_T16(X) : public Base
#define DEFINE_STRCUT_BASE_T16(w_base, w_op) \
InstT16 opcode:w_op; \
InstT16 opcode_base:w_base;
//Shift (immediate), add, subtract, move, and compare
//opcode_base == 0b00
DEFINE_OPCODE_T16(BASE_SASMC, 0b00)
//Data-processing
DEFINE_OPCODE_T16(DATA_PROC, 0b010000)
DEFINE_OPCODE_T16(SPDIABE, 0b010001)
DEFINE_OPCODE_T16(MISC, 0b1011)
DEFINE_OPCODE_T16(B, 0b11100)
DEFINE_STRUCT_T16(B) {
InstT16 imm11:11;
InstT16 opcode:5;
};
DEFINE_OPCODE_T16(B_COND, 0b1101)
DEFINE_STRUCT_T16(B_COND) {
InstT16 imm8;
InstT16 cond:4;
InstT16 opcode:4;
};
DEFINE_OPCODE_T16(BX_BLX_1, 0b01000111)
DEFINE_OPCODE_T16(BX_BLX_2, 0b000)
DEFINE_STRUCT_T16(BX_BLX) {
InstT16 opcode2:3;
InstT16 rm:4;
InstT16 op:1;
InstT16 opcode1:8;
};
#endif //SANDHOOK_NH_INST_STRUCT_T16_H
//
// Created by swift on 2019/5/12.
//
#ifndef SANDHOOK_NH_INST_STRUCT_T16_H
#define SANDHOOK_NH_INST_STRUCT_T16_H
#include "instruction.h"
#define STRUCT_T32(X) T32_STRUCT_##X
#define OPCODE_T32(X) T32_OPCODE_##X
#define DEFINE_OPCODE_T32(X, V) const U32 OPCODE_T32(X) = V;
#define DEFINE_STRUCT_T32(X) struct STRUCT_T32(X) : public Base
DEFINE_OPCODE_T32(B, 0b010)
DEFINE_STRUCT_T32(B) {
};
#endif //SANDHOOK_NH_INST_STRUCT_T16_H
//
// Created by swift on 2019/5/16.
//
#include "inst_t16.h"
#include "arm32_base.h"
#define SET_BASE_OPCODE(X) get()->opcode_base = OPCODE_T16(X)
#define SET_OPCODE(X) get()->opcode = OPCODE_T16(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_T16(X##_##INDEX)
using namespace SandHook::AsmA32;
T16_B::T16_B() {}
T16_B::T16_B(T16_STRUCT_B *inst) : T16_INST_PC_REL(inst) {
decode(inst);
}
T16_B::T16_B(Off offset) : offset(offset) {}
T16_B::T16_B(Label &label) {
bindLabel(label);
}
Off T16_B::getImmPCOffset() {
return signExtend32(11 + 1, COMBINE(get()->imm11, 0, 1));
}
void T16_B::decode(T16_STRUCT_B *inst) {
offset = getImmPCOffset();
}
void T16_B::assembler() {
SET_OPCODE(B);
get()->imm11 = TruncateToUint11(offset >> 1);
}
void T16_B::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm11 = TruncateToUint11(offset >> 1);
}
T16_B_COND::T16_B_COND() {}
T16_B_COND::T16_B_COND(STRUCT_T16(B_COND) *inst) : T16_INST_PC_REL(inst) {
decode(inst);
}
T16_B_COND::T16_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
T16_B_COND::T16_B_COND(Condition condition, Label &label) {
bindLabel(label);
}
void T16_B_COND::decode(STRUCT_T16(B_COND) *inst) {
DECODE_COND;
offset = getImmPCOffset();
}
void T16_B_COND::assembler() {
SET_OPCODE(B_COND);
ENCODE_COND;
ENCODE_OFFSET(8, 1);
}
void T16_B_COND::onOffsetApply(Off offset) {
this->offset = offset;
ENCODE_OFFSET(8, 1);
}
Off T16_B_COND::getImmPCOffset() {
return DECODE_OFFSET(8, 1);
}
void T16_BX_BLX::decode(STRUCT_T16(BX_BLX) *inst) {
DECODE_OP;
DECODE_RM(Reg);
}
void T16_BX_BLX::assembler() {
SET_OPCODE_MULTI(BX_BLX, 1);
SET_OPCODE_MULTI(BX_BLX, 2);
ENCODE_OP;
ENCODE_RM;
}
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_INST_T16_H
#define SANDHOOK_INST_T16_H
#include "arm_base.h"
#include "register_list_a32.h"
#include "inst_struct_t16.h"
#include "inst_code_arm32.h"
#define INST_T16(X) T16_##X
#define IS_OPCODE_T16(RAW,OP) INST_T16(OP)::is(RAW)
#define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstT16& inst) { \
union { \
InstT16 raw; \
STRUCT_T16(X) inst; \
} inst_test; \
inst_test.raw = inst; \
return COND; \
}
#define DEFINE_IS(X) DEFINE_IS_EXT(X, TEST_INST_FIELD(opcode,OPCODE_T16(X)))
#define TEST_INST_FIELD(F,V) inst_test.inst.F == V
#define INST_FIELD(F) inst_test.inst.F
#define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_T16(X##_##INDEX)
#define DEFINE_INST_CODE(X) \
inline U32 instCode() override { \
return InstCodeT16::X; \
}
using namespace SandHook::RegistersA32;
namespace SandHook {
namespace AsmA32 {
template<typename Inst>
class InstructionT16 : public Instruction<Inst> {
public:
InstructionT16() {}
InstructionT16(Inst *inst) : Instruction<Inst>(inst) {}
Inst mask(Inst raw) {
return raw & *(this->get());
}
U32 size() override {
return 2;
}
static inline U32 zeroExtend32(unsigned int bits, U32 value) {
return value << (32 - bits);
}
static inline S32 signExtend32(unsigned int bits, U32 value) {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
InstType instType() override {
return thumb16;
}
Arch arch() override {
return arm32;
}
};
template <typename Inst>
class T16_INST_PC_REL : public InstructionT16<Inst> {
public:
T16_INST_PC_REL() {};
T16_INST_PC_REL(Inst *inst) : InstructionT16<Inst>(inst) {};
virtual Off getImmPCOffset() {
return 0;
};
virtual Addr getImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset();
};
inline bool pcRelate() override {
return true;
};
};
class INST_T16(B) : public T16_INST_PC_REL<STRUCT_T16(B)> {
public:
T16_B();
T16_B(STRUCT_T16(B) *inst);
T16_B(Off offset);
T16_B(Label& label);
DEFINE_IS(B)
DEFINE_INST_CODE(B)
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override;
void decode(STRUCT_T16(B) *inst) override;
void assembler() override;
public:
Off offset;
};
class INST_T16(B_COND) : public T16_INST_PC_REL<STRUCT_T16(B_COND)> {
public:
T16_B_COND();
T16_B_COND(STRUCT_T16(B_COND) *inst);
T16_B_COND(Condition condition, Off offset);
T16_B_COND(Condition condition, Label& label);
DEFINE_IS_EXT(B_COND, TEST_INST_FIELD(opcode, OPCODE_T16(B_COND)) && INST_FIELD(cond) != 0b1110 && INST_FIELD(cond) != 0b1111)
DEFINE_INST_CODE(B_COND)
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(STRUCT_T16(B_COND) *inst) override;
void assembler() override;
public:
Condition condition;
Off offset;
};
class INST_T16(BX_BLX) : T16_INST_PC_REL<STRUCT_T16(BX_BLX)> {
public:
enum OP {
BX = 0b0,
BLX = 0b1
};
private:
void decode(T16_STRUCT_BX_BLX *inst) override;
void assembler() override;
public:
OP op;
RegisterA32* rm;
};
}
}
#endif //SANDHOOK_INST_T16_H
//
// Created by swift on 2019/5/16.
//
#include "inst_t32.h"
#include "inst_struct_t32.h"
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_INST_T32_H
#define SANDHOOK_INST_T32_H
#endif //SANDHOOK_INST_T32_H
......@@ -3,11 +3,24 @@
//
#include "register_a32.h"
#include "register_list_a32.h"
SandHook::Asm::RegisterA32::RegisterA32(U8 code) : Register(code) {
using namespace SandHook::RegistersA32;
SandHook::Asm::RegisterA32::RegisterA32(U8 code) : Register(code) {
}
SandHook::Asm::RegisterA32::RegisterA32() {
}
U8 SandHook::Asm::RegisterA32::getWide() {
return 4;
}
RegisterA32* RegisterA32::registers[ARM32_REGISTER_COUNT] = {
#define DEFINE_REGISTERS_X(N) \
&R##N,
ARM32_REGISTER_CODE_LIST(DEFINE_REGISTERS_X)
#undef DEFINE_REGISTERS_X
};
\ No newline at end of file
......@@ -16,19 +16,18 @@ namespace SandHook {
class RegisterA32 : public Register {
public:
enum RegisterType {
// The kInvalid value is used to detect uninitialized static instances,
// which are always zero-initialized before any constructors are called.
kInvalid = 0,
kRegister,
kVRegister,
kFPRegister = kVRegister,
kNoRegister
};
RegisterA32();
RegisterA32(U8 code);
U8 getWide() override;
static RegisterA32* get(U8 code) {
return registers[code];
}
private:
static RegisterA32* registers[];
};
}
}
......
//
// Created by swift on 2019/5/16.
//
#include "register_list_a32.h"
namespace SandHook {
namespace RegistersA32 {
#define INIT_REGISTERS(N) \
RegisterA32 R##N = RegisterA32(N);
ARM32_REGISTER_CODE_LIST(INIT_REGISTERS)
#undef INIT_REGISTERS
enum RegNum {
kIPRegNum = 12, kSPRegNum = 13, kLRRegNum = 14, kPCRegNum = 15
};
RegisterA32 SP = *Reg(kSPRegNum);
RegisterA32 IP = *Reg(kIPRegNum);
RegisterA32 LR = *Reg(kLRRegNum);
RegisterA32 PC = *Reg(kPCRegNum);
RegisterA32 UnknowRegiser = RegisterA32(38);
}}
\ No newline at end of file
//
// Created by swift on 2019/5/8.
//
#ifndef SANDHOOK_NH_REGISTER_LIST_A32_H
#define SANDHOOK_NH_REGISTER_LIST_A32_H
#include "register_a32.h"
using namespace SandHook::Asm;
// clang-format off
#define ARM32_REGISTER_COUNT 16
#define ARM32_REGISTER_CODE_LIST(R) \
R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \
R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15)
namespace SandHook {
namespace RegistersA32 {
#define DEFINE_REGISTERS(N) \
extern RegisterA32 R##N;
ARM32_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
extern RegisterA32 SP;
extern RegisterA32 IP;
extern RegisterA32 LR;
extern RegisterA32 PC;
extern RegisterA32 UnknowRegiser;
}}
#define Reg(N) RegisterA32::get(N)
#endif //SANDHOOK_NH_REGISTER_LIST_A32_H
......@@ -5,6 +5,8 @@
#include "assembler_a64.h"
using namespace SandHook::Assembler;
using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64;
AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer);
......
......@@ -9,6 +9,8 @@
#include "register_a64.h"
#include "inst_arm64.h"
using namespace SandHook::AsmA64;
namespace SandHook {
namespace Assembler {
......
......@@ -2,13 +2,14 @@
// Created by swift on 2019/5/6.
//
#include <inst_arm64.h>
#include "inst_arm64.h"
#include "decoder_arm64.h"
using namespace SandHook::Decoder;
using namespace SandHook::AsmA64;
#define CASE(X) \
if (IS_OPCODE(*pc, X)) { \
if (IS_OPCODE_A64(*pc, X)) { \
STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \
goto label_matched; \
......
......@@ -7,7 +7,11 @@
#define SET_OPCODE(X) get()->opcode = OPCODE_A64(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_A64(X##_##INDEX)
#define DECODE_OFFSET(bits, ext) signExtend64(bits + ext, COMBINE(get()->imm##bits, 0, ext))
#define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext)
using namespace SandHook::Asm;
using namespace SandHook::AsmA64;
template<typename InstStruct>
U32 InstructionA64<InstStruct>::size() {
......@@ -104,19 +108,19 @@ void A64_MOV_WIDE::assembler() {
SET_OPCODE(MOV_WIDE);
get()->imm16 = imme;
get()->hw = static_cast<InstA64>(shift / 16);
get()->opc = op;
ENCODE_OP;
get()->sf = rd->isX() ? 1 : 0;
get()->rd = rd->getCode();
ENCODE_RD;
}
void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) {
imme = static_cast<U16>(inst->imm16);
shift = static_cast<U8>(inst->hw * 16);
op = OP(inst->opc);
op = OP(inst->op);
if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd));
DECODE_RD(XReg);
} else {
rd = WReg(static_cast<U8>(inst->rd));
DECODE_RD(WReg);
}
}
......@@ -138,23 +142,23 @@ A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label &l) : op(op) {
}
Off A64_B_BL::getImmPCOffset() {
return signExtend64(26 + 2, COMBINE(get()->imm26, 0b00, 2));
return DECODE_OFFSET(26, 2);
}
void A64_B_BL::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm26 = TruncateToUint26(offset >> 2);
ENCODE_OFFSET(26, 2);
}
void A64_B_BL::decode(STRUCT_A64(B_BL) *inst) {
op = OP(inst->op);
DECODE_OP;
offset = getImmPCOffset();
}
void A64_B_BL::assembler() {
SET_OPCODE(B_BL);
get()->op = op;
get()->imm26 = TruncateToUint26(offset >> 2);
ENCODE_OP;
ENCODE_OFFSET(26, 2);
}
......@@ -177,30 +181,30 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) :
}
Off A64_CBZ_CBNZ::getImmPCOffset() {
return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2));
return DECODE_OFFSET(19, 2);
}
void A64_CBZ_CBNZ::decode(STRUCT_A64(CBZ_CBNZ) *inst) {
op = OP(get()->op);
DECODE_OP;
if (inst->sf == 1) {
rt = XReg(static_cast<U8>(inst->rt));
DECODE_RT(XReg);
} else {
rt = WReg(static_cast<U8>(inst->rt));
DECODE_RT(WReg);
}
offset = getImmPCOffset();
}
void A64_CBZ_CBNZ::assembler() {
SET_OPCODE(CBZ_CBNZ);
get()->op = op;
get()->rt = rt->getCode();
ENCODE_OP;
ENCODE_RT;
get()->sf = rt->isX() ? 1 : 0;
get()->imm19 = TruncateToUint19(offset >> 2);
ENCODE_OFFSET(19, 2);
}
void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
ENCODE_OFFSET(19, 2);
}
......@@ -215,18 +219,18 @@ A64_B_COND::A64_B_COND(STRUCT_A64(B_COND) &inst) : A64_INST_PC_REL(&inst) {
A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
Off A64_B_COND::getImmPCOffset() {
return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2));
return DECODE_OFFSET(19, 2);
}
void A64_B_COND::decode(STRUCT_A64(B_COND) *inst) {
condition = Condition(inst->cond);
DECODE_COND;
offset = getImmPCOffset();
}
void A64_B_COND::assembler() {
SET_OPCODE(B_COND);
get()->cond = condition;
get()->imm19 = TruncateToUint19(offset >> 2);
ENCODE_COND;
ENCODE_OFFSET(19, 2);
}
A64_B_COND::A64_B_COND(Condition condition, Label &label) {
......@@ -235,7 +239,7 @@ A64_B_COND::A64_B_COND(Condition condition, Label &label) {
void A64_B_COND::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
ENCODE_OFFSET(19, 2);
}
......@@ -259,27 +263,27 @@ A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label
}
Off A64_TBZ_TBNZ::getImmPCOffset() {
return signExtend64(14 + 2, COMBINE(get()->imm14, 0b00, 2));
return DECODE_OFFSET(14, 2);
}
void A64_TBZ_TBNZ::decode(STRUCT_A64(TBZ_TBNZ) *inst) {
bit = COMBINE(inst->b5, inst->b40, 5);
if (inst->b5 == 1) {
rt = XReg(static_cast<U8>(inst->rt));
DECODE_RT(XReg);
} else {
rt = WReg(static_cast<U8>(inst->rt));
DECODE_RT(WReg);
}
op = OP(inst->op);
DECODE_OP;
offset = getImmPCOffset();
}
void A64_TBZ_TBNZ::assembler() {
SET_OPCODE(TBZ_TBNZ);
get()->op = op;
ENCODE_OP;
get()->b5 = rt->isX() ? 1 : 0;
get()->rt = rt->getCode();
ENCODE_RT;
get()->b40 = static_cast<InstA64>(BITS(bit, sizeof(InstA64) - 5, sizeof(InstA64)));
get()->imm14 = TruncateToUint14(offset >> 2);
ENCODE_OFFSET(14, 2);
}
void A64_TBZ_TBNZ::onOffsetApply(Off offset) {
......@@ -316,9 +320,9 @@ void A64_LDR_LIT::onOffsetApply(Off offset) {
void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) {
op = OP(inst->op);
if (op == LDR_W) {
rt = WReg(static_cast<U8>(inst->rt));
DECODE_RT(WReg);
} else {
rt = XReg(static_cast<U8>(inst->rt));
DECODE_RT(XReg);
}
offset = getImmPCOffset();
}
......@@ -341,16 +345,15 @@ A64_BR_BLR_RET::A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst) : InstructionA64(&i
A64_BR_BLR_RET::A64_BR_BLR_RET(A64_BR_BLR_RET::OP op, XRegister &rn) : op(op), rn(&rn) {}
void A64_BR_BLR_RET::decode(A64_STRUCT_BR_BLR_RET *inst) {
rn = XReg(static_cast<U8>(inst->op));
op = OP(inst->rn);
DECODE_RN(XReg);
DECODE_OP;
}
void A64_BR_BLR_RET::assembler() {
SET_OPCODE_MULTI(BR_BLR_RET, 1);
SET_OPCODE_MULTI(BR_BLR_RET, 2);
SET_OPCODE_MULTI(BR_BLR_RET, 3);
get()->rn = rn->getCode();
get()->op = op;
ENCODE_RN;
ENCODE_OP;
}
A64_STR_IMM::A64_STR_IMM() {}
......@@ -462,7 +465,7 @@ void A64_STR_UIMM::decode(STRUCT_A64(STR_UIMM) *inst) {
void A64_STR_UIMM::assembler() {
SET_OPCODE(STR_IMM);
get()->rt = rt->getCode();
ENCODE_RT;
get()->rn = operand.base->getCode();
if (rt->isX()) {
get()->size = Size64;
......@@ -488,11 +491,11 @@ A64_MOV_REG::A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm) : rd(&rd), rm(&rm) {
void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) {
if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd));
rm = XReg(static_cast<U8>(inst->rm));
DECODE_RD(XReg);
DECODE_RM(XReg);
} else {
rd = WReg(static_cast<U8>(inst->rd));
rm = WReg(static_cast<U8>(inst->rm));
DECODE_RD(WReg);
DECODE_RM(WReg);
}
}
......@@ -500,8 +503,8 @@ void A64_MOV_REG::assembler() {
SET_OPCODE_MULTI(MOV_REG, 1);
SET_OPCODE_MULTI(MOV_REG, 2);
get()->sf = rd->isX() ? 1 : 0;
get()->rd = rd->getCode();
get()->rm = rm->getCode();
ENCODE_RD;
ENCODE_RM;
}
......@@ -519,12 +522,12 @@ A64_SUB_EXT_REG::A64_SUB_EXT_REG(S s, RegisterA64 &rd, RegisterA64 &rn, const Op
void A64_SUB_EXT_REG::decode(STRUCT_A64(SUB_EXT_REG) *inst) {
s = S(inst->S);
if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd));
rn = XReg(static_cast<U8>(inst->rn));
DECODE_RD(XReg);
DECODE_RN(XReg);
operand.reg = XReg(static_cast<U8>(inst->rm));
} else {
rd = WReg(static_cast<U8>(inst->rd));
rn = WReg(static_cast<U8>(inst->rn));
DECODE_RD(WReg);
DECODE_RN(WReg);
operand.reg = XReg(static_cast<U8>(inst->rm));
}
operand.extend = Extend(inst->option);
......@@ -540,8 +543,8 @@ void A64_SUB_EXT_REG::assembler() {
get()->option = operand.extend;
get()->imm3 = operand.shift;
get()->rm = operand.reg->getCode();
get()->rn = rn->getCode();
get()->rd = rd->getCode();
ENCODE_RN;
ENCODE_RD;
}
......@@ -557,7 +560,7 @@ A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el
op), el(el), imme(imme) {}
void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) {
op = OP(inst->op);
DECODE_OP;
el = ExceptionLevel(inst->ll);
imme = static_cast<U16>(inst->imm16);
}
......@@ -565,7 +568,7 @@ void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) {
void A64_EXCEPTION_GEN::assembler() {
SET_OPCODE_MULTI(EXCEPTION_GEN, 1);
SET_OPCODE_MULTI(EXCEPTION_GEN, 2);
get()->op = op;
ENCODE_OP;
get()->ll = el;
get()->imm16 = imme;
}
......
......@@ -13,7 +13,7 @@
#define INST_A64(X) A64_##X
#define IS_OPCODE(RAW,OP) INST_A64(OP)::is(RAW)
#define IS_OPCODE_A64(RAW,OP) INST_A64(OP)::is(RAW)
#define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstA64& inst) { \
......@@ -36,9 +36,12 @@ inline U32 instCode() override { \
return InstCodeA64::X; \
}
using namespace SandHook::RegistersA64;
using namespace SandHook::Asm;
namespace SandHook {
namespace Asm {
namespace AsmA64 {
template<typename Inst>
class InstructionA64 : public Instruction<Inst> {
......@@ -76,8 +79,6 @@ namespace SandHook {
};
enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode};
enum MemOp {MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH};
enum FPTrapFlags {
......@@ -768,4 +769,11 @@ namespace SandHook {
}
#undef DEFINE_IS_EXT
#undef DEFINE_IS
#undef TEST_INST_FIELD
#undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE
#endif //SANDHOOK_NH_INST_ARM64_H
......@@ -8,10 +8,11 @@
#include "instruction.h"
#include "inst_code_arm64.h"
#include "arm_base.h"
#define STRUCT_A64(X) A64_STRUCT_##X
#define OPCODE_A64(X) A64_OPCODE_##X
#define DEFINE_OPCODE(X, V) const U32 OPCODE_A64(X) = V;
#define DEFINE_OPCODE_A64(X, V) const U32 OPCODE_A64(X) = V;
#define DEFINE_STRUCT_A64(X) struct STRUCT_A64(X) : public Base
enum ImmBranchType {
......@@ -22,39 +23,6 @@ enum ImmBranchType {
TestBranchType = 4
};
// Condition codes.
enum Condition {
eq = 0, // Z set Equal.
ne = 1, // Z clear Not equal.
cs = 2, // C set Carry set.
cc = 3, // C clear Carry clear.
mi = 4, // N set Negative.
pl = 5, // N clear Positive or zero.
vs = 6, // V set Overflow.
vc = 7, // V clear No overflow.
hi = 8, // C set, Z clear Unsigned higher.
ls = 9, // C clear or Z set Unsigned lower or same.
ge = 10, // N == V Greater or equal.
lt = 11, // N != V Less than.
gt = 12, // Z clear, N == V Greater than.
le = 13, // Z set or N != V Less then or equal
al = 14, // Always.
nv = 15, // Behaves as always/al.
// Aliases.
hs = cs, // C set Unsigned higher or same.
lo = cc // C clear Unsigned lower.
};
enum Shift {
NO_SHIFT = -1,
LSL = 0x0,
LSR = 0x1,
ASR = 0x2,
ROR = 0x3,
MSL = 0x4
};
enum Extend {
NO_EXTEND = -1,
UXTB = 0,
......@@ -78,7 +46,7 @@ DEFINE_STRUCT_A64(UNKNOW) {
#define IMM_LO_W 2
#define IMM_HI_W 19
DEFINE_OPCODE(ADR_ADRP, 0b10000)
DEFINE_OPCODE_A64(ADR_ADRP, 0b10000)
struct STRUCT_A64(ADR_ADRP) {
InstA64 rd:WideReg;
InstA64 immhi:IMM_HI_W;
......@@ -87,18 +55,18 @@ struct STRUCT_A64(ADR_ADRP) {
InstA64 op:1;
};
DEFINE_OPCODE(MOV_WIDE, 0b100101)
DEFINE_OPCODE_A64(MOV_WIDE, 0b100101)
DEFINE_STRUCT_A64(MOV_WIDE) {
InstA64 rd:WideReg;
InstA64 imm16:16;
InstA64 hw:2;
InstA64 opcode:6;
InstA64 opc:2;
InstA64 op:2;
InstA64 sf:1;
};
DEFINE_OPCODE(MOV_REG_1, 0b0101010000)
DEFINE_OPCODE(MOV_REG_2, 0b00000011111)
DEFINE_OPCODE_A64(MOV_REG_1, 0b0101010000)
DEFINE_OPCODE_A64(MOV_REG_2, 0b00000011111)
DEFINE_STRUCT_A64(MOV_REG) {
InstA64 rd:WideReg;
InstA64 opcode2:11;
......@@ -107,14 +75,14 @@ DEFINE_STRUCT_A64(MOV_REG) {
InstA64 sf:1;
};
DEFINE_OPCODE(B_BL, 0b00101)
DEFINE_OPCODE_A64(B_BL, 0b00101)
DEFINE_STRUCT_A64(B_BL) {
InstA64 imm26:26;
InstA64 opcode:5;
InstA64 op:1;
};
DEFINE_OPCODE(CBZ_CBNZ, 0b011010)
DEFINE_OPCODE_A64(CBZ_CBNZ, 0b011010)
DEFINE_STRUCT_A64(CBZ_CBNZ) {
InstA64 rt:WideReg;
InstA64 imm19:19;
......@@ -123,7 +91,7 @@ DEFINE_STRUCT_A64(CBZ_CBNZ) {
InstA64 sf:1;
};
DEFINE_OPCODE(B_COND, 0b01010100)
DEFINE_OPCODE_A64(B_COND, 0b01010100)
DEFINE_STRUCT_A64(B_COND) {
InstA64 cond:4;
InstA64 unkown_0:1;
......@@ -131,7 +99,7 @@ DEFINE_STRUCT_A64(B_COND) {
InstA64 opcode:8;
};
DEFINE_OPCODE(TBZ_TBNZ, 0b011011)
DEFINE_OPCODE_A64(TBZ_TBNZ, 0b011011)
DEFINE_STRUCT_A64(TBZ_TBNZ) {
InstA64 rt:WideReg;
InstA64 imm14:14;
......@@ -141,7 +109,7 @@ DEFINE_STRUCT_A64(TBZ_TBNZ) {
InstA64 b5:1;
};
DEFINE_OPCODE(LDR_LIT, 0b011000)
DEFINE_OPCODE_A64(LDR_LIT, 0b011000)
DEFINE_STRUCT_A64(LDR_LIT) {
InstA64 rt:WideReg;
InstA64 imm19:19;
......@@ -150,7 +118,7 @@ DEFINE_STRUCT_A64(LDR_LIT) {
};
DEFINE_OPCODE(LDR_UIMM, 0b11100101)
DEFINE_OPCODE_A64(LDR_UIMM, 0b11100101)
DEFINE_STRUCT_A64(LDR_UIMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
......@@ -159,7 +127,7 @@ DEFINE_STRUCT_A64(LDR_UIMM) {
InstA64 size:2;
};
DEFINE_OPCODE(LDR_IMM, 0b111000010)
DEFINE_OPCODE_A64(LDR_IMM, 0b111000010)
DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
......@@ -169,17 +137,17 @@ DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 size:2;
};
DEFINE_OPCODE(LDRSW_UIMM, 0b11100110)
DEFINE_OPCODE_A64(LDRSW_UIMM, 0b11100110)
struct STRUCT_A64(LDRSW_UIMM) : public STRUCT_A64(LDR_UIMM) {
};
DEFINE_OPCODE(LDRSW_IMM, 0b111000100)
DEFINE_OPCODE_A64(LDRSW_IMM, 0b111000100)
struct STRUCT_A64(LDRSW_IMM) : public STRUCT_A64(LDR_IMM) {
};
DEFINE_OPCODE(BR_BLR_RET_1, 0b110101100)
DEFINE_OPCODE(BR_BLR_RET_2, 0b11111000000)
DEFINE_OPCODE(BR_BLR_RET_3, 0b00000)
DEFINE_OPCODE_A64(BR_BLR_RET_1, 0b110101100)
DEFINE_OPCODE_A64(BR_BLR_RET_2, 0b11111000000)
DEFINE_OPCODE_A64(BR_BLR_RET_3, 0b00000)
DEFINE_STRUCT_A64(BR_BLR_RET) {
InstA64 opcode3:5;
InstA64 rn:WideReg;
......@@ -189,7 +157,7 @@ DEFINE_STRUCT_A64(BR_BLR_RET) {
};
DEFINE_OPCODE(STR_IMM, 0b111000000)
DEFINE_OPCODE_A64(STR_IMM, 0b111000000)
DEFINE_STRUCT_A64(STR_IMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
......@@ -199,7 +167,7 @@ DEFINE_STRUCT_A64(STR_IMM) {
InstA64 size:2;
};
DEFINE_OPCODE(STR_UIMM, 0b11100100)
DEFINE_OPCODE_A64(STR_UIMM, 0b11100100)
DEFINE_STRUCT_A64(STR_UIMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
......@@ -208,8 +176,8 @@ DEFINE_STRUCT_A64(STR_UIMM) {
InstA64 size:2;
};
DEFINE_OPCODE(SUB_EXT_REG_1, 0b1)
DEFINE_OPCODE(SUB_EXT_REG_2, 0b01011001)
DEFINE_OPCODE_A64(SUB_EXT_REG_1, 0b1)
DEFINE_OPCODE_A64(SUB_EXT_REG_2, 0b01011001)
DEFINE_STRUCT_A64(SUB_EXT_REG) {
InstA64 rd:WideReg;
InstA64 rn:WideReg;
......@@ -222,8 +190,8 @@ DEFINE_STRUCT_A64(SUB_EXT_REG) {
InstA64 sf:1;
};
DEFINE_OPCODE(EXCEPTION_GEN_1, 0b11010100)
DEFINE_OPCODE(EXCEPTION_GEN_2, 0b000)
DEFINE_OPCODE_A64(EXCEPTION_GEN_1, 0b11010100)
DEFINE_OPCODE_A64(EXCEPTION_GEN_2, 0b000)
DEFINE_STRUCT_A64(EXCEPTION_GEN) {
InstA64 ll:2;
InstA64 opcode2:3;
......
......@@ -6,6 +6,8 @@
#include "register_list_a64.h"
using namespace SandHook::Asm;
using namespace SandHook::RegistersA64;
RegisterA64::RegisterA64() {}
......
......@@ -4,6 +4,9 @@
#include "register_list_a64.h"
namespace SandHook {
namespace RegistersA64 {
#define INIT_REGISTERS(N) \
WRegister W##N = WRegister(N); \
XRegister X##N = XRegister(N);
......@@ -19,6 +22,7 @@ XRegister LR = X30;
XRegister XZR = X31;
WRegister WZR = W31;
RegisterA64 UnknowRegiser = RegisterA64(38);
}
}
//cmp....
#define ZeroRegFor(X) X.isX() ? XZR : WZR
\ No newline at end of file
......@@ -19,21 +19,26 @@ using namespace SandHook::Asm;
R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \
R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
namespace SandHook {
namespace RegistersA64 {
#define DEFINE_REGISTERS(N) \
extern WRegister W##N; \
extern XRegister X##N;
AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
extern WRegister WSP;
extern XRegister SP;
extern XRegister IP0;
extern XRegister IP1;
extern XRegister LR;
extern WRegister WSP;
extern XRegister SP;
extern XRegister IP0;
extern XRegister IP1;
extern XRegister LR;
//zero reg
extern XRegister XZR;
extern WRegister WZR;
extern RegisterA64 UnknowRegiser;
extern XRegister XZR;
extern WRegister WZR;
extern RegisterA64 UnknowRegiser;
}}
#define XReg(N) XRegister::get(N)
#define WReg(N) WRegister::get(N)
......
......@@ -5,6 +5,9 @@
#include "code_relocate_a64.h"
#include "decoder_arm64.h"
using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64;
#define __ assemblerA64->
#define IMPL_RELOCATE(X) void CodeRelocateA64::relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException)
......
......@@ -10,6 +10,7 @@
using namespace SandHook::Assembler;
using namespace SandHook::Decoder;
using namespace SandHook::AsmA64;
#define DEFINE_RELOCATE(X) void relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException);
......
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_ARM_BASE_H
#define SANDHOOK_ARM_BASE_H
// Condition codes.
enum Condition {
eq = 0, // Z set Equal.
ne = 1, // Z clear Not equal.
cs = 2, // C set Carry set.
cc = 3, // C clear Carry clear.
mi = 4, // N set Negative.
pl = 5, // N clear Positive or zero.
vs = 6, // V set Overflow.
vc = 7, // V clear No overflow.
hi = 8, // C set, Z clear Unsigned higher.
ls = 9, // C clear or Z set Unsigned lower or same.
ge = 10, // N == V Greater or equal.
lt = 11, // N != V Less than.
gt = 12, // Z clear, N == V Greater than.
le = 13, // Z set or N != V Less then or equal
al = 14, // Always.
nv = 15, // Behaves as always/al.
// Aliases.
hs = cs, // C set Unsigned higher or same.
lo = cc // C clear Unsigned lower.
};
enum Shift {
NO_SHIFT = -1,
LSL = 0x0,
LSR = 0x1,
ASR = 0x2,
ROR = 0x3,
MSL = 0x4,
RRX = 0x4
};
enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode};
//decode field & encode field
//condition
#define DECODE_COND condition = Condition(inst->cond)
#define ENCODE_COND get()->cond = condition
//reg
#define DECODE_RD(Type) rd = Type(static_cast<U8>(get()->rd))
#define ENCODE_RD get()->rd = rd->getCode()
#define DECODE_RT(Type) rt = Type(static_cast<U8>(get()->rt))
#define ENCODE_RT get()->rt = rt->getCode()
#define DECODE_RM(Type) rm = Type(static_cast<U8>(get()->rm))
#define ENCODE_RM get()->rm = rm->getCode()
#define DECODE_RN(Type) rn = Type(static_cast<U8>(get()->rn))
#define ENCODE_RN get()->rn = rn->getCode()
//op
#define DECODE_OP op = OP(inst->op)
#define ENCODE_OP get()->op = op
#endif //SANDHOOK_ARM_BASE_H
//
// Created by swift on 2019/5/16.
//
#ifndef SANDHOOK_PLACE_HOLDER_H
#define SANDHOOK_PLACE_HOLDER_H
#endif //SANDHOOK_PLACE_HOLDER_H
......@@ -14,10 +14,11 @@ using namespace SandHook::Assembler;
using namespace SandHook::Utils;
#include "assembler_a64.h"
#include "code_relocate_a64.h"
#include "code_relocate_a64.h"
using namespace SandHook::RegistersA64;
AndroidCodeBuffer* backupBuffer = new AndroidCodeBuffer();
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock);
......
......@@ -13,6 +13,7 @@
using namespace SandHook::Asm;
using namespace SandHook::Decoder;
using namespace SandHook::Hook;
using namespace SandHook::AsmA64;
void (*dosth3Backup)(int, int) = nullptr;
void (*dosth4Backup)() = nullptr;
......@@ -92,7 +93,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
InstA64* codebl = reinterpret_cast<InstA64 *>((Addr)do1 + 8);
if (IS_OPCODE(*codebl, B_BL)) {
if (IS_OPCODE_A64(*codebl, B_BL)) {
//decode
A64_B_BL a64bl(*reinterpret_cast<STRUCT_A64(B_BL)*>(codebl));
......@@ -109,7 +110,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
}
if (IS_OPCODE(test.raw, STR_UIMM)) {
if (IS_OPCODE_A64(test.raw, STR_UIMM)) {
A64_STR_UIMM str(test.str);
str.assembler();
str.get();
......
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