Commit a3db525c authored by swift_gan's avatar swift_gan Committed by swift_gan

tweak register & add mov inst

parent 9dcdeade
...@@ -19,8 +19,9 @@ add_library( # Sets the name of the library. ...@@ -19,8 +19,9 @@ 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/decoder/decoder.cpp
src/main/cpp/archs/arm64/inst_arm64.cpp src/main/cpp/archs/arm64/inst/inst_arm64.cpp
src/main/cpp/archs/arm64/decoder_arm64.cpp src/main/cpp/archs/arm64/register/register_a64.cpp
src/main/cpp/archs/arm64/decoder/decoder_arm64.cpp
) )
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// //
#include "inst_arm64.h" #include "inst_arm64.h"
#include "../register/register_a64.h"
using namespace SandHook::Asm; using namespace SandHook::Asm;
...@@ -55,3 +56,36 @@ int A64_ADR_ADRP::getImm() { ...@@ -55,3 +56,36 @@ int A64_ADR_ADRP::getImm() {
return getImmPCRel(); return getImmPCRel();
} }
//Mov Wide
A64_MOV_WIDE::A64_MOV_WIDE() {}
A64_MOV_WIDE::A64_MOV_WIDE(aarch64_mov_wide *inst) : InstructionA64(inst) {
decode(inst);
}
A64_MOV_WIDE::A64_MOV_WIDE(A64_MOV_WIDE::MOV_WideOp op,RegisterA64* rd, U16 imme, U8 shift)
: shift(shift), op(op), imme(imme), rd(rd) {
assembler();
}
void A64_MOV_WIDE::assembler() {
get()->opcode = MOV_WIDE_OPCODE;
get()->imm16 = imme;
get()->hw = static_cast<InstA64>(shift / 16);
get()->opc = op;
get()->sf = rd->is64Bit() ? 1 : 0;
get()->rd = rd->getCode();
}
void A64_MOV_WIDE::decode(aarch64_mov_wide *inst) {
imme = static_cast<U16>(inst->imm16);
shift = static_cast<U8>(inst->hw * 16);
op = static_cast<MOV_WideOp>(inst->opc);
if (inst->sf == 0) {
rd = XRegister::get(static_cast<U8>(inst->rd));
} else {
rd = WRegister::get(static_cast<U8>(inst->rd));
}
}
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
#ifndef SANDHOOK_NH_INST_ARM64_H #ifndef SANDHOOK_NH_INST_ARM64_H
#define SANDHOOK_NH_INST_ARM64_H #define SANDHOOK_NH_INST_ARM64_H
#include <register.h>
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
#include "../../asm/instruction.h" #include "../../../asm/instruction.h"
#include "../../includes/base.h" #include "../../../includes/base.h"
#include "../register/register_a64.h"
namespace SandHook { namespace SandHook {
...@@ -78,6 +80,54 @@ namespace SandHook { ...@@ -78,6 +80,54 @@ namespace SandHook {
}; };
class A64_MOV_WIDE : public InstructionA64<aarch64_mov_wide> {
public:
enum MOV_WideOp {
// Move and keep.
MOV_WideOp_K = 0b00,
// Move with zero.
MOV_WideOp_Z = 0b10,
// Move with non-zero.
MOV_WideOp_N = 0b11,
};
A64_MOV_WIDE();
A64_MOV_WIDE(aarch64_mov_wide *inst);
A64_MOV_WIDE(A64_MOV_WIDE::MOV_WideOp op, RegisterA64* rd, U16 imme, U8 shift);
void assembler() override;
void decode(aarch64_mov_wide *decode) override;
inline U8 getShift() {
return shift;
}
inline MOV_WideOp getOpt() {
return op;
}
inline U16 getImme() {
return imme;
}
inline Register* getRd() {
return rd;
}
private:
//can be 16/32/64/128
//hw = shift / 16
U8 shift;
MOV_WideOp op;
U16 imme;
RegisterA64* rd;
};
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define SANDHOOK_NH_INST_AARCH64_H #define SANDHOOK_NH_INST_AARCH64_H
#include "../../asm/instruction.h" #include "../../../asm/instruction.h"
enum InstructionFields { enum InstructionFields {
...@@ -86,4 +86,15 @@ struct aarch64_pcrel_insts { ...@@ -86,4 +86,15 @@ struct aarch64_pcrel_insts {
struct aarch64_adr_adrp : public aarch64_pcrel_insts {}; struct aarch64_adr_adrp : public aarch64_pcrel_insts {};
#define MOV_WIDE_OPCODE 0b100101
struct aarch64_mov_wide {
InstA64 sf:1;
InstA64 opc:2;
InstA64 opcode:6;
InstA64 hw:2;
InstA64 imm16:16;
InstA64 rd:5;
};
#endif //SANDHOOK_NH_INST_AARCH64_H #endif //SANDHOOK_NH_INST_AARCH64_H
//
// Created by swift on 2019/5/8.
//
#include "register_a64.h"
#include "register_list_a64.h"
using namespace SandHook::Asm;
RegisterA64::RegisterA64() {}
RegisterA64::RegisterA64(U8 code) : Register(code) {}
XRegister* XRegister::registers[AARCH64_REGISTER_COUNT] = {
#define DEFINE_REGISTERS(N) \
&X##N,
AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
};
XRegister::XRegister(U8 code) : RegisterA64(code) {}
XRegister::XRegister() {}
U8 XRegister::getWide() {
return Reg64Bit;
}
WRegister* WRegister::registers[AARCH64_REGISTER_COUNT] = {
#define DEFINE_REGISTERS(N) \
&W##N,
AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
};
WRegister::WRegister(U8 code) : RegisterA64(code) {}
WRegister::WRegister() {}
U8 WRegister::getWide() {
return Reg32Bit;
}
//
// Created by swift on 2019/5/8.
//
#ifndef SANDHOOK_NH_REGISTER_A64_H
#define SANDHOOK_NH_REGISTER_A64_H
#include "register.h"
// clang-format off
#define AARCH64_REGISTER_COUNT 32
#define AARCH64_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) \
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 Asm {
class RegisterA64 : 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
};
enum SpecialRegisters {
kFpRegCode = 29,
kLinkRegCode = 30,
kSpRegCode = 31,
kZeroRegCode = 31,
kSPRegInternalCode = 63
};
RegisterA64();
RegisterA64(U8 code);
};
class XRegister : public RegisterA64 {
public:
XRegister();
XRegister(U8 code);
U8 getWide() override;
static XRegister* get(U8 code) {
return registers[code];
}
private:
static XRegister* registers[];
};
class WRegister : public RegisterA64 {
public:
WRegister();
WRegister(U8 code);
U8 getWide() override;
static WRegister* get(U8 code) {
return registers[code];
}
private:
static WRegister* registers[];
};
}
}
#endif //SANDHOOK_NH_REGISTER_A64_H
//
// Created by swift on 2019/5/8.
//
#ifndef SANDHOOK_NH_REGISTER_LIST_A64_H
#define SANDHOOK_NH_REGISTER_LIST_A64_H
#include "register_a64.h"
#include "../../../includes/base.h"
using namespace SandHook::Asm;
#define DEFINE_REGISTERS(N) \
WRegister W##N(N); \
XRegister X##N(N);
AARCH64_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
WRegister WSP(RegisterA64::kSPRegInternalCode);
XRegister SP(RegisterA64::kSPRegInternalCode);
#endif //SANDHOOK_NH_REGISTER_LIST_A64_H
...@@ -8,9 +8,13 @@ ...@@ -8,9 +8,13 @@
#include <malloc.h> #include <malloc.h>
#include "../includes/base.h" #include "../includes/base.h"
//aarch64
typedef U32 InstA64; typedef U32 InstA64;
//arm32
typedef U32 InstA32; typedef U32 InstA32;
//thumb16
typedef U16 InstT16; typedef U16 InstT16;
//thumb32
typedef U32 InstT32; typedef U32 InstT32;
#if defined(__aarch64__) #if defined(__aarch64__)
...@@ -86,6 +90,10 @@ namespace SandHook { ...@@ -86,6 +90,10 @@ namespace SandHook {
virtual bool pcRelate() { virtual bool pcRelate() {
return false; return false;
} }
virtual void decode(Inst* decode) {}
virtual void assembler() {}
}; };
class Data16 : public Unit<U16> { class Data16 : public Unit<U16> {
......
...@@ -9,19 +9,47 @@ ...@@ -9,19 +9,47 @@
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
enum RegVariant {
Reg32Bit = 32,
Reg64Bit = 64,
Reg128Bit = 128
};
class Register { class Register {
public: public:
bool isFP() {
Register() {}
Register(U8 code) : code(code) {}
inline U8 getCode() {
return code;
}
virtual bool isFP() {
return false; return false;
}; };
virtual U8 getWide() {
return 0;
};
inline bool is32Bit() {
return getWide() == Reg32Bit;
}
inline bool is64Bit() {
return getWide() == Reg64Bit;
}
inline bool is128Bit() {
return getWide() == Reg128Bit;
}
private: private:
U8 num; U8 code;
//byte
U8 wide;
U32 code;
Arch arch;
InstType instType;
}; };
} }
} }
......
...@@ -72,7 +72,6 @@ T AlignDown(T pointer, ...@@ -72,7 +72,6 @@ T AlignDown(T pointer,
#define OFFSET(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER) #define OFFSET(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
//data covert //data covert
// Macros for compile-time format checking. // Macros for compile-time format checking.
...@@ -178,4 +177,8 @@ static inline int32_t BITS32H(int64_t value) { ...@@ -178,4 +177,8 @@ static inline int32_t BITS32H(int64_t value) {
return static_cast<int32_t>(value >> 32); return static_cast<int32_t>(value >> 32);
} }
// left/right shift
#define LFT(a, b, c) ((a & ((1 << b) - 1)) << c)
#define RHT(a, b, c) ((a >> c) & ((1 << b) - 1))
#endif //SANDHOOK_BASE_H #endif //SANDHOOK_BASE_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