Commit 21256c16 authored by swift_gan's avatar swift_gan Committed by swift_gan

[Reconstitution]init

parent 1306c792
...@@ -27,7 +27,7 @@ dependencies { ...@@ -27,7 +27,7 @@ dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':hooklib') implementation project(':hooklib')
//implementation project(':nativehook') implementation project(':nativehook')
implementation project(':xposedcompat') implementation project(':xposedcompat')
//implementation project(':xposedcompat_new') //implementation project(':xposedcompat_new')
} }
...@@ -5,6 +5,7 @@ import android.app.Application; ...@@ -5,6 +5,7 @@ import android.app.Application;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import com.swift.sandhook.nativehook.NativeHook;
import com.swift.sandhook.test.TestClass; import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.testHookers.ActivityHooker; import com.swift.sandhook.testHookers.ActivityHooker;
import com.swift.sandhook.testHookers.CtrHook; import com.swift.sandhook.testHookers.CtrHook;
...@@ -22,7 +23,7 @@ import de.robv.android.xposed.XposedHelpers; ...@@ -22,7 +23,7 @@ import de.robv.android.xposed.XposedHelpers;
public class MyApp extends Application { public class MyApp extends Application {
//if you want test Android Q, please set true, because SDK_INT of Android Q is still 28 //if you want test Android Q, please Set true, because SDK_INT of Android Q is still 28
public final static boolean testAndroidQ = false; public final static boolean testAndroidQ = false;
@Override @Override
...@@ -36,6 +37,8 @@ public class MyApp extends Application { ...@@ -36,6 +37,8 @@ public class MyApp extends Application {
SandHookConfig.SDK_INT = 29; SandHookConfig.SDK_INT = 29;
} }
NativeHook.test();
SandHook.disableVMInline(); SandHook.disableVMInline();
SandHook.tryDisableProfile(getPackageName()); SandHook.tryDisableProfile(getPackageName());
SandHook.disableDex2oatInline(false); SandHook.disableDex2oatInline(false);
......
...@@ -71,6 +71,7 @@ include_directories( ...@@ -71,6 +71,7 @@ include_directories(
src/main/cpp/archs/arm/arm32/decoder src/main/cpp/archs/arm/arm32/decoder
src/main/cpp/archs/arm/arm32/hook src/main/cpp/archs/arm/arm32/hook
src/main/cpp/archs/arm/arm32/relocate src/main/cpp/archs/arm/arm32/relocate
src/main/cpp/antihook
) )
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a
......
...@@ -17,7 +17,7 @@ android { ...@@ -17,7 +17,7 @@ android {
cmake { cmake {
arguments '-DBUILD_TESTING=OFF' arguments '-DBUILD_TESTING=OFF'
cppFlags "-frtti -fexceptions -Wpointer-arith" cppFlags "-frtti -fexceptions -Wpointer-arith"
abiFilters 'armeabi-v7a', 'arm64-v8a' abiFilters 'arm64-v8a'
} }
} }
} }
......
...@@ -146,7 +146,7 @@ void AssemblerA32::Add(RegisterA32 &rd, RegisterA32 &rn, RegisterA32 &rm) { ...@@ -146,7 +146,7 @@ void AssemblerA32::Add(RegisterA32 &rd, RegisterA32 &rn, RegisterA32 &rm) {
} }
void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) { void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) {
if (rd.getCode() < 8 && rn.getCode() < 8) { if (rd.Code() < 8 && rn.Code() < 8) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG)(rd, rn))); Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG)(rd, rn)));
} else { } else {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG_EXT)(rd, rn))); Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG_EXT)(rd, rn)));
...@@ -154,7 +154,7 @@ void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) { ...@@ -154,7 +154,7 @@ void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) {
} }
void AssemblerA32::Pop(RegisterA32 &rt) { void AssemblerA32::Pop(RegisterA32 &rt) {
if (rt.getCode() < 8 || rt == PC) { if (rt.Code() < 8 || rt == PC) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(POP)(RegisterList(rt)))); Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(POP)(RegisterList(rt))));
} else { } else {
throw ErrorCodeException("error pop inst"); throw ErrorCodeException("error pop inst");
...@@ -162,7 +162,7 @@ void AssemblerA32::Pop(RegisterA32 &rt) { ...@@ -162,7 +162,7 @@ void AssemblerA32::Pop(RegisterA32 &rt) {
} }
void AssemblerA32::Push(RegisterA32 &rt) { void AssemblerA32::Push(RegisterA32 &rt) {
if (rt.getCode() < 8 || rt == PC) { if (rt.Code() < 8 || rt == PC) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(PUSH)(RegisterList(rt)))); Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(PUSH)(RegisterList(rt))));
} else { } else {
throw ErrorCodeException("error pop inst"); throw ErrorCodeException("error pop inst");
......
...@@ -23,7 +23,8 @@ goto label_matched; \ ...@@ -23,7 +23,8 @@ goto label_matched; \
Arm32Decoder* Arm32Decoder::instant = new Arm32Decoder(); Arm32Decoder* Arm32Decoder::instant = new Arm32Decoder();
void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) { void Arm32Decoder::Disassembler(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) {
bool thumb = isThumbCode(reinterpret_cast<Addr>(codeStart)); bool thumb = isThumbCode(reinterpret_cast<Addr>(codeStart));
if (thumb) { if (thumb) {
codeStart = getThumbCodeAddress(codeStart); codeStart = getThumbCodeAddress(codeStart);
...@@ -74,7 +75,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b ...@@ -74,7 +75,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
if (!visitor.visit(unit, pc)) { if (!visitor.visit(unit, pc)) {
break; break;
} }
pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->size()); pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->Size());
unit = nullptr; unit = nullptr;
} }
} }
......
...@@ -12,7 +12,8 @@ namespace SandHook { ...@@ -12,7 +12,8 @@ namespace SandHook {
class Arm32Decoder : public InstDecoder { class Arm32Decoder : public InstDecoder {
public: public:
void decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) override; void Disassembler(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) override;
public: public:
static Arm32Decoder* instant; static Arm32Decoder* instant;
}; };
......
...@@ -17,7 +17,7 @@ using namespace SandHook::Utils; ...@@ -17,7 +17,7 @@ using namespace SandHook::Utils;
#include "assembler_arm32.h" #include "assembler_arm32.h"
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { void *InlineHookArm32Android::InlineHook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* originCode; void* originCode;
...@@ -73,7 +73,7 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { ...@@ -73,7 +73,7 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) {
IMPORT_SHELLCODE(BP_SHELLCODE) IMPORT_SHELLCODE(BP_SHELLCODE)
IMPORT_LABEL(callback_addr_s, Addr) IMPORT_LABEL(callback_addr_s, Addr)
IMPORT_LABEL(origin_addr_s, Addr) IMPORT_LABEL(origin_addr_s, Addr)
bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) { bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* originCode; void* originCode;
......
...@@ -18,9 +18,9 @@ namespace SandHook { ...@@ -18,9 +18,9 @@ namespace SandHook {
inline ~InlineHookArm32Android() { inline ~InlineHookArm32Android() {
delete hookLock; delete hookLock;
} }
void *inlineHook(void *origin, void *replace) override; void *InlineHook(void *origin, void *replace) override;
bool breakPoint(void *point, void (*callback)(REG *)) override; bool BreakPoint(void *point, void (*callback)(REG *)) override;
protected: protected:
std::mutex* hookLock; std::mutex* hookLock;
......
...@@ -2,16 +2,15 @@ ...@@ -2,16 +2,15 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_ARM32_BASE_H #pragma once
#define SANDHOOK_ARM32_BASE_H
#include <ostream> #include <ostream>
#include "arm_base.h" #include "arm_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
#include "instruction.h" #include "instruction.h"
#define DECODE_OFFSET(bits, ext) signExtend32(bits + ext, COMBINE(get()->imm##bits, 0, ext)) #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) #define ENCODE_OFFSET(bits, ext) Get()->imm##bits = TruncateToUint##bits(offset >> ext)
#define CODE_OFFSET(I) I->offset + (I->instType() == A32 ? 2 * 4 : 2 * 2) #define CODE_OFFSET(I) I->offset + (I->instType() == A32 ? 2 * 4 : 2 * 2)
...@@ -47,8 +46,8 @@ namespace SandHook { ...@@ -47,8 +46,8 @@ namespace SandHook {
bool IsPostIndex() const { return addr_mode == PostIndex; } bool IsPostIndex() const { return addr_mode == PostIndex; }
public: public:
RegisterA32* rn; // base RegisterA32* rn; // base_
RegisterA32* rm; // register offset RegisterA32* rm; // register offset_
S32 offset; // valid if rm_ == no_reg S32 offset; // valid if rm_ == no_reg
Shift shift; Shift shift;
Sign sign; Sign sign;
...@@ -126,10 +125,10 @@ namespace SandHook { ...@@ -126,10 +125,10 @@ namespace SandHook {
private: private:
static U16 RegisterToList(RegisterA32& reg) { static U16 RegisterToList(RegisterA32& reg) {
if (reg.getCode() == UnknowRegiser.getCode()) { if (reg.Code() == UnknowRegiser.Code()) {
return 0; return 0;
} else { } else {
return static_cast<U16>(UINT16_C(1) << reg.getCode()); return static_cast<U16>(UINT16_C(1) << reg.Code());
} }
} }
...@@ -165,6 +164,4 @@ namespace SandHook { ...@@ -165,6 +164,4 @@ namespace SandHook {
std::ostream& operator<<(std::ostream& os, RegisterList registers); std::ostream& operator<<(std::ostream& os, RegisterList registers);
} }
} }
\ No newline at end of file
#endif //SANDHOOK_ARM32_BASE_H
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
//A64_STR_IMM::A64_STR_IMM() {} //A64_STR_IMM::A64_STR_IMM() {}
// //
//A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) *inst) : InstructionA64(inst) { //A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) *inst) : InstructionA64(inst) {
// decode(inst); // DisAssembler(inst);
//} //}
// //
//A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {} //A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {}
...@@ -17,11 +17,11 @@ ...@@ -17,11 +17,11 @@
// : condition(condition), rt(&rt), operand(operand) {} // : condition(condition), rt(&rt), operand(operand) {}
// //
//AddrMode A64_STR_IMM::decodeAddrMode() { //AddrMode A64_STR_IMM::decodeAddrMode() {
// if (get()->P == 1 && get()->W == 0) { // if (Get()->P == 1 && Get()->W == 0) {
// return Offset; // return Offset;
// } else if (get()->P == 0 && get()->W == 0) { // } else if (Get()->P == 0 && Get()->W == 0) {
// return PostIndex; // return PostIndex;
// } else if (get()->P == 1 && get()->W == 1) { // } else if (Get()->P == 1 && Get()->W == 1) {
// return PreIndex; // return PreIndex;
// } else { // } else {
// valid = false; // valid = false;
...@@ -29,20 +29,20 @@ ...@@ -29,20 +29,20 @@
// } // }
//} //}
// //
//void A64_STR_IMM::decode(STRUCT_A64(STR_IMM) *inst) { //void A64_STR_IMM::DisAssembler(STRUCT_A64(STR_IMM) *inst) {
// imm32 = zeroExtend32(12, inst->imm12); // imm32 = zeroExtend32(12, inst->imm12);
// condition = Condition(inst->cond); // condition = Condition(inst->cond);
// operand.addr_mode = decodeAddrMode(); // operand.addr_mode_ = decodeAddrMode();
// index = inst->P == 1; // index = inst->P == 1;
// wback = inst->P == 1 || inst->W == 0; // wback = inst->P == 1 || inst->W == 0;
// add = inst->U == 0; // add = inst->U == 0;
// rt = XReg(static_cast<U8>(inst->rt)); // rt = XReg(static_cast<U8>(inst->rt));
// operand.base = XReg(static_cast<U8>(inst->rn)); // operand.base_ = XReg(static_cast<U8>(inst->rn));
// operand.offset = add ? imm32 : -imm32; // operand.offset_ = add ? imm32 : -imm32;
//} //}
// //
// //
//void A64_STR_IMM::assembler() { //void A64_STR_IMM::Assembler() {
// INST_DCHECK(condition, Condition::nv) // INST_DCHECK(condition, Condition::nv)
// //
//} //}
\ No newline at end of file
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_ARM32_H #pragma once
#define SANDHOOK_NH_INST_ARM32_H
namespace SandHook { namespace SandHook {
...@@ -20,16 +19,16 @@ namespace SandHook { ...@@ -20,16 +19,16 @@ namespace SandHook {
// //
// DEFINE_IS_EXT(STR_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(STR_IMM)) && TEST_INST_FIELD(unkown1_0, 0) && TEST_INST_FIELD(unkown2_0, 0)) // DEFINE_IS_EXT(STR_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(STR_IMM)) && TEST_INST_FIELD(unkown1_0, 0) && TEST_INST_FIELD(unkown2_0, 0))
// //
// inline U32 instCode() override { // inline U32 InstCode() override {
// return STR_x; // return STR_x;
// } // }
// //
// void decode(STRUCT_A64(STR_IMM) *inst) override; // void DisAssembler(STRUCT_A64(STR_IMM) *inst) override;
// //
// void assembler() override; // void Assembler() override;
// //
// AddrMode getAddrMode() { // AddrMode getAddrMode() {
// return operand.addr_mode; // return operand.addr_mode_;
// } // }
// //
// private: // private:
...@@ -46,6 +45,4 @@ namespace SandHook { ...@@ -46,6 +45,4 @@ namespace SandHook {
// bool index; // bool index;
//}; //};
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_INST_ARM32_H
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_CODE_ARM32_H #pragma once
#define SANDHOOK_INST_CODE_ARM32_H
enum class InstCodeA32 { enum class InstCodeA32 : InstCode {
}; };
enum class InstCodeT16 { enum class InstCodeT16 : InstCode {
UNKNOW, UNKNOW,
BASE_SASMC, BASE_SASMC,
DATA_PROC, DATA_PROC,
...@@ -33,7 +32,7 @@ enum class InstCodeT16 { ...@@ -33,7 +32,7 @@ enum class InstCodeT16 {
ADD_REG_RDN ADD_REG_RDN
}; };
enum class InstCodeT32 { enum class InstCodeT32 : InstCode {
UNKNOW, UNKNOW,
B32, B32,
LDR_LIT, LDR_LIT,
...@@ -41,6 +40,4 @@ enum class InstCodeT32 { ...@@ -41,6 +40,4 @@ enum class InstCodeT32 {
LDR_UIMM, LDR_UIMM,
MOV_MOVT_IMM, MOV_MOVT_IMM,
SUB_IMM, SUB_IMM,
}; };
\ No newline at end of file
#endif //SANDHOOK_INST_CODE_ARM32_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_ARM32_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_ARM32_H
#include "instruction.h" #include "instruction.h"
...@@ -26,7 +25,4 @@ DEFINE_STRUCT_A32(STR_IMM) { ...@@ -26,7 +25,4 @@ DEFINE_STRUCT_A32(STR_IMM) {
InstA64 P:1; InstA64 P:1;
InstA64 opcode:3; InstA64 opcode:3;
InstA64 cond:4; InstA64 cond:4;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_STRCUT_ARM32_H
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_T16_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_T16_H
#include "instruction.h" #include "instruction.h"
#include "inst_code_arm32.h" #include "inst_code_arm32.h"
...@@ -19,7 +17,7 @@ ...@@ -19,7 +17,7 @@
InstT16 opcode_base:w_base; InstT16 opcode_base:w_base;
//Shift (immediate), add, subtract, move, and compare //Shift (immediate_), add, subtract, Move, and compare
//opcode_base == 0b00 //opcode_base == 0b00
DEFINE_OPCODE_T16(BASE_SASMC, 0b00) DEFINE_OPCODE_T16(BASE_SASMC, 0b00)
//Data-processing //Data-processing
...@@ -34,7 +32,7 @@ DEFINE_OPCODE_T16(MISC, 0b1011) ...@@ -34,7 +32,7 @@ DEFINE_OPCODE_T16(MISC, 0b1011)
#define T16_REG_WIDE 3 #define T16_REG_WIDE 3
//unknow inst //Unknow inst
DEFINE_STRUCT_T16(UNKNOW) { DEFINE_STRUCT_T16(UNKNOW) {
InstT16 raw; InstT16 raw;
}; };
...@@ -156,7 +154,4 @@ DEFINE_STRUCT_T16(PUSH) { ...@@ -156,7 +154,4 @@ DEFINE_STRUCT_T16(PUSH) {
InstT16 regs:8; InstT16 regs:8;
InstT16 M:1; InstT16 M:1;
InstT16 opcode:7; InstT16 opcode:7;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_STRUCT_T16_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_T32_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_T32_H
#include "instruction.h" #include "instruction.h"
...@@ -16,7 +15,7 @@ ...@@ -16,7 +15,7 @@
#define T32_REG_WIDE 4 #define T32_REG_WIDE 4
//unknow inst //Unknow inst
DEFINE_STRUCT_T32(UNKNOW) { DEFINE_STRUCT_T32(UNKNOW) {
InstT32 raw; InstT32 raw;
}; };
...@@ -96,5 +95,3 @@ DEFINE_STRUCT_T32(SUB_IMM) { ...@@ -96,5 +95,3 @@ DEFINE_STRUCT_T32(SUB_IMM) {
InstT32 imm3:3; InstT32 imm3:3;
InstT32 opcode2:1; InstT32 opcode2:1;
}; };
#endif //SANDHOOK_NH_INST_STRUCT_T32_H
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
#include "arm32_base.h" #include "arm32_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
#define SET_BASE_OPCODE(X) get()->opcode_base = OPCODE_T16(X) #define SET_BASE_OPCODE(X) Get()->opcode_base = OPCODE_T16(X)
#define SET_OPCODE(X) get()->opcode = 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) #define SET_OPCODE_MULTI(X, INDEX) Get()->opcode##INDEX = OPCODE_T16(X##_##INDEX)
using namespace SandHook::AsmA32; using namespace SandHook::AsmA32;
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -18,44 +18,44 @@ using namespace SandHook::RegistersA32; ...@@ -18,44 +18,44 @@ using namespace SandHook::RegistersA32;
//Unknow //Unknow
T16_UNKNOW::T16_UNKNOW(STRUCT_T16(UNKNOW) &inst) : InstructionT16(&inst) { T16_UNKNOW::T16_UNKNOW(STRUCT_T16(UNKNOW) &inst) : InstructionT16(&inst) {
decode(&inst); Disassembler(&inst);
} }
void T16_UNKNOW::decode(T16_STRUCT_UNKNOW *inst) { void T16_UNKNOW::Disassembler(T16_STRUCT_UNKNOW *inst) {
inst_backup = *inst; inst_backup = *inst;
} }
void T16_UNKNOW::assembler() { void T16_UNKNOW::Assembler() {
set(inst_backup); Set(inst_backup);
} }
//B //B
T16_B::T16_B() {} T16_B::T16_B() {}
T16_B::T16_B(T16_STRUCT_B *inst) : T16_INST_PC_REL(inst) { T16_B::T16_B(T16_STRUCT_B *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T16_B::T16_B(Off offset) : offset(offset) {} T16_B::T16_B(Off offset) : offset(offset) {}
T16_B::T16_B(Label &label) { T16_B::T16_B(Label &label) {
bindLabel(label); BindLabel(label);
} }
Off T16_B::getImmPCOffset() { Off T16_B::GetImmPCOffset() {
return DECODE_OFFSET(11, 1); return DECODE_OFFSET(11, 1);
} }
void T16_B::decode(T16_STRUCT_B *inst) { void T16_B::Disassembler(T16_STRUCT_B *inst) {
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_B::assembler() { void T16_B::Assembler() {
SET_OPCODE(B); SET_OPCODE(B);
DECODE_OFFSET(11, 1); DECODE_OFFSET(11, 1);
} }
void T16_B::onOffsetApply(Off offset) { void T16_B::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
DECODE_OFFSET(11, 1); DECODE_OFFSET(11, 1);
} }
...@@ -66,32 +66,32 @@ void T16_B::onOffsetApply(Off offset) { ...@@ -66,32 +66,32 @@ void T16_B::onOffsetApply(Off offset) {
T16_B_COND::T16_B_COND() {} T16_B_COND::T16_B_COND() {}
T16_B_COND::T16_B_COND(STRUCT_T16(B_COND) *inst) : T16_INST_PC_REL(inst) { T16_B_COND::T16_B_COND(STRUCT_T16(B_COND) *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T16_B_COND::T16_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {} T16_B_COND::T16_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
T16_B_COND::T16_B_COND(Condition condition, Label &label) { T16_B_COND::T16_B_COND(Condition condition, Label &label) {
bindLabel(label); BindLabel(label);
} }
void T16_B_COND::decode(STRUCT_T16(B_COND) *inst) { void T16_B_COND::Disassembler(STRUCT_T16(B_COND) *inst) {
DECODE_COND; DECODE_COND;
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_B_COND::assembler() { void T16_B_COND::Assembler() {
SET_OPCODE(B_COND); SET_OPCODE(B_COND);
ENCODE_COND; ENCODE_COND;
ENCODE_OFFSET(8, 1); ENCODE_OFFSET(8, 1);
} }
void T16_B_COND::onOffsetApply(Off offset) { void T16_B_COND::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(8, 1); ENCODE_OFFSET(8, 1);
} }
Off T16_B_COND::getImmPCOffset() { Off T16_B_COND::GetImmPCOffset() {
return DECODE_OFFSET(8, 1); return DECODE_OFFSET(8, 1);
} }
...@@ -101,15 +101,15 @@ Off T16_B_COND::getImmPCOffset() { ...@@ -101,15 +101,15 @@ Off T16_B_COND::getImmPCOffset() {
T16_BX_BLX::T16_BX_BLX(T16_BX_BLX::OP op, RegisterA32 &rm) : op(op), rm(&rm) {} T16_BX_BLX::T16_BX_BLX(T16_BX_BLX::OP op, RegisterA32 &rm) : op(op), rm(&rm) {}
T16_BX_BLX::T16_BX_BLX(T16_STRUCT_BX_BLX *inst) : T16_INST_PC_REL(inst) { T16_BX_BLX::T16_BX_BLX(T16_STRUCT_BX_BLX *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
void T16_BX_BLX::decode(STRUCT_T16(BX_BLX) *inst) { void T16_BX_BLX::Disassembler(STRUCT_T16(BX_BLX) *inst) {
DECODE_OP; DECODE_OP;
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_BX_BLX::assembler() { void T16_BX_BLX::Assembler() {
SET_OPCODE_MULTI(BX_BLX, 1); SET_OPCODE_MULTI(BX_BLX, 1);
SET_OPCODE_MULTI(BX_BLX, 2); SET_OPCODE_MULTI(BX_BLX, 2);
ENCODE_OP; ENCODE_OP;
...@@ -119,7 +119,7 @@ void T16_BX_BLX::assembler() { ...@@ -119,7 +119,7 @@ void T16_BX_BLX::assembler() {
//CBZ CBNZ //CBZ CBNZ
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst) : T16_INST_PC_REL(inst) { T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : op(op), offset(offset), T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : op(op), offset(offset),
...@@ -128,22 +128,22 @@ T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : o ...@@ -128,22 +128,22 @@ T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : o
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Label& label, RegisterA32 &rn) : op(op), T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Label& label, RegisterA32 &rn) : op(op),
rn(&rn) { rn(&rn) {
bindLabel(label); BindLabel(label);
} }
Off T16_CBZ_CBNZ::getImmPCOffset() { Off T16_CBZ_CBNZ::GetImmPCOffset() {
return COMBINE(get()->i, get()->imm5, 5) << 2; return COMBINE(Get()->i, Get()->imm5, 5) << 2;
} }
void T16_CBZ_CBNZ::decode(T16_STRUCT_CBZ_CBNZ *inst) { void T16_CBZ_CBNZ::Disassembler(T16_STRUCT_CBZ_CBNZ *inst) {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_OP; DECODE_OP;
} }
void T16_CBZ_CBNZ::assembler() { void T16_CBZ_CBNZ::Assembler() {
SET_OPCODE_MULTI(CBZ_CBNZ, 1); SET_OPCODE_MULTI(CBZ_CBNZ, 1);
SET_OPCODE_MULTI(CBZ_CBNZ, 2); SET_OPCODE_MULTI(CBZ_CBNZ, 2);
SET_OPCODE_MULTI(CBZ_CBNZ, 3); SET_OPCODE_MULTI(CBZ_CBNZ, 3);
...@@ -152,7 +152,7 @@ void T16_CBZ_CBNZ::assembler() { ...@@ -152,7 +152,7 @@ void T16_CBZ_CBNZ::assembler() {
ENCODE_OFFSET(5, 2); ENCODE_OFFSET(5, 2);
} }
void T16_CBZ_CBNZ::onOffsetApply(Off offset) { void T16_CBZ_CBNZ::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(5, 2); ENCODE_OFFSET(5, 2);
} }
...@@ -160,32 +160,32 @@ void T16_CBZ_CBNZ::onOffsetApply(Off offset) { ...@@ -160,32 +160,32 @@ void T16_CBZ_CBNZ::onOffsetApply(Off offset) {
//LDR_LIT //LDR_LIT
T16_LDR_LIT::T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst) : T16_INST_PC_REL(inst) { T16_LDR_LIT::T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T16_LDR_LIT::T16_LDR_LIT(Off offset, RegisterA32 &rt) : offset(offset), rt(&rt) { T16_LDR_LIT::T16_LDR_LIT(Off offset, RegisterA32 &rt) : offset(offset), rt(&rt) {
} }
Off T16_LDR_LIT::getImmPCOffset() { Off T16_LDR_LIT::GetImmPCOffset() {
return get()->imm8 << 2; return Get()->imm8 << 2;
} }
Addr T16_LDR_LIT::getImmPCOffsetTarget() { Addr T16_LDR_LIT::GetImmPCOffsetTarget() {
return ALIGN((Addr) getPC() + offset, 4); return ALIGN((Addr) getPC() + offset, 4);
} }
void T16_LDR_LIT::onOffsetApply(Off offset) { void T16_LDR_LIT::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(8, 2); ENCODE_OFFSET(8, 2);
} }
void T16_LDR_LIT::decode(T16_STRUCT_LDR_LIT *inst) { void T16_LDR_LIT::Disassembler(T16_STRUCT_LDR_LIT *inst) {
DECODE_RT(Reg); DECODE_RT(Reg);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_LDR_LIT::assembler() { void T16_LDR_LIT::Assembler() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_RT; ENCODE_RT;
ENCODE_OFFSET(8, 2); ENCODE_OFFSET(8, 2);
...@@ -194,22 +194,22 @@ void T16_LDR_LIT::assembler() { ...@@ -194,22 +194,22 @@ void T16_LDR_LIT::assembler() {
//ADD IMM RD = RN //ADD IMM RD = RN
T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(T16_STRUCT_ADD_IMM_RDN *inst) : InstructionT16(inst) { T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(T16_STRUCT_ADD_IMM_RDN *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8) : rdn(rdn), imm8(imm8) {} T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8) : rdn(rdn), imm8(imm8) {}
void T16_ADD_IMM_RDN::decode(T16_STRUCT_ADD_IMM_RDN *inst) { void T16_ADD_IMM_RDN::Disassembler(T16_STRUCT_ADD_IMM_RDN *inst) {
rdn = Reg(inst->rdn); rdn = Reg(inst->rdn);
imm8 = inst->imm8; imm8 = inst->imm8;
} }
void T16_ADD_IMM_RDN::assembler() { void T16_ADD_IMM_RDN::Assembler() {
SET_OPCODE(ADD_IMM_RDN); SET_OPCODE(ADD_IMM_RDN);
get()->imm8 = imm8; Get()->imm8 = imm8;
get()->rdn = rdn->getCode(); Get()->rdn = rdn->Code();
} }
...@@ -217,56 +217,56 @@ void T16_ADD_IMM_RDN::assembler() { ...@@ -217,56 +217,56 @@ void T16_ADD_IMM_RDN::assembler() {
//ADR //ADR
T16_ADR::T16_ADR(T16_STRUCT_ADR *inst) : T16_INST_PC_REL(inst) { T16_ADR::T16_ADR(T16_STRUCT_ADR *inst) : T16_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T16_ADR::T16_ADR(RegisterA32 &rd, Off offset) : rd(&rd), offset(offset) {} T16_ADR::T16_ADR(RegisterA32 &rd, Off offset) : rd(&rd), offset(offset) {}
T16_ADR::T16_ADR(RegisterA32 &rd, Label &label) : rd(&rd) { T16_ADR::T16_ADR(RegisterA32 &rd, Label &label) : rd(&rd) {
bindLabel(label); BindLabel(label);
} }
Off T16_ADR::getImmPCOffset() { Off T16_ADR::GetImmPCOffset() {
return COMBINE(get()->imm8, 0 ,2); return COMBINE(Get()->imm8, 0 ,2);
} }
Addr T16_ADR::getImmPCOffsetTarget() { Addr T16_ADR::GetImmPCOffsetTarget() {
return RoundDown((Addr) getPC() + offset, 4); return RoundDown((Addr) getPC() + offset, 4);
} }
void T16_ADR::onOffsetApply(Off offset) { void T16_ADR::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
get()->imm8 = (U32)offset >> 2; Get()->imm8 = (U32)offset >> 2;
} }
void T16_ADR::decode(T16_STRUCT_ADR *inst) { void T16_ADR::Disassembler(T16_STRUCT_ADR *inst) {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RD(Reg); DECODE_RD(Reg);
} }
void T16_ADR::assembler() { void T16_ADR::Assembler() {
SET_OPCODE(ADR); SET_OPCODE(ADR);
ENCODE_RD; ENCODE_RD;
get()->imm8 = (U32)offset >> 2; Get()->imm8 = (U32)offset >> 2;
} }
T16_CMP_REG::T16_CMP_REG() {} T16_CMP_REG::T16_CMP_REG() {}
T16_CMP_REG::T16_CMP_REG(T16_STRUCT_CMP_REG *inst) : InstructionT16(inst) { T16_CMP_REG::T16_CMP_REG(T16_STRUCT_CMP_REG *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_CMP_REG::T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn) : rm(&rm), rn(&rn) {} T16_CMP_REG::T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn) : rm(&rm), rn(&rn) {}
void T16_CMP_REG::decode(T16_STRUCT_CMP_REG *inst) { void T16_CMP_REG::Disassembler(T16_STRUCT_CMP_REG *inst) {
DECODE_RM(Reg); DECODE_RM(Reg);
DECODE_RN(Reg); DECODE_RN(Reg);
} }
void T16_CMP_REG::assembler() { void T16_CMP_REG::Assembler() {
SET_BASE_OPCODE(DATA_PROC); SET_BASE_OPCODE(DATA_PROC);
SET_OPCODE(CMP_REG); SET_OPCODE(CMP_REG);
ENCODE_RM; ENCODE_RM;
...@@ -277,24 +277,24 @@ void T16_CMP_REG::assembler() { ...@@ -277,24 +277,24 @@ void T16_CMP_REG::assembler() {
//MOV REG //MOV REG
T16_MOV_REG::T16_MOV_REG(T16_STRUCT_MOV_REG *inst) : InstructionT16(inst) { T16_MOV_REG::T16_MOV_REG(T16_STRUCT_MOV_REG *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_MOV_REG::T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm) : rm(&rm), rd(&rd) { T16_MOV_REG::T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm) : rm(&rm), rd(&rd) {
} }
void T16_MOV_REG::decode(T16_STRUCT_MOV_REG *inst) { void T16_MOV_REG::Disassembler(T16_STRUCT_MOV_REG *inst) {
DECODE_RM(Reg); DECODE_RM(Reg);
rd = Reg(static_cast<U8>(COMBINE(inst->D, inst->rd, 3))); rd = Reg(static_cast<U8>(COMBINE(inst->D, inst->rd, 3)));
} }
void T16_MOV_REG::assembler() { void T16_MOV_REG::Assembler() {
SET_BASE_OPCODE(DATA_PROC); SET_BASE_OPCODE(DATA_PROC);
SET_OPCODE(MOV_REG); SET_OPCODE(MOV_REG);
ENCODE_RM; ENCODE_RM;
get()->rd = BITS(rd->getCode(), 0, 2); Get()->rd = BITS(rd->Code(), 0, 2);
get()->D = BIT(rd->getCode(), 3); Get()->D = BIT(rd->Code(), 3);
} }
bool T16_MOV_REG::pcRelate() { bool T16_MOV_REG::pcRelate() {
...@@ -306,23 +306,23 @@ bool T16_MOV_REG::pcRelate() { ...@@ -306,23 +306,23 @@ bool T16_MOV_REG::pcRelate() {
T16_ADD_REG::T16_ADD_REG() {} T16_ADD_REG::T16_ADD_REG() {}
T16_ADD_REG::T16_ADD_REG(T16_STRUCT_ADD_REG *inst) : InstructionT16(inst) { T16_ADD_REG::T16_ADD_REG(T16_STRUCT_ADD_REG *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_ADD_REG::T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm) : rd(rd), rn(rn), T16_ADD_REG::T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm) : rd(rd), rn(rn),
rm(rm) {} rm(rm) {}
void T16_ADD_REG::decode(T16_STRUCT_ADD_REG *inst) { void T16_ADD_REG::Disassembler(T16_STRUCT_ADD_REG *inst) {
DECODE_RD(Reg); DECODE_RD(Reg);
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_ADD_REG::assembler() { void T16_ADD_REG::Assembler() {
SET_OPCODE(ADD_REG); SET_OPCODE(ADD_REG);
INST_ASSERT(rd->getCode() > 7); INST_ASSERT(rd->Code() > 7);
INST_ASSERT(rn->getCode() > 7); INST_ASSERT(rn->Code() > 7);
INST_ASSERT(rm->getCode() > 7); INST_ASSERT(rm->Code() > 7);
ENCODE_RD; ENCODE_RD;
ENCODE_RN; ENCODE_RN;
ENCODE_RM; ENCODE_RM;
...@@ -331,65 +331,65 @@ void T16_ADD_REG::assembler() { ...@@ -331,65 +331,65 @@ void T16_ADD_REG::assembler() {
T16_CMP_REG_EXT::T16_CMP_REG_EXT(T16_STRUCT_CMP_REG_EXT *inst) : InstructionT16(inst) { T16_CMP_REG_EXT::T16_CMP_REG_EXT(T16_STRUCT_CMP_REG_EXT *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_CMP_REG_EXT::T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm) : rn(&rn), rm(&rm) {} T16_CMP_REG_EXT::T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm) : rn(&rn), rm(&rm) {}
void T16_CMP_REG_EXT::decode(T16_STRUCT_CMP_REG_EXT *inst) { void T16_CMP_REG_EXT::Disassembler(T16_STRUCT_CMP_REG_EXT *inst) {
rn = Reg(COMBINE(inst->N, inst->rn, 3)); rn = Reg(COMBINE(inst->N, inst->rn, 3));
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_CMP_REG_EXT::assembler() { void T16_CMP_REG_EXT::Assembler() {
SET_OPCODE(CMP_REG_EXT); SET_OPCODE(CMP_REG_EXT);
ENCODE_RM; ENCODE_RM;
get()->rn = BITS(rn->getCode(), 0, 2); Get()->rn = BITS(rn->Code(), 0, 2);
get()->N = BIT(rn->getCode(), 3); Get()->N = BIT(rn->Code(), 3);
} }
//POP //POP
T16_POP::T16_POP(T16_STRUCT_POP *inst) : InstructionT16(inst) { T16_POP::T16_POP(T16_STRUCT_POP *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_POP::T16_POP(const RegisterList &registerList) : registerList(registerList) {} T16_POP::T16_POP(const RegisterList &registerList) : registerList(registerList) {}
void T16_POP::decode(T16_STRUCT_POP *inst) { void T16_POP::Disassembler(T16_STRUCT_POP *inst) {
registerList.SetList(COMBINE(inst->P << 7, inst->regs, 8)); registerList.SetList(COMBINE(inst->P << 7, inst->regs, 8));
} }
void T16_POP::assembler() { void T16_POP::Assembler() {
SET_OPCODE(POP); SET_OPCODE(POP);
U16 regs = registerList.GetList(); U16 regs = registerList.GetList();
get()->regs = BITS(regs, 0, 7); Get()->regs = BITS(regs, 0, 7);
get()->P = BIT(regs, 15); Get()->P = BIT(regs, 15);
} }
//PUSH //PUSH
T16_PUSH::T16_PUSH(T16_STRUCT_PUSH *inst) : InstructionT16(inst) { T16_PUSH::T16_PUSH(T16_STRUCT_PUSH *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_PUSH::T16_PUSH(const RegisterList &registerList) : registerList(registerList) {} T16_PUSH::T16_PUSH(const RegisterList &registerList) : registerList(registerList) {}
void T16_PUSH::decode(T16_STRUCT_PUSH *inst) { void T16_PUSH::Disassembler(T16_STRUCT_PUSH *inst) {
registerList.SetList(COMBINE(inst->M << 6, inst->regs, 8)); registerList.SetList(COMBINE(inst->M << 6, inst->regs, 8));
} }
void T16_PUSH::assembler() { void T16_PUSH::Assembler() {
SET_OPCODE(PUSH); SET_OPCODE(PUSH);
U16 regs = registerList.GetList(); U16 regs = registerList.GetList();
get()->regs = BITS(regs, 0, 7); Get()->regs = BITS(regs, 0, 7);
get()->M = BIT(regs, 14); Get()->M = BIT(regs, 14);
} }
// Add reg rdn T2 // Add reg_ rdn T2
T16_ADD_REG_RDN::T16_ADD_REG_RDN(T16_STRUCT_ADD_REG_RDN *inst) : InstructionT16(inst) { T16_ADD_REG_RDN::T16_ADD_REG_RDN(T16_STRUCT_ADD_REG_RDN *inst) : InstructionT16(inst) {
decode(inst); Disassembler(inst);
} }
T16_ADD_REG_RDN::T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm) : rdn(&rdn), rm(&rm) {} T16_ADD_REG_RDN::T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm) : rdn(&rdn), rm(&rm) {}
...@@ -398,13 +398,13 @@ bool T16_ADD_REG_RDN::pcRelate() { ...@@ -398,13 +398,13 @@ bool T16_ADD_REG_RDN::pcRelate() {
return *rm == PC; return *rm == PC;
} }
void T16_ADD_REG_RDN::decode(T16_STRUCT_ADD_REG_RDN *inst) { void T16_ADD_REG_RDN::Disassembler(T16_STRUCT_ADD_REG_RDN *inst) {
DECODE_RM(Reg); DECODE_RM(Reg);
rdn = Reg(inst->rdn); rdn = Reg(inst->rdn);
} }
void T16_ADD_REG_RDN::assembler() { void T16_ADD_REG_RDN::Assembler() {
SET_OPCODE(ADD_REG_RDN); SET_OPCODE(ADD_REG_RDN);
ENCODE_RM; ENCODE_RM;
get()->rdn = rdn->getCode(); Get()->rdn = rdn->Code();
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_T16_H #pragma once
#define SANDHOOK_INST_T16_H
#include "arm_base.h" #include "arm_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
...@@ -13,10 +12,10 @@ ...@@ -13,10 +12,10 @@
#define INST_T16(X) T16_##X #define INST_T16(X) T16_##X
#define IS_OPCODE_T16(RAW, OP) INST_T16(OP)::is(RAW) #define IS_OPCODE_T16(RAW, OP) INST_T16(OP)::Is(RAW)
#define DEFINE_IS_EXT(X, COND) \ #define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstT16& inst) { \ inline static bool Is(InstT16& inst) { \
union { \ union { \
InstT16 raw; \ InstT16 raw; \
STRUCT_T16(X) inst; \ STRUCT_T16(X) inst; \
...@@ -44,62 +43,52 @@ namespace SandHook { ...@@ -44,62 +43,52 @@ namespace SandHook {
namespace AsmA32 { namespace AsmA32 {
template<typename Inst> template<typename S, U32 C>
class InstructionT16 : public Instruction<Inst> { class InstructionT16 : public Instruction<S,C> {
public: public:
InstructionT16() {} InstructionT16() {}
InstructionT16(Inst *inst) : Instruction<Inst>(inst) {} InstructionT16(void *inst) : Instruction<S,C>(inst) {}
Inst mask(Inst raw) { INLINE U32 Size() override {
return raw & *(this->get());
}
U32 size() override {
return 2; return 2;
} }
void *getPC() override { INLINE void *GetPC() override {
return reinterpret_cast<void *>((Addr) Instruction<Inst>::getPC() + 2 * 2); return reinterpret_cast<void *>((Addr) Instruction<S,C>::GetPC() + 2 * 2);
}
Addr getVPC() override {
return Instruction<Inst>::getVPC() + 2 * 2;
} }
static inline S32 signExtend32(unsigned int bits, U32 value) { INLINE Addr GetVPC() override {
return ExtractSignedBitfield32(bits - 1, 0, value); return Instruction<S,C>::GetVPC() + 2 * 2;
} }
InstType instType() override { INLINE InstType InstType() override {
return thumb16; return thumb16;
} }
Arch arch() override { INLINE Arch Arch() override {
return arm32; return arm32;
} }
}; };
template<typename Inst> template<typename S,U32 C>
class T16_INST_PC_REL : public InstructionT16<Inst> { class T16_INST_PC_REL : public InstructionT16<S,C> {
public: public:
T16_INST_PC_REL() {}; T16_INST_PC_REL(void *inst) : InstructionT16<S,C>(inst) {};
T16_INST_PC_REL(Inst *inst) : InstructionT16<Inst>(inst) {}; INLINE virtual Off GetImmPCOffset() {
virtual Off getImmPCOffset() {
return 0; return 0;
}; };
virtual Addr getImmPCOffsetTarget() { INLINE virtual Addr GetImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset(); return (Addr) this->GetPC() + GetImmPCOffset();
}; };
inline bool pcRelate() override { INLINE bool PcRelate() override {
return true; return true;
}; };
...@@ -111,15 +100,13 @@ namespace SandHook { ...@@ -111,15 +100,13 @@ namespace SandHook {
T16_UNKNOW(STRUCT_T16(UNKNOW) &inst); T16_UNKNOW(STRUCT_T16(UNKNOW) &inst);
DEFINE_INST_CODE(UNKNOW)
inline bool unknow() override { inline bool unknow() override {
return true; return true;
} }
void decode(T16_STRUCT_UNKNOW *inst) override; void Disassembler(T16_STRUCT_UNKNOW *inst) override;
void assembler() override; void Assembler() override;
private: private:
STRUCT_T16(UNKNOW) inst_backup; STRUCT_T16(UNKNOW) inst_backup;
...@@ -140,13 +127,13 @@ namespace SandHook { ...@@ -140,13 +127,13 @@ namespace SandHook {
DEFINE_INST_CODE(B) DEFINE_INST_CODE(B)
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(STRUCT_T16(B) *inst) override; void Disassembler(STRUCT_T16(B) *inst) override;
void assembler() override; void Assembler() override;
public: public:
Off offset; Off offset;
...@@ -167,13 +154,13 @@ namespace SandHook { ...@@ -167,13 +154,13 @@ namespace SandHook {
DEFINE_INST_CODE(B_COND) DEFINE_INST_CODE(B_COND)
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_T16(B_COND) *inst) override; void Disassembler(STRUCT_T16(B_COND) *inst) override;
void assembler() override; void Assembler() override;
public: public:
Condition condition; Condition condition;
...@@ -197,9 +184,9 @@ namespace SandHook { ...@@ -197,9 +184,9 @@ namespace SandHook {
DEFINE_INST_CODE(BX_BLX) DEFINE_INST_CODE(BX_BLX)
void decode(T16_STRUCT_BX_BLX *inst) override; void Disassembler(T16_STRUCT_BX_BLX *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -226,13 +213,13 @@ namespace SandHook { ...@@ -226,13 +213,13 @@ namespace SandHook {
DEFINE_INST_CODE(CBZ_CBNZ) DEFINE_INST_CODE(CBZ_CBNZ)
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(T16_STRUCT_CBZ_CBNZ *inst) override; void Disassembler(T16_STRUCT_CBZ_CBNZ *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -251,15 +238,15 @@ namespace SandHook { ...@@ -251,15 +238,15 @@ namespace SandHook {
DEFINE_INST_CODE(LDR_LIT) DEFINE_INST_CODE(LDR_LIT)
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(T16_STRUCT_LDR_LIT *inst) override; void Disassembler(T16_STRUCT_LDR_LIT *inst) override;
void assembler() override; void Assembler() override;
public: public:
Off offset; Off offset;
...@@ -277,9 +264,9 @@ namespace SandHook { ...@@ -277,9 +264,9 @@ namespace SandHook {
DEFINE_INST_CODE(ADD_IMM_RDN) DEFINE_INST_CODE(ADD_IMM_RDN)
void decode(T16_STRUCT_ADD_IMM_RDN *inst) override; void Disassembler(T16_STRUCT_ADD_IMM_RDN *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32 *rdn; RegisterA32 *rdn;
...@@ -299,15 +286,15 @@ namespace SandHook { ...@@ -299,15 +286,15 @@ namespace SandHook {
DEFINE_INST_CODE(ADR) DEFINE_INST_CODE(ADR)
Off getImmPCOffset() override; Off GetImmPCOffset() override;
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(T16_STRUCT_ADR *inst) override; void Disassembler(T16_STRUCT_ADR *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32 *rd; RegisterA32 *rd;
...@@ -328,9 +315,9 @@ namespace SandHook { ...@@ -328,9 +315,9 @@ namespace SandHook {
DEFINE_IS_EXT(CMP_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) && DEFINE_IS_EXT(CMP_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) &&
TEST_INST_FIELD(opcode, OPCODE_T16(CMP_REG))) TEST_INST_FIELD(opcode, OPCODE_T16(CMP_REG)))
void decode(T16_STRUCT_CMP_REG *inst) override; void Disassembler(T16_STRUCT_CMP_REG *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32 *rm; RegisterA32 *rm;
...@@ -350,9 +337,9 @@ namespace SandHook { ...@@ -350,9 +337,9 @@ namespace SandHook {
DEFINE_IS_EXT(MOV_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) && DEFINE_IS_EXT(MOV_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) &&
TEST_INST_FIELD(opcode, OPCODE_T16(MOV_REG))) TEST_INST_FIELD(opcode, OPCODE_T16(MOV_REG)))
void decode(T16_STRUCT_MOV_REG *inst) override; void Disassembler(T16_STRUCT_MOV_REG *inst) override;
void assembler() override; void Assembler() override;
bool pcRelate() override; bool pcRelate() override;
...@@ -374,9 +361,9 @@ namespace SandHook { ...@@ -374,9 +361,9 @@ namespace SandHook {
DEFINE_INST_CODE(ADD_REG) DEFINE_INST_CODE(ADD_REG)
void decode(T16_STRUCT_ADD_REG *inst) override; void Disassembler(T16_STRUCT_ADD_REG *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32 *rd; RegisterA32 *rd;
...@@ -396,9 +383,9 @@ namespace SandHook { ...@@ -396,9 +383,9 @@ namespace SandHook {
DEFINE_INST_CODE(CMP_REG_EXT) DEFINE_INST_CODE(CMP_REG_EXT)
void decode(T16_STRUCT_CMP_REG_EXT *inst) override; void Disassembler(T16_STRUCT_CMP_REG_EXT *inst) override;
void assembler() override; void Assembler() override;
public: public:
...@@ -417,9 +404,9 @@ namespace SandHook { ...@@ -417,9 +404,9 @@ namespace SandHook {
DEFINE_INST_CODE(POP) DEFINE_INST_CODE(POP)
void decode(T16_STRUCT_POP *inst) override; void Disassembler(T16_STRUCT_POP *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterList registerList; RegisterList registerList;
...@@ -436,9 +423,9 @@ namespace SandHook { ...@@ -436,9 +423,9 @@ namespace SandHook {
DEFINE_INST_CODE(PUSH) DEFINE_INST_CODE(PUSH)
void decode(T16_STRUCT_PUSH *inst) override; void Disassembler(T16_STRUCT_PUSH *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterList registerList; RegisterList registerList;
...@@ -459,9 +446,9 @@ namespace SandHook { ...@@ -459,9 +446,9 @@ namespace SandHook {
bool pcRelate() override; bool pcRelate() override;
void decode(T16_STRUCT_ADD_REG_RDN *inst) override; void Disassembler(T16_STRUCT_ADD_REG_RDN *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32* rdn; RegisterA32* rdn;
...@@ -475,6 +462,4 @@ namespace SandHook { ...@@ -475,6 +462,4 @@ namespace SandHook {
#undef DEFINE_IS #undef DEFINE_IS
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST_CODE
\ No newline at end of file
#endif //SANDHOOK_INST_T16_H
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
#include "inst_struct_t32.h" #include "inst_struct_t32.h"
#define SET_BASE_OPCODE(X) get()->opcode_base = OPCODE_T32(X) #define SET_BASE_OPCODE(X) Get()->opcode_base = OPCODE_T32(X)
#define SET_OPCODE(X) get()->opcode = OPCODE_T32(X) #define SET_OPCODE(X) Get()->opcode = OPCODE_T32(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_T32(X##_##INDEX) #define SET_OPCODE_MULTI(X, INDEX) Get()->opcode##INDEX = OPCODE_T32(X##_##INDEX)
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::AsmA32; using namespace SandHook::AsmA32;
...@@ -19,78 +19,78 @@ using namespace SandHook::AsmA32; ...@@ -19,78 +19,78 @@ using namespace SandHook::AsmA32;
//Unknow //Unknow
T32_UNKNOW::T32_UNKNOW(STRUCT_T32(UNKNOW) &inst) : InstructionT32(&inst) { T32_UNKNOW::T32_UNKNOW(STRUCT_T32(UNKNOW) &inst) : InstructionT32(&inst) {
decode(&inst); Disassembler(&inst);
} }
void T32_UNKNOW::decode(T32_STRUCT_UNKNOW *inst) { void T32_UNKNOW::Disassembler(T32_STRUCT_UNKNOW *inst) {
inst_backup = *inst; inst_backup = *inst;
} }
void T32_UNKNOW::assembler() { void T32_UNKNOW::Assembler() {
set(inst_backup); Set(inst_backup);
} }
T32_B32::T32_B32(T32_STRUCT_B32 *inst) : T32_INST_PC_REL(inst) { T32_B32::T32_B32(T32_STRUCT_B32 *inst) : T32_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Off offset) : op(op), x(x), offset(offset) {} T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Off offset) : op(op), x(x), offset(offset) {}
T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Label &label) : op(op), x(x) { T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Label &label) : op(op), x(x) {
bindLabel(label); BindLabel(label);
} }
Off T32_B32::getImmPCOffset() { Off T32_B32::GetImmPCOffset() {
U32 S = get()->S; U32 S = Get()->S;
U32 imm21 = COMBINE(get()->imm10, get()->imm11, 11); U32 imm21 = COMBINE(Get()->imm10, Get()->imm11, 11);
if (get()->X == 0 && op == BL) { if (Get()->X == 0 && op == BL) {
imm21 &= ~(1 << 0); imm21 &= ~(1 << 0);
} }
U32 i1 = !(get()->J1 ^ S); U32 i1 = !(Get()->J1 ^ S);
U32 i2 = !(get()->J2 ^ S); U32 i2 = !(Get()->J2 ^ S);
U32 i1i2 = COMBINE(i1, i2, 1); U32 i1i2 = COMBINE(i1, i2, 1);
U32 Si1i2 = COMBINE(-S, i1i2, 2); U32 Si1i2 = COMBINE(-S, i1i2, 2);
return signExtend32(25, COMBINE(Si1i2, imm21, 21) << 1); return SignExtend32(25, COMBINE(Si1i2, imm21, 21) << 1);
} }
void T32_B32::decode(T32_STRUCT_B32 *inst) { void T32_B32::Disassembler(T32_STRUCT_B32 *inst) {
DECODE_OP; DECODE_OP;
x = X(inst->X); x = X(inst->X);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T32_B32::assembler() { void T32_B32::Assembler() {
SET_OPCODE(B32); SET_OPCODE(B32);
ENCODE_OP; ENCODE_OP;
get()->X = x; Get()->X = x;
U32 imm24 = TruncateToUint25(offset) >> 1; U32 imm24 = TruncateToUint25(offset) >> 1;
get()->imm11 = BITS(imm24, 0, 10); Get()->imm11 = BITS(imm24, 0, 10);
get()->imm10 = BITS(imm24, 11, 20); Get()->imm10 = BITS(imm24, 11, 20);
if (get()->X == 0) { if (Get()->X == 0) {
get()->imm11 |= (1 << 0); Get()->imm11 |= (1 << 0);
} }
get()->S = BIT(imm24, 23); Get()->S = BIT(imm24, 23);
U32 i1 = BIT(imm24, 22); U32 i1 = BIT(imm24, 22);
U32 i2 = BIT(imm24, 21); U32 i2 = BIT(imm24, 21);
if (i1 == 1) { if (i1 == 1) {
get()->J1 = get()->S; Get()->J1 = Get()->S;
} else { } else {
get()->J1 = !get()->S; Get()->J1 = !Get()->S;
} }
if (i2 == 1) { if (i2 == 1) {
get()->J2 = get()->S; Get()->J2 = Get()->S;
} else { } else {
get()->J2 = !get()->S; Get()->J2 = !Get()->S;
} }
} }
Addr T32_B32::getImmPCOffsetTarget() { Addr T32_B32::GetImmPCOffsetTarget() {
if (x == arm && op == BL) { if (x == arm && op == BL) {
void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4)); void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4));
return offset + reinterpret_cast<Addr>(base); return offset + reinterpret_cast<Addr>(base);
} else { } else {
return T32_INST_PC_REL::getImmPCOffsetTarget(); return T32_INST_PC_REL::GetImmPCOffsetTarget();
} }
} }
...@@ -100,67 +100,67 @@ T32_LDR_UIMM::T32_LDR_UIMM(T32_STRUCT_LDR_UIMM *inst) : InstructionT32(inst) {} ...@@ -100,67 +100,67 @@ T32_LDR_UIMM::T32_LDR_UIMM(T32_STRUCT_LDR_UIMM *inst) : InstructionT32(inst) {}
T32_LDR_UIMM::T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset) : rt(&rt), rn(&rn), T32_LDR_UIMM::T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset) : rt(&rt), rn(&rn),
offset(offset) {} offset(offset) {}
void T32_LDR_UIMM::decode(T32_STRUCT_LDR_UIMM *inst) { void T32_LDR_UIMM::Disassembler(T32_STRUCT_LDR_UIMM *inst) {
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_RT(Reg); DECODE_RT(Reg);
INST_ASSERT(rn == &PC); INST_ASSERT(rn == &PC);
offset = inst->imm12; offset = inst->imm12;
} }
void T32_LDR_UIMM::assembler() { void T32_LDR_UIMM::Assembler() {
SET_OPCODE(LDR_UIMM); SET_OPCODE(LDR_UIMM);
ENCODE_RN; ENCODE_RN;
ENCODE_RT; ENCODE_RT;
INST_ASSERT(rn == &PC); INST_ASSERT(rn == &PC);
get()->imm12 = offset; Get()->imm12 = offset;
} }
T32_LDR_LIT::T32_LDR_LIT() {} T32_LDR_LIT::T32_LDR_LIT() {}
T32_LDR_LIT::T32_LDR_LIT(T32_STRUCT_LDR_LIT *inst) : T32_INST_PC_REL(inst) { T32_LDR_LIT::T32_LDR_LIT(T32_STRUCT_LDR_LIT *inst) : T32_INST_PC_REL(inst) {
decode(inst); Disassembler(inst);
} }
T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset) : op(op), s(s), rt(&rt), offset(offset) {} T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset) : op(op), s(s), rt(&rt), offset(offset) {}
T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label) : op(op), s(s), rt(&rt) { T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label) : op(op), s(s), rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off T32_LDR_LIT::getImmPCOffset() { Off T32_LDR_LIT::GetImmPCOffset() {
return get()->U == add ? get()->imm12 : -get()->imm12; return Get()->U == add ? Get()->imm12 : -Get()->imm12;
} }
void T32_LDR_LIT::onOffsetApply(Off offset) { void T32_LDR_LIT::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
if (offset >= 0) { if (offset >= 0) {
get()->U = add; Get()->U = add;
get()->imm12 = static_cast<InstT32>(offset); Get()->imm12 = static_cast<InstT32>(offset);
} else { } else {
get()->U = cmp; Get()->U = cmp;
get()->imm12 = static_cast<InstT32>(-offset); Get()->imm12 = static_cast<InstT32>(-offset);
} }
} }
void T32_LDR_LIT::decode(T32_STRUCT_LDR_LIT *inst) { void T32_LDR_LIT::Disassembler(T32_STRUCT_LDR_LIT *inst) {
DECODE_OP; DECODE_OP;
DECODE_RT(Reg); DECODE_RT(Reg);
s = S(inst->S); s = S(inst->S);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T32_LDR_LIT::assembler() { void T32_LDR_LIT::Assembler() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->S = s; Get()->S = s;
if (offset >= 0) { if (offset >= 0) {
get()->U = add; Get()->U = add;
get()->imm12 = static_cast<InstT32>(offset); Get()->imm12 = static_cast<InstT32>(offset);
} else { } else {
get()->U = cmp; Get()->U = cmp;
get()->imm12 = static_cast<InstT32>(-offset); Get()->imm12 = static_cast<InstT32>(-offset);
} }
} }
...@@ -168,14 +168,14 @@ void T32_LDR_LIT::assembler() { ...@@ -168,14 +168,14 @@ void T32_LDR_LIT::assembler() {
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM() {} T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM() {}
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst) : InstructionT32(inst) { T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst) : InstructionT32(inst) {
decode(inst); Disassembler(inst);
} }
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_MOV_MOVT_IMM::OP op, RegisterA32 &rd, U16 imm16) : op(op), T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_MOV_MOVT_IMM::OP op, RegisterA32 &rd, U16 imm16) : op(op),
rd(&rd), rd(&rd),
imm16(imm16) {} imm16(imm16) {}
void T32_MOV_MOVT_IMM::decode(T32_STRUCT_MOV_MOVT_IMM *inst) { void T32_MOV_MOVT_IMM::Disassembler(T32_STRUCT_MOV_MOVT_IMM *inst) {
DECODE_OP; DECODE_OP;
DECODE_RD(Reg); DECODE_RD(Reg);
U16 imm4i = COMBINE(inst->imm4, inst->i, 1); U16 imm4i = COMBINE(inst->imm4, inst->i, 1);
...@@ -183,27 +183,27 @@ void T32_MOV_MOVT_IMM::decode(T32_STRUCT_MOV_MOVT_IMM *inst) { ...@@ -183,27 +183,27 @@ void T32_MOV_MOVT_IMM::decode(T32_STRUCT_MOV_MOVT_IMM *inst) {
imm16 = COMBINE(imm4i, imm38, 11); imm16 = COMBINE(imm4i, imm38, 11);
} }
void T32_MOV_MOVT_IMM::assembler() { void T32_MOV_MOVT_IMM::Assembler() {
SET_OPCODE_MULTI(MOV_MOVT_IMM, 1); SET_OPCODE_MULTI(MOV_MOVT_IMM, 1);
SET_OPCODE_MULTI(MOV_MOVT_IMM, 2); SET_OPCODE_MULTI(MOV_MOVT_IMM, 2);
ENCODE_OP; ENCODE_OP;
ENCODE_RD; ENCODE_RD;
get()->imm8 = BITS(imm16, 0, 7); Get()->imm8 = BITS(imm16, 0, 7);
get()->imm3 = BITS(imm16, 8 ,10); Get()->imm3 = BITS(imm16, 8 ,10);
get()->i = BIT(imm16, 11); Get()->i = BIT(imm16, 11);
get()->imm4 = BITS(imm16, 12, 15); Get()->imm4 = BITS(imm16, 12, 15);
} }
T32_LDR_IMM::T32_LDR_IMM(T32_STRUCT_LDR_IMM *inst) : InstructionT32(inst) { T32_LDR_IMM::T32_LDR_IMM(T32_STRUCT_LDR_IMM *inst) : InstructionT32(inst) {
decode(inst); Disassembler(inst);
} }
T32_LDR_IMM::T32_LDR_IMM(T32_LDR_IMM::OP op, RegisterA32 &rt, const MemOperand &operand) : op(op), T32_LDR_IMM::T32_LDR_IMM(T32_LDR_IMM::OP op, RegisterA32 &rt, const MemOperand &operand) : op(op),
rt(&rt), rt(&rt),
operand(operand) {} operand(operand) {}
void T32_LDR_IMM::decode(T32_STRUCT_LDR_IMM *inst) { void T32_LDR_IMM::Disassembler(T32_STRUCT_LDR_IMM *inst) {
DECODE_OP; DECODE_OP;
DECODE_RT(Reg); DECODE_RT(Reg);
operand.rn = Reg(static_cast<U8>(inst->rn)); operand.rn = Reg(static_cast<U8>(inst->rn));
...@@ -219,31 +219,31 @@ void T32_LDR_IMM::decode(T32_STRUCT_LDR_IMM *inst) { ...@@ -219,31 +219,31 @@ void T32_LDR_IMM::decode(T32_STRUCT_LDR_IMM *inst) {
operand.offset = inst->U == 0 ? -inst->imm8 : inst->imm8; operand.offset = inst->U == 0 ? -inst->imm8 : inst->imm8;
} }
void T32_LDR_IMM::assembler() { void T32_LDR_IMM::Assembler() {
SET_OPCODE_MULTI(LDR_IMM, 1); SET_OPCODE_MULTI(LDR_IMM, 1);
SET_OPCODE_MULTI(LDR_IMM, 2); SET_OPCODE_MULTI(LDR_IMM, 2);
ENCODE_OP; ENCODE_OP;
get()->rn = operand.rn->getCode(); Get()->rn = operand.rn->Code();
if (operand.offset < 0) { if (operand.offset < 0) {
get()->imm8 = static_cast<InstT32>(-operand.offset); Get()->imm8 = static_cast<InstT32>(-operand.offset);
get()->U = 0; Get()->U = 0;
} else { } else {
get()->imm8 = static_cast<InstT32>(operand.offset); Get()->imm8 = static_cast<InstT32>(operand.offset);
get()->U = 1; Get()->U = 1;
} }
switch (operand.addr_mode) { switch (operand.addr_mode) {
case Offset: case Offset:
get()->P = 1; Get()->P = 1;
get()->U = 0; Get()->U = 0;
get()->W = 0; Get()->W = 0;
break; break;
case PostIndex: case PostIndex:
get()->P = 0; Get()->P = 0;
get()->W = 1; Get()->W = 1;
break; break;
case PreIndex: case PreIndex:
get()->P = 1; Get()->P = 1;
get()->W = 1; Get()->W = 1;
break; break;
default: default:
valid = false; valid = false;
...@@ -253,5 +253,5 @@ void T32_LDR_IMM::assembler() { ...@@ -253,5 +253,5 @@ void T32_LDR_IMM::assembler() {
T32_SUB_IMM::T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst) : InstructionT32(inst) { T32_SUB_IMM::T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst) : InstructionT32(inst) {
decode(inst); DisAssembler(inst);
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_T32_H #pragma once
#define SANDHOOK_INST_T32_H
#include "arm_base.h" #include "arm_base.h"
#include "arm32_base.h" #include "arm32_base.h"
...@@ -54,7 +54,7 @@ namespace SandHook { ...@@ -54,7 +54,7 @@ namespace SandHook {
InstructionT32(Inst *inst) : Instruction<Inst>(inst) {} InstructionT32(Inst *inst) : Instruction<Inst>(inst) {}
Inst mask(Inst raw) { Inst mask(Inst raw) {
return raw & *(this->get()); return raw & *(this->Get());
} }
U32 size() override { U32 size() override {
...@@ -62,14 +62,14 @@ namespace SandHook { ...@@ -62,14 +62,14 @@ namespace SandHook {
} }
void *getPC() override { void *getPC() override {
return reinterpret_cast<void *>((Addr) Instruction<Inst>::getPC() + 2 * 2); return reinterpret_cast<void *>((Addr) Instruction<Inst>::GetPC() + 2 * 2);
} }
Addr getVPC() override { Addr getVPC() override {
return Instruction<Inst>::getVPC() + 2 * 2; return Instruction<Inst>::GetVPC() + 2 * 2;
} }
static inline S32 signExtend32(unsigned int bits, U32 value) { static inline S32 SignExtend32(unsigned int bits, U32 value) {
return ExtractSignedBitfield32(bits - 1, 0, value); return ExtractSignedBitfield32(bits - 1, 0, value);
} }
...@@ -92,12 +92,12 @@ namespace SandHook { ...@@ -92,12 +92,12 @@ namespace SandHook {
T32_INST_PC_REL(Inst *inst) : InstructionT32<Inst>(inst) {}; T32_INST_PC_REL(Inst *inst) : InstructionT32<Inst>(inst) {};
virtual Off getImmPCOffset() { virtual Off GetImmPCOffset() {
return 0; return 0;
}; };
virtual Addr getImmPCOffsetTarget() { virtual Addr GetImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset(); return (Addr) this->GetPC() + GetImmPCOffset();
}; };
inline bool pcRelate() override { inline bool pcRelate() override {
...@@ -118,9 +118,9 @@ namespace SandHook { ...@@ -118,9 +118,9 @@ namespace SandHook {
return true; return true;
} }
void decode(T32_STRUCT_UNKNOW *inst) override; void Disassembler(T32_STRUCT_UNKNOW *inst) override;
void assembler() override; void Assembler() override;
private: private:
STRUCT_T32(UNKNOW) inst_backup; STRUCT_T32(UNKNOW) inst_backup;
...@@ -150,13 +150,13 @@ namespace SandHook { ...@@ -150,13 +150,13 @@ namespace SandHook {
DEFINE_IS_EXT(B32, TEST_INST_FIELD(opcode, OPCODE_T32(B32)) && (TEST_INST_FIELD(op, B) || TEST_INST_FIELD(op, BL))) DEFINE_IS_EXT(B32, TEST_INST_FIELD(opcode, OPCODE_T32(B32)) && (TEST_INST_FIELD(op, B) || TEST_INST_FIELD(op, BL)))
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(T32_STRUCT_B32 *inst) override; void Disassembler(T32_STRUCT_B32 *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -174,9 +174,9 @@ namespace SandHook { ...@@ -174,9 +174,9 @@ namespace SandHook {
DEFINE_IS(LDR_UIMM) DEFINE_IS(LDR_UIMM)
void decode(T32_STRUCT_LDR_UIMM *inst) override; void Disassembler(T32_STRUCT_LDR_UIMM *inst) override;
void assembler() override; void Assembler() override;
public: public:
RegisterA32* rt; RegisterA32* rt;
...@@ -216,13 +216,13 @@ namespace SandHook { ...@@ -216,13 +216,13 @@ namespace SandHook {
DEFINE_INST_CODE(LDR_LIT) DEFINE_INST_CODE(LDR_LIT)
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(T32_STRUCT_LDR_LIT *inst) override; void Disassembler(T32_STRUCT_LDR_LIT *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -250,9 +250,9 @@ namespace SandHook { ...@@ -250,9 +250,9 @@ namespace SandHook {
DEFINE_INST_CODE(MOV_MOVT_IMM) DEFINE_INST_CODE(MOV_MOVT_IMM)
void decode(T32_STRUCT_MOV_MOVT_IMM *inst) override; void Disassembler(T32_STRUCT_MOV_MOVT_IMM *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -280,9 +280,9 @@ namespace SandHook { ...@@ -280,9 +280,9 @@ namespace SandHook {
DEFINE_INST_CODE(LDR_IMM) DEFINE_INST_CODE(LDR_IMM)
void decode(T32_STRUCT_LDR_IMM *inst) override; void Disassembler(T32_STRUCT_LDR_IMM *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -315,5 +315,3 @@ namespace SandHook { ...@@ -315,5 +315,3 @@ namespace SandHook {
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST_CODE
#endif //SANDHOOK_INST_T32_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_REGISTER_A32_H #pragma once
#define SANDHOOK_NH_REGISTER_A32_H
#include "base.h" #include "base.h"
#include "register.h" #include "register.h"
...@@ -36,7 +35,7 @@ namespace SandHook { ...@@ -36,7 +35,7 @@ namespace SandHook {
U8 getWide() override; U8 getWide() override;
virtual bool isUnkonw () { virtual bool isUnkonw () {
return getCode() == 38; return Code() == 38;
} }
static RegisterA32* get(U8 code) { static RegisterA32* get(U8 code) {
...@@ -47,6 +46,4 @@ namespace SandHook { ...@@ -47,6 +46,4 @@ namespace SandHook {
static RegisterA32* registers[]; static RegisterA32* registers[];
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_A32_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_REGISTER_LIST_A32_H #pragma once
#define SANDHOOK_NH_REGISTER_LIST_A32_H
#include "register_arm32.h" #include "register_arm32.h"
...@@ -30,6 +29,4 @@ namespace RegistersA32 { ...@@ -30,6 +29,4 @@ namespace RegistersA32 {
extern RegisterA32 PC; extern RegisterA32 PC;
extern RegisterA32 UnknowRegiser; extern RegisterA32 UnknowRegiser;
}} }}
#define Reg(N) RegisterA32::get(N) #define Reg(N) RegisterA32::get(N)
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_LIST_A32_H
...@@ -26,8 +26,8 @@ CodeRelocateA32::CodeRelocateA32(AssemblerA32 &assembler) : CodeRelocate(assembl ...@@ -26,8 +26,8 @@ CodeRelocateA32::CodeRelocateA32(AssemblerA32 &assembler) : CodeRelocate(assembl
bool CodeRelocateA32::visit(Unit<Base> *unit, void *pc) { bool CodeRelocateA32::visit(Unit<Base> *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC()); relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC());
curOffset += unit->size(); curOffset += unit->Size();
if (unit->refcount() == 0) { if (unit->RefCount() == 0) {
delete unit; delete unit;
} }
return true; return true;
...@@ -44,7 +44,7 @@ void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) t ...@@ -44,7 +44,7 @@ void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) t
__ allocBufferFirst(static_cast<U32>(len * 8)); __ allocBufferFirst(static_cast<U32>(len * 8));
void* curPc = __ getPC(); void* curPc = __ getPC();
if (toPc == nullptr) { if (toPc == nullptr) {
Disassembler::get()->decode(startPc, len, *this, true); Disassembler::Get()->Disassembler(startPc, len, *this, true);
} else { } else {
//TODO //TODO
} }
...@@ -54,25 +54,25 @@ void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) t ...@@ -54,25 +54,25 @@ void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) t
void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = __ getPC(); void* curPc = __ getPC();
//insert later bind labels //insert later AddBind labels
__ Emit(getLaterBindLabel(curOffset)); __ Emit(getLaterBindLabel(curOffset));
if (!instruction->pcRelate()) { if (!instruction->pcRelate()) {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
return curPc; return curPc;
} }
if (instruction->instType() == thumb32) { if (instruction->InstType() == thumb32) {
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(T32, B32) CASE(T32, B32)
CASE(T32, LDR_LIT) CASE(T32, LDR_LIT)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
} else if (instruction->instType() == thumb16) { } else if (instruction->InstType() == thumb16) {
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(T16, B) CASE(T16, B)
CASE(T16, B_COND) CASE(T16, B_COND)
CASE(T16, BX_BLX) CASE(T16, BX_BLX)
...@@ -82,11 +82,11 @@ void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -82,11 +82,11 @@ void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) thro
CASE(T16, ADD_REG_RDN) CASE(T16, ADD_REG_RDN)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
} else { } else {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
return curPc; return curPc;
} }
...@@ -99,7 +99,7 @@ IMPL_RELOCATE(T16, B_COND) { ...@@ -99,7 +99,7 @@ IMPL_RELOCATE(T16, B_COND) {
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
if (inst->condition == al) { if (inst->condition == al) {
Label* target_label = new Label; Label* target_label = new Label;
...@@ -130,7 +130,7 @@ IMPL_RELOCATE(T16, B) { ...@@ -130,7 +130,7 @@ IMPL_RELOCATE(T16, B) {
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
Label* target_label = new Label(); Label* target_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
...@@ -142,26 +142,26 @@ IMPL_RELOCATE(T16, B) { ...@@ -142,26 +142,26 @@ IMPL_RELOCATE(T16, B) {
IMPL_RELOCATE(T16, BX_BLX) { IMPL_RELOCATE(T16, BX_BLX) {
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
inst->ref(); inst->Ref();
} }
IMPL_RELOCATE(T16, CBZ_CBNZ) { IMPL_RELOCATE(T16, CBZ_CBNZ) {
inst->ref(); inst->Ref();
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
Label* true_label = new Label; Label* true_label = new Label;
Label* false_label = new Label; Label* false_label = new Label;
Label* target_label = new Label(); Label* target_label = new Label();
inst->bindLabel(*true_label); inst->BindLabel(*true_label);
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
__ B(false_label); __ B(false_label);
__ Emit(true_label); __ Emit(true_label);
...@@ -176,13 +176,13 @@ IMPL_RELOCATE(T16, CBZ_CBNZ) { ...@@ -176,13 +176,13 @@ IMPL_RELOCATE(T16, CBZ_CBNZ) {
IMPL_RELOCATE(T16, LDR_LIT) { IMPL_RELOCATE(T16, LDR_LIT) {
if (inRelocateRange(CODE_OFFSET(inst), inst->rt->getWide())) { if (inRelocateRange(CODE_OFFSET(inst), inst->rt->getWide())) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rt, targetAddr); __ Mov(*inst->rt, targetAddr);
__ Ldr(*inst->rt, MemOperand(inst->rt, 0)); __ Ldr(*inst->rt, MemOperand(inst->rt, 0));
...@@ -191,13 +191,13 @@ IMPL_RELOCATE(T16, LDR_LIT) { ...@@ -191,13 +191,13 @@ IMPL_RELOCATE(T16, LDR_LIT) {
IMPL_RELOCATE(T16, ADR) { IMPL_RELOCATE(T16, ADR) {
if (inRelocateRange(CODE_OFFSET(inst), inst->rd->getWide())) { if (inRelocateRange(CODE_OFFSET(inst), inst->rd->getWide())) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rd, targetAddr); __ Mov(*inst->rd, targetAddr);
...@@ -206,7 +206,7 @@ IMPL_RELOCATE(T16, ADR) { ...@@ -206,7 +206,7 @@ IMPL_RELOCATE(T16, ADR) {
IMPL_RELOCATE(T16, ADD_REG_RDN) { IMPL_RELOCATE(T16, ADD_REG_RDN) {
if (*inst->rm != PC) { if (*inst->rm != PC) {
inst->ref(); inst->Ref();
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
return; return;
} }
...@@ -223,13 +223,13 @@ IMPL_RELOCATE(T16, ADD_REG_RDN) { ...@@ -223,13 +223,13 @@ IMPL_RELOCATE(T16, ADD_REG_RDN) {
IMPL_RELOCATE(T32, B32) { IMPL_RELOCATE(T32, B32) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base> *>(inst)); __ Emit(reinterpret_cast<Instruction<Base> *>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
if (inst->x == T32_B32::thumb) { if (inst->x == T32_B32::thumb) {
...@@ -248,13 +248,13 @@ IMPL_RELOCATE(T32, B32) { ...@@ -248,13 +248,13 @@ IMPL_RELOCATE(T32, B32) {
IMPL_RELOCATE(T32, LDR_LIT) { IMPL_RELOCATE(T32, LDR_LIT) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(Addr))) { if (inRelocateRange(CODE_OFFSET(inst), sizeof(Addr))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rt, targetAddr); __ Mov(*inst->rt, targetAddr);
switch (inst->op) { switch (inst->op) {
...@@ -276,7 +276,7 @@ IMPL_RELOCATE(T32, LDR_LIT) { ...@@ -276,7 +276,7 @@ IMPL_RELOCATE(T32, LDR_LIT) {
} }
break; break;
default: default:
inst->ref(); inst->Ref();
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base>*>(inst));
} }
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_CODE_RELOCATE_ARM32_H #pragma once
#define SANDHOOK_CODE_RELOCATE_ARM32_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -55,6 +54,4 @@ namespace SandHook { ...@@ -55,6 +54,4 @@ namespace SandHook {
} }
} }
#undef DEFINE_RELOCATE #undef DEFINE_RELOCATE
\ No newline at end of file
#endif //SANDHOOK_CODE_RELOCATE_ARM32_H
...@@ -12,19 +12,19 @@ AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) { ...@@ -12,19 +12,19 @@ AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer); codeContainer.setCodeBuffer(codeBuffer);
} }
void *AssemblerA64::getPC() { void *AssemblerA64::GetPC() {
return reinterpret_cast<void *>(codeContainer.curPc); return reinterpret_cast<void *>(codeContainer.curPc);
} }
void *AssemblerA64::getStartPC() { void *AssemblerA64::GetStartPC() {
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(codeContainer.startPc);
} }
void AssemblerA64::allocBufferFirst(U32 size) { void AssemblerA64::AllocBufferFirst(U32 size) {
codeContainer.allocBufferFirst(size); codeContainer.allocBufferFirst(size);
} }
void *AssemblerA64::finish() { void *AssemblerA64::Finish() {
codeContainer.commit(); codeContainer.commit();
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(codeContainer.startPc);
} }
...@@ -95,7 +95,7 @@ void AssemblerA64::B(Off offset) { ...@@ -95,7 +95,7 @@ void AssemblerA64::B(Off offset) {
} }
void AssemblerA64::B(Label *label) { void AssemblerA64::B(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, *label))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, label)));
} }
void AssemblerA64::Bl(Off offset) { void AssemblerA64::Bl(Off offset) {
...@@ -103,7 +103,7 @@ void AssemblerA64::Bl(Off offset) { ...@@ -103,7 +103,7 @@ void AssemblerA64::Bl(Off offset) {
} }
void AssemblerA64::Bl(Label *label) { void AssemblerA64::Bl(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, *label))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, label)));
} }
void AssemblerA64::B(Condition condition, Off offset) { void AssemblerA64::B(Condition condition, Off offset) {
...@@ -111,11 +111,11 @@ void AssemblerA64::B(Condition condition, Off offset) { ...@@ -111,11 +111,11 @@ void AssemblerA64::B(Condition condition, Off offset) {
} }
void AssemblerA64::B(Condition condition, Label *label) { void AssemblerA64::B(Condition condition, Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, *label))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, label)));
} }
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Label *label) { void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, *label)))); Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, label))));
} }
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Off offset) { void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Off offset) {
...@@ -127,7 +127,7 @@ void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Off offset) { ...@@ -127,7 +127,7 @@ void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Off offset) {
} }
void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Label *label) { void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, *label)))); Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, label))));
} }
...@@ -136,7 +136,7 @@ void AssemblerA64::Cbz(RegisterA64 &rt, Off offset) { ...@@ -136,7 +136,7 @@ void AssemblerA64::Cbz(RegisterA64 &rt, Off offset) {
} }
void AssemblerA64::Cbz(RegisterA64 &rt, Label *label) { void AssemblerA64::Cbz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, *label, rt)))); Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, label, rt))));
} }
...@@ -146,11 +146,11 @@ void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) { ...@@ -146,11 +146,11 @@ void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) {
} }
void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) { void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, *label, rt)))); Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, label, rt))));
} }
void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) { void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) { if (memOperand.addr_mode_ == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_UIMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_IMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_IMM)(rt, memOperand)));
...@@ -158,7 +158,7 @@ void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) { ...@@ -158,7 +158,7 @@ void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) {
} }
void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) { void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) {
if (memOperand.addr_mode == Offset && memOperand.offset >= 0) { if (memOperand.addr_mode_ == Offset && memOperand.offset_ >= 0) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_UIMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_IMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_IMM)(rt, memOperand)));
...@@ -166,15 +166,15 @@ void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) { ...@@ -166,15 +166,15 @@ void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) {
} }
void AssemblerA64::Ldr(RegisterA64 &rt, Label* label) { void AssemblerA64::Ldr(RegisterA64 &rt, Label* label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(rt.isX() ? INST_A64(LDR_LIT)::LDR_X : INST_A64(LDR_LIT)::LDR_W, rt, *label))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(rt.isX() ? INST_A64(LDR_LIT)::LDR_X : INST_A64(LDR_LIT)::LDR_W, rt, label)));
} }
void AssemblerA64::Ldrsw(RegisterA64 &rt, Label* label) { void AssemblerA64::Ldrsw(RegisterA64 &rt, Label* label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(INST_A64(LDR_LIT)::LDR_SW, rt, *label))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(INST_A64(LDR_LIT)::LDR_SW, rt, label)));
} }
void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) { void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) { if (memOperand.addr_mode_ == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_IMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_IMM)(rt, memOperand)));
...@@ -182,7 +182,7 @@ void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) { ...@@ -182,7 +182,7 @@ void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) {
} }
// If the current stack pointer is sp, then it must be aligned to 16 bytes // If the current stack pointer is sp, then it must be aligned to 16 bytes
// on entry and the total size of the specified registers must also be a // on entry and the total Size of the specified registers must also be a
// multiple of 16 bytes. // multiple of 16 bytes.
void AssemblerA64::Pop(RegisterA64 &rd) { void AssemblerA64::Pop(RegisterA64 &rd) {
if (rd.isX()) { if (rd.isX()) {
...@@ -193,7 +193,7 @@ void AssemblerA64::Pop(RegisterA64 &rd) { ...@@ -193,7 +193,7 @@ void AssemblerA64::Pop(RegisterA64 &rd) {
} }
// If the current stack pointer is sp, then it must be aligned to 16 bytes // If the current stack pointer is sp, then it must be aligned to 16 bytes
// on entry and the total size of the specified registers must also be a // on entry and the total Size of the specified registers must also be a
// multiple of 16 bytes. // multiple of 16 bytes.
void AssemblerA64::Push(RegisterA64 &rt) { void AssemblerA64::Push(RegisterA64 &rt) {
if (rt.isX()) { if (rt.isX()) {
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_ASSEMBLER_A64_H #pragma once
#define SANDHOOK_NH_ASSEMBLER_A64_H
#include "assembler.h" #include "assembler.h"
#include "register_arm64.h" #include "register_arm64.h"
...@@ -19,10 +18,10 @@ namespace SandHook { ...@@ -19,10 +18,10 @@ namespace SandHook {
public: public:
AssemblerA64(CodeBuffer* codeBuffer); AssemblerA64(CodeBuffer* codeBuffer);
void allocBufferFirst(U32 size); void AllocBufferFirst(U32 size);
void* getStartPC(); void* GetStartPC();
void* getPC(); void* GetPC();
void* finish(); void* Finish();
void Emit(U32 data32); void Emit(U32 data32);
void Emit(U64 data64); void Emit(U64 data64);
...@@ -99,6 +98,4 @@ namespace SandHook { ...@@ -99,6 +98,4 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ASSEMBLER_A64_H
...@@ -10,14 +10,14 @@ using namespace SandHook::AsmA64; ...@@ -10,14 +10,14 @@ using namespace SandHook::AsmA64;
#define CASE(X) \ #define CASE(X) \
if (IS_OPCODE_A64(*pc, X)) { \ if (IS_OPCODE_A64(*pc, X)) { \
STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \ unit = reinterpret_cast<BaseUnit*>(new INST_A64(X)(pc)); \
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \
goto label_matched; \ goto label_matched; \
} }
Arm64Decoder* Arm64Decoder::instant = new Arm64Decoder(); Arm64Decoder* Arm64Decoder::instant = new Arm64Decoder();
void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) { void Arm64Decoder::Disassembler(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) {
InstA64 *pc = reinterpret_cast<InstA64 *>(codeStart); InstA64 *pc = reinterpret_cast<InstA64 *>(codeStart);
Addr endAddr = (Addr) codeStart + codeLen; Addr endAddr = (Addr) codeStart + codeLen;
Unit<Base>* unit = nullptr; Unit<Base>* unit = nullptr;
...@@ -48,12 +48,13 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b ...@@ -48,12 +48,13 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
label_matched: label_matched:
if (unit == nullptr) { if (unit == nullptr) {
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(UNKNOW)(*reinterpret_cast<STRUCT_A64(UNKNOW) *>(pc))); unit = reinterpret_cast<BaseUnit*>(new INST_A64(UNKNOW)(pc));
} }
if (!visitor.visit(unit, pc)) { reinterpret_cast<BaseInst*>(unit)->Disassembler();
if (!visitor.Visit(unit, pc)) {
break; break;
} }
pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->size()); pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->Size());
unit = nullptr; unit = nullptr;
} }
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_DECODER_ARM64_H #pragma once
#define SANDHOOK_NH_DECODER_ARM64_H
#include "decoder.h" #include "decoder.h"
...@@ -12,12 +11,11 @@ namespace SandHook { ...@@ -12,12 +11,11 @@ namespace SandHook {
class Arm64Decoder : public InstDecoder { class Arm64Decoder : public InstDecoder {
public: public:
void decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) override; void Disassembler(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) override;
public: public:
static Arm64Decoder* instant; static Arm64Decoder* instant;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_DECODER_ARM64_H
...@@ -15,7 +15,7 @@ using namespace SandHook::Utils; ...@@ -15,7 +15,7 @@ using namespace SandHook::Utils;
#include "assembler_arm64.h" #include "assembler_arm64.h"
#include "code_relocate_arm64.h" #include "code_relocate_arm64.h"
using namespace SandHook::RegistersA64; using namespace SandHook::RegistersA64;
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { void *InlineHookArm64Android::Hook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* backup = nullptr; void* backup = nullptr;
...@@ -43,15 +43,15 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { ...@@ -43,15 +43,15 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
__ Br(IP1); __ Br(IP1);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) origin + codeContainerInline->size()); __ Emit((Addr) origin + codeContainerInline->size());
__ finish(); __ Finish();
#undef __ #undef __
//commit inline trampoline //commit inline trampoline
assemblerInline.finish(); assemblerInline.Finish();
return backup; return backup;
} }
bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[])) { bool InlineHookArm64Android::BreakPoint(void *point, void (*callback)(REG regs[])) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* backup = nullptr; void* backup = nullptr;
...@@ -71,7 +71,7 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[] ...@@ -71,7 +71,7 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[]
__ Br(IP1); __ Br(IP1);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) point + 4 * 4); __ Emit((Addr) point + 4 * 4);
__ finish(); __ Finish();
#undef __ #undef __
...@@ -114,11 +114,11 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[] ...@@ -114,11 +114,11 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[]
__ Mov(IP1, (Addr) backup); __ Mov(IP1, (Addr) backup);
__ Br(IP1); __ Br(IP1);
__ finish(); __ Finish();
#undef __ #undef __
void* secondTrampoline = assemblerTrampoline.getStartPC(); void* secondTrampoline = assemblerTrampoline.GetStartPC();
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assemblerInline.
Label* target_addr_label = new Label(); Label* target_addr_label = new Label();
...@@ -126,7 +126,7 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[] ...@@ -126,7 +126,7 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[]
__ Br(IP1); __ Br(IP1);
__ Emit(target_addr_label); __ Emit(target_addr_label);
__ Emit((Addr) secondTrampoline); __ Emit((Addr) secondTrampoline);
__ finish(); __ Finish();
#undef __ #undef __
return true; return true;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_HOOK_ARM64_H #pragma once
#define SANDHOOK_HOOK_ARM64_H
#include "hook.h" #include "hook.h"
...@@ -11,20 +10,8 @@ namespace SandHook { ...@@ -11,20 +10,8 @@ namespace SandHook {
namespace Hook { namespace Hook {
class InlineHookArm64Android : public InlineHook { class InlineHookArm64Android : public InlineHook {
public: public:
inline InlineHookArm64Android() { void *Hook(void *origin, void *replace) override;
hookLock = new std::mutex(); bool BreakPoint(void *point, void (*callback)(REG[])) override;
};
inline ~InlineHookArm64Android() {
delete hookLock;
}
void *inlineHook(void *origin, void *replace) override;
bool breakPoint(void *point, void (*callback)(REG[])) override;
protected:
std::mutex* hookLock;
}; };
} }
} }
#endif //SANDHOOK_HOOK_ARM64_H
...@@ -4,121 +4,95 @@ ...@@ -4,121 +4,95 @@
#include "inst_arm64.h" #include "inst_arm64.h"
#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 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) #define ENCODE_OFFSET(bits, ext) Get()->imm##bits = TruncateToUint##bits(offset >> ext)
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::AsmA64; using namespace SandHook::AsmA64;
template<typename InstStruct> //PC Rel Inst
U32 InstructionA64<InstStruct>::size() {
return sizeof(InstA64);
}
//Unknow
A64_UNKNOW::A64_UNKNOW(STRUCT_A64(UNKNOW) &inst) : InstructionA64(&inst) {
decode(&inst);
}
void A64_UNKNOW::decode(A64_STRUCT_UNKNOW *inst) {
inst_backup = *inst;
}
void A64_UNKNOW::assembler() { template<typename S,U32 C>
set(inst_backup); Addr A64_INST_PC_REL<S,C>::GetImmPCOffsetTarget() {
return this->GetImmPCOffset() + reinterpret_cast<Addr>(this->GetPC());
} }
//PC Rel Inst template<typename S,U32 C>
bool A64_INST_PC_REL<S,C>::PcRelate() {
template<typename Inst> return true;
A64_INST_PC_REL<Inst>::A64_INST_PC_REL(Inst *inst):InstructionA64<Inst>(inst) {
} }
template<typename Inst> template<typename S, U32 C>
A64_INST_PC_REL<Inst>::A64_INST_PC_REL() {} A64_INST_PC_REL<S, C>::A64_INST_PC_REL() {}
template<typename Inst> template<typename S, U32 C>
Addr A64_INST_PC_REL<Inst>::getImmPCOffsetTarget() { A64_INST_PC_REL<S, C>::A64_INST_PC_REL(void *inst) : InstructionA64<S,C>(inst) {
return this->getImmPCOffset() + reinterpret_cast<Addr>(this->getPC());
}
template<typename Inst>
bool A64_INST_PC_REL<Inst>::pcRelate() {
return true;
} }
//ADR ADRP //ADR ADRP
A64_ADR_ADRP::A64_ADR_ADRP() {}
A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst) { A64_ADR_ADRP::A64_ADR_ADRP(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, S64 offset) : op(op), rd(&rd), A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, S64 offset) : op(op), rd(&rd),
offset(offset) { offset(offset) {
} }
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, Label &label) { A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, Label *label) {
bindLabel(label); BindLabel(label);
} }
Off A64_ADR_ADRP::getImmPCOffset() { Off A64_ADR_ADRP::GetImmPCOffset() {
U32 hi = get()->immhi; U32 hi = Get()->immhi;
U32 lo = get()->immlo; U32 lo = Get()->immlo;
U64 imm = COMBINE(hi, lo, IMM_LO_W); U64 imm = COMBINE(hi, lo, IMM_LO_W);
if (isADRP()) { if (IsADRP()) {
return signExtend64(IMM_HI_W + IMM_LO_W + PAGE_OFFSET, imm << PAGE_OFFSET); return SignExtend64(IMM_HI_W + IMM_LO_W + PAGE_OFFSET, imm << PAGE_OFFSET);
} else { } else {
return signExtend64(IMM_HI_W + IMM_LO_W, imm); return SignExtend64(IMM_HI_W + IMM_LO_W, imm);
} }
} }
Addr A64_ADR_ADRP::getImmPCOffsetTarget() { Addr A64_ADR_ADRP::GetImmPCOffsetTarget() {
void* base = AlignDown(getPC(), P_SIZE); void* base = AlignDown(GetPC(), P_SIZE);
return offset + reinterpret_cast<Addr>(base); return offset + reinterpret_cast<Addr>(base);
} }
void A64_ADR_ADRP::assembler() { void A64_ADR_ADRP::Assembler() {
SET_OPCODE(ADR_ADRP); SET_OPCODE(ADR_ADRP);
} }
void A64_ADR_ADRP::decode(STRUCT_A64(ADR_ADRP) *inst) { void A64_ADR_ADRP::Disassembler() {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_OP; DECODE_OP;
} }
//Mov Wide //Mov Wide
A64_MOV_WIDE::A64_MOV_WIDE() {} A64_MOV_WIDE::A64_MOV_WIDE(void* inst) : InstructionA64(inst) {}
A64_MOV_WIDE::A64_MOV_WIDE(STRUCT_A64(MOV_WIDE) &inst) : InstructionA64(&inst) {
decode(&inst);
}
A64_MOV_WIDE::A64_MOV_WIDE(A64_MOV_WIDE::OP op,RegisterA64* rd, U16 imme, U8 shift) A64_MOV_WIDE::A64_MOV_WIDE(A64_MOV_WIDE::OP op,RegisterA64* rd, U16 imme, U8 shift)
: shift(shift), op(op), imme(imme), rd(rd) {} : shift(shift), op(op), imme(imme), rd(rd) {}
void A64_MOV_WIDE::assembler() { 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);
ENCODE_OP; ENCODE_OP;
get()->sf = rd->isX() ? 1 : 0; Get()->sf = rd->isX() ? 1 : 0;
ENCODE_RD; ENCODE_RD;
} }
void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { void A64_MOV_WIDE::Disassembler() {
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(Get()->imm16);
shift = static_cast<U8>(inst->hw * 16); shift = static_cast<U8>(Get()->hw * 16);
op = OP(inst->op); op = OP(Get()->op);
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
} else { } else {
DECODE_RD(WReg); DECODE_RD(WReg);
...@@ -129,34 +103,31 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { ...@@ -129,34 +103,31 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) {
//B BL //B BL
A64_B_BL::A64_B_BL() {} A64_B_BL::A64_B_BL(void *inst) : A64_INST_PC_REL(inst) {
A64_B_BL::A64_B_BL(STRUCT_A64(B_BL) &inst) : A64_INST_PC_REL(&inst) {
decode(&inst);
} }
A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) { A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) {
} }
A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label &l) : op(op) { A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label *l) : op(op) {
bindLabel(l); BindLabel(l);
} }
Off A64_B_BL::getImmPCOffset() { Off A64_B_BL::GetImmPCOffset() {
return DECODE_OFFSET(26, 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;
ENCODE_OFFSET(26, 2); ENCODE_OFFSET(26, 2);
} }
void A64_B_BL::decode(STRUCT_A64(B_BL) *inst) { void A64_B_BL::Disassembler() {
DECODE_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);
ENCODE_OP; ENCODE_OP;
ENCODE_OFFSET(26, 2); ENCODE_OFFSET(26, 2);
...@@ -166,44 +137,41 @@ void A64_B_BL::assembler() { ...@@ -166,44 +137,41 @@ void A64_B_BL::assembler() {
//CBZ CBNZ //CBZ CBNZ
A64_CBZ_CBNZ::A64_CBZ_CBNZ() {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst) { A64_CBZ_CBNZ::A64_CBZ_CBNZ(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 &rt) : op(op), A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 &rt) : op(op),
offset(offset), offset(offset),
rt(&rt) {} rt(&rt) {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) : op(op), A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label *label, RegisterA64 &rt) : op(op),
rt(&rt) { rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off A64_CBZ_CBNZ::getImmPCOffset() { Off A64_CBZ_CBNZ::GetImmPCOffset() {
return DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_CBZ_CBNZ::decode(STRUCT_A64(CBZ_CBNZ) *inst) { void A64_CBZ_CBNZ::Disassembler() {
DECODE_OP; DECODE_OP;
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RT(XReg); DECODE_RT(XReg);
} else { } else {
DECODE_RT(WReg); 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);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->sf = rt->isX() ? 1 : 0; Get()->sf = rt->isX() ? 1 : 0;
ENCODE_OFFSET(19, 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;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
...@@ -211,34 +179,32 @@ void A64_CBZ_CBNZ::onOffsetApply(Off offset) { ...@@ -211,34 +179,32 @@ void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
//B.Cond //B.Cond
A64_B_COND::A64_B_COND() {} A64_B_COND::A64_B_COND(void *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(STRUCT_A64(B_COND) &inst) : A64_INST_PC_REL(&inst) { A64_B_COND::A64_B_COND(Condition condition, Label *label) {
decode(&inst); BindLabel(label);
} }
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 DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_B_COND::decode(STRUCT_A64(B_COND) *inst) { void A64_B_COND::Disassembler() {
DECODE_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);
ENCODE_COND; ENCODE_COND;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
A64_B_COND::A64_B_COND(Condition condition, Label &label) { void A64_B_COND::OnOffsetApply(Off offset) {
bindLabel(label);
}
void A64_B_COND::onOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
...@@ -246,82 +212,74 @@ void A64_B_COND::onOffsetApply(Off offset) { ...@@ -246,82 +212,74 @@ void A64_B_COND::onOffsetApply(Off offset) {
//TBZ TBNZ //TBZ TBNZ
A64_TBZ_TBNZ::A64_TBZ_TBNZ() {}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst) : A64_INST_PC_REL(&inst) { A64_TBZ_TBNZ::A64_TBZ_TBNZ(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op), A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op),
rt(&rt), rt(&rt),
bit(bit), bit(bit),
offset(offset) {} offset(offset) {}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label &label) : op(op), A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label *label) : op(op),
rt(&rt), rt(&rt),
bit(bit) { bit(bit) {
bindLabel(label); BindLabel(label);
} }
Off A64_TBZ_TBNZ::getImmPCOffset() { Off A64_TBZ_TBNZ::GetImmPCOffset() {
return DECODE_OFFSET(14, 2); return DECODE_OFFSET(14, 2);
} }
void A64_TBZ_TBNZ::decode(STRUCT_A64(TBZ_TBNZ) *inst) { void A64_TBZ_TBNZ::Disassembler() {
bit = COMBINE(inst->b5, inst->b40, 5); bit = COMBINE(Get()->b5, Get()->b40, 5);
if (inst->b5 == 1) { if (Get()->b5 == 1) {
DECODE_RT(XReg); DECODE_RT(XReg);
} else { } else {
DECODE_RT(WReg); DECODE_RT(WReg);
} }
DECODE_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);
ENCODE_OP; ENCODE_OP;
get()->b5 = rt->isX() ? 1 : 0; Get()->b5 = rt->isX() ? 1 : 0;
ENCODE_RT; 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)));
ENCODE_OFFSET(14, 2); ENCODE_OFFSET(14, 2);
} }
void A64_TBZ_TBNZ::onOffsetApply(Off offset) { void A64_TBZ_TBNZ::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
get()->imm14 = TruncateToUint14(offset >> 2); Get()->imm14 = TruncateToUint14(offset >> 2);
} }
// LDR(literal) // LDR(literal)
A64_LDR_LIT::A64_LDR_LIT() {} A64_LDR_LIT::A64_LDR_LIT(void *inst) : A64_INST_PC_REL(inst) {}
A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&inst) {
decode(&inst);
}
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Off offset) : op(op), rt(&rt), A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Off offset) : op(op), rt(&rt),
offset(offset) {} offset(offset) {}
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Label& label) : op(op), rt(&rt) { A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Label *label) : op(op), rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off A64_LDR_LIT::getImmPCOffset() { Off A64_LDR_LIT::GetImmPCOffset() {
return DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_LDR_LIT::onOffsetApply(Off offset) { void A64_LDR_LIT::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { void A64_LDR_LIT::Disassembler() {
DECODE_OP; DECODE_OP;
offset = getImmPCOffset(); offset = GetImmPCOffset();
ENCODE_OFFSET(19, 2);
if (op == LDR_W) { if (op == LDR_W) {
DECODE_RT(WReg); DECODE_RT(WReg);
} else { } else {
...@@ -329,7 +287,7 @@ void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { ...@@ -329,7 +287,7 @@ void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) {
} }
} }
void A64_LDR_LIT::assembler() { void A64_LDR_LIT::Assembler() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
...@@ -337,21 +295,18 @@ void A64_LDR_LIT::assembler() { ...@@ -337,21 +295,18 @@ void A64_LDR_LIT::assembler() {
} }
//BR BLR RET
A64_BR_BLR_RET::A64_BR_BLR_RET() {} A64_BR_BLR_RET::A64_BR_BLR_RET(void *inst) : InstructionA64(inst) {}
A64_BR_BLR_RET::A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst) : InstructionA64(&inst) {
decode(&inst);
}
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::Disassembler() {
DECODE_RN(XReg); DECODE_RN(XReg);
DECODE_OP; 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); SET_OPCODE_MULTI(BR_BLR_RET, 3);
...@@ -359,141 +314,132 @@ void A64_BR_BLR_RET::assembler() { ...@@ -359,141 +314,132 @@ void A64_BR_BLR_RET::assembler() {
ENCODE_OP; ENCODE_OP;
} }
A64_STR_IMM::A64_STR_IMM() {}
A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) &inst) : A64LoadAndStoreImm(&inst) { //STR IMM
decode(&inst);
}
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) { A64_STR_IMM::A64_STR_IMM(void *inst) : A64LoadAndStoreImm(inst) {}
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
} }
void A64_STR_IMM::decode(STRUCT_A64(STR_IMM) *inst) { void A64_STR_IMM::Disassembler() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
valid = false; valid_ = false;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
} }
void A64_STR_IMM::assembler() { void A64_STR_IMM::Assembler() {
SET_OPCODE(STR_IMM); SET_OPCODE(STR_IMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
get()->addrmode = Offset; Get()->addrmode = Offset;
valid = false; valid_ = false;
} }
} }
A64_STR_UIMM::A64_STR_UIMM() {}
A64_STR_UIMM::A64_STR_UIMM(STRUCT_A64(STR_UIMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) { A64_STR_UIMM::A64_STR_UIMM(void *inst) : A64LoadAndStoreImm(inst) {}
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
} }
void A64_STR_UIMM::decode(STRUCT_A64(STR_UIMM) *inst) { void A64_STR_UIMM::Disassembler() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << regSize; offset = Get()->imm12 << regSize;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_STR_UIMM::assembler() { void A64_STR_UIMM::Assembler() {
SET_OPCODE(STR_UIMM); SET_OPCODE(STR_UIMM);
ENCODE_RT; ENCODE_RT;
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
get()->imm12 = operand.offset >> get()->size; Get()->imm12 = operand.offset_ >> Get()->size;
} }
A64_MOV_REG::A64_MOV_REG(void *inst) : InstructionA64(inst) {
A64_MOV_REG::A64_MOV_REG() {}
A64_MOV_REG::A64_MOV_REG(STRUCT_A64(MOV_REG) &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_MOV_REG::A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm) : rd(&rd), rm(&rm) { 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::Disassembler() {
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_RM(XReg); DECODE_RM(XReg);
} else { } else {
...@@ -502,418 +448,391 @@ void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) { ...@@ -502,418 +448,391 @@ void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) {
} }
} }
void A64_MOV_REG::assembler() { 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;
ENCODE_RD; ENCODE_RD;
ENCODE_RM; ENCODE_RM;
} }
A64_SUB_EXT_REG::A64_SUB_EXT_REG(void *inst) : InstructionA64(inst) {}
A64_SUB_EXT_REG::A64_SUB_EXT_REG() {}
A64_SUB_EXT_REG::A64_SUB_EXT_REG(STRUCT_A64(SUB_EXT_REG) &inst) : InstructionA64(&inst) {
decode(&inst);
}
A64_SUB_EXT_REG::A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand, A64_SUB_EXT_REG::A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand,
FlagsUpdate flagsUpdate) : rd(&rd), rn(&rn), operand(operand), FlagsUpdate flagsUpdate) : rd(&rd), rn(&rn), operand(operand),
flagsUpdate(flagsUpdate) {} flagsUpdate(flagsUpdate) {}
void A64_SUB_EXT_REG::decode(STRUCT_A64(SUB_EXT_REG) *inst) { void A64_SUB_EXT_REG::Disassembler() {
flagsUpdate = FlagsUpdate(inst->S); flagsUpdate = FlagsUpdate(Get()->S);
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_RN(XReg); DECODE_RN(XReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg_ = XReg(static_cast<U8>(Get()->rm));
} else { } else {
DECODE_RD(WReg); DECODE_RD(WReg);
DECODE_RN(WReg); DECODE_RN(WReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg_ = XReg(static_cast<U8>(Get()->rm));
} }
operand.extend = Extend(inst->option); operand.extend_ = Extend(Get()->option);
INST_ASSERT(inst->imm3 > 4); INST_ASSERT(Get()->imm3 > 4);
operand.shift = Shift(inst->imm3); operand.shift_ = Shift(Get()->imm3);
} }
void A64_SUB_EXT_REG::assembler() { void A64_SUB_EXT_REG::Assembler() {
SET_OPCODE_MULTI(SUB_EXT_REG, 1); SET_OPCODE_MULTI(SUB_EXT_REG, 1);
SET_OPCODE_MULTI(SUB_EXT_REG, 2); SET_OPCODE_MULTI(SUB_EXT_REG, 2);
get()->S = flagsUpdate; Get()->S = flagsUpdate;
get()->sf = rd->isX() ? 1 : 0; Get()->sf = rd->isX() ? 1 : 0;
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_->Code();
ENCODE_RN; ENCODE_RN;
ENCODE_RD; ENCODE_RD;
} }
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(void* inst) : InstructionA64(inst) {
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN() {}
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(STRUCT_A64(EXCEPTION_GEN) &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el, U16 imme) : op( A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el, U16 imme) : op(
op), el(el), imme(imme) {} op), el(el), imme(imme) {}
void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) { void A64_EXCEPTION_GEN::Disassembler() {
DECODE_OP; DECODE_OP;
el = ExceptionLevel(inst->ll); el = ExceptionLevel(Get()->ll);
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(Get()->imm16);
} }
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);
ENCODE_OP; ENCODE_OP;
get()->ll = el; Get()->ll = el;
get()->imm16 = imme; Get()->imm16 = imme;
} }
A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {} A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {}
A64_SVC::A64_SVC() {} A64_SVC::A64_SVC(void *inst) : A64_EXCEPTION_GEN(inst) {}
A64_SVC::A64_SVC(STRUCT_A64(SVC) &inst) : A64_EXCEPTION_GEN(inst) {}
A64_LDR_IMM::A64_LDR_IMM(void *inst) : A64LoadAndStoreImm(inst) {
A64_LDR_IMM::A64_LDR_IMM() {}
A64_LDR_IMM::A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
} }
A64_LDR_IMM::A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, A64_LDR_IMM::A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {} operand) {}
void A64_LDR_IMM::decode(STRUCT_A64(LDR_IMM) *inst) { void A64_LDR_IMM::Disassembler() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
valid = false; valid_ = false;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDR_IMM::assembler() { void A64_LDR_IMM::Assembler() {
SET_OPCODE(LDR_IMM); SET_OPCODE(LDR_IMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
get()->addrmode = Offset; Get()->addrmode = Offset;
valid = false; valid_ = false;
} }
} }
A64_LDR_UIMM::A64_LDR_UIMM() {}
A64_LDR_UIMM::A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64LoadAndStoreImm(&inst) { A64_LDR_UIMM::A64_LDR_UIMM(void *inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
} }
A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {} operand) {}
void A64_LDR_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) { void A64_LDR_UIMM::Disassembler() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << regSize; offset = Get()->imm12 << regSize;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDR_UIMM::assembler() { void A64_LDR_UIMM::Assembler() {
SET_OPCODE(LDR_UIMM); SET_OPCODE(LDR_UIMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
get()->imm12 = static_cast<InstA64>(operand.offset >> get()->size); Get()->imm12 = static_cast<InstA64>(operand.offset_ >> Get()->size);
} }
A64_LDRSW_IMM::A64_LDRSW_IMM() {}
A64_LDRSW_IMM::A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst) : A64_LDR_IMM(inst) {} A64_LDRSW_IMM::A64_LDRSW_IMM(void *inst) : A64_LDR_IMM(inst) {}
A64_LDRSW_IMM::A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand) : A64_LDR_IMM(rt, A64_LDRSW_IMM::A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand) : A64_LDR_IMM(rt,
operand) {} operand) {}
void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) { void A64_LDRSW_IMM::Disassembler() {
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
} }
void A64_LDRSW_IMM::assembler() { void A64_LDRSW_IMM::Assembler() {
SET_OPCODE(LDRSW_IMM); SET_OPCODE(LDRSW_IMM);
get()->size = Size32; Get()->size = Size32;
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
} }
A64_LDRSW_UIMM::A64_LDRSW_UIMM(void *inst) : A64_LDR_UIMM(inst) {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM() {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64_LDR_UIMM(inst) {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_LDR_UIMM(rt, A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_LDR_UIMM(rt,
operand) {} operand) {}
void A64_LDRSW_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) { void A64_LDRSW_UIMM::Disassembler() {
DECODE_RT(XReg); DECODE_RT(XReg);
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << Size32; offset = Get()->imm12 << Size32;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDRSW_UIMM::assembler() { void A64_LDRSW_UIMM::Assembler() {
SET_OPCODE(LDRSW_UIMM); SET_OPCODE(LDRSW_UIMM);
get()->size = Size32; Get()->size = Size32;
ENCODE_RT; ENCODE_RT;
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm12 = operand.offset >> Size32; Get()->imm12 = operand.offset_ >> Size32;
} }
A64_STP_LDP::A64_STP_LDP(A64_STRUCT_STP_LDP &inst) : InstructionA64(&inst) { A64_STP_LDP::A64_STP_LDP(void *inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_STP_LDP::A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand) : op(op), rt1(&rt1), A64_STP_LDP::A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand) : op(op), rt1(&rt1),
rt2(&rt2), rt2(&rt2),
operand(operand) {} operand(operand) {}
void A64_STP_LDP::decode(A64_STRUCT_STP_LDP *inst) { void A64_STP_LDP::Disassembler() {
DECODE_OP; DECODE_OP;
Size s = Size(inst->size); RegSize s = RegSize(Get()->size);
if (s == Size64) { if (s == Size64) {
rt1 = XReg(inst->rt); rt1 = XReg(Get()->rt);
rt2 = XReg(inst->rt2); rt2 = XReg(Get()->rt2);
operand.offset = signExtend64(7, inst->imm7) << 3; operand.offset_ = SignExtend64(7, Get()->imm7) << 3;
} else { } else {
rt1 = WReg(inst->rt); rt1 = WReg(Get()->rt);
rt2 = WReg(inst->rt2); rt2 = WReg(Get()->rt2);
operand.offset = signExtend64(7, inst->imm7) << 2; operand.offset_ = SignExtend64(7, Get()->imm7) << 2;
} }
operand.base = XReg(inst->rn); operand.base_ = XReg(Get()->rn);
AdMod adMod = AdMod(inst->addrmode); AdMod adMod = AdMod(Get()->addrmode);
switch (adMod) { switch (adMod) {
case SignOffset: case SignOffset:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
break; break;
case PostIndex: case PostIndex:
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
} }
} }
void A64_STP_LDP::assembler() { void A64_STP_LDP::Assembler() {
SET_OPCODE(STP_LDP); SET_OPCODE(STP_LDP);
ENCODE_OP; ENCODE_OP;
get()->size = rt1->isX() ? Size64 : Size32; Get()->size = rt1->isX() ? Size64 : Size32;
get()->rt = rt1->getCode(); Get()->rt = rt1->Code();
get()->rt2 = rt2->getCode(); Get()->rt2 = rt2->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case Offset: case Offset:
get()->addrmode = SignOffset; Get()->addrmode = SignOffset;
break; break;
case AddrMode::PostIndex: case AddrMode::PostIndex:
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
} }
get()->imm7 = TruncateToUint7(operand.offset >> (rt1->isX() ? 3 : 2)); Get()->imm7 = TruncateToUint7(operand.offset_ >> (rt1->isX() ? 3 : 2));
} }
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(void *inst) : InstructionA64(&inst) {
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM() {}
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_STRUCT_ADD_SUB_IMM &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_ADD_SUB_IMM::OP op, A64_ADD_SUB_IMM::S sign, RegisterA64 &rd, A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_ADD_SUB_IMM::OP op, A64_ADD_SUB_IMM::S sign, RegisterA64 &rd,
const Operand &operand) : op(op), sign(sign), rd(&rd), operand(operand) {} const Operand &operand) : op(op), sign(sign), rd(&rd), operand(operand) {}
void A64_ADD_SUB_IMM::decode(A64_STRUCT_ADD_SUB_IMM *inst) { void A64_ADD_SUB_IMM::Disassembler() {
DECODE_OP; DECODE_OP;
if (inst->sf == Size64) { if (Get()->sf == Size64) {
DECODE_RD(XReg); DECODE_RD(XReg);
operand.reg = XReg(inst->rn); operand.reg_ = XReg(Get()->rn);
} else { } else {
DECODE_RD(XReg); DECODE_RD(XReg);
operand.reg = WReg(inst->rn); operand.reg_ = WReg(Get()->rn);
} }
sign = S(inst->S); sign = S(Get()->S);
DECODE_SHIFT; DECODE_SHIFT;
if (operand.shift == LSL) { if (operand.shift_ == LSL) {
operand.shift_extend_imm = get()->imm12; operand.shift_extend_imm_ = Get()->imm12;
} else if (operand.shift == LSR) { } else if (operand.shift_ == LSR) {
operand.shift_extend_imm = get()->imm12 << 12; operand.shift_extend_imm_ = Get()->imm12 << 12;
} else { } else {
valid = false; valid_ = false;
} }
} }
void A64_ADD_SUB_IMM::assembler() { void A64_ADD_SUB_IMM::Assembler() {
SET_OPCODE(ADD_SUB_IMM); SET_OPCODE(ADD_SUB_IMM);
ENCODE_OP; ENCODE_OP;
ENCODE_RD; ENCODE_RD;
get()->rn = operand.reg->getCode(); Get()->rn = operand.reg_->Code();
get()->sf = rd->isX() ? Size64 : Size32; Get()->sf = rd->isX() ? Size64 : Size32;
get()->S = sign; Get()->S = sign;
ENCODE_SHIFT; ENCODE_SHIFT;
if (operand.shift == LSL) { if (operand.shift_ == LSL) {
get()->imm12 = operand.shift_extend_imm; Get()->imm12 = operand.shift_extend_imm_;
} else if (operand.shift == LSR) { } else if (operand.shift_ == LSR) {
get()->imm12 = operand.shift_extend_imm >> 12; Get()->imm12 = operand.shift_extend_imm_ >> 12;
} else { } else {
valid = false; valid_ = false;
} }
} }
A64_MSR_MRS::A64_MSR_MRS(A64_STRUCT_MSR_MRS &inst) : InstructionA64(&inst) { A64_MSR_MRS::A64_MSR_MRS(void *inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_MSR_MRS::A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt) : op(op), systemRegister( A64_MSR_MRS::A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt) : op(op), system_reg(
&systemRegister), rt(&rt) {} &systemRegister), rt(&rt) {}
void A64_MSR_MRS::decode(A64_STRUCT_MSR_MRS *inst) { void A64_MSR_MRS::Disassembler() {
DECODE_OP; DECODE_OP;
DECODE_RT(XReg); DECODE_RT(XReg);
//TODO system_reg->value = static_cast<U16>(Get()->sysreg);
} }
void A64_MSR_MRS::assembler() { void A64_MSR_MRS::Assembler() {
SET_OPCODE(MSR_MRS); SET_OPCODE(MSR_MRS);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->sysreg = systemRegister->value(); Get()->sysreg = system_reg->value;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_INST_ARM64_H #pragma once
#define SANDHOOK_NH_INST_ARM64_H
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
#include "instruction.h" #include "instruction.h"
...@@ -13,10 +12,10 @@ ...@@ -13,10 +12,10 @@
#define INST_A64(X) A64_##X #define INST_A64(X) A64_##X
#define IS_OPCODE_A64(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) { \
union { \ union { \
InstA64 raw; \ InstA64 raw; \
STRUCT_A64(X) inst; \ STRUCT_A64(X) inst; \
...@@ -31,12 +30,13 @@ return COND; \ ...@@ -31,12 +30,13 @@ return COND; \
#define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_A64(X##_##INDEX) #define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_A64(X##_##INDEX)
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
inline U32 instCode() override { \
return ENUM_VALUE(InstCodeA64, InstCodeA64::X); \ #define DEFINE_INST_EXT(X,P) class INST_A64(X) : public INST_A64(P)
}
#define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X)> #define DEFINE_INST_EXT_(X,P) class INST_A64(X) : public P<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
#define DEFINE_INST_PCREL(X) class INST_A64(X) : public A64_INST_PC_REL<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
#define CAST_A64(X,V) reinterpret_cast<SandHook::AsmA64::INST_A64(X) *>(V) #define CAST_A64(X,V) reinterpret_cast<SandHook::AsmA64::INST_A64(X) *>(V)
...@@ -47,33 +47,23 @@ namespace SandHook { ...@@ -47,33 +47,23 @@ namespace SandHook {
namespace AsmA64 { namespace AsmA64 {
template<typename Inst> template<typename S, U32 C>
class InstructionA64 : public Instruction<Inst> { class InstructionA64 : public Instruction<S, C> {
public: public:
InstructionA64() {} InstructionA64() {}
InstructionA64(Inst *inst) : Instruction<Inst>(inst) {} InstructionA64(void *inst) : Instruction<S, C>(inst) {}
Inst mask(Inst raw) {
return raw & *(this->get());
}
U32 size() override;
static inline S64 signExtend64(unsigned int bits, U64 value) {
return ExtractSignedBitfield64(bits - 1, 0, value);
}
static inline S32 signExtend32(unsigned int bits, U32 value) { U32 Size() override {
return ExtractSignedBitfield32(bits - 1, 0, value); return 4;
} };
InstType instType() override { InstType InstType() override {
return A64; return A64;
} }
Arch arch() override { Arch Arch() override {
return arm64; return arm64;
} }
...@@ -102,117 +92,108 @@ namespace SandHook { ...@@ -102,117 +92,108 @@ namespace SandHook {
public: public:
inline explicit Operand(){}; inline explicit Operand(){};
inline explicit Operand(S64 imm) inline explicit Operand(S64 imm)
: immediate(imm), reg(&UnknowRegiser), shift(NO_SHIFT), extend(NO_EXTEND), shift_extend_imm(0) {} : immediate_(imm), reg_(&UnknowRegiser), shift_(NO_SHIFT), extend_(NO_EXTEND), shift_extend_imm_(0) {}
inline explicit Operand(RegisterA64* reg, int32_t imm = 0, Shift shift = LSL) inline explicit Operand(RegisterA64* reg, int32_t imm = 0, Shift shift = LSL)
: immediate(0), reg(reg), shift(shift), extend(NO_EXTEND), shift_extend_imm(imm) {} : immediate_(0), reg_(reg), shift_(shift), extend_(NO_EXTEND), shift_extend_imm_(imm) {}
inline explicit Operand(RegisterA64* reg, Extend extend, int32_t imm = 0) inline explicit Operand(RegisterA64* reg, Extend extend, int32_t imm = 0)
: immediate(0), reg(reg), shift(NO_SHIFT), extend(extend), shift_extend_imm(imm) {} : immediate_(0), reg_(reg), shift_(NO_SHIFT), extend_(extend), shift_extend_imm_(imm) {}
// ===== // =====
bool IsImmediate() const { return reg->is(UnknowRegiser); } bool IsImmediate() const { return *reg_ == UnknowRegiser; }
bool IsShiftedRegister() const { return (shift != NO_SHIFT); } bool IsShiftedRegister() const { return (shift_ != NO_SHIFT); }
bool IsExtendedRegister() const { return (extend != NO_EXTEND); } bool IsExtendedRegister() const { return (extend_ != NO_EXTEND); }
public: public:
S64 immediate; S64 immediate_;
RegisterA64* reg; RegisterA64* reg_;
Shift shift; Shift shift_;
Extend extend; Extend extend_;
int32_t shift_extend_imm; int32_t shift_extend_imm_;
}; };
class MemOperand { class MemOperand {
public: public:
inline explicit MemOperand() {} inline explicit MemOperand() {}
inline explicit MemOperand(RegisterA64* base, Off offset = 0, AddrMode addr_mode = Offset) inline explicit MemOperand(RegisterA64* base, Off offset = 0, AddrMode addr_mode = Offset)
: base(base), reg_offset(&UnknowRegiser), offset(offset), addr_mode(addr_mode), shift(NO_SHIFT), : base_(base), reg_offset_(&UnknowRegiser), offset_(offset), addr_mode_(addr_mode), shift_(NO_SHIFT),
extend(NO_EXTEND), shift_extend_imm(0) {} extend_(NO_EXTEND), shift_extend_imm_(0) {}
inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Extend extend, unsigned extend_imm) inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Extend extend, unsigned extend_imm)
: base(base), reg_offset(reg_offset), offset(0), addr_mode(Offset), shift(NO_SHIFT), extend(extend), : base_(base), reg_offset_(reg_offset), offset_(0), addr_mode_(Offset), shift_(NO_SHIFT), extend_(extend),
shift_extend_imm(extend_imm) {} shift_extend_imm_(extend_imm) {}
inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Shift shift = LSL, unsigned shift_imm = 0) inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Shift shift = LSL, unsigned shift_imm = 0)
: base(base), reg_offset(reg_offset), offset(0), addr_mode(Offset), shift(shift), extend(NO_EXTEND), : base_(base), reg_offset_(reg_offset), offset_(0), addr_mode_(Offset), shift_(shift), extend_(NO_EXTEND),
shift_extend_imm(shift_imm) {} shift_extend_imm_(shift_imm) {}
inline explicit MemOperand(RegisterA64* base, const Operand &offset, AddrMode addr_mode = Offset) inline explicit MemOperand(RegisterA64* base, const Operand &offset, AddrMode addr_mode = Offset)
: base(base), reg_offset(&UnknowRegiser), addr_mode(addr_mode) { : base_(base), reg_offset_(&UnknowRegiser), addr_mode_(addr_mode) {
if (offset.IsShiftedRegister()) { if (offset.IsShiftedRegister()) {
reg_offset = offset.reg; reg_offset_ = offset.reg_;
shift = offset.shift; shift_ = offset.shift_;
shift_extend_imm = offset.shift_extend_imm; shift_extend_imm_ = offset.shift_extend_imm_;
extend = NO_EXTEND; extend_ = NO_EXTEND;
this->offset = 0; this->offset_ = 0;
} else if (offset.IsExtendedRegister()) { } else if (offset.IsExtendedRegister()) {
reg_offset = offset.reg; reg_offset_ = offset.reg_;
extend = offset.extend; extend_ = offset.extend_;
shift_extend_imm = offset.shift_extend_imm; shift_extend_imm_ = offset.shift_extend_imm_;
shift = NO_SHIFT; shift_ = NO_SHIFT;
this->offset = 0; this->offset_ = 0;
} }
} }
// ===== // =====
bool IsImmediateOffset() const { return (addr_mode == Offset); } bool IsImmediateOffset() const { return (addr_mode_ == Offset); }
bool IsRegisterOffset() const { return (addr_mode == Offset); } bool IsRegisterOffset() const { return (addr_mode_ == Offset); }
bool IsPreIndex() const { return addr_mode == PreIndex; } bool IsPreIndex() const { return addr_mode_ == PreIndex; }
bool IsPostIndex() const { return addr_mode == PostIndex; } bool IsPostIndex() const { return addr_mode_ == PostIndex; }
public: public:
RegisterA64* base; RegisterA64* base_;
RegisterA64* reg_offset; RegisterA64* reg_offset_;
Off offset; Off offset_;
AddrMode addr_mode; AddrMode addr_mode_;
Shift shift; Shift shift_;
Extend extend; Extend extend_;
S32 shift_extend_imm; S32 shift_extend_imm_;
}; };
class INST_A64(UNKNOW) : public InstructionA64<STRUCT_A64(UNKNOW)> { DEFINE_INST(UNKNOW) {
public: public:
A64_UNKNOW(STRUCT_A64(UNKNOW) &inst); A64_UNKNOW(void *inst) : InstructionA64(inst) {}
DEFINE_INST_CODE(UNKNOW) INLINE bool Unknow() override {
inline bool unknow() override {
return true; return true;
} }
void decode(A64_STRUCT_UNKNOW *inst) override;
void assembler() override;
private:
STRUCT_A64(UNKNOW) inst_backup;
}; };
template <typename Inst> template <typename S,U32 C>
class A64_INST_PC_REL : public InstructionA64<Inst> { class A64_INST_PC_REL : public InstructionA64<S, C> {
public: public:
A64_INST_PC_REL(); A64_INST_PC_REL();
A64_INST_PC_REL(Inst *inst); A64_INST_PC_REL(void *inst);
virtual Off getImmPCOffset() = 0; virtual Off GetImmPCOffset() = 0;
virtual Addr getImmPCOffsetTarget(); virtual Addr GetImmPCOffsetTarget();
bool pcRelate() override; bool PcRelate() override;
}; };
class INST_A64(ADR_ADRP) : public A64_INST_PC_REL<STRUCT_A64(ADR_ADRP)> { DEFINE_INST_PCREL(ADR_ADRP) {
public: public:
enum OP { enum OP {
...@@ -220,29 +201,25 @@ namespace SandHook { ...@@ -220,29 +201,25 @@ namespace SandHook {
ADRP = 0b1, ADRP = 0b1,
}; };
A64_ADR_ADRP(); A64_ADR_ADRP(void *inst);
A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst);
A64_ADR_ADRP(OP op, XRegister &rd, S64 offset); A64_ADR_ADRP(OP op, XRegister &rd, S64 offset);
A64_ADR_ADRP(OP op, XRegister &rd, Label &label); A64_ADR_ADRP(OP op, XRegister &rd, Label *label);
DEFINE_IS(ADR_ADRP) DEFINE_IS(ADR_ADRP)
DEFINE_INST_CODE(ADR_ADRP) bool IsADRP() {
return Get()->op == OP::ADRP;
bool isADRP() {
return get()->op == OP::ADRP;
} }
Off getImmPCOffset() override; Off GetImmPCOffset() override;
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
void decode(A64_STRUCT_ADR_ADRP *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -252,7 +229,7 @@ namespace SandHook { ...@@ -252,7 +229,7 @@ namespace SandHook {
class INST_A64(MOV_WIDE) : public InstructionA64<STRUCT_A64(MOV_WIDE)> { DEFINE_INST(MOV_WIDE) {
public: public:
enum OP { enum OP {
...@@ -271,23 +248,19 @@ namespace SandHook { ...@@ -271,23 +248,19 @@ namespace SandHook {
Shift3 = 48 Shift3 = 48
}; };
A64_MOV_WIDE(); A64_MOV_WIDE(void* inst);
A64_MOV_WIDE(STRUCT_A64(MOV_WIDE) &inst);
A64_MOV_WIDE(A64_MOV_WIDE::OP op, RegisterA64* rd, U16 imme, U8 shift); A64_MOV_WIDE(A64_MOV_WIDE::OP op, RegisterA64* rd, U16 imme, U8 shift);
DEFINE_IS(MOV_WIDE) DEFINE_IS(MOV_WIDE)
DEFINE_INST_CODE(MOV_WIDE) void Assembler() override;
void assembler() override; void Disassembler() override;
void decode(STRUCT_A64(MOV_WIDE) *decode) override;
public: public:
//can be 16/32/64/128 //can be 16/32/64/128
//hw = shift / 16 //hw = shift_ / 16
U8 shift; U8 shift;
OP op; OP op;
U16 imme; U16 imme;
...@@ -296,7 +269,7 @@ namespace SandHook { ...@@ -296,7 +269,7 @@ namespace SandHook {
class INST_A64(B_BL) : public A64_INST_PC_REL<STRUCT_A64(B_BL)> { DEFINE_INST_PCREL(B_BL) {
public: public:
enum OP { enum OP {
...@@ -304,13 +277,11 @@ namespace SandHook { ...@@ -304,13 +277,11 @@ namespace SandHook {
BL = 0b1 BL = 0b1
}; };
A64_B_BL(); A64_B_BL(void *inst) ;
A64_B_BL(STRUCT_A64(B_BL) &inst);
A64_B_BL(OP op, Off offset); A64_B_BL(OP op, Off offset);
A64_B_BL(OP op, Label &l); A64_B_BL(OP op, Label *l);
DEFINE_IS(B_BL) DEFINE_IS(B_BL)
...@@ -322,15 +293,13 @@ namespace SandHook { ...@@ -322,15 +293,13 @@ namespace SandHook {
return op; return op;
} }
DEFINE_INST_CODE(B_BL) Off GetImmPCOffset() override;
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_A64(B_BL) *decode) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
...@@ -339,7 +308,7 @@ namespace SandHook { ...@@ -339,7 +308,7 @@ namespace SandHook {
}; };
class INST_A64(CBZ_CBNZ) : public A64_INST_PC_REL<STRUCT_A64(CBZ_CBNZ)> { DEFINE_INST_PCREL(CBZ_CBNZ) {
public: public:
enum OP { enum OP {
...@@ -347,25 +316,21 @@ namespace SandHook { ...@@ -347,25 +316,21 @@ namespace SandHook {
CBNZ = 1 CBNZ = 1
}; };
A64_CBZ_CBNZ(); A64_CBZ_CBNZ(void *inst);
A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst);
A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 &rt); A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 &rt);
A64_CBZ_CBNZ(OP op, Label& label, RegisterA64 &rt); A64_CBZ_CBNZ(OP op, Label *label, RegisterA64 &rt);
DEFINE_IS(CBZ_CBNZ) DEFINE_IS(CBZ_CBNZ)
DEFINE_INST_CODE(CBZ_CBNZ) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(STRUCT_A64(CBZ_CBNZ) *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -374,27 +339,24 @@ namespace SandHook { ...@@ -374,27 +339,24 @@ namespace SandHook {
}; };
class INST_A64(B_COND) : public A64_INST_PC_REL<STRUCT_A64(B_COND)> { DEFINE_INST_PCREL(B_COND) {
public: public:
A64_B_COND();
A64_B_COND(STRUCT_A64(B_COND) &inst); A64_B_COND(void *inst);
A64_B_COND(Condition condition, Off offset); A64_B_COND(Condition condition, Off offset);
A64_B_COND(Condition condition, Label& label); A64_B_COND(Condition condition, Label *label);
DEFINE_IS(B_COND) DEFINE_IS(B_COND)
DEFINE_INST_CODE(B_COND) Off GetImmPCOffset() override;
Off getImmPCOffset() override; void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; void Disassembler() override;
void decode(STRUCT_A64(B_COND) *inst) override; void Assembler() override;
void assembler() override;
public: public:
Condition condition; Condition condition;
...@@ -402,7 +364,7 @@ namespace SandHook { ...@@ -402,7 +364,7 @@ namespace SandHook {
}; };
class INST_A64(TBZ_TBNZ) : public A64_INST_PC_REL<STRUCT_A64(TBZ_TBNZ)> { DEFINE_INST_PCREL(TBZ_TBNZ) {
public: public:
enum OP { enum OP {
...@@ -410,25 +372,22 @@ namespace SandHook { ...@@ -410,25 +372,22 @@ namespace SandHook {
TBNZ = 1 TBNZ = 1
}; };
A64_TBZ_TBNZ();
A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst); A64_TBZ_TBNZ(void *inst);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Off offset); A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Off offset);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Label& label); A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Label* label);
DEFINE_IS(TBZ_TBNZ) DEFINE_IS(TBZ_TBNZ)
DEFINE_INST_CODE(TBZ_TBNZ) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(STRUCT_A64(TBZ_TBNZ) *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -438,7 +397,7 @@ namespace SandHook { ...@@ -438,7 +397,7 @@ namespace SandHook {
}; };
class INST_A64(LDR_LIT) : public A64_INST_PC_REL<STRUCT_A64(LDR_LIT)> { DEFINE_INST_PCREL(LDR_LIT) {
public: public:
enum OP { enum OP {
...@@ -448,25 +407,21 @@ namespace SandHook { ...@@ -448,25 +407,21 @@ namespace SandHook {
LDR_PRFM = 0b11 LDR_PRFM = 0b11
}; };
A64_LDR_LIT(); A64_LDR_LIT(void *inst);
A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst);
A64_LDR_LIT(OP op, RegisterA64 &rt, Off offset); A64_LDR_LIT(OP op, RegisterA64 &rt, Off offset);
A64_LDR_LIT(OP op, RegisterA64 &rt, Label& label); A64_LDR_LIT(OP op, RegisterA64 &rt, Label* label);
DEFINE_IS(LDR_LIT) DEFINE_IS(LDR_LIT)
DEFINE_INST_CODE(LDR_LIT) Off GetImmPCOffset() override;
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_A64(LDR_LIT) *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -484,19 +439,15 @@ namespace SandHook { ...@@ -484,19 +439,15 @@ namespace SandHook {
RET = 0b11 RET = 0b11
}; };
A64_BR_BLR_RET(); A64_BR_BLR_RET(void *inst);
A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst);
A64_BR_BLR_RET(OP op, XRegister &rn); A64_BR_BLR_RET(OP op, XRegister &rn);
DEFINE_IS_EXT(BR_BLR_RET, TEST_INST_OPCODE(BR_BLR_RET, 1) && TEST_INST_OPCODE(BR_BLR_RET, 2) && TEST_INST_OPCODE(BR_BLR_RET,3)) DEFINE_IS_EXT(BR_BLR_RET, TEST_INST_OPCODE(BR_BLR_RET, 1) && TEST_INST_OPCODE(BR_BLR_RET, 2) && TEST_INST_OPCODE(BR_BLR_RET,3))
DEFINE_INST_CODE(BR_BLR_RET) void Disassembler() override;
void decode(A64_STRUCT_BR_BLR_RET *inst) override; void Assembler() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -504,8 +455,8 @@ namespace SandHook { ...@@ -504,8 +455,8 @@ namespace SandHook {
}; };
template <typename Inst> template <typename S, U32 C>
class A64LoadAndStoreImm : public InstructionA64<Inst> { class A64LoadAndStoreImm : public InstructionA64<S,C> {
public: public:
enum AdMod { enum AdMod {
...@@ -514,14 +465,12 @@ namespace SandHook { ...@@ -514,14 +465,12 @@ namespace SandHook {
PreIndex = 0b11 PreIndex = 0b11
}; };
enum Size { enum RegSize {
Size32 = 0b10, Size32 = 0b10,
Size64 = 0b11 Size64 = 0b11
}; };
A64LoadAndStoreImm() {} A64LoadAndStoreImm(void *inst) : InstructionA64<S,C>(inst) {}
A64LoadAndStoreImm(Inst *inst) : InstructionA64<Inst>(inst) {}
A64LoadAndStoreImm(RegisterA64 *rt, const MemOperand &operand) : rt(rt), A64LoadAndStoreImm(RegisterA64 *rt, const MemOperand &operand) : rt(rt),
operand(operand) {} operand(operand) {}
...@@ -529,70 +478,58 @@ namespace SandHook { ...@@ -529,70 +478,58 @@ namespace SandHook {
RegisterA64* rt; RegisterA64* rt;
MemOperand operand = MemOperand(); MemOperand operand = MemOperand();
protected: protected:
Off offset;
AdMod addrMode; AdMod addrMode;
Size regSize; RegSize regSize;
U8 scale; U8 scale;
bool wback; bool wback;
bool postindex; bool postindex;
Off offset;
}; };
class INST_A64(STR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_IMM)> { DEFINE_INST_EXT_(STR_IMM, A64LoadAndStoreImm) {
public: public:
A64_STR_IMM(); A64_STR_IMM(void *inst);
A64_STR_IMM(STRUCT_A64(STR_IMM)& inst);
A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand); A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(STR_IMM) DEFINE_IS(STR_IMM)
DEFINE_INST_CODE(STR_IMM) void Disassembler() override;
void decode(STRUCT_A64(STR_IMM) *inst) override;
void assembler() override; void Assembler() override;
}; };
class INST_A64(STR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_UIMM)> { DEFINE_INST_EXT_(STR_UIMM, A64LoadAndStoreImm) {
public: public:
A64_STR_UIMM(); A64_STR_UIMM(void *inst);
A64_STR_UIMM(STRUCT_A64(STR_UIMM)& inst);
A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand); A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(STR_UIMM) DEFINE_IS(STR_UIMM)
DEFINE_INST_CODE(STR_UIMM) void Disassembler() override;
void decode(STRUCT_A64(STR_UIMM) *inst) override; void Assembler() override;
void assembler() override;
}; };
DEFINE_INST(MOV_REG) { DEFINE_INST(MOV_REG) {
public: public:
A64_MOV_REG(); A64_MOV_REG(void *inst);
A64_MOV_REG(STRUCT_A64(MOV_REG) &inst);
A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm); A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm);
DEFINE_IS_EXT(MOV_REG, TEST_INST_OPCODE(MOV_REG, 1) && TEST_INST_OPCODE(MOV_REG, 2)) DEFINE_IS_EXT(MOV_REG, TEST_INST_OPCODE(MOV_REG, 1) && TEST_INST_OPCODE(MOV_REG, 2))
DEFINE_INST_CODE(MOV_REG) void Disassembler() override;
void decode(A64_STRUCT_MOV_REG *inst) override; void Assembler() override;
void assembler() override;
public: public:
RegisterA64* rd; RegisterA64* rd;
...@@ -603,20 +540,16 @@ namespace SandHook { ...@@ -603,20 +540,16 @@ namespace SandHook {
DEFINE_INST(SUB_EXT_REG) { DEFINE_INST(SUB_EXT_REG) {
public: public:
A64_SUB_EXT_REG(); A64_SUB_EXT_REG(void *inst);
A64_SUB_EXT_REG(STRUCT_A64(SUB_EXT_REG) &inst);
A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand, A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand,
FlagsUpdate flagsUpdate); FlagsUpdate flagsUpdate);
DEFINE_IS_EXT(SUB_EXT_REG, TEST_INST_OPCODE(SUB_EXT_REG, 1) && TEST_INST_OPCODE(SUB_EXT_REG, 2)) DEFINE_IS_EXT(SUB_EXT_REG, TEST_INST_OPCODE(SUB_EXT_REG, 1) && TEST_INST_OPCODE(SUB_EXT_REG, 2))
DEFINE_INST_CODE(SUB_EXT_REG) void Disassembler() override;
void decode(A64_STRUCT_SUB_EXT_REG *inst) override; void Assembler() override;
void assembler() override;
public: public:
...@@ -637,19 +570,15 @@ namespace SandHook { ...@@ -637,19 +570,15 @@ namespace SandHook {
DCP = 0b101 DCP = 0b101
}; };
A64_EXCEPTION_GEN(); A64_EXCEPTION_GEN(void *inst);
A64_EXCEPTION_GEN(STRUCT_A64(EXCEPTION_GEN) &inst);
A64_EXCEPTION_GEN(OP op, ExceptionLevel el, U16 imme); A64_EXCEPTION_GEN(OP op, ExceptionLevel el, U16 imme);
DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2)) DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2))
DEFINE_INST_CODE(EXCEPTION_GEN) void Disassembler() override;
void decode(STRUCT_A64(EXCEPTION_GEN) *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -658,89 +587,77 @@ namespace SandHook { ...@@ -658,89 +587,77 @@ namespace SandHook {
}; };
class INST_A64(SVC) : public INST_A64(EXCEPTION_GEN) { DEFINE_INST_EXT(SVC, EXCEPTION_GEN) {
public: public:
A64_SVC(U16 imme);
A64_SVC(); A64_SVC(U16 imme);
A64_SVC(STRUCT_A64(SVC) &inst); A64_SVC(void *inst);
DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1)) DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1))
DEFINE_INST_CODE(SVC)
}; };
class INST_A64(LDR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_IMM)> { DEFINE_INST_EXT_(LDR_IMM, A64LoadAndStoreImm) {
public: public:
A64_LDR_IMM();
A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst); A64_LDR_IMM(void *inst);
A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand); A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_IMM) DEFINE_IS(LDR_IMM)
DEFINE_INST_CODE(LDR_IMM) void Disassembler() override;
void decode(STRUCT_A64(LDR_IMM) *inst) override; void Assembler() override;
void assembler() override;
}; };
class INST_A64(LDR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_UIMM)> { DEFINE_INST_EXT_(LDR_UIMM, A64LoadAndStoreImm) {
public: public:
A64_LDR_UIMM();
A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst); A64_LDR_UIMM(void *inst);
A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand); A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_UIMM) DEFINE_IS(LDR_UIMM)
DEFINE_INST_CODE(LDR_UIMM) void Disassembler() override;
void decode(STRUCT_A64(LDR_UIMM) *inst) override;
void assembler() override; void Assembler() override;
}; };
DEFINE_INST_EXT(LDRSW_IMM, LDR_IMM) {
class INST_A64(LDRSW_IMM) : public INST_A64(LDR_IMM) {
public: public:
A64_LDRSW_IMM();
A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst); A64_LDRSW_IMM(void *inst);
A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand); A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) && TEST_INST_FIELD(size, Size32)) DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) &&
TEST_INST_FIELD(size , Size32))
DEFINE_INST_CODE(LDRSW_IMM)
void decode(STRUCT_A64(LDR_IMM) *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
}; };
class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) { DEFINE_INST_EXT(LDRSW_UIMM, LDR_UIMM) {
public: public:
A64_LDRSW_UIMM(); A64_LDRSW_UIMM();
A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst); A64_LDRSW_UIMM(void *inst);
A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand); A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_UIMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_UIMM)) && TEST_INST_FIELD(size, Size32)) DEFINE_IS_EXT(LDRSW_UIMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_UIMM)) &&
TEST_INST_FIELD(size, Size32))
DEFINE_INST_CODE(LDRSW_UIMM) void Disassembler() override;
void decode(STRUCT_A64(LDR_UIMM) *inst) override; void Assembler() override;
void assembler() override;
}; };
...@@ -757,22 +674,20 @@ namespace SandHook { ...@@ -757,22 +674,20 @@ namespace SandHook {
PreIndex = 0b11 PreIndex = 0b11
}; };
enum Size { enum RegSize {
Size32 = 0b00, Size32 = 0b00,
Size64 = 0b10 Size64 = 0b10
}; };
A64_STP_LDP(A64_STRUCT_STP_LDP &inst); A64_STP_LDP(void *inst);
A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand); A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand);
DEFINE_IS(STP_LDP) DEFINE_IS(STP_LDP)
DEFINE_INST_CODE(STP_LDP) void Disassembler() override;
void decode(A64_STRUCT_STP_LDP *inst) override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
...@@ -795,24 +710,20 @@ namespace SandHook { ...@@ -795,24 +710,20 @@ namespace SandHook {
UnSign = 0b0 UnSign = 0b0
}; };
enum Size { enum RegSize {
Size32 = 0b0, Size32 = 0b0,
Size64 = 0b1 Size64 = 0b1
}; };
A64_ADD_SUB_IMM(); A64_ADD_SUB_IMM(void *inst);
A64_ADD_SUB_IMM(A64_STRUCT_ADD_SUB_IMM &inst);
A64_ADD_SUB_IMM(OP op, S sign, RegisterA64 &rd, const Operand &operand); A64_ADD_SUB_IMM(OP op, S sign, RegisterA64 &rd, const Operand &operand);
DEFINE_IS(ADD_SUB_IMM) DEFINE_IS(ADD_SUB_IMM)
DEFINE_INST_CODE(ADD_SUB_IMM) void Disassembler() override;
void decode(A64_STRUCT_ADD_SUB_IMM *inst) override; void Assembler() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -830,21 +741,19 @@ namespace SandHook { ...@@ -830,21 +741,19 @@ namespace SandHook {
MRS = 1 MRS = 1
}; };
A64_MSR_MRS(A64_STRUCT_MSR_MRS &inst); A64_MSR_MRS(void *inst);
A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt); A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt);
DEFINE_INST_CODE(MSR_MRS)
DEFINE_IS(MSR_MRS) DEFINE_IS(MSR_MRS)
void decode(A64_STRUCT_MSR_MRS *inst) override; void Disassembler() override;
void assembler() override; void Assembler() override;
public: public:
OP op; OP op;
SystemRegister* systemRegister; SystemRegister* system_reg;
RegisterA64* rt; RegisterA64* rt;
}; };
...@@ -858,5 +767,6 @@ namespace SandHook { ...@@ -858,5 +767,6 @@ namespace SandHook {
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST_CODE
#undef DEFINE_INST_EXT
#endif //SANDHOOK_NH_INST_ARM64_H #undef DEFINE_INST_EXT_
#undef DEFINE_INST_PCREL
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_INST_CODE_ARM64_H #pragma once
#define SANDHOOK_NH_INST_CODE_ARM64_H
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
enum class InstCodeA64 { enum class InstCodeA64 : InstCode {
UNKNOW, UNKNOW,
MOV_WIDE, MOV_WIDE,
MOV_REG, MOV_REG,
...@@ -30,6 +29,4 @@ enum class InstCodeA64 { ...@@ -30,6 +29,4 @@ enum class InstCodeA64 {
STP_LDP, STP_LDP,
ADD_SUB_IMM, ADD_SUB_IMM,
MSR_MRS MSR_MRS
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_CODE_ARM64_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/5. // Created by swift on 2019/5/5.
// //
#ifndef SANDHOOK_NH_INST_AARCH64_H #pragma once
#define SANDHOOK_NH_INST_AARCH64_H
#include "instruction.h" #include "instruction.h"
...@@ -39,7 +38,7 @@ enum FieldWide { ...@@ -39,7 +38,7 @@ enum FieldWide {
WideReg = 5, WideReg = 5,
}; };
//unknow inst //Unknow inst
DEFINE_STRUCT_A64(UNKNOW) { DEFINE_STRUCT_A64(UNKNOW) {
InstA64 raw; InstA64 raw;
}; };
...@@ -233,6 +232,4 @@ DEFINE_STRUCT_A64(MSR_MRS) { ...@@ -233,6 +232,4 @@ DEFINE_STRUCT_A64(MSR_MRS) {
InstA64 sysreg:16; InstA64 sysreg:16;
InstA64 op:1; InstA64 op:1;
InstA64 opcode:10; InstA64 opcode:10;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_AARCH64_H
...@@ -26,7 +26,7 @@ XRegister::XRegister(U8 code) : RegisterA64(code) {} ...@@ -26,7 +26,7 @@ XRegister::XRegister(U8 code) : RegisterA64(code) {}
XRegister::XRegister() {} XRegister::XRegister() {}
U8 XRegister::getWide() { U8 XRegister::Wide() {
return Reg64Bit; return Reg64Bit;
} }
...@@ -43,6 +43,6 @@ WRegister::WRegister(U8 code) : RegisterA64(code) {} ...@@ -43,6 +43,6 @@ WRegister::WRegister(U8 code) : RegisterA64(code) {}
WRegister::WRegister() {} WRegister::WRegister() {}
U8 WRegister::getWide() { U8 WRegister::Wide() {
return Reg32Bit; return Reg32Bit;
} }
// //
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#pragma once
#ifndef SANDHOOK_NH_REGISTER_A64_H
#define SANDHOOK_NH_REGISTER_A64_H
#include "register.h" #include "register.h"
...@@ -62,7 +60,7 @@ namespace SandHook { ...@@ -62,7 +60,7 @@ namespace SandHook {
XRegister(); XRegister();
XRegister(U8 code); XRegister(U8 code);
U8 getWide() override; U8 Wide() override;
static XRegister* get(U8 code) { static XRegister* get(U8 code) {
return registers[code]; return registers[code];
...@@ -75,9 +73,10 @@ namespace SandHook { ...@@ -75,9 +73,10 @@ namespace SandHook {
class WRegister : public RegisterA64 { class WRegister : public RegisterA64 {
public: public:
WRegister(); WRegister();
WRegister(U8 code); WRegister(U8 code);
U8 getWide() override; U8 Wide() override;
static WRegister* get(U8 code) { static WRegister* get(U8 code) {
return registers[code]; return registers[code];
...@@ -87,6 +86,8 @@ namespace SandHook { ...@@ -87,6 +86,8 @@ namespace SandHook {
static WRegister* registers[]; static WRegister* registers[];
}; };
class SystemRegister { class SystemRegister {
public: public:
...@@ -98,34 +99,31 @@ namespace SandHook { ...@@ -98,34 +99,31 @@ namespace SandHook {
U16 op0:2; U16 op0:2;
}; };
SystemRegister(U16 value) : value(value) {}
SystemRegister(U16 op0, U16 op1, U16 crn, U16 crm, U16 op2) { SystemRegister(U16 op0, U16 op1, U16 crn, U16 crm, U16 op2) {
reg.op0 = op0; reg.op0 = op0;
reg.op1 = op1; reg.op1 = op1;
reg.CRn = crn; reg.CRn = crn;
reg.CRm = crm; reg.CRm = crm;
reg.op2 = op2; reg.op2 = op2;
value = ForceCast<U16>(reg);
} }
U16 value() { bool operator==(const SystemRegister &rhs) const {
return value == rhs.value;
union { }
U16 raw;
SystemReg reg;
} ret;
ret.reg = reg;
return ret.raw; bool operator!=(const SystemRegister &rhs) const {
return !(rhs == *this);
} }
public: public:
U16 value;
SystemReg reg; SystemReg reg;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_A64_H
...@@ -18,7 +18,7 @@ namespace SandHook { ...@@ -18,7 +18,7 @@ namespace SandHook {
XRegister IP0 = X16; XRegister IP0 = X16;
XRegister IP1 = X17; XRegister IP1 = X17;
XRegister LR = X30; XRegister LR = X30;
//zero reg //zero reg_
XRegister XZR = X31; XRegister XZR = X31;
WRegister WZR = W31; WRegister WZR = W31;
RegisterA64 UnknowRegiser = RegisterA64(38); RegisterA64 UnknowRegiser = RegisterA64(38);
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_REGISTER_LIST_A64_H #pragma once
#define SANDHOOK_NH_REGISTER_LIST_A64_H
#include "register_arm64.h" #include "register_arm64.h"
#include "base.h" #include "base.h"
...@@ -34,7 +33,7 @@ namespace SandHook { ...@@ -34,7 +33,7 @@ namespace SandHook {
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;
...@@ -58,6 +57,4 @@ namespace SandHook { ...@@ -58,6 +57,4 @@ namespace SandHook {
} }
#define XReg(N) XRegister::get(N) #define XReg(N) XRegister::get(N)
#define WReg(N) WRegister::get(N) #define WReg(N) WRegister::get(N)
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_LIST_A64_H
...@@ -24,10 +24,10 @@ CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembl ...@@ -24,10 +24,10 @@ CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembl
assemblerA64 = &assembler; assemblerA64 = &assembler;
} }
bool CodeRelocateA64::visit(Unit<Base> *unit, void *pc) { bool CodeRelocateA64::Visit(Unit<Base> *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC()); relocate(reinterpret_cast<BaseInst *>(unit), __ GetPC());
curOffset += unit->size(); curOffset += unit->Size();
if (unit->refcount() == 0) { if (unit->RefCount() == 0) {
delete unit; delete unit;
} }
return true; return true;
...@@ -38,28 +38,28 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t ...@@ -38,28 +38,28 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t
startAddr = reinterpret_cast<Addr>(startPc); startAddr = reinterpret_cast<Addr>(startPc);
length = len; length = len;
curOffset = 0; curOffset = 0;
__ allocBufferFirst(static_cast<U32>(len * 8)); __ AllocBufferFirst(static_cast<U32>(len * 8));
void* curPc = __ getPC(); void* curPc = __ GetPC();
if (toPc == nullptr) { if (toPc == nullptr) {
Disassembler::get()->decode(startPc, len, *this, true); Disassembler::get()->Disassembler(startPc, len, *this, true);
} else { } else {
//TODO //TODO
} }
return curPc; return curPc;
} }
void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA64::relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = __ getPC(); void* curPc = __ GetPC();
//insert later bind labels //insert later AddBind labels
__ Emit(getLaterBindLabel(curOffset)); __ Emit(getLaterBindLabel(curOffset));
if (!instruction->pcRelate()) { if (!instruction->PcRelate()) {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
return curPc; return curPc;
} }
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(B_BL) CASE(B_BL)
CASE(B_COND) CASE(B_COND)
CASE(TBZ_TBNZ) CASE(TBZ_TBNZ)
...@@ -68,7 +68,7 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -68,7 +68,7 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro
CASE(ADR_ADRP) CASE(ADR_ADRP)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
return curPc; return curPc;
} }
...@@ -76,13 +76,13 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -76,13 +76,13 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro
IMPL_RELOCATE(B_BL) { IMPL_RELOCATE(B_BL) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (inRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(getLaterBindLabel(inst->offset + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
if (inst->op == inst->BL) { if (inst->op == inst->BL) {
Addr lr = reinterpret_cast<Addr>(toPc); Addr lr = reinterpret_cast<Addr>(toPc);
...@@ -98,13 +98,13 @@ IMPL_RELOCATE(B_BL) { ...@@ -98,13 +98,13 @@ IMPL_RELOCATE(B_BL) {
IMPL_RELOCATE(B_COND) { IMPL_RELOCATE(B_COND) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (inRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(getLaterBindLabel(inst->offset + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -122,13 +122,13 @@ IMPL_RELOCATE(B_COND) { ...@@ -122,13 +122,13 @@ IMPL_RELOCATE(B_COND) {
IMPL_RELOCATE(TBZ_TBNZ) { IMPL_RELOCATE(TBZ_TBNZ) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (inRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(getLaterBindLabel(inst->offset + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -150,13 +150,13 @@ IMPL_RELOCATE(TBZ_TBNZ) { ...@@ -150,13 +150,13 @@ IMPL_RELOCATE(TBZ_TBNZ) {
IMPL_RELOCATE(CBZ_CBNZ) { IMPL_RELOCATE(CBZ_CBNZ) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (inRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(getLaterBindLabel(inst->offset + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -177,14 +177,14 @@ IMPL_RELOCATE(CBZ_CBNZ) { ...@@ -177,14 +177,14 @@ IMPL_RELOCATE(CBZ_CBNZ) {
} }
IMPL_RELOCATE(LDR_LIT) { IMPL_RELOCATE(LDR_LIT) {
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->GetImmPCOffsetTarget();
XRegister* rtX = XReg(inst->rt->getCode()); XRegister* rtX = XReg(inst->rt->Code());
WRegister* rtW = WReg(inst->rt->getCode()); WRegister* rtW = WReg(inst->rt->Code());
if (inRelocateRange(inst->offset, sizeof(Addr))) { if (inRelocateRange(inst->offset, sizeof(Addr))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(getLaterBindLabel(inst->offset + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
...@@ -211,5 +211,5 @@ IMPL_RELOCATE(LDR_LIT) { ...@@ -211,5 +211,5 @@ IMPL_RELOCATE(LDR_LIT) {
} }
IMPL_RELOCATE(ADR_ADRP) { IMPL_RELOCATE(ADR_ADRP) {
__ Mov(*inst->rd, inst->getImmPCOffsetTarget()); __ Mov(*inst->rd, inst->GetImmPCOffsetTarget());
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_CODE_RELOCATE_A64_H #pragma once
#define SANDHOOK_NH_CODE_RELOCATE_A64_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -23,11 +22,11 @@ namespace SandHook { ...@@ -23,11 +22,11 @@ namespace SandHook {
public: public:
CodeRelocateA64(AssemblerA64 &assembler); CodeRelocateA64(AssemblerA64 &assembler);
void* relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override; void* relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) override;
void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override; void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override;
bool visit(Unit<Base> *unit, void *pc) override; bool Visit(Unit<Base> *unit, void *pc) override;
DEFINE_RELOCATE(B_BL) DEFINE_RELOCATE(B_BL)
...@@ -49,6 +48,4 @@ namespace SandHook { ...@@ -49,6 +48,4 @@ namespace SandHook {
} }
} }
#undef DEFINE_RELOCATE #undef DEFINE_RELOCATE
\ No newline at end of file
#endif //SANDHOOK_NH_CODE_RELOCATE_A64_H
...@@ -2,30 +2,29 @@ ...@@ -2,30 +2,29 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_ARM_BASE_H #pragma once
#define SANDHOOK_ARM_BASE_H
// Condition codes. // Condition codes.
enum Condition { enum Condition {
eq = 0, // Z set Equal. eq = 0, // Z Set Equal.
ne = 1, // Z clear Not equal. ne = 1, // Z clear Not equal.
cs = 2, // C set Carry set. cs = 2, // C Set Carry Set.
cc = 3, // C clear Carry clear. cc = 3, // C clear Carry clear.
mi = 4, // N set Negative. mi = 4, // N Set Negative.
pl = 5, // N clear Positive or zero. pl = 5, // N clear Positive or zero.
vs = 6, // V set Overflow. vs = 6, // V Set Overflow.
vc = 7, // V clear No overflow. vc = 7, // V clear No overflow.
hi = 8, // C set, Z clear Unsigned higher. hi = 8, // C Set, Z clear Unsigned higher.
ls = 9, // C clear or Z set Unsigned lower or same. ls = 9, // C clear or Z Set Unsigned lower or same.
ge = 10, // N == V Greater or equal. ge = 10, // N == V Greater or equal.
lt = 11, // N != V Less than. lt = 11, // N != V Less than.
gt = 12, // Z clear, N == V Greater than. gt = 12, // Z clear, N == V Greater than.
le = 13, // Z set or N != V Less then or equal le = 13, // Z Set or N != V Less then or equal
al = 14, // Always. al = 14, // Always.
nv = 15, // Behaves as always/al. nv = 15, // Behaves as always/al.
// Aliases. // Aliases.
hs = cs, // C set Unsigned higher or same. hs = cs, // C Set Unsigned higher or same.
lo = cc // C clear Unsigned lower. lo = cc // C clear Unsigned lower.
}; };
...@@ -42,31 +41,29 @@ enum Shift { ...@@ -42,31 +41,29 @@ enum Shift {
enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode}; enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode};
//decode field & encode field //Disassembler field & encode field
//condition //condition
#define DECODE_COND condition = Condition(inst->cond) #define DECODE_COND condition = Condition(Get()->cond)
#define ENCODE_COND get()->cond = condition #define ENCODE_COND Get()->cond = condition
//reg //reg_
#define DECODE_RD(Type) rd = Type(static_cast<U8>(get()->rd)) #define DECODE_RD(Type) rd = Type(static_cast<U8>(Get()->rd))
#define ENCODE_RD get()->rd = rd->getCode() #define ENCODE_RD Get()->rd = rd->Code()
#define DECODE_RT(Type) rt = Type(static_cast<U8>(get()->rt)) #define DECODE_RT(Type) rt = Type(static_cast<U8>(Get()->rt))
#define ENCODE_RT get()->rt = rt->getCode() #define ENCODE_RT Get()->rt = rt->Code()
#define DECODE_RM(Type) rm = Type(static_cast<U8>(get()->rm)) #define DECODE_RM(Type) rm = Type(static_cast<U8>(Get()->rm))
#define ENCODE_RM get()->rm = rm->getCode() #define ENCODE_RM Get()->rm = rm->Code()
#define DECODE_RN(Type) rn = Type(static_cast<U8>(get()->rn)) #define DECODE_RN(Type) rn = Type(static_cast<U8>(Get()->rn))
#define ENCODE_RN get()->rn = rn->getCode() #define ENCODE_RN Get()->rn = rn->Code()
//op //op
#define DECODE_OP op = OP(inst->op) #define DECODE_OP op = OP(Get()->op)
#define ENCODE_OP get()->op = op #define ENCODE_OP Get()->op = op
#define DECODE_SHIFT operand.shift = Shift(inst->shift) #define DECODE_SHIFT operand.shift_ = Shift(Get()->shift)
#define ENCODE_SHIFT get()->shift = operand.shift #define ENCODE_SHIFT Get()->shift = operand.shift_
\ No newline at end of file
#endif //SANDHOOK_ARM_BASE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/6/1. // Created by swift on 2019/6/1.
// //
#ifndef SANDHOOK_SHELL_CODE_ARM_H #pragma once
#define SANDHOOK_SHELL_CODE_ARM_H
//for shell code //for shell code
#define FUNCTION_START(x) \ #define FUNCTION_START(x) \
...@@ -29,6 +28,4 @@ extern "C" void x##_END(); ...@@ -29,6 +28,4 @@ extern "C" void x##_END();
#define IMPORT_LABEL(X,T) extern T X; #define IMPORT_LABEL(X,T) extern T X;
#define SHELLCODE_LEN(x) (Addr)x##_END - (Addr)x #define SHELLCODE_LEN(x) (Addr)x##_END - (Addr)x
\ No newline at end of file
#endif //SANDHOOK_SHELL_CODE_ARM_H
// //
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#pragma once
#ifndef SANDHOOK_PLACE_HOLDER_H
#define SANDHOOK_PLACE_HOLDER_H
#endif //SANDHOOK_PLACE_HOLDER_H
// //
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#pragma once
#ifndef SANDHOOK_CPU_H
#define SANDHOOK_CPU_H
#include "register.h" #include "register.h"
...@@ -17,4 +15,3 @@ namespace SandHook { ...@@ -17,4 +15,3 @@ namespace SandHook {
} }
} }
#endif //SANDHOOK_CPU_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_DATA_H #pragma once
#define SANDHOOK_NH_DATA_H
#include "unit.h" #include "unit.h"
...@@ -21,15 +20,22 @@ public: \ ...@@ -21,15 +20,22 @@ public: \
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename DType> template <typename D>
class Data : public Unit<DType> { class Data : public Unit<D> {
public: public:
Data(DType raw) : Unit<DType>() {
this->set(raw); Data(D raw) : backup_(raw) {}
}
inline UnitType unitType() override { INLINE UnitTypeDef UnitType() override {
return UnitType::UnitData; return UnitTypeDef::UnitData;
}; };
void Move(D *dest) override {
*dest = backup_;
}
private:
D backup_;
}; };
...@@ -52,6 +58,4 @@ namespace SandHook { ...@@ -52,6 +58,4 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_DATA_H
//
// Created by SwiftGan on 2019/4/15.
//
#ifndef SANDHOOK_IMME_H
#define SANDHOOK_IMME_H
#include "../includes/base.h"
namespace SandHook {
namespace Asm {
template <typename ImmeType>
class Imme {
public:
virtual ImmeType get() = 0;
virtual void set(ImmeType imme) = 0;
U8 size() {
return immeSize;
};
private:
//byte
U8 immeSize;
ImmeType value;
Arch arch;
InstType instType;
};
}
}
#endif //SANDHOOK_IMME_H
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_INSTRUCTION_H #pragma once
#define SANDHOOK_INSTRUCTION_H
#include <memory>
#include "unit.h" #include "unit.h"
#include "label.h" #include "label.h"
...@@ -23,84 +23,87 @@ typedef U32 InstRaw; ...@@ -23,84 +23,87 @@ typedef U32 InstRaw;
#define INST_CHECK(X,V) \ #define INST_CHECK(X,V) \
CHECK(X,V, valid = false;) CHECK(X,V, valid_ = false;)
#define INST_DCHECK(X,V) \ #define INST_DCHECK(X,V) \
DCHECK(X,V, valid = false;) DCHECK(X,V, valid_ = false;)
#define INST_ASSERT(COND) \ #define INST_ASSERT(COND) \
if (COND) { \ if (COND) { \
valid = false; \ valid_ = false; \
} }
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename Inst> template <typename S, U32 C>
class Instruction : public Unit<Inst>, public LabelBinder { class Instruction : public Unit<S>, public LabelBinder {
public: public:
Instruction() {} Instruction() {}
Instruction(Inst *inst) : Unit<Inst>(inst) {} Instruction(void *inst) : Unit<S>(inst) {}
Instruction(S *inst) : Unit<S>(inst) {}
UnitType unitType() override { UnitTypeDef UnitType() override {
return UnitType::UnitInst; return UnitTypeDef::UnitInst;
}; };
virtual InstType instType() { virtual InstType InstType() {
return unknowInst; return unknowInst;
} }
virtual Arch arch() { virtual Arch Arch() {
return unknowArch; return unknowArch;
} }
virtual U32 instCode() { virtual U32 InstCode() {
return 0; return C;
}; };
virtual bool pcRelate() { virtual bool PcRelate() {
return false; return false;
} }
virtual bool unknow() { virtual bool Unknow() {
return false; return false;
} }
inline bool isValid() const { inline bool Valid() const {
return valid; return valid_;
} }
virtual void onOffsetApply(Off offset) {} virtual void OnOffsetApply(Off offset) {}
void onLabelApply(Addr pc) override { void OnLabelApply(Addr pc) override {
onOffsetApply(pc - this->getVPC()); OnOffsetApply(pc - this->GetVPC());
} }
inline void bindLabel(Label &l) { INLINE void BindLabel(Label *label) {
label = &l; label_ = label;
l.addBinder(this); label->AddBind(this);
} }
virtual void decode(Inst* inst) { virtual void Disassembler() {
inst_backup = *inst; backup_ = *this->pc_;
} }
virtual void assembler() { virtual void Assembler() {
this->set(inst_backup); *this->pc_ = backup_;
} }
protected: protected:
bool valid = true; bool valid_ = true;
Label* label = nullptr; Label* label_ = nullptr;
Inst inst_backup; S backup_;
}; };
class Void : public Unit<Base> { class Void : public Unit<Base> {
public: public:
Void(U32 size) : size_(size) {} Void(U32 size) : size_(size) {}
U32 size() override { U32 Size() override {
return size_; return size_;
} }
...@@ -108,7 +111,8 @@ namespace SandHook { ...@@ -108,7 +111,8 @@ namespace SandHook {
U32 size_; U32 size_;
}; };
using BaseInst = Instruction<Base,0>;
using BaseInstRef = std::shared_ptr<BaseInst>;
} }
} }
#endif //SANDHOOK_INSTRUCTION_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_LABEL_H #pragma once
#define SANDHOOK_NH_LABEL_H
#include "unit.h" #include "unit.h"
#include <list> #include <list>
...@@ -13,53 +12,42 @@ namespace SandHook { ...@@ -13,53 +12,42 @@ namespace SandHook {
class LabelBinder { class LabelBinder {
public: public:
virtual void onLabelApply(Addr pc) = 0; virtual void OnLabelApply(Addr pc) = 0;
}; };
class Label : public Unit<Base> { class Label : public BaseUnit {
public: public:
Label() {} Label() {}
Label(void *pc) : pc(pc) {} Label(void *pc) : Unit<Base>(pc) {}
inline UnitType unitType() override { enum UnitTypeDef UnitType() override {
return UnitType::UnitLabel; return UnitTypeDef::UnitLabel;
} }
inline U32 size() override { INLINE U32 Size() override {
return 0; return 0;
} }
inline void setPC(void* pc) { INLINE void AddBind(LabelBinder *binder) {
this->pc = pc;
}
inline void *getPC() override {
return pc;
}
inline void addBinder(LabelBinder* binder) {
binders.push_back(binder); binders.push_back(binder);
} }
inline void removeBinder(LabelBinder* binder) { INLINE void RemoveBind(LabelBinder *binder) {
binders.push_back(binder); binders.push_back(binder);
} }
inline void bindLabel() { INLINE void BindLabel() {
std::list<LabelBinder*>::iterator binder; std::list<LabelBinder*>::iterator binder;
for(binder = binders.begin();binder != binders.end(); ++binder) { for(binder = binders.begin();binder != binders.end(); ++binder) {
(*binder)->onLabelApply(getVPC()); (*binder)->OnLabelApply(GetVPC());
} }
} }
private: private:
void* pc;
std::list<LabelBinder*> binders = std::list<LabelBinder*>(); std::list<LabelBinder*> binders = std::list<LabelBinder*>();
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_LABEL_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_MEMORY_H #pragma once
#define SANDHOOK_MEMORY_H
namespace SandHook { namespace SandHook {
namespace VM { namespace VM {
...@@ -12,5 +11,3 @@ namespace SandHook { ...@@ -12,5 +11,3 @@ namespace SandHook {
}; };
} }
} }
#endif //SANDHOOK_MEMORY_H
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_REGISTER_H #pragma once
#define SANDHOOK_REGISTER_H
#include "../includes/base.h" #include "base.h"
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
...@@ -23,61 +22,55 @@ namespace SandHook { ...@@ -23,61 +22,55 @@ namespace SandHook {
Register() {} Register() {}
Register(U8 code) : code(code) {} Register(U8 code) : code_(code) {}
inline U8 getCode() { inline U8 Code() {
return code; return code_;
} }
virtual bool isFP() { virtual bool IsFP() {
return false; return false;
}; };
virtual U8 getWide() { virtual U8 Wide() {
return 0; return 0;
}; };
inline U8 getWideInBytes() { INLINE U8 WideInBytes() {
return static_cast<U8>(getWide() / BITS_OF_BYTE); return static_cast<U8>(Wide() / BITS_OF_BYTE);
}; };
inline bool is32Bit() { INLINE bool is32Bit() {
return getWide() == Reg32Bit; return Wide() == Reg32Bit;
} }
inline bool is64Bit() { INLINE bool is64Bit() {
return getWide() == Reg64Bit; return Wide() == Reg64Bit;
} }
inline bool is128Bit() { INLINE bool is128Bit() {
return getWide() == Reg128Bit; return Wide() == Reg128Bit;
}
virtual bool is(const Register &rhs) {
return rhs.code == code;
} }
bool operator==(const Register &rhs) const { bool operator==(const Register &rhs) const {
return code == rhs.code; return code_ == rhs.code_;
} }
bool operator!=(const Register &rhs) const { bool operator!=(const Register &rhs) const {
return code != rhs.code; return code_ != rhs.code_;
} }
virtual void setData(Data data) { virtual void SetData(Data data) {
this->data = data; data_ = data;
} }
virtual Data& getData() { virtual Data& GetData() {
return data; return data_;
} }
private: private:
U8 code; U8 code_;
Data data; Data data_;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_REGISTER_H
...@@ -2,110 +2,86 @@ ...@@ -2,110 +2,86 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_UNIT_H #pragma once
#define SANDHOOK_NH_UNIT_H
#include <malloc.h> #include <malloc.h>
#include "../includes/base.h" #include <memory>
#include "base.h"
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename Raw> template <typename S>
class Unit { class Unit {
public: public:
Unit() { Unit() {}
if (unitType() != UnitVoid) {
raw = reinterpret_cast<Raw *>(malloc(size()));
memset(raw, 0, size());
auto_alloc = true;
}
}
Unit<Raw>(Raw *raw) : raw(raw) {} Unit<S>(S *pc) : pc_(pc) {}
Unit<Raw>(Raw raw) { Unit<S>(void *pc) : pc_(ForceCast<S*>(pc)) {}
Unit();
*this->raw = raw;
}
virtual void* getPC() { virtual void* GetPC() {
return auto_alloc ? nullptr : raw; return pc_;
} }
virtual Addr getVPC() { virtual Addr GetVPC() {
return vPos; return virtual_pc_;
} }
inline void setVPos(Addr vPos) { INLINE void SetVPC(Addr vPos) {
this->vPos = vPos; virtual_pc_ = vPos;
} }
inline Raw* get() const { INLINE S* Get() {
return raw; return pc_;
} }
inline void set(Raw raw) const { INLINE void Set(S raw) {
*this->raw = raw; *pc_ = raw;
} }
inline void set(Raw* raw) { INLINE void Set(S *raw) {
if (auto_alloc) { pc_ = raw;
free(this->raw);
auto_alloc = false;
}
this->raw = raw;
} }
inline void copy(void* dest) { INLINE void Copy(S *dest) {
memcpy(dest, getPC(), size()); *dest = *pc_;
} }
virtual void Move(S *dest) {
inline void move(Raw* dest) { *dest = *pc_;
memcpy(dest, raw, size()); pc_ = dest;
if (auto_alloc) {
free(raw);
auto_alloc = false;
}
raw = dest;
} }
virtual UnitType unitType() { virtual UnitTypeDef UnitType() {
return UnitType::UnitUnknow; return UnitTypeDef::UnitUnknow;
}; };
virtual U32 size() { virtual U32 Size() {
return sizeof(Raw); return sizeof(S);
} }
inline U8 ref() { INLINE U8 Ref() {
return ++ref_count; return ++ref_count_;
} }
inline U8 release() { INLINE U8 Release() {
return --ref_count; return --ref_count_;
} }
inline U8 refcount() { INLINE U8 RefCount() {
return ref_count; return ref_count_;
} }
virtual ~Unit() { protected:
if (auto_alloc) { S* pc_ = nullptr;
free(raw); Addr virtual_pc_ = 0;
} U8 ref_count_ = 0;
}
private:
Raw* raw = nullptr;
Addr vPos = 0;
bool auto_alloc = false;
U8 ref_count = 0;
}; };
using BaseUnit = Unit<Base>;
using BaseUnitRef = std::shared_ptr<BaseUnit>;
} }
} }
#endif //SANDHOOK_NH_UNIT_H
...@@ -16,13 +16,13 @@ void CodeContainer::setCodeBuffer(CodeBuffer *codeBuffer) { ...@@ -16,13 +16,13 @@ void CodeContainer::setCodeBuffer(CodeBuffer *codeBuffer) {
void CodeContainer::append(Unit<Base> *unit) { void CodeContainer::append(Unit<Base> *unit) {
units.push_back(unit); units.push_back(unit);
unit->setVPos(curPc); unit->SetVPC(curPc);
switch (unit->unitType()) { switch (unit->UnitType()) {
case UnitLabel: case UnitLabel:
labels.push_back((Label*)unit); labels.push_back((Label*)unit);
break; break;
default: default:
curPc += unit->size(); curPc += unit->Size();
} }
} }
...@@ -37,30 +37,30 @@ void CodeContainer::commit() { ...@@ -37,30 +37,30 @@ void CodeContainer::commit() {
} }
Addr pcNow = reinterpret_cast<Addr>(bufferStart); Addr pcNow = reinterpret_cast<Addr>(bufferStart);
//commit to code buffer & assembler inst //commit to code buffer & Assembler inst
std::list<Unit<Base>*>::iterator unit; std::list<BaseUnit*>::iterator unit;
for(unit = units.begin();unit != units.end(); ++unit) { for(unit = units.begin();unit != units.end(); ++unit) {
if ((*unit)->unitType() == UnitData) { if ((*unit)->UnitType() == UnitData) {
(*unit)->move(reinterpret_cast<Base *>(pcNow)); (*unit)->Move(reinterpret_cast<Base*>(pcNow));
} else if ((*unit)->unitType() != UnitLabel) { } else if ((*unit)->UnitType() != UnitLabel) {
(*unit)->set(reinterpret_cast<Base *>(pcNow)); (*unit)->Set(reinterpret_cast<Base*>(pcNow));
} }
if ((*unit)->unitType() == UnitInst) { if ((*unit)->UnitType() == UnitInst) {
reinterpret_cast<Instruction<Base>*>(*unit)->assembler(); reinterpret_cast<BaseInst*>(*unit)->Assembler();
} }
pcNow += (*unit)->size(); pcNow += (*unit)->Size();
} }
//bind labels //AddBind labels
std::list<Label*>::iterator label; std::list<Label*>::iterator label;
for(label = labels.begin();label != labels.end(); ++label) { for(label = labels.begin();label != labels.end(); ++label) {
(*label)->bindLabel(); (*label)->BindLabel();
} }
//flush I cache //flush I cache
flushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart)); flushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart));
//set pc //Set pc
startPc = reinterpret_cast<Addr>(bufferStart); startPc = reinterpret_cast<Addr>(bufferStart);
curPc = pcNow; curPc = pcNow;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_CODE_BUFFER_H #pragma once
#define SANDHOOK_NH_CODE_BUFFER_H
#include <mutex> #include <mutex>
#include "assembler.h" #include "assembler.h"
...@@ -48,5 +47,3 @@ namespace SandHook { ...@@ -48,5 +47,3 @@ namespace SandHook {
}; };
} }
} }
#endif //SANDHOOK_NH_CODE_BUFFER_H
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
bool DefaultVisitor::visit(Unit<Base> *unit, void *pc) { bool DefaultVisitor::Visit(Unit<Base> *unit, void *pc) {
bool res = visitor(unit, pc); bool res = visitor(unit, pc);
delete unit; delete unit;
return res; return res;
......
...@@ -9,11 +9,16 @@ ...@@ -9,11 +9,16 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <elf.h>
#include "log.h" #include "log.h"
using namespace SandHook::Elf; using namespace SandHook::Elf;
TextSegment::TextSegment(void *start, void *end) : start(start), end(end) {}
ElfImg::ElfImg(const char *elf) { ElfImg::ElfImg(const char *elf) {
this->elf = elf; this->elf = elf;
//load elf //load elf
...@@ -84,8 +89,8 @@ ElfImg::ElfImg(const char *elf) { ...@@ -84,8 +89,8 @@ ElfImg::ElfImg(const char *elf) {
LOGW("can't find symtab from sections\n"); LOGW("can't find symtab from sections\n");
} }
//load module base //load module rang
base = getModuleBase(elf); baseInRam = getModuleBase(elf);
} }
ElfImg::~ElfImg() { ElfImg::~ElfImg() {
...@@ -136,8 +141,8 @@ Elf_Addr ElfImg::getSymbOffset(const char *name) { ...@@ -136,8 +141,8 @@ Elf_Addr ElfImg::getSymbOffset(const char *name) {
Elf_Addr ElfImg::getSymbAddress(const char *name) { Elf_Addr ElfImg::getSymbAddress(const char *name) {
Elf_Addr offset = getSymbOffset(name); Elf_Addr offset = getSymbOffset(name);
if (offset > 0 && base != nullptr) { if (offset > 0 && baseInRam != nullptr) {
return static_cast<Elf_Addr>((size_t) base + offset - bias); return static_cast<Elf_Addr>((size_t) baseInRam + offset - bias);
} else { } else {
return 0; return 0;
} }
...@@ -167,7 +172,47 @@ void *ElfImg::getModuleBase(const char *name) { ...@@ -167,7 +172,47 @@ void *ElfImg::getModuleBase(const char *name) {
fclose(maps); fclose(maps);
LOGD("get module base %s: %lu", name, load_addr); LOGD("Get module baseInRam %s: %lu", name, load_addr);
return reinterpret_cast<void *>(load_addr); return reinterpret_cast<void *>(load_addr);
} }
bool isRXPerm(const char *perm) {
bool r = false, x = false;
for (int i = 0; i < 5; ++i) {
if (perm[i] == 'r') {
r = true;
}
if (perm[i] == 'x') {
x = true;
}
}
return r && x;
}
void ElfImg::searchMaps() {
FILE *f;
if ((f = fopen("/proc/self/maps", "r")) == NULL) {
return;
}
char buf[PATH_MAX], perm[12] = {'\0'}, dev[12] = {'\0'}, mapname[PATH_MAX] = {'\0'};
Addr begin, end, inode, foo;
while (!feof(f)) {
if (fgets(buf, sizeof(buf), f) == 0)
break;
mapname[0] = '\0';
sscanf(buf, "%lx-%lx %s %lx %s %ld %s", &begin, &end, perm,
&foo, dev, &inode, mapname);
if (strstr(buf, elf)) {
if (baseInRam == nullptr) {
baseInRam = reinterpret_cast<void *>(begin);
}
endInRam = reinterpret_cast<void *>(end);
if (isRXPerm(perm)) {
textSegments.emplace_back((void*)begin, (void*)end);
}
}
}
fclose(f);
}
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/7. // Created by swift on 2019/5/7.
// //
#ifndef SANDHOOK_NH_ASSEMBLER_H #pragma once
#define SANDHOOK_NH_ASSEMBLER_H
#include "label.h" #include "label.h"
#include "instruction.h" #include "instruction.h"
...@@ -41,7 +40,7 @@ namespace SandHook { ...@@ -41,7 +40,7 @@ namespace SandHook {
void setCodeBuffer(CodeBuffer *codeBuffer); void setCodeBuffer(CodeBuffer *codeBuffer);
//allow code relocate to get new pc first //allow code relocate to Get new pc first
void allocBufferFirst(U32 size); void allocBufferFirst(U32 size);
void append(Unit<Base>* unit); void append(Unit<Base>* unit);
void commit(); void commit();
...@@ -64,6 +63,4 @@ namespace SandHook { ...@@ -64,6 +63,4 @@ namespace SandHook {
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ASSEMBLER_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_BASE_H #pragma once
#define SANDHOOK_BASE_H
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
...@@ -22,6 +21,8 @@ typedef int64_t S64; ...@@ -22,6 +21,8 @@ typedef int64_t S64;
typedef size_t Addr; typedef size_t Addr;
using InstCode = U32;
//32bit //32bit
#if defined(__i386__) || defined(__arm__) #if defined(__i386__) || defined(__arm__)
typedef S32 Off; typedef S32 Off;
...@@ -30,8 +31,6 @@ typedef S32 Off; ...@@ -30,8 +31,6 @@ typedef S32 Off;
typedef S64 Off; typedef S64 Off;
#endif #endif
const int PTR_BYTE = sizeof(void*);
#define PAGE_OFFSET 12 #define PAGE_OFFSET 12
const int BITS_OF_BYTE = 8; const int BITS_OF_BYTE = 8;
...@@ -44,7 +43,7 @@ enum Arch { ...@@ -44,7 +43,7 @@ enum Arch {
unknowArch unknowArch
}; };
enum UnitType { enum UnitTypeDef {
UnitInst, UnitInst,
UnitData, UnitData,
UnitLabel, UnitLabel,
...@@ -79,12 +78,17 @@ struct Unsigned<64> { ...@@ -79,12 +78,17 @@ struct Unsigned<64> {
}; };
struct Base {}; struct Base {
};
#define INLINE __always_inline
template <typename T> template <typename T>
T AlignDown(T pointer, T AlignDown(T pointer,
typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type alignment) { typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type alignment) {
// Use C-style casts to get static_cast behaviour for integral types (T), and // Use C-style casts to Get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types. // 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_raw =
...@@ -181,26 +185,26 @@ INT_1_TO_32_LIST(DECLARE_TRUNCATE_TO_UINT_32) ...@@ -181,26 +185,26 @@ INT_1_TO_32_LIST(DECLARE_TRUNCATE_TO_UINT_32)
//位提取 //位提取
// Bit field extraction. // Bit field extraction.
inline uint64_t ExtractUnsignedBitfield64(int msb, int lsb, uint64_t x) { inline U64 ExtractUnsignedBitfield64(int msb, int lsb, U64 x) {
if ((msb == 63) && (lsb == 0)) return x; if ((msb == 63) && (lsb == 0)) return x;
return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1); return (x >> lsb) & ((static_cast<U64>(1) << (1 + msb - lsb)) - 1);
} }
inline int64_t ExtractSignedBitfield64(int msb, int lsb, U64 x) { inline S64 ExtractSignedBitfield64(int msb, int lsb, U64 x) {
uint64_t temp = ExtractUnsignedBitfield64(msb, lsb, x); U64 temp = ExtractUnsignedBitfield64(msb, lsb, x);
// If the highest extracted bit is set, sign extend. // If the highest extracted bit is Set, sign extend_.
if ((temp >> (msb - lsb)) == 1) { if ((temp >> (msb - lsb)) == 1) {
temp |= ~UINT64_C(0) << (msb - lsb); temp |= ~UINT64_C(0) << (msb - lsb);
} }
int64_t result; S64 result;
memcpy(&result, &temp, sizeof(result)); memcpy(&result, &temp, sizeof(result));
return result; return result;
} }
inline int32_t ExtractSignedBitfield32(int msb, int lsb, U32 x) { inline int32_t ExtractSignedBitfield32(int msb, int lsb, U32 x) {
uint32_t temp = TruncateToUint32(ExtractSignedBitfield64(msb, lsb, x)); U32 temp = TruncateToUint32(ExtractSignedBitfield64(msb, lsb, x));
int32_t result; S32 result;
memcpy(&result, &temp, sizeof(result)); memcpy(&result, &temp, sizeof(result));
return result; return result;
} }
...@@ -216,25 +220,17 @@ inline T SignExtend(T val, int bitSize) { ...@@ -216,25 +220,17 @@ inline T SignExtend(T val, int bitSize) {
} }
inline U16 BITS16L(U32 value) { #define BITS16L(value) static_cast<U16>(value & 0xffff)
return static_cast<U16>(value & 0xffff);
}
inline U16 BITS16H(U32 value) { #define BITS16H(value) static_cast<U16>(value >> 16)
return static_cast<U16>(value >> 16);
}
inline U32 BITS32L(U64 value) { #define BITS32L(value) static_cast<U32>(value)
return static_cast<U32>(value);
}
inline U32 BITS32H(U64 value) { #define BITS32H(value) static_cast<U32>(value >> 32)
return static_cast<U32>(value >> 32);
}
#define COMBINE(hi, lo, lowide) (hi << lowide) | lo #define COMBINE(hi, lo, lowide) (hi << lowide) | lo
/* borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h */ /* borrow from gdb, refer: binutils-gdb/gdb/Arch/arm.h */
#define SUB_MASK(x) ((1L << ((x) + 1)) - 1) #define SUB_MASK(x) ((1L << ((x) + 1)) - 1)
#define BITS(obj, st, fn) (((obj) >> (st)) & SUB_MASK((fn) - (st))) #define BITS(obj, st, fn) (((obj) >> (st)) & SUB_MASK((fn) - (st)))
#define BIT(obj, st) (((obj) >> (st)) & 1) #define BIT(obj, st) (((obj) >> (st)) & 1)
...@@ -254,4 +250,21 @@ if (X != V) { \ ...@@ -254,4 +250,21 @@ if (X != V) { \
#define ENUM_VALUE(Type, Value) static_cast<std::underlying_type<Type>::type>(Value) #define ENUM_VALUE(Type, Value) static_cast<std::underlying_type<Type>::type>(Value)
#endif //SANDHOOK_BASE_H static inline S64 SignExtend64(unsigned int bits, U64 value) {
return ExtractSignedBitfield64(bits - 1, 0, value);
}
static inline S32 SignExtend32(unsigned int bits, U32 value) {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
template<typename U, typename T>
U ForceCast(T *x) {
return (U) (uintptr_t) x;
}
template<typename U, typename T>
U ForceCast(T &x) {
return *(U *) &x;
}
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_CODE_RELOCATE_H #pragma once
#define SANDHOOK_NH_CODE_RELOCATE_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -23,7 +22,7 @@ namespace SandHook { ...@@ -23,7 +22,7 @@ namespace SandHook {
CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {} CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {}
virtual void* relocate(Instruction<Base> *instruction, void* toPc) throw(ErrorCodeException) = 0; virtual void* relocate(BaseInst *instruction, void* toPc) throw(ErrorCodeException) = 0;
virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0; virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0;
bool inRelocateRange(Off targetOffset, Addr targetLen); bool inRelocateRange(Off targetOffset, Addr targetLen);
...@@ -45,6 +44,4 @@ namespace SandHook { ...@@ -45,6 +44,4 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_CODE_RELOCATE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_COMPILER_H #pragma once
#define SANDHOOK_NH_COMPILER_H
// Helper to check whether the version of GCC used is greater than the specified // Helper to check whether the version of GCC used is greater than the specified
// requirement. // requirement.
...@@ -57,6 +56,4 @@ ...@@ -57,6 +56,4 @@
#define COMPILER_HAS_BUILTIN_POPCOUNT false #define COMPILER_HAS_BUILTIN_POPCOUNT false
// clang-format on // clang-format on
#endif #endif
\ No newline at end of file
#endif //SANDHOOK_NH_COMPILER_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_DECODER_H #pragma once
#define SANDHOOK_NH_DECODER_H
#include "base.h" #include "base.h"
#include "instruction.h" #include "instruction.h"
...@@ -16,7 +15,7 @@ namespace SandHook { ...@@ -16,7 +15,7 @@ namespace SandHook {
class InstVisitor { class InstVisitor {
public: public:
//need free unit //need free unit
virtual bool visit(Unit<Base>* unit, void* pc) { virtual bool Visit(Unit<Base> *unit, void *pc) {
delete unit; delete unit;
return false; return false;
}; };
...@@ -24,19 +23,20 @@ namespace SandHook { ...@@ -24,19 +23,20 @@ namespace SandHook {
class DefaultVisitor : public InstVisitor { class DefaultVisitor : public InstVisitor {
public: public:
DefaultVisitor(bool (*visitor)(Unit<Base> *, void *)); DefaultVisitor(bool (*visitor)(BaseUnit *, void *));
bool visit(Unit<Base> *unit, void *pc) override; bool Visit(BaseUnit *unit, void *pc) override;
private: private:
bool (*visitor)(Unit<Base>*, void*); bool (*visitor)(BaseUnit*, void*);
}; };
class InstDecoder { class InstDecoder {
public: public:
virtual void decode(void* codeStart, Addr codeLen, InstVisitor& visitor, bool onlyPcRelInst = false) = 0; virtual void Disassembler(void *codeStart, Addr codeLen, InstVisitor &visitor,
inline void decode(void* codeStart, Addr codeLen, bool (*visitor)(Unit<Base>*, void*), bool onlyPcRelInst = false) { bool onlyPcRelInst = false) = 0;
inline void Disassembler(void* codeStart, Addr codeLen, bool (*visitor)(Unit<Base>*, void*), bool onlyPcRelInst = false) {
InstVisitor vis = DefaultVisitor(visitor); InstVisitor vis = DefaultVisitor(visitor);
decode(codeStart, codeLen, vis, onlyPcRelInst); Disassembler(codeStart, codeLen, vis, onlyPcRelInst);
}; };
}; };
...@@ -48,5 +48,3 @@ namespace SandHook { ...@@ -48,5 +48,3 @@ namespace SandHook {
}; };
} }
} }
#endif //SANDHOOK_NH_DECODER_H
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_ELF_H #pragma once
#define SANDHOOK_NH_ELF_H
#include <linux/elf.h> #include <linux/elf.h>
#include <list>
#include "base.h" #include "base.h"
#if defined(__LP64__) #if defined(__LP64__)
...@@ -32,6 +32,13 @@ typedef Elf32_Off Elf_Off; ...@@ -32,6 +32,13 @@ typedef Elf32_Off Elf_Off;
namespace SandHook { namespace SandHook {
namespace Elf { namespace Elf {
struct TextSegment {
TextSegment(void *start, void *end);
void* start;
void* end;
};
class ElfImg { class ElfImg {
public: public:
...@@ -45,9 +52,14 @@ namespace SandHook { ...@@ -45,9 +52,14 @@ namespace SandHook {
~ElfImg(); ~ElfImg();
private:
void searchMaps();
private: private:
const char* elf = nullptr; const char* elf = nullptr;
void* base = nullptr; void* baseInRam = nullptr;
void* endInRam = nullptr;
std::list<TextSegment> textSegments = std::list<TextSegment>();
char* buffer = nullptr; char* buffer = nullptr;
off_t size = 0; off_t size = 0;
off_t bias = -4396; off_t bias = -4396;
...@@ -69,6 +81,4 @@ namespace SandHook { ...@@ -69,6 +81,4 @@ namespace SandHook {
Elf_Off dynsym_size = 0; Elf_Off dynsym_size = 0;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ELF_H
...@@ -20,12 +20,13 @@ namespace SandHook { ...@@ -20,12 +20,13 @@ namespace SandHook {
class InlineHook { class InlineHook {
public: public:
//return == backup method //return == backup method
virtual void* inlineHook(void* origin, void* replace) = 0; virtual void *Hook(void *origin, void *replace) = 0;
virtual bool breakPoint(void* point, void (*callback)(REG[])) { virtual bool BreakPoint(void *point, void (*callback)(REG[])) {
return false; return false;
}; };
protected: protected:
static CodeBuffer* backupBuffer; static CodeBuffer* backupBuffer;
std::mutex hookLock;
public: public:
static InlineHook* instance; static InlineHook* instance;
}; };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace SandHook::Asm; using namespace SandHook::Asm;
//in range of copy //in range of Copy
bool CodeRelocate::inRelocateRange(Off targetOffset, Addr targetLen) { bool CodeRelocate::inRelocateRange(Off targetOffset, Addr targetLen) {
Off startP = curOffset + targetOffset; Off startP = curOffset + targetOffset;
Off endP = startP + targetLen; Off endP = startP + targetLen;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// //
#include <jni.h> #include <jni.h>
#include <sys/mman.h>
#include <log.h>
#include "sandhook_native.h" #include "sandhook_native.h"
#include "hook.h" #include "hook.h"
#include "elf.h" #include "elf.h"
...@@ -10,6 +12,138 @@ ...@@ -10,6 +12,138 @@
using namespace SandHook::Hook; using namespace SandHook::Hook;
using namespace SandHook::Elf; using namespace SandHook::Elf;
int m1 = 5;
int m3 = 1036;
int m2 = 1035;
int m4 = 5;
void (*dosth3Backup)(int, int) = nullptr;
void (*dosth4Backup)() = nullptr;
void (*dosth4Backup2)() = nullptr;
void (*innerSuspendVM)() = nullptr;
static void (*heapPreForkBackup)(void *) = nullptr;
static void myHeapPreFork(void *heap) {
heapPreForkBackup(heap);
}
void SuspendVMReplace() {
LOGE("VM Suspend!");
innerSuspendVM();
}
void do2() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
}
void do3(int x, int y) {
do2();
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = a + b + c;
LOGE("do3 = %d", y);
}
void do5() {
LOGE("x = %d", 5);
}
void do4() {
int a = 1 + 1;
int b = a + 1;
int d = a + 1;
int e = a + 1;
LOGE("x = %d", 7);
}
void do4replace() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth4Backup();
}
void do4replace2() {
int a = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth4Backup2();
}
void do3replace(int x, int y) {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth3Backup(x, y);
}
void do1() {
do2();
}
void breakCallback(REG regs[]) {
LOGE("breakCallback = %d SP = %d", regs[0], regs);
}
class Visitor : public InstVisitor {
bool Visit(Unit<Base> *unit, void *pc) override {
BaseInst* instruction = reinterpret_cast<BaseInst *>(unit);
instruction->Assembler();
return true;
}
};
extern "C"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) {
dosth4Backup = reinterpret_cast<void (*)()>(InlineHook::instance->Hook(
reinterpret_cast<void *>(do4),
reinterpret_cast<void *>(do4replace)));
dosth4Backup2 = reinterpret_cast<void (*)()>(InlineHook::instance->Hook(
reinterpret_cast<void *>(do4),
reinterpret_cast<void *>(do4replace2)));
do4();
if (sizeof(void*) == 8) {
heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
reinterpret_cast<void *>(myHeapPreFork)));
innerSuspendVM = reinterpret_cast<void (*)()>(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art3Dbg9SuspendVMEv",
reinterpret_cast<void *>(SuspendVMReplace)));
} else {
heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandInlineHookSym("/system/lib/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
reinterpret_cast<void *>(myHeapPreFork)));
innerSuspendVM = reinterpret_cast<void (*)()>(SandInlineHookSym("/system/lib/libart.so", "_ZN3art3Dbg9SuspendVMEv",
reinterpret_cast<void *>(SuspendVMReplace)));
}
void* do3P = reinterpret_cast<void *>(do3);
InlineHook::instance->BreakPoint(reinterpret_cast<void *>((Addr)do3), breakCallback);
LOGE("ok");
do3(100, 2);
}
extern "C" extern "C"
EXPORT void* SandGetSym(const char* so, const char* symb) { EXPORT void* SandGetSym(const char* so, const char* symb) {
...@@ -19,7 +153,7 @@ EXPORT void* SandGetSym(const char* so, const char* symb) { ...@@ -19,7 +153,7 @@ EXPORT void* SandGetSym(const char* so, const char* symb) {
extern "C" extern "C"
EXPORT void* SandInlineHook(void* origin, void* replace) { EXPORT void* SandInlineHook(void* origin, void* replace) {
return InlineHook::instance->inlineHook(origin, replace); return InlineHook::instance->Hook(origin, replace);
} }
extern "C" extern "C"
...@@ -29,10 +163,10 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace) ...@@ -29,10 +163,10 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace)
if (origin == nullptr) if (origin == nullptr)
return nullptr; return nullptr;
return InlineHook::instance->inlineHook(origin, replace); return InlineHook::instance->Hook(origin, replace);
} }
extern "C" extern "C"
EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])) { EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])) {
return InlineHook::instance->breakPoint(origin, callback); return InlineHook::instance->BreakPoint(origin, callback);
} }
\ No newline at end of file
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_SANDHOOK_NATIVE_H #pragma once
#define SANDHOOK_SANDHOOK_NATIVE_H
typedef size_t REG; typedef size_t REG;
...@@ -19,6 +18,4 @@ extern "C" ...@@ -19,6 +18,4 @@ extern "C"
EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace); EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace);
extern "C" extern "C"
EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])); EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[]));
\ No newline at end of file
#endif //SANDHOOK_SANDHOOK_NATIVE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_LOCK_H #pragma once
#define SANDHOOK_NH_LOCK_H
#include <mutex> #include <mutex>
...@@ -21,6 +20,4 @@ namespace SandHook { ...@@ -21,6 +20,4 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_LOCK_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/2/15. // Created by SwiftGan on 2019/2/15.
// //
#ifndef SANDHOOK_LOG_H #pragma once
#define SANDHOOK_LOG_H
#include "android/log.h" #include "android/log.h"
...@@ -11,6 +10,4 @@ ...@@ -11,6 +10,4 @@
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
\ No newline at end of file
#endif //SANDHOOK_LOG_H
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_PLATFORM_H #pragma once
#define SANDHOOK_NH_PLATFORM_H
#include "base.h" #include "base.h"
extern "C" bool flushCache(Addr addr, Off len); extern "C" bool flushCache(Addr addr, Off len);
extern "C" bool memUnprotect(Addr addr, Addr len); extern "C" bool memUnprotect(Addr addr, Addr len);
\ No newline at end of file
#endif //SANDHOOK_NH_PLATFORM_H
include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook', ':xposedcompat_new' include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook'
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