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

[Reconstitution]init

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