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) ...@@ -11,28 +11,31 @@ cmake_minimum_required(VERSION 3.4.1)
# Gradle automatically packages shared libraries with your APK. # Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library. add_library( # Sets the name of the library.
sandhook-native sandhook-native
# Sets the library as a shared library. # Sets the library as a shared library.
SHARED SHARED
# 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/decoder/decoder.cpp
src/main/cpp/archs/arm64/assembler/assembler_a64.cpp src/main/cpp/archs/arm/arm64/assembler/assembler_a64.cpp
src/main/cpp/archs/arm64/inst/inst_arm64.cpp src/main/cpp/archs/arm/arm64/inst/inst_arm64.cpp
src/main/cpp/archs/arm64/register/register_a64.cpp src/main/cpp/archs/arm/arm64/register/register_a64.cpp
src/main/cpp/archs/arm64/register/register_list_a64.cpp src/main/cpp/archs/arm/arm64/register/register_list_a64.cpp
src/main/cpp/archs/arm64/decoder/decoder_arm64.cpp src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm64/relocate/code_relocate_a64.cpp src/main/cpp/archs/arm/arm64/relocate/code_relocate_a64.cpp
src/main/cpp/archs/arm32/inst/inst_arm32.cpp src/main/cpp/archs/arm/arm32/inst/inst_arm32.cpp
src/main/cpp/archs/arm32/register/register_a32.cpp src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp
src/main/cpp/relocate/code_relocate.cpp src/main/cpp/archs/arm/arm32/inst/inst_t16.cpp
src/main/cpp/elf/elf.cpp src/main/cpp/archs/arm/arm32/register/register_a32.cpp
src/main/cpp/assembler/assembler.cpp src/main/cpp/archs/arm/arm32/register/register_list_a32.cpp
src/main/cpp/buffer/code_buffer.cpp src/main/cpp/relocate/code_relocate.cpp
src/main/cpp/utils/platform.cpp src/main/cpp/elf/elf.cpp
src/main/cpp/hook/hook.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( ...@@ -43,13 +46,14 @@ include_directories(
src/main/cpp/utils src/main/cpp/utils
src/main/cpp/includes src/main/cpp/includes
src/main/cpp/buffer src/main/cpp/buffer
src/main/cpp/archs/arm64/inst src/main/cpp/archs/arm
src/main/cpp/archs/arm64/register src/main/cpp/archs/arm/arm64/inst
src/main/cpp/archs/arm64/decoder src/main/cpp/archs/arm/arm64/register
src/main/cpp/archs/arm64/assembler src/main/cpp/archs/arm/arm64/decoder
src/main/cpp/archs/arm64/relocate src/main/cpp/archs/arm/arm64/assembler
src/main/cpp/archs/arm32/inst src/main/cpp/archs/arm/arm64/relocate
src/main/cpp/archs/arm32/register 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 # Searches for a specified prebuilt library and stores the path as a
...@@ -59,22 +63,22 @@ include_directories( ...@@ -59,22 +63,22 @@ include_directories(
# completing its build. # completing its build.
find_library( # Sets the name of the path variable. find_library( # Sets the name of the path variable.
log-lib log-lib
# Specifies the name of the NDK library that # Specifies the name of the NDK library that
# you want CMake to locate. # you want CMake to locate.
log ) log)
# Specifies libraries CMake should link to your target library. You # Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this # can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries. # build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library. target_link_libraries( # Specifies the target library.
sandhook-native sandhook-native
# Links the target library to the log library # Links the target library to the log library
# included in the NDK. # included in the NDK.
${log-lib} ) ${log-lib})
add_definitions(-std=c++11) 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 @@ ...@@ -2,11 +2,11 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRCUT_ARM32_H #ifndef SANDHOOK_NH_INST_STRUCT_ARM32_H
#define SANDHOOK_NH_INST_STRCUT_ARM32_H #define SANDHOOK_NH_INST_STRUCT_ARM32_H
#include "../../../asm/instruction.h" #include "instruction.h"
#define STRUCT_A32(X) A32_STRUCT_##X #define STRUCT_A32(X) A32_STRUCT_##X
#define OPCODE_A32(X) A32_OPCODE_##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 @@ ...@@ -3,11 +3,24 @@
// //
#include "register_a32.h" #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() { 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 { ...@@ -16,19 +16,18 @@ namespace SandHook {
class RegisterA32 : public Register { class RegisterA32 : public Register {
public: 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();
RegisterA32(U8 code); 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 @@ ...@@ -5,6 +5,8 @@
#include "assembler_a64.h" #include "assembler_a64.h"
using namespace SandHook::Assembler; using namespace SandHook::Assembler;
using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64;
AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) { AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer); codeContainer.setCodeBuffer(codeBuffer);
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "register_a64.h" #include "register_a64.h"
#include "inst_arm64.h" #include "inst_arm64.h"
using namespace SandHook::AsmA64;
namespace SandHook { namespace SandHook {
namespace Assembler { namespace Assembler {
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#include <inst_arm64.h> #include "inst_arm64.h"
#include "decoder_arm64.h" #include "decoder_arm64.h"
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
using namespace SandHook::AsmA64;
#define CASE(X) \ #define CASE(X) \
if (IS_OPCODE(*pc, X)) { \ if (IS_OPCODE_A64(*pc, X)) { \
STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \ STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \ unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \
goto label_matched; \ goto label_matched; \
......
...@@ -7,7 +7,11 @@ ...@@ -7,7 +7,11 @@
#define SET_OPCODE(X) get()->opcode = OPCODE_A64(X) #define SET_OPCODE(X) get()->opcode = OPCODE_A64(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_A64(X##_##INDEX) #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::Asm;
using namespace SandHook::AsmA64;
template<typename InstStruct> template<typename InstStruct>
U32 InstructionA64<InstStruct>::size() { U32 InstructionA64<InstStruct>::size() {
...@@ -104,19 +108,19 @@ void A64_MOV_WIDE::assembler() { ...@@ -104,19 +108,19 @@ void A64_MOV_WIDE::assembler() {
SET_OPCODE(MOV_WIDE); SET_OPCODE(MOV_WIDE);
get()->imm16 = imme; get()->imm16 = imme;
get()->hw = static_cast<InstA64>(shift / 16); get()->hw = static_cast<InstA64>(shift / 16);
get()->opc = op; ENCODE_OP;
get()->sf = rd->isX() ? 1 : 0; get()->sf = rd->isX() ? 1 : 0;
get()->rd = rd->getCode(); ENCODE_RD;
} }
void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) {
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(inst->imm16);
shift = static_cast<U8>(inst->hw * 16); shift = static_cast<U8>(inst->hw * 16);
op = OP(inst->opc); op = OP(inst->op);
if (inst->sf == 1) { if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd)); DECODE_RD(XReg);
} else { } 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) { ...@@ -138,23 +142,23 @@ A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label &l) : op(op) {
} }
Off A64_B_BL::getImmPCOffset() { 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) { void A64_B_BL::onOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
get()->imm26 = TruncateToUint26(offset >> 2); ENCODE_OFFSET(26, 2);
} }
void A64_B_BL::decode(STRUCT_A64(B_BL) *inst) { void A64_B_BL::decode(STRUCT_A64(B_BL) *inst) {
op = OP(inst->op); DECODE_OP;
offset = getImmPCOffset(); offset = getImmPCOffset();
} }
void A64_B_BL::assembler() { void A64_B_BL::assembler() {
SET_OPCODE(B_BL); SET_OPCODE(B_BL);
get()->op = op; ENCODE_OP;
get()->imm26 = TruncateToUint26(offset >> 2); ENCODE_OFFSET(26, 2);
} }
...@@ -177,30 +181,30 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) : ...@@ -177,30 +181,30 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) :
} }
Off A64_CBZ_CBNZ::getImmPCOffset() { 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) { void A64_CBZ_CBNZ::decode(STRUCT_A64(CBZ_CBNZ) *inst) {
op = OP(get()->op); DECODE_OP;
if (inst->sf == 1) { if (inst->sf == 1) {
rt = XReg(static_cast<U8>(inst->rt)); DECODE_RT(XReg);
} else { } else {
rt = WReg(static_cast<U8>(inst->rt)); DECODE_RT(WReg);
} }
offset = getImmPCOffset(); offset = getImmPCOffset();
} }
void A64_CBZ_CBNZ::assembler() { void A64_CBZ_CBNZ::assembler() {
SET_OPCODE(CBZ_CBNZ); SET_OPCODE(CBZ_CBNZ);
get()->op = op; ENCODE_OP;
get()->rt = rt->getCode(); ENCODE_RT;
get()->sf = rt->isX() ? 1 : 0; get()->sf = rt->isX() ? 1 : 0;
get()->imm19 = TruncateToUint19(offset >> 2); ENCODE_OFFSET(19, 2);
} }
void A64_CBZ_CBNZ::onOffsetApply(Off offset) { void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
this->offset = 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) { ...@@ -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) {} A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
Off A64_B_COND::getImmPCOffset() { 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) { void A64_B_COND::decode(STRUCT_A64(B_COND) *inst) {
condition = Condition(inst->cond); DECODE_COND;
offset = getImmPCOffset(); offset = getImmPCOffset();
} }
void A64_B_COND::assembler() { void A64_B_COND::assembler() {
SET_OPCODE(B_COND); SET_OPCODE(B_COND);
get()->cond = condition; ENCODE_COND;
get()->imm19 = TruncateToUint19(offset >> 2); ENCODE_OFFSET(19, 2);
} }
A64_B_COND::A64_B_COND(Condition condition, Label &label) { A64_B_COND::A64_B_COND(Condition condition, Label &label) {
...@@ -235,7 +239,7 @@ 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) { void A64_B_COND::onOffsetApply(Off offset) {
this->offset = 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 ...@@ -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() { 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) { void A64_TBZ_TBNZ::decode(STRUCT_A64(TBZ_TBNZ) *inst) {
bit = COMBINE(inst->b5, inst->b40, 5); bit = COMBINE(inst->b5, inst->b40, 5);
if (inst->b5 == 1) { if (inst->b5 == 1) {
rt = XReg(static_cast<U8>(inst->rt)); DECODE_RT(XReg);
} else { } else {
rt = WReg(static_cast<U8>(inst->rt)); DECODE_RT(WReg);
} }
op = OP(inst->op); DECODE_OP;
offset = getImmPCOffset(); offset = getImmPCOffset();
} }
void A64_TBZ_TBNZ::assembler() { void A64_TBZ_TBNZ::assembler() {
SET_OPCODE(TBZ_TBNZ); SET_OPCODE(TBZ_TBNZ);
get()->op = op; ENCODE_OP;
get()->b5 = rt->isX() ? 1 : 0; 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()->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) { void A64_TBZ_TBNZ::onOffsetApply(Off offset) {
...@@ -316,9 +320,9 @@ void A64_LDR_LIT::onOffsetApply(Off offset) { ...@@ -316,9 +320,9 @@ void A64_LDR_LIT::onOffsetApply(Off offset) {
void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) {
op = OP(inst->op); op = OP(inst->op);
if (op == LDR_W) { if (op == LDR_W) {
rt = WReg(static_cast<U8>(inst->rt)); DECODE_RT(WReg);
} else { } else {
rt = XReg(static_cast<U8>(inst->rt)); DECODE_RT(XReg);
} }
offset = getImmPCOffset(); offset = getImmPCOffset();
} }
...@@ -341,16 +345,15 @@ A64_BR_BLR_RET::A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst) : InstructionA64(&i ...@@ -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) {} 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) { void A64_BR_BLR_RET::decode(A64_STRUCT_BR_BLR_RET *inst) {
rn = XReg(static_cast<U8>(inst->op)); DECODE_RN(XReg);
op = OP(inst->rn); DECODE_OP;
} }
void A64_BR_BLR_RET::assembler() { void A64_BR_BLR_RET::assembler() {
SET_OPCODE_MULTI(BR_BLR_RET, 1); SET_OPCODE_MULTI(BR_BLR_RET, 1);
SET_OPCODE_MULTI(BR_BLR_RET, 2); SET_OPCODE_MULTI(BR_BLR_RET, 2);
SET_OPCODE_MULTI(BR_BLR_RET, 3); ENCODE_RN;
get()->rn = rn->getCode(); ENCODE_OP;
get()->op = op;
} }
A64_STR_IMM::A64_STR_IMM() {} A64_STR_IMM::A64_STR_IMM() {}
...@@ -462,7 +465,7 @@ void A64_STR_UIMM::decode(STRUCT_A64(STR_UIMM) *inst) { ...@@ -462,7 +465,7 @@ void A64_STR_UIMM::decode(STRUCT_A64(STR_UIMM) *inst) {
void A64_STR_UIMM::assembler() { void A64_STR_UIMM::assembler() {
SET_OPCODE(STR_IMM); SET_OPCODE(STR_IMM);
get()->rt = rt->getCode(); ENCODE_RT;
get()->rn = operand.base->getCode(); get()->rn = operand.base->getCode();
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; get()->size = Size64;
...@@ -488,11 +491,11 @@ A64_MOV_REG::A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm) : rd(&rd), rm(&rm) { ...@@ -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) { void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) {
if (inst->sf == 1) { if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd)); DECODE_RD(XReg);
rm = XReg(static_cast<U8>(inst->rm)); DECODE_RM(XReg);
} else { } else {
rd = WReg(static_cast<U8>(inst->rd)); DECODE_RD(WReg);
rm = WReg(static_cast<U8>(inst->rm)); DECODE_RM(WReg);
} }
} }
...@@ -500,8 +503,8 @@ void A64_MOV_REG::assembler() { ...@@ -500,8 +503,8 @@ void A64_MOV_REG::assembler() {
SET_OPCODE_MULTI(MOV_REG, 1); SET_OPCODE_MULTI(MOV_REG, 1);
SET_OPCODE_MULTI(MOV_REG, 2); SET_OPCODE_MULTI(MOV_REG, 2);
get()->sf = rd->isX() ? 1 : 0; get()->sf = rd->isX() ? 1 : 0;
get()->rd = rd->getCode(); ENCODE_RD;
get()->rm = rm->getCode(); ENCODE_RM;
} }
...@@ -519,12 +522,12 @@ A64_SUB_EXT_REG::A64_SUB_EXT_REG(S s, RegisterA64 &rd, RegisterA64 &rn, const Op ...@@ -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) { void A64_SUB_EXT_REG::decode(STRUCT_A64(SUB_EXT_REG) *inst) {
s = S(inst->S); s = S(inst->S);
if (inst->sf == 1) { if (inst->sf == 1) {
rd = XReg(static_cast<U8>(inst->rd)); DECODE_RD(XReg);
rn = XReg(static_cast<U8>(inst->rn)); DECODE_RN(XReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg = XReg(static_cast<U8>(inst->rm));
} else { } else {
rd = WReg(static_cast<U8>(inst->rd)); DECODE_RD(WReg);
rn = WReg(static_cast<U8>(inst->rn)); DECODE_RN(WReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg = XReg(static_cast<U8>(inst->rm));
} }
operand.extend = Extend(inst->option); operand.extend = Extend(inst->option);
...@@ -540,8 +543,8 @@ void A64_SUB_EXT_REG::assembler() { ...@@ -540,8 +543,8 @@ void A64_SUB_EXT_REG::assembler() {
get()->option = operand.extend; get()->option = operand.extend;
get()->imm3 = operand.shift; get()->imm3 = operand.shift;
get()->rm = operand.reg->getCode(); get()->rm = operand.reg->getCode();
get()->rn = rn->getCode(); ENCODE_RN;
get()->rd = rd->getCode(); ENCODE_RD;
} }
...@@ -557,7 +560,7 @@ A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el ...@@ -557,7 +560,7 @@ A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el
op), el(el), imme(imme) {} op), el(el), imme(imme) {}
void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) { void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) {
op = OP(inst->op); DECODE_OP;
el = ExceptionLevel(inst->ll); el = ExceptionLevel(inst->ll);
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(inst->imm16);
} }
...@@ -565,7 +568,7 @@ void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) { ...@@ -565,7 +568,7 @@ void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) {
void A64_EXCEPTION_GEN::assembler() { void A64_EXCEPTION_GEN::assembler() {
SET_OPCODE_MULTI(EXCEPTION_GEN, 1); SET_OPCODE_MULTI(EXCEPTION_GEN, 1);
SET_OPCODE_MULTI(EXCEPTION_GEN, 2); SET_OPCODE_MULTI(EXCEPTION_GEN, 2);
get()->op = op; ENCODE_OP;
get()->ll = el; get()->ll = el;
get()->imm16 = imme; get()->imm16 = imme;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define INST_A64(X) A64_##X #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) \ #define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstA64& inst) { \ inline static bool is(InstA64& inst) { \
...@@ -36,9 +36,12 @@ inline U32 instCode() override { \ ...@@ -36,9 +36,12 @@ inline U32 instCode() override { \
return InstCodeA64::X; \ return InstCodeA64::X; \
} }
using namespace SandHook::RegistersA64;
using namespace SandHook::Asm;
namespace SandHook { namespace SandHook {
namespace Asm { namespace AsmA64 {
template<typename Inst> template<typename Inst>
class InstructionA64 : public Instruction<Inst> { class InstructionA64 : public Instruction<Inst> {
...@@ -76,8 +79,6 @@ namespace SandHook { ...@@ -76,8 +79,6 @@ namespace SandHook {
}; };
enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode};
enum MemOp {MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH}; enum MemOp {MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH};
enum FPTrapFlags { enum FPTrapFlags {
...@@ -768,4 +769,11 @@ namespace SandHook { ...@@ -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 #endif //SANDHOOK_NH_INST_ARM64_H
...@@ -8,10 +8,11 @@ ...@@ -8,10 +8,11 @@
#include "instruction.h" #include "instruction.h"
#include "inst_code_arm64.h" #include "inst_code_arm64.h"
#include "arm_base.h"
#define STRUCT_A64(X) A64_STRUCT_##X #define STRUCT_A64(X) A64_STRUCT_##X
#define OPCODE_A64(X) A64_OPCODE_##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 #define DEFINE_STRUCT_A64(X) struct STRUCT_A64(X) : public Base
enum ImmBranchType { enum ImmBranchType {
...@@ -22,39 +23,6 @@ enum ImmBranchType { ...@@ -22,39 +23,6 @@ enum ImmBranchType {
TestBranchType = 4 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 { enum Extend {
NO_EXTEND = -1, NO_EXTEND = -1,
UXTB = 0, UXTB = 0,
...@@ -78,7 +46,7 @@ DEFINE_STRUCT_A64(UNKNOW) { ...@@ -78,7 +46,7 @@ DEFINE_STRUCT_A64(UNKNOW) {
#define IMM_LO_W 2 #define IMM_LO_W 2
#define IMM_HI_W 19 #define IMM_HI_W 19
DEFINE_OPCODE(ADR_ADRP, 0b10000) DEFINE_OPCODE_A64(ADR_ADRP, 0b10000)
struct STRUCT_A64(ADR_ADRP) { struct STRUCT_A64(ADR_ADRP) {
InstA64 rd:WideReg; InstA64 rd:WideReg;
InstA64 immhi:IMM_HI_W; InstA64 immhi:IMM_HI_W;
...@@ -87,18 +55,18 @@ struct STRUCT_A64(ADR_ADRP) { ...@@ -87,18 +55,18 @@ struct STRUCT_A64(ADR_ADRP) {
InstA64 op:1; InstA64 op:1;
}; };
DEFINE_OPCODE(MOV_WIDE, 0b100101) DEFINE_OPCODE_A64(MOV_WIDE, 0b100101)
DEFINE_STRUCT_A64(MOV_WIDE) { DEFINE_STRUCT_A64(MOV_WIDE) {
InstA64 rd:WideReg; InstA64 rd:WideReg;
InstA64 imm16:16; InstA64 imm16:16;
InstA64 hw:2; InstA64 hw:2;
InstA64 opcode:6; InstA64 opcode:6;
InstA64 opc:2; InstA64 op:2;
InstA64 sf:1; InstA64 sf:1;
}; };
DEFINE_OPCODE(MOV_REG_1, 0b0101010000) DEFINE_OPCODE_A64(MOV_REG_1, 0b0101010000)
DEFINE_OPCODE(MOV_REG_2, 0b00000011111) DEFINE_OPCODE_A64(MOV_REG_2, 0b00000011111)
DEFINE_STRUCT_A64(MOV_REG) { DEFINE_STRUCT_A64(MOV_REG) {
InstA64 rd:WideReg; InstA64 rd:WideReg;
InstA64 opcode2:11; InstA64 opcode2:11;
...@@ -107,14 +75,14 @@ DEFINE_STRUCT_A64(MOV_REG) { ...@@ -107,14 +75,14 @@ DEFINE_STRUCT_A64(MOV_REG) {
InstA64 sf:1; InstA64 sf:1;
}; };
DEFINE_OPCODE(B_BL, 0b00101) DEFINE_OPCODE_A64(B_BL, 0b00101)
DEFINE_STRUCT_A64(B_BL) { DEFINE_STRUCT_A64(B_BL) {
InstA64 imm26:26; InstA64 imm26:26;
InstA64 opcode:5; InstA64 opcode:5;
InstA64 op:1; InstA64 op:1;
}; };
DEFINE_OPCODE(CBZ_CBNZ, 0b011010) DEFINE_OPCODE_A64(CBZ_CBNZ, 0b011010)
DEFINE_STRUCT_A64(CBZ_CBNZ) { DEFINE_STRUCT_A64(CBZ_CBNZ) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 imm19:19; InstA64 imm19:19;
...@@ -123,7 +91,7 @@ DEFINE_STRUCT_A64(CBZ_CBNZ) { ...@@ -123,7 +91,7 @@ DEFINE_STRUCT_A64(CBZ_CBNZ) {
InstA64 sf:1; InstA64 sf:1;
}; };
DEFINE_OPCODE(B_COND, 0b01010100) DEFINE_OPCODE_A64(B_COND, 0b01010100)
DEFINE_STRUCT_A64(B_COND) { DEFINE_STRUCT_A64(B_COND) {
InstA64 cond:4; InstA64 cond:4;
InstA64 unkown_0:1; InstA64 unkown_0:1;
...@@ -131,7 +99,7 @@ DEFINE_STRUCT_A64(B_COND) { ...@@ -131,7 +99,7 @@ DEFINE_STRUCT_A64(B_COND) {
InstA64 opcode:8; InstA64 opcode:8;
}; };
DEFINE_OPCODE(TBZ_TBNZ, 0b011011) DEFINE_OPCODE_A64(TBZ_TBNZ, 0b011011)
DEFINE_STRUCT_A64(TBZ_TBNZ) { DEFINE_STRUCT_A64(TBZ_TBNZ) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 imm14:14; InstA64 imm14:14;
...@@ -141,7 +109,7 @@ DEFINE_STRUCT_A64(TBZ_TBNZ) { ...@@ -141,7 +109,7 @@ DEFINE_STRUCT_A64(TBZ_TBNZ) {
InstA64 b5:1; InstA64 b5:1;
}; };
DEFINE_OPCODE(LDR_LIT, 0b011000) DEFINE_OPCODE_A64(LDR_LIT, 0b011000)
DEFINE_STRUCT_A64(LDR_LIT) { DEFINE_STRUCT_A64(LDR_LIT) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 imm19:19; InstA64 imm19:19;
...@@ -150,7 +118,7 @@ DEFINE_STRUCT_A64(LDR_LIT) { ...@@ -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) { DEFINE_STRUCT_A64(LDR_UIMM) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -159,7 +127,7 @@ DEFINE_STRUCT_A64(LDR_UIMM) { ...@@ -159,7 +127,7 @@ DEFINE_STRUCT_A64(LDR_UIMM) {
InstA64 size:2; InstA64 size:2;
}; };
DEFINE_OPCODE(LDR_IMM, 0b111000010) DEFINE_OPCODE_A64(LDR_IMM, 0b111000010)
DEFINE_STRUCT_A64(LDR_IMM) { DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -169,17 +137,17 @@ DEFINE_STRUCT_A64(LDR_IMM) { ...@@ -169,17 +137,17 @@ DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 size:2; InstA64 size:2;
}; };
DEFINE_OPCODE(LDRSW_UIMM, 0b11100110) DEFINE_OPCODE_A64(LDRSW_UIMM, 0b11100110)
struct STRUCT_A64(LDRSW_UIMM) : public STRUCT_A64(LDR_UIMM) { 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) { struct STRUCT_A64(LDRSW_IMM) : public STRUCT_A64(LDR_IMM) {
}; };
DEFINE_OPCODE(BR_BLR_RET_1, 0b110101100) DEFINE_OPCODE_A64(BR_BLR_RET_1, 0b110101100)
DEFINE_OPCODE(BR_BLR_RET_2, 0b11111000000) DEFINE_OPCODE_A64(BR_BLR_RET_2, 0b11111000000)
DEFINE_OPCODE(BR_BLR_RET_3, 0b00000) DEFINE_OPCODE_A64(BR_BLR_RET_3, 0b00000)
DEFINE_STRUCT_A64(BR_BLR_RET) { DEFINE_STRUCT_A64(BR_BLR_RET) {
InstA64 opcode3:5; InstA64 opcode3:5;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -189,7 +157,7 @@ DEFINE_STRUCT_A64(BR_BLR_RET) { ...@@ -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) { DEFINE_STRUCT_A64(STR_IMM) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -199,7 +167,7 @@ DEFINE_STRUCT_A64(STR_IMM) { ...@@ -199,7 +167,7 @@ DEFINE_STRUCT_A64(STR_IMM) {
InstA64 size:2; InstA64 size:2;
}; };
DEFINE_OPCODE(STR_UIMM, 0b11100100) DEFINE_OPCODE_A64(STR_UIMM, 0b11100100)
DEFINE_STRUCT_A64(STR_UIMM) { DEFINE_STRUCT_A64(STR_UIMM) {
InstA64 rt:WideReg; InstA64 rt:WideReg;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -208,8 +176,8 @@ DEFINE_STRUCT_A64(STR_UIMM) { ...@@ -208,8 +176,8 @@ DEFINE_STRUCT_A64(STR_UIMM) {
InstA64 size:2; InstA64 size:2;
}; };
DEFINE_OPCODE(SUB_EXT_REG_1, 0b1) DEFINE_OPCODE_A64(SUB_EXT_REG_1, 0b1)
DEFINE_OPCODE(SUB_EXT_REG_2, 0b01011001) DEFINE_OPCODE_A64(SUB_EXT_REG_2, 0b01011001)
DEFINE_STRUCT_A64(SUB_EXT_REG) { DEFINE_STRUCT_A64(SUB_EXT_REG) {
InstA64 rd:WideReg; InstA64 rd:WideReg;
InstA64 rn:WideReg; InstA64 rn:WideReg;
...@@ -222,8 +190,8 @@ DEFINE_STRUCT_A64(SUB_EXT_REG) { ...@@ -222,8 +190,8 @@ DEFINE_STRUCT_A64(SUB_EXT_REG) {
InstA64 sf:1; InstA64 sf:1;
}; };
DEFINE_OPCODE(EXCEPTION_GEN_1, 0b11010100) DEFINE_OPCODE_A64(EXCEPTION_GEN_1, 0b11010100)
DEFINE_OPCODE(EXCEPTION_GEN_2, 0b000) DEFINE_OPCODE_A64(EXCEPTION_GEN_2, 0b000)
DEFINE_STRUCT_A64(EXCEPTION_GEN) { DEFINE_STRUCT_A64(EXCEPTION_GEN) {
InstA64 ll:2; InstA64 ll:2;
InstA64 opcode2:3; InstA64 opcode2:3;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "register_list_a64.h" #include "register_list_a64.h"
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::RegistersA64;
RegisterA64::RegisterA64() {} RegisterA64::RegisterA64() {}
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "register_list_a64.h" #include "register_list_a64.h"
namespace SandHook {
namespace RegistersA64 {
#define INIT_REGISTERS(N) \ #define INIT_REGISTERS(N) \
WRegister W##N = WRegister(N); \ WRegister W##N = WRegister(N); \
XRegister X##N = XRegister(N); XRegister X##N = XRegister(N);
...@@ -19,6 +22,7 @@ XRegister LR = X30; ...@@ -19,6 +22,7 @@ XRegister LR = X30;
XRegister XZR = X31; XRegister XZR = X31;
WRegister WZR = W31; WRegister WZR = W31;
RegisterA64 UnknowRegiser = RegisterA64(38); RegisterA64 UnknowRegiser = RegisterA64(38);
}
}
//cmp.... //cmp....
#define ZeroRegFor(X) X.isX() ? XZR : WZR #define ZeroRegFor(X) X.isX() ? XZR : WZR
\ No newline at end of file
...@@ -19,21 +19,26 @@ using namespace SandHook::Asm; ...@@ -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(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) R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
namespace SandHook {
namespace RegistersA64 {
#define DEFINE_REGISTERS(N) \ #define DEFINE_REGISTERS(N) \
extern WRegister W##N; \ extern WRegister W##N; \
extern XRegister X##N; extern XRegister X##N;
AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS) AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS #undef DEFINE_REGISTERS
extern WRegister WSP; extern WRegister WSP;
extern XRegister SP; extern XRegister SP;
extern XRegister IP0; extern XRegister IP0;
extern XRegister IP1; extern XRegister IP1;
extern XRegister LR; extern XRegister LR;
//zero reg //zero reg
extern XRegister XZR; extern XRegister XZR;
extern WRegister WZR; extern WRegister WZR;
extern RegisterA64 UnknowRegiser; extern RegisterA64 UnknowRegiser;
}}
#define XReg(N) XRegister::get(N) #define XReg(N) XRegister::get(N)
#define WReg(N) WRegister::get(N) #define WReg(N) WRegister::get(N)
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#include "code_relocate_a64.h" #include "code_relocate_a64.h"
#include "decoder_arm64.h" #include "decoder_arm64.h"
using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64;
#define __ assemblerA64-> #define __ assemblerA64->
#define IMPL_RELOCATE(X) void CodeRelocateA64::relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException) #define IMPL_RELOCATE(X) void CodeRelocateA64::relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException)
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
using namespace SandHook::Assembler; using namespace SandHook::Assembler;
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
using namespace SandHook::AsmA64;
#define DEFINE_RELOCATE(X) void relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException); #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; ...@@ -14,10 +14,11 @@ using namespace SandHook::Assembler;
using namespace SandHook::Utils; using namespace SandHook::Utils;
#include "assembler_a64.h" #include "assembler_a64.h"
#include "code_relocate_a64.h" #include "code_relocate_a64.h"
#include "code_relocate_a64.h" #include "code_relocate_a64.h"
using namespace SandHook::RegistersA64;
AndroidCodeBuffer* backupBuffer = new AndroidCodeBuffer(); AndroidCodeBuffer* backupBuffer = new AndroidCodeBuffer();
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
using namespace SandHook::Hook; using namespace SandHook::Hook;
using namespace SandHook::AsmA64;
void (*dosth3Backup)(int, int) = nullptr; void (*dosth3Backup)(int, int) = nullptr;
void (*dosth4Backup)() = nullptr; void (*dosth4Backup)() = nullptr;
...@@ -92,7 +93,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) ...@@ -92,7 +93,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
InstA64* codebl = reinterpret_cast<InstA64 *>((Addr)do1 + 8); InstA64* codebl = reinterpret_cast<InstA64 *>((Addr)do1 + 8);
if (IS_OPCODE(*codebl, B_BL)) { if (IS_OPCODE_A64(*codebl, B_BL)) {
//decode //decode
A64_B_BL a64bl(*reinterpret_cast<STRUCT_A64(B_BL)*>(codebl)); 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) ...@@ -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); A64_STR_UIMM str(test.str);
str.assembler(); str.assembler();
str.get(); 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