Unverified Commit 14dae38a authored by ganyao114's avatar ganyao114 Committed by GitHub

Merge pull request #22 from ganyao114/rewrite_native_hook

Rewrite native hook
parents 1306c792 f9a5dd10
...@@ -27,7 +27,7 @@ dependencies { ...@@ -27,7 +27,7 @@ dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':hooklib') implementation project(':hooklib')
//implementation project(':nativehook') implementation project(':nativehook')
implementation project(':xposedcompat') implementation project(':xposedcompat')
//implementation project(':xposedcompat_new') //implementation project(':xposedcompat_new')
} }
...@@ -5,6 +5,7 @@ import android.app.Application; ...@@ -5,6 +5,7 @@ import android.app.Application;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import com.swift.sandhook.nativehook.NativeHook;
import com.swift.sandhook.test.TestClass; import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.testHookers.ActivityHooker; import com.swift.sandhook.testHookers.ActivityHooker;
import com.swift.sandhook.testHookers.CtrHook; import com.swift.sandhook.testHookers.CtrHook;
...@@ -22,7 +23,7 @@ import de.robv.android.xposed.XposedHelpers; ...@@ -22,7 +23,7 @@ import de.robv.android.xposed.XposedHelpers;
public class MyApp extends Application { public class MyApp extends Application {
//if you want test Android Q, please set true, because SDK_INT of Android Q is still 28 //if you want test Android Q, please Set true, because SDK_INT of Android Q is still 28
public final static boolean testAndroidQ = false; public final static boolean testAndroidQ = false;
@Override @Override
......
...@@ -1330,7 +1330,7 @@ JitCompile->CommitCode->CommitCodeInternal ...@@ -1330,7 +1330,7 @@ JitCompile->CommitCode->CommitCodeInternal
- 并且在跳转的时候要注意入口地址符合要求 - 并且在跳转的时候要注意入口地址符合要求
```cpp ```cpp
bool isThumbCode(Size codeAddr) { bool IsThumbCode(Size codeAddr) {
return (codeAddr & 0x1) == 0x1; return (codeAddr & 0x1) == 0x1;
} }
``` ```
......
...@@ -71,6 +71,7 @@ include_directories( ...@@ -71,6 +71,7 @@ include_directories(
src/main/cpp/archs/arm/arm32/decoder src/main/cpp/archs/arm/arm32/decoder
src/main/cpp/archs/arm/arm32/hook src/main/cpp/archs/arm/arm32/hook
src/main/cpp/archs/arm/arm32/relocate src/main/cpp/archs/arm/arm32/relocate
src/main/cpp/antihook
) )
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a
......
...@@ -10,44 +10,44 @@ using namespace SandHook::RegistersA32; ...@@ -10,44 +10,44 @@ using namespace SandHook::RegistersA32;
using namespace SandHook::AsmA32; using namespace SandHook::AsmA32;
AssemblerA32::AssemblerA32(CodeBuffer* codeBuffer) { AssemblerA32::AssemblerA32(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer); code_container.SetCodeBuffer(codeBuffer);
} }
void *AssemblerA32::getPC() { void *AssemblerA32::GetPC() {
return reinterpret_cast<void *>(codeContainer.curPc); return reinterpret_cast<void *>(code_container.cur_pc);
} }
void *AssemblerA32::getStartPC() { void *AssemblerA32::GetStartPC() {
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(code_container.start_pc);
} }
void AssemblerA32::allocBufferFirst(U32 size) { void AssemblerA32::AllocBufferFirst(U32 size) {
codeContainer.allocBufferFirst(size); code_container.AllocBufferFirst(size);
} }
void *AssemblerA32::finish() { void *AssemblerA32::Finish() {
codeContainer.commit(); code_container.Commit();
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(code_container.start_pc);
} }
void AssemblerA32::Emit(U32 data32) { void AssemblerA32::Emit(U32 data32) {
Emit(reinterpret_cast<Unit<Base>*>(new Data32(data32))); Emit(reinterpret_cast<BaseUnit*>(new Data32(data32)));
} }
void AssemblerA32::Emit(U16 data16) { void AssemblerA32::Emit(U16 data16) {
Emit(reinterpret_cast<Unit<Base>*>(new Data16(data16))); Emit(reinterpret_cast<BaseUnit*>(new Data16(data16)));
} }
void AssemblerA32::Emit(Unit<Base> *unit) { void AssemblerA32::Emit(BaseUnit *unit) {
codeContainer.append(unit); code_container.Append(unit);
} }
void AssemblerA32::Mov(RegisterA32 &rd, U16 imm16) { void AssemblerA32::Mov(RegisterA32 &rd, U16 imm16) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(MOV_MOVT_IMM)(INST_T32(MOV_MOVT_IMM)::MOV, rd, imm16))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(MOV_MOVT_IMM)(INST_T32(MOV_MOVT_IMM)::MOV, rd, imm16)));
} }
void AssemblerA32::Movt(RegisterA32 &rd, U16 imm16) { void AssemblerA32::Movt(RegisterA32 &rd, U16 imm16) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(MOV_MOVT_IMM)(INST_T32(MOV_MOVT_IMM)::MOVT, rd, imm16))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(MOV_MOVT_IMM)(INST_T32(MOV_MOVT_IMM)::MOVT, rd, imm16)));
} }
void AssemblerA32::Mov(RegisterA32 &rd, U32 imm32) { void AssemblerA32::Mov(RegisterA32 &rd, U32 imm32) {
...@@ -58,119 +58,119 @@ void AssemblerA32::Mov(RegisterA32 &rd, U32 imm32) { ...@@ -58,119 +58,119 @@ void AssemblerA32::Mov(RegisterA32 &rd, U32 imm32) {
} }
void AssemblerA32::Ldr(RegisterA32 &rt, Off offset) { void AssemblerA32::Ldr(RegisterA32 &rt, Off offset) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDR, INST_T32(LDR_LIT)::UnSign, rt, offset))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDR, INST_T32(LDR_LIT)::UnSign, rt, offset)));
} }
void AssemblerA32::Ldr(RegisterA32 &rt, Label *label) { void AssemblerA32::Ldr(RegisterA32 &rt, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDR, INST_T32(LDR_LIT)::UnSign, rt, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDR, INST_T32(LDR_LIT)::UnSign, rt, label)));
} }
void AssemblerA32::Ldrb(RegisterA32 &rt, Label *label) { void AssemblerA32::Ldrb(RegisterA32 &rt, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRB, INST_T32(LDR_LIT)::UnSign,rt, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRB, INST_T32(LDR_LIT)::UnSign,rt, label)));
} }
void AssemblerA32::Ldrh(RegisterA32 &rt, Label *label) { void AssemblerA32::Ldrh(RegisterA32 &rt, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRH, INST_T32(LDR_LIT)::UnSign,rt, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRH, INST_T32(LDR_LIT)::UnSign,rt, label)));
} }
void AssemblerA32::Ldrsb(RegisterA32 &rt, Label *label) { void AssemblerA32::Ldrsb(RegisterA32 &rt, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRB, INST_T32(LDR_LIT)::Sign,rt, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRB, INST_T32(LDR_LIT)::Sign,rt, label)));
} }
void AssemblerA32::Ldrsh(RegisterA32 &rt, Label *label) { void AssemblerA32::Ldrsh(RegisterA32 &rt, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRH, INST_T32(LDR_LIT)::Sign,rt, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_LIT)(INST_T32(LDR_LIT)::LDRH, INST_T32(LDR_LIT)::Sign,rt, label)));
} }
void AssemblerA32::Ldr(RegisterA32 &rt, const MemOperand &operand) { void AssemblerA32::Ldr(RegisterA32 &rt, const MemOperand &operand) {
if (operand.addr_mode == Offset && operand.offset >= 0) { if (operand.addr_mode == Offset && operand.offset >= 0) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_UIMM)(rt, *operand.rn, operand.addr_mode))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_UIMM)(rt, *operand.rn, operand.addr_mode)));
} else { } else {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDR, rt, operand))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDR, rt, operand)));
} }
} }
void AssemblerA32::Ldrb(RegisterA32 &rt, const MemOperand &operand) { void AssemblerA32::Ldrb(RegisterA32 &rt, const MemOperand &operand) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRB, rt, operand))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRB, rt, operand)));
} }
void AssemblerA32::Ldrh(RegisterA32 &rt, const MemOperand &operand) { void AssemblerA32::Ldrh(RegisterA32 &rt, const MemOperand &operand) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRH, rt, operand))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRH, rt, operand)));
} }
void AssemblerA32::Ldrsb(RegisterA32 &rt, const MemOperand &operand) { void AssemblerA32::Ldrsb(RegisterA32 &rt, const MemOperand &operand) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRSB, rt, operand))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRSB, rt, operand)));
} }
void AssemblerA32::Ldrsh(RegisterA32 &rt, const MemOperand &operand) { void AssemblerA32::Ldrsh(RegisterA32 &rt, const MemOperand &operand) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRSH, rt, operand))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(LDR_IMM)(INST_T32(LDR_IMM)::LDRSH, rt, operand)));
} }
void AssemblerA32::B(Label *label) { void AssemblerA32::B(Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(B)(*label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(B)(label)));
} }
void AssemblerA32::Bl(Label *label) { void AssemblerA32::Bl(Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(B32)(INST_T32(B32)::BL, INST_T32(B32)::arm, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(B32)(INST_T32(B32)::BL, INST_T32(B32)::arm, label)));
} }
void AssemblerA32::Blx(Label *label) { void AssemblerA32::Blx(Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(B32)(INST_T32(B32)::BL, INST_T32(B32)::thumb, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(B32)(INST_T32(B32)::BL, INST_T32(B32)::thumb, label)));
} }
void AssemblerA32::Bx(Label *label) { void AssemblerA32::Bx(Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T32(B32)(INST_T32(B32)::B, INST_T32(B32)::thumb, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T32(B32)(INST_T32(B32)::B, INST_T32(B32)::thumb, label)));
} }
void AssemblerA32::Mov(RegisterA32 &rd, RegisterA32 &rm) { void AssemblerA32::Mov(RegisterA32 &rd, RegisterA32 &rm) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(MOV_REG)(rd, rm))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(MOV_REG)(rd, rm)));
} }
void AssemblerA32::Bx(RegisterA32 &rm) { void AssemblerA32::Bx(RegisterA32 &rm) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(BX_BLX)(INST_T16(BX_BLX)::BX, rm))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(BX_BLX)(INST_T16(BX_BLX)::BX, rm)));
} }
void AssemblerA32::Blx(RegisterA32 &rm) { void AssemblerA32::Blx(RegisterA32 &rm) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(BX_BLX)(INST_T16(BX_BLX)::BLX, rm))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(BX_BLX)(INST_T16(BX_BLX)::BLX, rm)));
} }
void AssemblerA32::B(Condition condition, Label* label) { void AssemblerA32::B(Condition condition, Label* label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(B_COND)(condition, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(B_COND)(condition, label)));
} }
void AssemblerA32::Add(RegisterA32 &rdn, U8 imm8) { void AssemblerA32::Add(RegisterA32 &rdn, U8 imm8) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(ADD_IMM_RDN)(&rdn, imm8))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(ADD_IMM_RDN)(&rdn, imm8)));
} }
void AssemblerA32::Add(RegisterA32 &rd, RegisterA32 &rn, RegisterA32 &rm) { void AssemblerA32::Add(RegisterA32 &rd, RegisterA32 &rn, RegisterA32 &rm) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(ADD_REG)(&rd, &rn, &rm))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(ADD_REG)(&rd, &rn, &rm)));
} }
void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) { void AssemblerA32::Cmp(RegisterA32 &rd, RegisterA32 &rn) {
if (rd.getCode() < 8 && rn.getCode() < 8) { if (rd.Code() < 8 && rn.Code() < 8) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG)(rd, rn))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(CMP_REG)(rd, rn)));
} else { } else {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(CMP_REG_EXT)(rd, rn))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(CMP_REG_EXT)(rd, rn)));
} }
} }
void AssemblerA32::Pop(RegisterA32 &rt) { void AssemblerA32::Pop(RegisterA32 &rt) {
if (rt.getCode() < 8 || rt == PC) { if (rt.Code() < 8 || rt == PC) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(POP)(RegisterList(rt)))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(POP)(RegisterList(rt))));
} else { } else {
throw ErrorCodeException("error pop inst"); throw ErrorCodeException("error pop inst");
} }
} }
void AssemblerA32::Push(RegisterA32 &rt) { void AssemblerA32::Push(RegisterA32 &rt) {
if (rt.getCode() < 8 || rt == PC) { if (rt.Code() < 8 || rt == PC) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(PUSH)(RegisterList(rt)))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(PUSH)(RegisterList(rt))));
} else { } else {
throw ErrorCodeException("error pop inst"); throw ErrorCodeException("error pop inst");
} }
} }
void AssemblerA32::Adr(RegisterA32 &rd, Label *label) { void AssemblerA32::Adr(RegisterA32 &rd, Label *label) {
Emit(reinterpret_cast<Unit<Base>*>(new INST_T16(ADR)(rd, *label))); Emit(reinterpret_cast<BaseUnit*>(new INST_T16(ADR)(rd, label)));
} }
void AssemblerA32::Nop16() { void AssemblerA32::Nop16() {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "inst_t32.h" #include "inst_t32.h"
#define ALIGN_FOR_LDR \ #define ALIGN_FOR_LDR \
if ((Addr) __ getPC() % 4 != 0) { \ if ((Addr) __ GetPC() % 4 != 0) { \
__ Nop16(); \ __ Nop16(); \
} }
...@@ -24,14 +24,14 @@ namespace SandHook { ...@@ -24,14 +24,14 @@ namespace SandHook {
public: public:
AssemblerA32(CodeBuffer* codeBuffer); AssemblerA32(CodeBuffer* codeBuffer);
void allocBufferFirst(U32 size); void AllocBufferFirst(U32 size);
void* getStartPC(); void* GetStartPC();
void* getPC(); void* GetPC();
void* finish(); void* Finish();
void Emit(U32 data32); void Emit(U32 data32);
void Emit(U16 data16); void Emit(U16 data16);
void Emit(Unit<Base>* unit); void Emit(BaseUnit* unit);
void Mov(RegisterA32 &rd, U16 imm16); void Mov(RegisterA32 &rd, U16 imm16);
...@@ -78,7 +78,7 @@ namespace SandHook { ...@@ -78,7 +78,7 @@ namespace SandHook {
void Nop16(); void Nop16();
public: public:
CodeContainer codeContainer = CodeContainer(nullptr); CodeContainer code_container = CodeContainer(nullptr);
}; };
} }
} }
......
...@@ -11,8 +11,7 @@ using namespace SandHook::AsmA32; ...@@ -11,8 +11,7 @@ using namespace SandHook::AsmA32;
#define CASE(T, X) \ #define CASE(T, X) \
if (IS_OPCODE_##T(*reinterpret_cast<Inst##T *>(pc), X)) { \ if (IS_OPCODE_##T(*reinterpret_cast<Inst##T *>(pc), X)) { \
STRUCT_##T(X) *s = reinterpret_cast<STRUCT_##T(X) *>(pc); \ unit = reinterpret_cast<BaseUnit*>(new INST_##T(X)(pc)); \
unit = reinterpret_cast<Unit<Base> *>(new INST_##T(X)(s)); \
goto label_matched; \ goto label_matched; \
} }
...@@ -23,16 +22,17 @@ goto label_matched; \ ...@@ -23,16 +22,17 @@ goto label_matched; \
Arm32Decoder* Arm32Decoder::instant = new Arm32Decoder(); Arm32Decoder* Arm32Decoder::instant = new Arm32Decoder();
void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) { void Arm32Decoder::Disassemble(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool thumb = isThumbCode(reinterpret_cast<Addr>(codeStart)); bool onlyPcRelInst) {
bool thumb = IsThumbCode(reinterpret_cast<Addr>(codeStart));
if (thumb) { if (thumb) {
codeStart = getThumbCodeAddress(codeStart); codeStart = GetThumbCodeAddress(codeStart);
} }
void *pc = codeStart; void *pc = codeStart;
Addr endAddr = (Addr) codeStart + codeLen; Addr endAddr = (Addr) codeStart + codeLen;
Unit<Base>* unit = nullptr; BaseUnit *unit = nullptr;
while((Addr) pc < endAddr) { while((Addr) pc < endAddr) {
bool thumb32 = isThumb32(*reinterpret_cast<InstT16*>(pc)); bool thumb32 = IsThumb32(*reinterpret_cast<InstT16*>(pc));
if (thumb && thumb32) { if (thumb && thumb32) {
CASE_T32(SUB_IMM) CASE_T32(SUB_IMM)
CASE_T32(B32) CASE_T32(B32)
...@@ -43,7 +43,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b ...@@ -43,7 +43,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
CASE_T32(MOV_MOVT_IMM) CASE_T32(MOV_MOVT_IMM)
} }
if (unit == nullptr) { if (unit == nullptr) {
unit = reinterpret_cast<Unit<Base> *>(new INST_T32(UNKNOW)(*reinterpret_cast<STRUCT_T32(UNKNOW) *>(pc))); unit = reinterpret_cast<BaseUnit*>(new INST_T32(UNKNOW)(pc));
} }
} else if (thumb) { } else if (thumb) {
CASE_T16(B) CASE_T16(B)
...@@ -63,18 +63,19 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b ...@@ -63,18 +63,19 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
CASE_T16(PUSH) CASE_T16(PUSH)
} }
if (unit == nullptr) { if (unit == nullptr) {
unit = reinterpret_cast<Unit<Base> *>(new INST_T16(UNKNOW)(*reinterpret_cast<STRUCT_T16(UNKNOW) *>(pc))); unit = reinterpret_cast<BaseUnit*>(new INST_T16(UNKNOW)(pc));
} }
} else { } else {
//TODO arm32 support //TODO arm32 support
unit = reinterpret_cast<Unit<Base> *>(new INST_T32(UNKNOW)(*reinterpret_cast<STRUCT_T32(UNKNOW) *>(pc))); unit = reinterpret_cast<BaseUnit*>(new INST_T32(UNKNOW)(pc));
} }
label_matched: label_matched:
if (!visitor.visit(unit, pc)) { reinterpret_cast<BaseInst*>(unit)->Disassemble();
if (!visitor.Visit(unit, pc)) {
break; break;
} }
pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->size()); pc = reinterpret_cast<void*>((Addr)pc + unit->Size());
unit = nullptr; unit = nullptr;
} }
} }
......
...@@ -12,7 +12,8 @@ namespace SandHook { ...@@ -12,7 +12,8 @@ namespace SandHook {
class Arm32Decoder : public InstDecoder { class Arm32Decoder : public InstDecoder {
public: public:
void decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) override; void Disassemble(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) override;
public: public:
static Arm32Decoder* instant; static Arm32Decoder* instant;
}; };
......
...@@ -17,29 +17,29 @@ using namespace SandHook::Utils; ...@@ -17,29 +17,29 @@ using namespace SandHook::Utils;
#include "assembler_arm32.h" #include "assembler_arm32.h"
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { void *InlineHookArm32Android::Hook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* originCode; void* origin_code;
if (isThumbCode((Addr)origin)) { if (IsThumbCode((Addr) origin)) {
originCode = getThumbCodeAddress(origin); origin_code = GetThumbCodeAddress(origin);
} else { } else {
LOGE("hook %d error!, only support thumb2 now!", origin); LOGE("hook %d error!, only support thumb2 now!", origin);
return nullptr; return nullptr;
} }
bool changeMode = isThumbCode((Addr) origin) != isThumbCode((Addr) replace); bool change_mode = IsThumbCode((Addr) origin) != IsThumbCode((Addr) replace);
void* backup = nullptr; void* backup = nullptr;
AssemblerA32 assemblerBackup(backupBuffer); AssemblerA32 assembler_backup(backup_buffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(originCode)); StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin_code));
AssemblerA32 assemblerInline(&inlineBuffer); AssemblerA32 assembler_inline(&inline_buffer);
CodeContainer* codeContainerInline = &assemblerInline.codeContainer; CodeContainer* code_container_inline = &assembler_inline.code_container;
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assembler_inline.
if (!changeMode) { if (!change_mode) {
Label *target_addr_label = new Label(); Label *target_addr_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_addr_label); __ Ldr(PC, target_addr_label);
...@@ -53,65 +53,65 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { ...@@ -53,65 +53,65 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) {
#undef __ #undef __
//build backup method //build backup method
CodeRelocateA32 relocate = CodeRelocateA32(assemblerBackup); CodeRelocateA32 relocate = CodeRelocateA32(assembler_backup);
backup = relocate.relocate(origin, codeContainerInline->size(), nullptr); backup = relocate.Relocate(origin, code_container_inline->Size(), nullptr);
#define __ assemblerBackup. #define __ assembler_backup.
Label* origin_addr_label = new Label(); Label* origin_addr_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, origin_addr_label); __ Ldr(PC, origin_addr_label);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(reinterpret_cast<Addr>(originCode) + relocate.curOffset))); __ Emit((Addr) GetThumbPC(reinterpret_cast<void *>(reinterpret_cast<Addr>(origin_code) + relocate.cur_offset)));
__ finish(); __ Finish();
#undef __ #undef __
//commit inline trampoline //commit inline trampoline
assemblerInline.finish(); assembler_inline.Finish();
return getThumbPC(backup); return GetThumbPC(backup);
} }
IMPORT_SHELLCODE(BP_SHELLCODE) IMPORT_SHELLCODE(BP_SHELLCODE)
IMPORT_LABEL(callback_addr_s, Addr) IMPORT_LABEL(callback_addr_s, Addr)
IMPORT_LABEL(origin_addr_s, Addr) IMPORT_LABEL(origin_addr_s, Addr)
bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) { bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* originCode; void* origin_code;
if (isThumbCode((Addr)origin)) { if (IsThumbCode((Addr) origin)) {
originCode = getThumbCodeAddress(origin); origin_code = GetThumbCodeAddress(origin);
} else { } else {
LOGE("hook %d error!, only support thumb2 now!", origin); LOGE("hook %d error!, only support thumb2 now!", origin);
return false; return false;
} }
bool changeMode = isThumbCode((Addr) origin) != isThumbCode((Addr) callback); bool change_mode = IsThumbCode((Addr) origin) != IsThumbCode((Addr) callback);
void* backup = nullptr; void* backup = nullptr;
AssemblerA32 assemblerBackup(backupBuffer); AssemblerA32 assembler_backup(backup_buffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(originCode)); StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin_code));
AssemblerA32 assemblerInline(&inlineBuffer); AssemblerA32 assembler_inline(&inline_buffer);
//build backup method //build backup method
CodeRelocateA32 relocate = CodeRelocateA32(assemblerBackup); CodeRelocateA32 relocate = CodeRelocateA32(assembler_backup);
backup = relocate.relocate(origin, changeMode ? (4 * 2 + 2) : (4 * 2), nullptr); backup = relocate.Relocate(origin, change_mode ? (4 * 2 + 2) : (4 * 2), nullptr);
#define __ assemblerBackup. #define __ assembler_backup.
Label* origin_addr_label = new Label(); Label* origin_addr_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, origin_addr_label); __ Ldr(PC, origin_addr_label);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(reinterpret_cast<Addr>(originCode) + relocate.curOffset))); __ Emit((Addr) GetThumbPC(reinterpret_cast<void *>(reinterpret_cast<Addr>(origin_code) + relocate.cur_offset)));
__ finish(); __ Finish();
#undef __ #undef __
//build trampoline //build trampoline
origin_addr_s = (Addr) getThumbPC(backup); origin_addr_s = (Addr) GetThumbPC(backup);
callback_addr_s = (Addr) callback; callback_addr_s = (Addr) callback;
void* trampoline = backupBuffer->copy((void*)BP_SHELLCODE, SHELLCODE_LEN(BP_SHELLCODE)); void* trampoline = backup_buffer->Copy((void*)BP_SHELLCODE, SHELLCODE_LEN(BP_SHELLCODE));
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assembler_inline.
if (!changeMode) { if (!change_mode) {
Label *target_addr_label = new Label(); Label *target_addr_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_addr_label); __ Ldr(PC, target_addr_label);
...@@ -121,7 +121,7 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) { ...@@ -121,7 +121,7 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) {
__ Mov(IP, (Addr) trampoline); __ Mov(IP, (Addr) trampoline);
__ Bx(IP); __ Bx(IP);
} }
__ finish(); __ Finish();
#undef __ #undef __
return true; return true;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_HOOK_ARM32_H #pragma once
#define SANDHOOK_HOOK_ARM32_H
#include "hook.h" #include "hook.h"
...@@ -18,9 +17,9 @@ namespace SandHook { ...@@ -18,9 +17,9 @@ namespace SandHook {
inline ~InlineHookArm32Android() { inline ~InlineHookArm32Android() {
delete hookLock; delete hookLock;
} }
void *inlineHook(void *origin, void *replace) override; void *Hook(void *origin, void *replace) override;
bool breakPoint(void *point, void (*callback)(REG *)) override; bool BreakPoint(void *point, void (*callback)(REG *)) override;
protected: protected:
std::mutex* hookLock; std::mutex* hookLock;
...@@ -28,5 +27,3 @@ namespace SandHook { ...@@ -28,5 +27,3 @@ namespace SandHook {
} }
} }
\ No newline at end of file
#endif //SANDHOOK_HOOK_ARM32_H
...@@ -2,18 +2,17 @@ ...@@ -2,18 +2,17 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_ARM32_BASE_H #pragma once
#define SANDHOOK_ARM32_BASE_H
#include <ostream> #include <ostream>
#include "arm_base.h" #include "arm_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
#include "instruction.h" #include "instruction.h"
#define DECODE_OFFSET(bits, ext) signExtend32(bits + ext, COMBINE(get()->imm##bits, 0, ext)) #define DECODE_OFFSET(bits, ext) SignExtend32(bits + ext, COMBINE(Get()->imm##bits, 0, ext))
#define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext) #define ENCODE_OFFSET(bits, ext) Get()->imm##bits = TruncateToUint##bits(offset >> ext)
#define CODE_OFFSET(I) I->offset + (I->instType() == A32 ? 2 * 4 : 2 * 2) #define CODE_OFFSET(I) I->offset + (I->InstType() == A32 ? 2 * 4 : 2 * 2)
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -47,8 +46,8 @@ namespace SandHook { ...@@ -47,8 +46,8 @@ namespace SandHook {
bool IsPostIndex() const { return addr_mode == PostIndex; } bool IsPostIndex() const { return addr_mode == PostIndex; }
public: public:
RegisterA32* rn; // base RegisterA32* rn; // base_
RegisterA32* rm; // register offset RegisterA32* rm; // register offset_
S32 offset; // valid if rm_ == no_reg S32 offset; // valid if rm_ == no_reg
Shift shift; Shift shift;
Sign sign; Sign sign;
...@@ -126,10 +125,10 @@ namespace SandHook { ...@@ -126,10 +125,10 @@ namespace SandHook {
private: private:
static U16 RegisterToList(RegisterA32& reg) { static U16 RegisterToList(RegisterA32& reg) {
if (reg.getCode() == UnknowRegiser.getCode()) { if (reg.Code() == UnknowRegiser.Code()) {
return 0; return 0;
} else { } else {
return static_cast<U16>(UINT16_C(1) << reg.getCode()); return static_cast<U16>(UINT16_C(1) << reg.Code());
} }
} }
...@@ -144,20 +143,20 @@ namespace SandHook { ...@@ -144,20 +143,20 @@ namespace SandHook {
return (registers.GetList() >> first) & ((1 << count) - 1); return (registers.GetList() >> first) & ((1 << count) - 1);
} }
inline bool isThumbCode(Addr codeAddr) { inline bool IsThumbCode(Addr codeAddr) {
return (codeAddr & 0x1) == 0x1; return (codeAddr & 0x1) == 0x1;
} }
inline bool isThumb32(InstT16 code) { inline bool IsThumb32(InstT16 code) {
return ((code & 0xF000) == 0xF000) || ((code & 0xF800) == 0xE800); return ((code & 0xF000) == 0xF000) || ((code & 0xF800) == 0xE800);
} }
inline void* getThumbCodeAddress(void* code) { inline void* GetThumbCodeAddress(void *code) {
Addr addr = reinterpret_cast<Addr>(code) & (~0x1); Addr addr = reinterpret_cast<Addr>(code) & (~0x1);
return reinterpret_cast<void*>(addr); return reinterpret_cast<void*>(addr);
} }
inline void* getThumbPC(void* code) { inline void* GetThumbPC(void *code) {
Addr addr = reinterpret_cast<Addr>(code) & (~0x1); Addr addr = reinterpret_cast<Addr>(code) & (~0x1);
return reinterpret_cast<void*>(addr + 1); return reinterpret_cast<void*>(addr + 1);
} }
...@@ -166,5 +165,3 @@ namespace SandHook { ...@@ -166,5 +165,3 @@ namespace SandHook {
} }
} }
\ No newline at end of file
#endif //SANDHOOK_ARM32_BASE_H
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
//A64_STR_IMM::A64_STR_IMM() {} //A64_STR_IMM::A64_STR_IMM() {}
// //
//A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) *inst) : InstructionA64(inst) { //A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) *inst) : InstructionA64(inst) {
// decode(inst); // DisAssembler(inst);
//} //}
// //
//A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {} //A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {}
...@@ -17,11 +17,11 @@ ...@@ -17,11 +17,11 @@
// : condition(condition), rt(&rt), operand(operand) {} // : condition(condition), rt(&rt), operand(operand) {}
// //
//AddrMode A64_STR_IMM::decodeAddrMode() { //AddrMode A64_STR_IMM::decodeAddrMode() {
// if (get()->P == 1 && get()->W == 0) { // if (Get()->P == 1 && Get()->W == 0) {
// return Offset; // return Offset;
// } else if (get()->P == 0 && get()->W == 0) { // } else if (Get()->P == 0 && Get()->W == 0) {
// return PostIndex; // return PostIndex;
// } else if (get()->P == 1 && get()->W == 1) { // } else if (Get()->P == 1 && Get()->W == 1) {
// return PreIndex; // return PreIndex;
// } else { // } else {
// valid = false; // valid = false;
...@@ -29,20 +29,20 @@ ...@@ -29,20 +29,20 @@
// } // }
//} //}
// //
//void A64_STR_IMM::decode(STRUCT_A64(STR_IMM) *inst) { //void A64_STR_IMM::DisAssembler(STRUCT_A64(STR_IMM) *inst) {
// imm32 = zeroExtend32(12, inst->imm12); // imm32 = zeroExtend32(12, inst->imm12);
// condition = Condition(inst->cond); // condition = Condition(inst->cond);
// operand.addr_mode = decodeAddrMode(); // operand.addr_mode_ = decodeAddrMode();
// index = inst->P == 1; // index = inst->P == 1;
// wback = inst->P == 1 || inst->W == 0; // wback = inst->P == 1 || inst->W == 0;
// add = inst->U == 0; // add = inst->U == 0;
// rt = XReg(static_cast<U8>(inst->rt)); // rt = XReg(static_cast<U8>(inst->rt));
// operand.base = XReg(static_cast<U8>(inst->rn)); // operand.base_ = XReg(static_cast<U8>(inst->rn));
// operand.offset = add ? imm32 : -imm32; // operand.offset_ = add ? imm32 : -imm32;
//} //}
// //
// //
//void A64_STR_IMM::assembler() { //void A64_STR_IMM::Assemble() {
// INST_DCHECK(condition, Condition::nv) // INST_DCHECK(condition, Condition::nv)
// //
//} //}
\ No newline at end of file
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_ARM32_H #pragma once
#define SANDHOOK_NH_INST_ARM32_H
namespace SandHook { namespace SandHook {
...@@ -20,16 +19,16 @@ namespace SandHook { ...@@ -20,16 +19,16 @@ namespace SandHook {
// //
// DEFINE_IS_EXT(STR_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(STR_IMM)) && TEST_INST_FIELD(unkown1_0, 0) && TEST_INST_FIELD(unkown2_0, 0)) // DEFINE_IS_EXT(STR_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(STR_IMM)) && TEST_INST_FIELD(unkown1_0, 0) && TEST_INST_FIELD(unkown2_0, 0))
// //
// inline U32 instCode() override { // inline U32 InstCode() override {
// return STR_x; // return STR_x;
// } // }
// //
// void decode(STRUCT_A64(STR_IMM) *inst) override; // void DisAssembler(STRUCT_A64(STR_IMM) *inst) override;
// //
// void assembler() override; // void Assemble() override;
// //
// AddrMode getAddrMode() { // AddrMode getAddrMode() {
// return operand.addr_mode; // return operand.addr_mode_;
// } // }
// //
// private: // private:
...@@ -47,5 +46,3 @@ namespace SandHook { ...@@ -47,5 +46,3 @@ namespace SandHook {
//}; //};
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_INST_ARM32_H
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_CODE_ARM32_H #pragma once
#define SANDHOOK_INST_CODE_ARM32_H
enum class InstCodeA32 { enum class InstCodeA32 : InstCode {
}; };
enum class InstCodeT16 { enum class InstCodeT16 : InstCode {
UNKNOW, UNKNOW,
BASE_SASMC, BASE_SASMC,
DATA_PROC, DATA_PROC,
...@@ -33,7 +32,7 @@ enum class InstCodeT16 { ...@@ -33,7 +32,7 @@ enum class InstCodeT16 {
ADD_REG_RDN ADD_REG_RDN
}; };
enum class InstCodeT32 { enum class InstCodeT32 : InstCode {
UNKNOW, UNKNOW,
B32, B32,
LDR_LIT, LDR_LIT,
...@@ -42,5 +41,3 @@ enum class InstCodeT32 { ...@@ -42,5 +41,3 @@ enum class InstCodeT32 {
MOV_MOVT_IMM, MOV_MOVT_IMM,
SUB_IMM, SUB_IMM,
}; };
\ No newline at end of file
#endif //SANDHOOK_INST_CODE_ARM32_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_ARM32_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_ARM32_H
#include "instruction.h" #include "instruction.h"
...@@ -27,6 +26,3 @@ DEFINE_STRUCT_A32(STR_IMM) { ...@@ -27,6 +26,3 @@ DEFINE_STRUCT_A32(STR_IMM) {
InstA64 opcode:3; InstA64 opcode:3;
InstA64 cond:4; InstA64 cond:4;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_STRCUT_ARM32_H
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_T16_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_T16_H
#include "instruction.h" #include "instruction.h"
#include "inst_code_arm32.h" #include "inst_code_arm32.h"
...@@ -19,7 +17,7 @@ ...@@ -19,7 +17,7 @@
InstT16 opcode_base:w_base; InstT16 opcode_base:w_base;
//Shift (immediate), add, subtract, move, and compare //Shift (immediate_), add, subtract, Move, and compare
//opcode_base == 0b00 //opcode_base == 0b00
DEFINE_OPCODE_T16(BASE_SASMC, 0b00) DEFINE_OPCODE_T16(BASE_SASMC, 0b00)
//Data-processing //Data-processing
...@@ -34,7 +32,7 @@ DEFINE_OPCODE_T16(MISC, 0b1011) ...@@ -34,7 +32,7 @@ DEFINE_OPCODE_T16(MISC, 0b1011)
#define T16_REG_WIDE 3 #define T16_REG_WIDE 3
//unknow inst //Unknow inst
DEFINE_STRUCT_T16(UNKNOW) { DEFINE_STRUCT_T16(UNKNOW) {
InstT16 raw; InstT16 raw;
}; };
...@@ -157,6 +155,3 @@ DEFINE_STRUCT_T16(PUSH) { ...@@ -157,6 +155,3 @@ DEFINE_STRUCT_T16(PUSH) {
InstT16 M:1; InstT16 M:1;
InstT16 opcode:7; InstT16 opcode:7;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_STRUCT_T16_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_T32_H #pragma once
#define SANDHOOK_NH_INST_STRUCT_T32_H
#include "instruction.h" #include "instruction.h"
...@@ -16,7 +15,7 @@ ...@@ -16,7 +15,7 @@
#define T32_REG_WIDE 4 #define T32_REG_WIDE 4
//unknow inst //Unknow inst
DEFINE_STRUCT_T32(UNKNOW) { DEFINE_STRUCT_T32(UNKNOW) {
InstT32 raw; InstT32 raw;
}; };
...@@ -96,5 +95,3 @@ DEFINE_STRUCT_T32(SUB_IMM) { ...@@ -96,5 +95,3 @@ DEFINE_STRUCT_T32(SUB_IMM) {
InstT32 imm3:3; InstT32 imm3:3;
InstT32 opcode2:1; InstT32 opcode2:1;
}; };
#endif //SANDHOOK_NH_INST_STRUCT_T32_H
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
#include "arm32_base.h" #include "arm32_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
#define SET_BASE_OPCODE(X) get()->opcode_base = OPCODE_T16(X) #define SET_BASE_OPCODE(X) Get()->opcode_base = OPCODE_T16(X)
#define SET_OPCODE(X) get()->opcode = OPCODE_T16(X) #define SET_OPCODE(X) Get()->opcode = OPCODE_T16(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_T16(X##_##INDEX) #define SET_OPCODE_MULTI(X, INDEX) Get()->opcode##INDEX = OPCODE_T16(X##_##INDEX)
using namespace SandHook::AsmA32; using namespace SandHook::AsmA32;
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -17,45 +17,34 @@ using namespace SandHook::RegistersA32; ...@@ -17,45 +17,34 @@ using namespace SandHook::RegistersA32;
//Unknow //Unknow
T16_UNKNOW::T16_UNKNOW(STRUCT_T16(UNKNOW) &inst) : InstructionT16(&inst) { T16_UNKNOW::T16_UNKNOW(void *inst) : InstructionT16(inst) {
decode(&inst);
}
void T16_UNKNOW::decode(T16_STRUCT_UNKNOW *inst) {
inst_backup = *inst;
}
void T16_UNKNOW::assembler() {
set(inst_backup);
} }
//B //B
T16_B::T16_B() {}
T16_B::T16_B(T16_STRUCT_B *inst) : T16_INST_PC_REL(inst) { T16_B::T16_B(void *inst) : T16_INST_PC_REL(inst) {
decode(inst);
} }
T16_B::T16_B(Off offset) : offset(offset) {} T16_B::T16_B(Off offset) : offset(offset) {}
T16_B::T16_B(Label &label) { T16_B::T16_B(Label *label) {
bindLabel(label); BindLabel(label);
} }
Off T16_B::getImmPCOffset() { Off T16_B::GetImmPCOffset() {
return DECODE_OFFSET(11, 1); return DECODE_OFFSET(11, 1);
} }
void T16_B::decode(T16_STRUCT_B *inst) { void T16_B::Disassemble() {
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_B::assembler() { void T16_B::Assemble() {
SET_OPCODE(B); SET_OPCODE(B);
DECODE_OFFSET(11, 1); DECODE_OFFSET(11, 1);
} }
void T16_B::onOffsetApply(Off offset) { void T16_B::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
DECODE_OFFSET(11, 1); DECODE_OFFSET(11, 1);
} }
...@@ -63,53 +52,49 @@ void T16_B::onOffsetApply(Off offset) { ...@@ -63,53 +52,49 @@ void T16_B::onOffsetApply(Off offset) {
//B Cond //B Cond
T16_B_COND::T16_B_COND() {}
T16_B_COND::T16_B_COND(STRUCT_T16(B_COND) *inst) : T16_INST_PC_REL(inst) { T16_B_COND::T16_B_COND(void *inst) : T16_INST_PC_REL(inst) {
decode(inst);
} }
T16_B_COND::T16_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {} T16_B_COND::T16_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
T16_B_COND::T16_B_COND(Condition condition, Label &label) { T16_B_COND::T16_B_COND(Condition condition, Label *label) {
bindLabel(label); BindLabel(label);
} }
void T16_B_COND::decode(STRUCT_T16(B_COND) *inst) { void T16_B_COND::Disassemble() {
DECODE_COND; DECODE_COND;
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_B_COND::assembler() { void T16_B_COND::Assemble() {
SET_OPCODE(B_COND); SET_OPCODE(B_COND);
ENCODE_COND; ENCODE_COND;
ENCODE_OFFSET(8, 1); ENCODE_OFFSET(8, 1);
} }
void T16_B_COND::onOffsetApply(Off offset) { void T16_B_COND::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(8, 1); ENCODE_OFFSET(8, 1);
} }
Off T16_B_COND::getImmPCOffset() { Off T16_B_COND::GetImmPCOffset() {
return DECODE_OFFSET(8, 1); return DECODE_OFFSET(8, 1);
} }
//BX BLX //BX BLX
T16_BX_BLX::T16_BX_BLX(T16_BX_BLX::OP op, RegisterA32 &rm) : op(op), rm(&rm) {}
T16_BX_BLX::T16_BX_BLX(T16_STRUCT_BX_BLX *inst) : T16_INST_PC_REL(inst) { T16_BX_BLX::T16_BX_BLX(void *inst) : T16_INST_PC_REL(inst) {}
decode(inst);
}
void T16_BX_BLX::decode(STRUCT_T16(BX_BLX) *inst) { T16_BX_BLX::T16_BX_BLX(T16_BX_BLX::OP op, RegisterA32 &rm) : op(op), rm(&rm) {}
void T16_BX_BLX::Disassemble() {
DECODE_OP; DECODE_OP;
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_BX_BLX::assembler() { void T16_BX_BLX::Assemble() {
SET_OPCODE_MULTI(BX_BLX, 1); SET_OPCODE_MULTI(BX_BLX, 1);
SET_OPCODE_MULTI(BX_BLX, 2); SET_OPCODE_MULTI(BX_BLX, 2);
ENCODE_OP; ENCODE_OP;
...@@ -118,32 +103,26 @@ void T16_BX_BLX::assembler() { ...@@ -118,32 +103,26 @@ void T16_BX_BLX::assembler() {
//CBZ CBNZ //CBZ CBNZ
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst) : T16_INST_PC_REL(inst) { T16_CBZ_CBNZ::T16_CBZ_CBNZ(void *inst) : T16_INST_PC_REL(inst) {}
decode(inst);
}
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : op(op), offset(offset), T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : op(op), offset(offset),
rn(&rn) {} rn(&rn) {}
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Label* label, RegisterA32 &rn) : op(op), rn(&rn) {
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Label& label, RegisterA32 &rn) : op(op), BindLabel(label);
rn(&rn) {
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) { void T16_CBZ_CBNZ::Disassemble() {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_OP; DECODE_OP;
} }
void T16_CBZ_CBNZ::assembler() { void T16_CBZ_CBNZ::Assemble() {
SET_OPCODE_MULTI(CBZ_CBNZ, 1); SET_OPCODE_MULTI(CBZ_CBNZ, 1);
SET_OPCODE_MULTI(CBZ_CBNZ, 2); SET_OPCODE_MULTI(CBZ_CBNZ, 2);
SET_OPCODE_MULTI(CBZ_CBNZ, 3); SET_OPCODE_MULTI(CBZ_CBNZ, 3);
...@@ -152,40 +131,36 @@ void T16_CBZ_CBNZ::assembler() { ...@@ -152,40 +131,36 @@ void T16_CBZ_CBNZ::assembler() {
ENCODE_OFFSET(5, 2); ENCODE_OFFSET(5, 2);
} }
void T16_CBZ_CBNZ::onOffsetApply(Off offset) { void T16_CBZ_CBNZ::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(5, 2); ENCODE_OFFSET(5, 2);
} }
//LDR_LIT //LDR_LIT
T16_LDR_LIT::T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst) : T16_INST_PC_REL(inst) { T16_LDR_LIT::T16_LDR_LIT(void *inst) : T16_INST_PC_REL(inst) {}
decode(inst);
}
T16_LDR_LIT::T16_LDR_LIT(Off offset, RegisterA32 &rt) : offset(offset), rt(&rt) { T16_LDR_LIT::T16_LDR_LIT(Off offset, RegisterA32 &rt) : offset(offset), rt(&rt) {}
Off T16_LDR_LIT::GetImmPCOffset() {
return Get()->imm8 << 2;
} }
Off T16_LDR_LIT::getImmPCOffset() { Addr T16_LDR_LIT::GetImmPCOffsetTarget() {
return get()->imm8 << 2; return ALIGN((Addr) GetPC() + offset, 4);
} }
Addr T16_LDR_LIT::getImmPCOffsetTarget() { void T16_LDR_LIT::OnOffsetApply(Off offset) {
return ALIGN((Addr) getPC() + offset, 4);
}
void T16_LDR_LIT::onOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(8, 2); ENCODE_OFFSET(8, 2);
} }
void T16_LDR_LIT::decode(T16_STRUCT_LDR_LIT *inst) { void T16_LDR_LIT::Disassemble() {
DECODE_RT(Reg); DECODE_RT(Reg);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T16_LDR_LIT::assembler() { void T16_LDR_LIT::Assemble() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_RT; ENCODE_RT;
ENCODE_OFFSET(8, 2); ENCODE_OFFSET(8, 2);
...@@ -193,80 +168,72 @@ void T16_LDR_LIT::assembler() { ...@@ -193,80 +168,72 @@ void T16_LDR_LIT::assembler() {
//ADD IMM RD = RN //ADD IMM RD = RN
T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(T16_STRUCT_ADD_IMM_RDN *inst) : InstructionT16(inst) { T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8) : rdn(rdn), imm8(imm8) {} T16_ADD_IMM_RDN::T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8) : rdn(rdn), imm8(imm8) {}
void T16_ADD_IMM_RDN::decode(T16_STRUCT_ADD_IMM_RDN *inst) { void T16_ADD_IMM_RDN::Disassemble() {
rdn = Reg(inst->rdn); rdn = Reg(Get()->rdn);
imm8 = inst->imm8; imm8 = Get()->imm8;
} }
void T16_ADD_IMM_RDN::assembler() { void T16_ADD_IMM_RDN::Assemble() {
SET_OPCODE(ADD_IMM_RDN); SET_OPCODE(ADD_IMM_RDN);
get()->imm8 = imm8; Get()->imm8 = imm8;
get()->rdn = rdn->getCode(); Get()->rdn = rdn->Code();
} }
//ADR //ADR
T16_ADR::T16_ADR(T16_STRUCT_ADR *inst) : T16_INST_PC_REL(inst) { T16_ADR::T16_ADR(void *inst) : T16_INST_PC_REL(inst) {}
decode(inst);
}
T16_ADR::T16_ADR(RegisterA32 &rd, Off offset) : rd(&rd), offset(offset) {} T16_ADR::T16_ADR(RegisterA32 &rd, Off offset) : rd(&rd), offset(offset) {}
T16_ADR::T16_ADR(RegisterA32 &rd, Label &label) : rd(&rd) { T16_ADR::T16_ADR(RegisterA32 &rd, Label *label) : rd(&rd) {
bindLabel(label); BindLabel(label);
} }
Off T16_ADR::getImmPCOffset() { Off T16_ADR::GetImmPCOffset() {
return COMBINE(get()->imm8, 0 ,2); return COMBINE(Get()->imm8, 0 ,2);
} }
Addr T16_ADR::getImmPCOffsetTarget() { Addr T16_ADR::GetImmPCOffsetTarget() {
return RoundDown((Addr) getPC() + offset, 4); return RoundDown((Addr) GetPC() + offset, 4);
} }
void T16_ADR::onOffsetApply(Off offset) { void T16_ADR::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
get()->imm8 = (U32)offset >> 2; Get()->imm8 = (U32)offset >> 2;
} }
void T16_ADR::decode(T16_STRUCT_ADR *inst) { void T16_ADR::Disassemble() {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RD(Reg); DECODE_RD(Reg);
} }
void T16_ADR::assembler() { void T16_ADR::Assemble() {
SET_OPCODE(ADR); SET_OPCODE(ADR);
ENCODE_RD; ENCODE_RD;
get()->imm8 = (U32)offset >> 2; Get()->imm8 = (U32)offset >> 2;
} }
T16_CMP_REG::T16_CMP_REG() {}
T16_CMP_REG::T16_CMP_REG(T16_STRUCT_CMP_REG *inst) : InstructionT16(inst) {
decode(inst);
}
T16_CMP_REG::T16_CMP_REG(void *inst) : InstructionT16(inst) {}
T16_CMP_REG::T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn) : rm(&rm), rn(&rn) {} T16_CMP_REG::T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn) : rm(&rm), rn(&rn) {}
void T16_CMP_REG::decode(T16_STRUCT_CMP_REG *inst) { void T16_CMP_REG::Disassemble() {
DECODE_RM(Reg); DECODE_RM(Reg);
DECODE_RN(Reg); DECODE_RN(Reg);
} }
void T16_CMP_REG::assembler() { void T16_CMP_REG::Assemble() {
SET_BASE_OPCODE(DATA_PROC); SET_BASE_OPCODE(DATA_PROC);
SET_OPCODE(CMP_REG); SET_OPCODE(CMP_REG);
ENCODE_RM; ENCODE_RM;
...@@ -274,55 +241,47 @@ void T16_CMP_REG::assembler() { ...@@ -274,55 +241,47 @@ void T16_CMP_REG::assembler() {
} }
//MOV REG //MOV REG
T16_MOV_REG::T16_MOV_REG(T16_STRUCT_MOV_REG *inst) : InstructionT16(inst) { T16_MOV_REG::T16_MOV_REG(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_MOV_REG::T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm) : rm(&rm), rd(&rd) {}
T16_MOV_REG::T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm) : rm(&rm), rd(&rd) { void T16_MOV_REG::Disassemble() {
}
void T16_MOV_REG::decode(T16_STRUCT_MOV_REG *inst) {
DECODE_RM(Reg); DECODE_RM(Reg);
rd = Reg(static_cast<U8>(COMBINE(inst->D, inst->rd, 3))); rd = Reg(static_cast<U8>(COMBINE(Get()->D, Get()->rd, 3)));
} }
void T16_MOV_REG::assembler() { void T16_MOV_REG::Assemble() {
SET_BASE_OPCODE(DATA_PROC); SET_BASE_OPCODE(DATA_PROC);
SET_OPCODE(MOV_REG); SET_OPCODE(MOV_REG);
ENCODE_RM; ENCODE_RM;
get()->rd = BITS(rd->getCode(), 0, 2); Get()->rd = BITS(rd->Code(), 0, 2);
get()->D = BIT(rd->getCode(), 3); Get()->D = BIT(rd->Code(), 3);
} }
bool T16_MOV_REG::pcRelate() { bool T16_MOV_REG::PcRelate() {
return rd == &PC || rm == &PC; return rd == &PC || rm == &PC;
} }
T16_ADD_REG::T16_ADD_REG() {}
T16_ADD_REG::T16_ADD_REG(T16_STRUCT_ADD_REG *inst) : InstructionT16(inst) { T16_ADD_REG::T16_ADD_REG(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_ADD_REG::T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm) : rd(rd), rn(rn), T16_ADD_REG::T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm) : rd(rd), rn(rn),
rm(rm) {} rm(rm) {}
void T16_ADD_REG::decode(T16_STRUCT_ADD_REG *inst) { void T16_ADD_REG::Disassemble() {
DECODE_RD(Reg); DECODE_RD(Reg);
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_ADD_REG::assembler() { void T16_ADD_REG::Assemble() {
SET_OPCODE(ADD_REG); SET_OPCODE(ADD_REG);
INST_ASSERT(rd->getCode() > 7); INST_ASSERT(rd->Code() > 7);
INST_ASSERT(rn->getCode() > 7); INST_ASSERT(rn->Code() > 7);
INST_ASSERT(rm->getCode() > 7); INST_ASSERT(rm->Code() > 7);
ENCODE_RD; ENCODE_RD;
ENCODE_RN; ENCODE_RN;
ENCODE_RM; ENCODE_RM;
...@@ -330,81 +289,73 @@ void T16_ADD_REG::assembler() { ...@@ -330,81 +289,73 @@ void T16_ADD_REG::assembler() {
T16_CMP_REG_EXT::T16_CMP_REG_EXT(T16_STRUCT_CMP_REG_EXT *inst) : InstructionT16(inst) { T16_CMP_REG_EXT::T16_CMP_REG_EXT(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_CMP_REG_EXT::T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm) : rn(&rn), rm(&rm) {} T16_CMP_REG_EXT::T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm) : rn(&rn), rm(&rm) {}
void T16_CMP_REG_EXT::decode(T16_STRUCT_CMP_REG_EXT *inst) { void T16_CMP_REG_EXT::Disassemble() {
rn = Reg(COMBINE(inst->N, inst->rn, 3)); rn = Reg(COMBINE(Get()->N, Get()->rn, 3));
DECODE_RM(Reg); DECODE_RM(Reg);
} }
void T16_CMP_REG_EXT::assembler() { void T16_CMP_REG_EXT::Assemble() {
SET_OPCODE(CMP_REG_EXT); SET_OPCODE(CMP_REG_EXT);
ENCODE_RM; ENCODE_RM;
get()->rn = BITS(rn->getCode(), 0, 2); Get()->rn = BITS(rn->Code(), 0, 2);
get()->N = BIT(rn->getCode(), 3); Get()->N = BIT(rn->Code(), 3);
} }
//POP //POP
T16_POP::T16_POP(T16_STRUCT_POP *inst) : InstructionT16(inst) { T16_POP::T16_POP(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_POP::T16_POP(const RegisterList &registerList) : registerList(registerList) {} T16_POP::T16_POP(const RegisterList &registerList) : registerList(registerList) {}
void T16_POP::decode(T16_STRUCT_POP *inst) { void T16_POP::Disassemble() {
registerList.SetList(COMBINE(inst->P << 7, inst->regs, 8)); registerList.SetList(COMBINE(Get()->P << 7, Get()->regs, 8));
} }
void T16_POP::assembler() { void T16_POP::Assemble() {
SET_OPCODE(POP); SET_OPCODE(POP);
U16 regs = registerList.GetList(); U16 regs = registerList.GetList();
get()->regs = BITS(regs, 0, 7); Get()->regs = BITS(regs, 0, 7);
get()->P = BIT(regs, 15); Get()->P = BIT(regs, 15);
} }
//PUSH //PUSH
T16_PUSH::T16_PUSH(T16_STRUCT_PUSH *inst) : InstructionT16(inst) { T16_PUSH::T16_PUSH(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_PUSH::T16_PUSH(const RegisterList &registerList) : registerList(registerList) {} T16_PUSH::T16_PUSH(const RegisterList &registerList) : registerList(registerList) {}
void T16_PUSH::decode(T16_STRUCT_PUSH *inst) { void T16_PUSH::Disassemble() {
registerList.SetList(COMBINE(inst->M << 6, inst->regs, 8)); registerList.SetList(COMBINE(Get()->M << 6, Get()->regs, 8));
} }
void T16_PUSH::assembler() { void T16_PUSH::Assemble() {
SET_OPCODE(PUSH); SET_OPCODE(PUSH);
U16 regs = registerList.GetList(); U16 regs = registerList.GetList();
get()->regs = BITS(regs, 0, 7); Get()->regs = BITS(regs, 0, 7);
get()->M = BIT(regs, 14); Get()->M = BIT(regs, 14);
} }
// Add reg rdn T2 // Add reg_ rdn T2
T16_ADD_REG_RDN::T16_ADD_REG_RDN(T16_STRUCT_ADD_REG_RDN *inst) : InstructionT16(inst) { T16_ADD_REG_RDN::T16_ADD_REG_RDN(void *inst) : InstructionT16(inst) {}
decode(inst);
}
T16_ADD_REG_RDN::T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm) : rdn(&rdn), rm(&rm) {} T16_ADD_REG_RDN::T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm) : rdn(&rdn), rm(&rm) {}
bool T16_ADD_REG_RDN::pcRelate() { bool T16_ADD_REG_RDN::PcRelate() {
return *rm == PC; return *rm == PC;
} }
void T16_ADD_REG_RDN::decode(T16_STRUCT_ADD_REG_RDN *inst) { void T16_ADD_REG_RDN::Disassemble() {
DECODE_RM(Reg); DECODE_RM(Reg);
rdn = Reg(inst->rdn); rdn = Reg(Get()->rdn);
} }
void T16_ADD_REG_RDN::assembler() { void T16_ADD_REG_RDN::Assemble() {
SET_OPCODE(ADD_REG_RDN); SET_OPCODE(ADD_REG_RDN);
ENCODE_RM; ENCODE_RM;
get()->rdn = rdn->getCode(); Get()->rdn = rdn->Code();
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_T16_H #pragma once
#define SANDHOOK_INST_T16_H
#include "arm_base.h" #include "arm_base.h"
#include "register_list_arm32.h" #include "register_list_arm32.h"
...@@ -13,10 +12,10 @@ ...@@ -13,10 +12,10 @@
#define INST_T16(X) T16_##X #define INST_T16(X) T16_##X
#define IS_OPCODE_T16(RAW, OP) INST_T16(OP)::is(RAW) #define IS_OPCODE_T16(RAW, OP) INST_T16(OP)::Is(RAW)
#define DEFINE_IS_EXT(X, COND) \ #define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstT16& inst) { \ inline static bool Is(InstT16& inst) { \
union { \ union { \
InstT16 raw; \ InstT16 raw; \
STRUCT_T16(X) inst; \ STRUCT_T16(X) inst; \
...@@ -33,10 +32,14 @@ return COND; \ ...@@ -33,10 +32,14 @@ return COND; \
#define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_T16(X##_##INDEX) #define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_T16(X##_##INDEX)
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST(X) class INST_T16(X) : public InstructionT16<STRUCT_T16(X), ENUM_VALUE(InstCodeT16, InstCodeT16::X)>
inline U32 instCode() override { \
return ENUM_VALUE(InstCodeT16, InstCodeT16::X); \ #define DEFINE_INST_EXT(X,P) class INST_T16(X) : public INST_T16(P)
}
#define DEFINE_INST_EXT_(X,P) class INST_T16(X) : public P<STRUCT_T16(X), ENUM_VALUE(InstCodeT16, InstCodeT16::X)>
#define DEFINE_INST_PCREL(X) class INST_T16(X) : public T16_INST_PC_REL<STRUCT_T16(X), ENUM_VALUE(InstCodeT16, InstCodeT16::X)>
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -44,136 +47,114 @@ namespace SandHook { ...@@ -44,136 +47,114 @@ namespace SandHook {
namespace AsmA32 { namespace AsmA32 {
template<typename Inst> template<typename S, U32 C>
class InstructionT16 : public Instruction<Inst> { class InstructionT16 : public Instruction<S,C> {
public: public:
InstructionT16() {} InstructionT16() {}
InstructionT16(Inst *inst) : Instruction<Inst>(inst) {} InstructionT16(void *inst) : Instruction<S,C>(inst) {}
Inst mask(Inst raw) {
return raw & *(this->get());
}
U32 size() override { inline U32 Size() override {
return 2; return 2;
} }
void *getPC() override { inline void *GetPC() override {
return reinterpret_cast<void *>((Addr) Instruction<Inst>::getPC() + 2 * 2); return reinterpret_cast<void *>((Addr) Instruction<S,C>::GetPC() + 2 * 2);
} }
Addr getVPC() override { inline Addr GetVPC() override {
return Instruction<Inst>::getVPC() + 2 * 2; return Instruction<S,C>::GetVPC() + 2 * 2;
} }
static inline S32 signExtend32(unsigned int bits, U32 value) { inline InstType InstType() override {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
InstType instType() override {
return thumb16; return thumb16;
} }
Arch arch() override { inline Arch Arch() override {
return arm32; return arm32;
} }
}; };
template<typename Inst> template<typename S,U32 C>
class T16_INST_PC_REL : public InstructionT16<Inst> { class T16_INST_PC_REL : public InstructionT16<S,C> {
public: public:
T16_INST_PC_REL() {}; T16_INST_PC_REL() {}
T16_INST_PC_REL(Inst *inst) : InstructionT16<Inst>(inst) {}; T16_INST_PC_REL(void *inst) : InstructionT16<S,C>(inst) {};
virtual Off getImmPCOffset() { inline virtual Off GetImmPCOffset() {
return 0; return 0;
}; };
virtual Addr getImmPCOffsetTarget() { inline virtual Addr GetImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset(); return (Addr) this->GetPC() + GetImmPCOffset();
}; };
inline bool pcRelate() override { inline bool PcRelate() override {
return true; return true;
}; };
}; };
class INST_T16(UNKNOW) : public InstructionT16<STRUCT_T16(UNKNOW)> { DEFINE_INST(UNKNOW) {
public: public:
T16_UNKNOW(STRUCT_T16(UNKNOW) &inst); T16_UNKNOW(void *inst);
DEFINE_INST_CODE(UNKNOW)
inline bool unknow() override { inline bool Unknow() override {
return true; return true;
} }
void decode(T16_STRUCT_UNKNOW *inst) override;
void assembler() override;
private:
STRUCT_T16(UNKNOW) inst_backup;
}; };
class INST_T16(B) : public T16_INST_PC_REL<STRUCT_T16(B)> { DEFINE_INST_PCREL(B) {
public: public:
T16_B();
T16_B(STRUCT_T16(B) *inst); T16_B(void *inst);
T16_B(Off offset); T16_B(Off offset);
T16_B(Label &label); T16_B(Label *label);
DEFINE_IS(B) DEFINE_IS(B)
DEFINE_INST_CODE(B) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; Off GetImmPCOffset() override;
Off getImmPCOffset() override; void Disassemble() override;
void decode(STRUCT_T16(B) *inst) override; void Assemble() override;
void assembler() override;
public: public:
Off offset; Off offset;
}; };
class INST_T16(B_COND) : public T16_INST_PC_REL<STRUCT_T16(B_COND)> { DEFINE_INST_PCREL(B_COND) {
public: public:
T16_B_COND();
T16_B_COND(STRUCT_T16(B_COND) *inst); T16_B_COND(void *inst);
T16_B_COND(Condition condition, Off offset); T16_B_COND(Condition condition, Off offset);
T16_B_COND(Condition condition, Label &label); T16_B_COND(Condition condition, Label *label);
DEFINE_IS_EXT(B_COND, TEST_INST_FIELD(opcode, OPCODE_T16(B_COND)) && DEFINE_IS_EXT(B_COND, TEST_INST_FIELD(opcode, OPCODE_T16(B_COND)) &&
INST_FIELD(cond) != 0b1110 && INST_FIELD(cond) != 0b1111) INST_FIELD(cond) != 0b1110 && INST_FIELD(cond) != 0b1111)
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 Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
Condition condition; Condition condition;
...@@ -181,7 +162,7 @@ namespace SandHook { ...@@ -181,7 +162,7 @@ namespace SandHook {
}; };
class INST_T16(BX_BLX) : public T16_INST_PC_REL<STRUCT_T16(BX_BLX)> { DEFINE_INST_PCREL(BX_BLX) {
public: public:
enum OP { enum OP {
...@@ -189,17 +170,15 @@ namespace SandHook { ...@@ -189,17 +170,15 @@ namespace SandHook {
BLX = 0b1 BLX = 0b1
}; };
T16_BX_BLX(T16_STRUCT_BX_BLX *inst); T16_BX_BLX(void *inst);
T16_BX_BLX(OP op, RegisterA32 &rm); T16_BX_BLX(OP op, RegisterA32 &rm);
DEFINE_IS_EXT(BX_BLX, TEST_INST_OPCODE(BX_BLX, 1) && TEST_INST_OPCODE(BX_BLX, 2)) DEFINE_IS_EXT(BX_BLX, TEST_INST_OPCODE(BX_BLX, 1) && TEST_INST_OPCODE(BX_BLX, 2))
DEFINE_INST_CODE(BX_BLX) void Disassemble() override;
void decode(T16_STRUCT_BX_BLX *inst) override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -207,32 +186,30 @@ namespace SandHook { ...@@ -207,32 +186,30 @@ namespace SandHook {
}; };
class INST_T16(CBZ_CBNZ) : public T16_INST_PC_REL<STRUCT_T16(CBZ_CBNZ)> { DEFINE_INST_PCREL(CBZ_CBNZ) {
public: public:
enum OP { enum OP {
CBZ = 0b0, CBZ = 0b0,
CBNZ = 0b1 CBNZ = 0b1
}; };
T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst); T16_CBZ_CBNZ(void *inst);
T16_CBZ_CBNZ(OP op, Off offset, RegisterA32 &rn); T16_CBZ_CBNZ(OP op, Off offset, RegisterA32 &rn);
T16_CBZ_CBNZ(OP op, Label &label, RegisterA32 &rn); T16_CBZ_CBNZ(OP op, Label *label, RegisterA32 &rn);
DEFINE_IS_EXT(CBZ_CBNZ, DEFINE_IS_EXT(CBZ_CBNZ,
TEST_INST_OPCODE(CBZ_CBNZ, 1) && TEST_INST_OPCODE(CBZ_CBNZ, 2) && TEST_INST_OPCODE(CBZ_CBNZ, 1) && TEST_INST_OPCODE(CBZ_CBNZ, 2) &&
TEST_INST_OPCODE(CBZ_CBNZ, 3)) TEST_INST_OPCODE(CBZ_CBNZ, 3))
DEFINE_INST_CODE(CBZ_CBNZ) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; Off GetImmPCOffset() override;
Off getImmPCOffset() override; void Disassemble() override;
void decode(T16_STRUCT_CBZ_CBNZ *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -241,25 +218,24 @@ namespace SandHook { ...@@ -241,25 +218,24 @@ namespace SandHook {
}; };
class INST_T16(LDR_LIT) : public T16_INST_PC_REL<STRUCT_T16(LDR_LIT)> { DEFINE_INST_PCREL(LDR_LIT) {
public: public:
T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst);
T16_LDR_LIT(void *inst);
T16_LDR_LIT(Off offset, RegisterA32 &rt); T16_LDR_LIT(Off offset, RegisterA32 &rt);
DEFINE_IS(LDR_LIT) DEFINE_IS(LDR_LIT)
DEFINE_INST_CODE(LDR_LIT) Addr GetImmPCOffsetTarget() override;
Addr getImmPCOffsetTarget() override; Off GetImmPCOffset() override;
Off getImmPCOffset() override; void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; void Disassemble() override;
void decode(T16_STRUCT_LDR_LIT *inst) override; void Assemble() override;
void assembler() override;
public: public:
Off offset; Off offset;
...@@ -267,47 +243,43 @@ namespace SandHook { ...@@ -267,47 +243,43 @@ namespace SandHook {
}; };
class INST_T16(ADD_IMM_RDN) : public InstructionT16<STRUCT_T16(ADD_IMM_RDN)> { DEFINE_INST(ADD_IMM_RDN) {
public: public:
T16_ADD_IMM_RDN(T16_STRUCT_ADD_IMM_RDN *inst); T16_ADD_IMM_RDN(void *inst);
T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8); T16_ADD_IMM_RDN(RegisterA32 *rdn, U8 imm8);
DEFINE_IS(ADD_IMM_RDN) DEFINE_IS(ADD_IMM_RDN)
DEFINE_INST_CODE(ADD_IMM_RDN) void Disassemble() override;
void decode(T16_STRUCT_ADD_IMM_RDN *inst) override;
void assembler() override; void Assemble() override;
public: public:
RegisterA32 *rdn; RegisterA32 *rdn;
U8 imm8; U8 imm8;
}; };
class INST_T16(ADR) : public T16_INST_PC_REL<STRUCT_T16(ADR)> { DEFINE_INST_PCREL(ADR) {
public: public:
T16_ADR(T16_STRUCT_ADR *inst); T16_ADR(void *inst);
T16_ADR(RegisterA32 &rd, Off offset); T16_ADR(RegisterA32 &rd, Off offset);
T16_ADR(RegisterA32 &rd, Label &label); T16_ADR(RegisterA32 &rd, Label *label);
DEFINE_IS(ADR) DEFINE_IS(ADR)
DEFINE_INST_CODE(ADR) Off GetImmPCOffset() override;
Off getImmPCOffset() override; Addr GetImmPCOffsetTarget() override;
Addr getImmPCOffsetTarget() override; void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; void Disassemble() override;
void decode(T16_STRUCT_ADR *inst) override; void Assemble() override;
void assembler() override;
public: public:
RegisterA32 *rd; RegisterA32 *rd;
...@@ -315,22 +287,20 @@ namespace SandHook { ...@@ -315,22 +287,20 @@ namespace SandHook {
}; };
class INST_T16(CMP_REG) : public InstructionT16<STRUCT_T16(CMP_REG)> { DEFINE_INST(CMP_REG) {
public: public:
T16_CMP_REG(); T16_CMP_REG();
T16_CMP_REG(T16_STRUCT_CMP_REG *inst); T16_CMP_REG(void *inst);
T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn); T16_CMP_REG(RegisterA32 &rm, RegisterA32 &rn);
DEFINE_INST_CODE(CMP_REG)
DEFINE_IS_EXT(CMP_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) && DEFINE_IS_EXT(CMP_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) &&
TEST_INST_FIELD(opcode, OPCODE_T16(CMP_REG))) TEST_INST_FIELD(opcode, OPCODE_T16(CMP_REG)))
void decode(T16_STRUCT_CMP_REG *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
RegisterA32 *rm; RegisterA32 *rm;
...@@ -338,23 +308,21 @@ namespace SandHook { ...@@ -338,23 +308,21 @@ namespace SandHook {
}; };
class INST_T16(MOV_REG) : public InstructionT16<STRUCT_T16(MOV_REG)> { DEFINE_INST(MOV_REG) {
public: public:
T16_MOV_REG(T16_STRUCT_MOV_REG *inst);
T16_MOV_REG(void *inst);
T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm); T16_MOV_REG(RegisterA32 &rd, RegisterA32 &rm);
DEFINE_INST_CODE(MOV_REG)
DEFINE_IS_EXT(MOV_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) && DEFINE_IS_EXT(MOV_REG, TEST_INST_FIELD(opcode_base, OPCODE_T16(DATA_PROC)) &&
TEST_INST_FIELD(opcode, OPCODE_T16(MOV_REG))) TEST_INST_FIELD(opcode, OPCODE_T16(MOV_REG)))
void decode(T16_STRUCT_MOV_REG *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
bool pcRelate() override; bool PcRelate() override;
public: public:
RegisterA32 *rd; RegisterA32 *rd;
...@@ -362,21 +330,18 @@ namespace SandHook { ...@@ -362,21 +330,18 @@ namespace SandHook {
}; };
class INST_T16(ADD_REG) : public InstructionT16<STRUCT_T16(ADD_REG)> { DEFINE_INST(ADD_REG) {
public: public:
T16_ADD_REG();
T16_ADD_REG(T16_STRUCT_ADD_REG *inst); T16_ADD_REG(void *inst);
T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm); T16_ADD_REG(RegisterA32 *rd, RegisterA32 *rn, RegisterA32 *rm);
DEFINE_IS(ADD_REG) DEFINE_IS(ADD_REG)
DEFINE_INST_CODE(ADD_REG) void Disassemble() override;
void decode(T16_STRUCT_ADD_REG *inst) override; void Assemble() override;
void assembler() override;
public: public:
RegisterA32 *rd; RegisterA32 *rd;
...@@ -385,20 +350,18 @@ namespace SandHook { ...@@ -385,20 +350,18 @@ namespace SandHook {
}; };
class INST_T16(CMP_REG_EXT) : public InstructionT16<STRUCT_T16(CMP_REG_EXT)> { DEFINE_INST(CMP_REG_EXT) {
public: public:
T16_CMP_REG_EXT(T16_STRUCT_CMP_REG_EXT *inst); T16_CMP_REG_EXT(void *inst);
T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm); T16_CMP_REG_EXT(RegisterA32 &rn, RegisterA32 &rm);
DEFINE_IS(CMP_REG_EXT) DEFINE_IS(CMP_REG_EXT)
DEFINE_INST_CODE(CMP_REG_EXT) void Disassemble() override;
void decode(T16_STRUCT_CMP_REG_EXT *inst) override;
void assembler() override; void Assemble() override;
public: public:
...@@ -407,47 +370,44 @@ namespace SandHook { ...@@ -407,47 +370,44 @@ namespace SandHook {
}; };
class INST_T16(POP) : public InstructionT16<STRUCT_T16(POP)> { DEFINE_INST(POP) {
public: public:
T16_POP(T16_STRUCT_POP *inst); T16_POP(void *inst);
T16_POP(const RegisterList &registerList); T16_POP(const RegisterList &registerList);
DEFINE_IS(POP) DEFINE_IS(POP)
DEFINE_INST_CODE(POP) void Disassemble() override;
void decode(T16_STRUCT_POP *inst) override; void Assemble() override;
void assembler() override;
public: public:
RegisterList registerList; RegisterList registerList;
}; };
class INST_T16(PUSH) : public InstructionT16<STRUCT_T16(PUSH)> { DEFINE_INST(PUSH) {
public: public:
T16_PUSH(T16_STRUCT_PUSH *inst);
T16_PUSH(void *inst);
T16_PUSH(const RegisterList &registerList); T16_PUSH(const RegisterList &registerList);
DEFINE_IS(PUSH) DEFINE_IS(PUSH)
DEFINE_INST_CODE(PUSH) void Disassemble() override;
void decode(T16_STRUCT_PUSH *inst) override; void Assemble() override;
void assembler() override;
public: public:
RegisterList registerList; RegisterList registerList;
}; };
class INST_T16(ADD_REG_RDN) : public InstructionT16<STRUCT_T16(ADD_REG_RDN)> { DEFINE_INST(ADD_REG_RDN) {
public: public:
T16_ADD_REG_RDN(T16_STRUCT_ADD_REG_RDN *inst); T16_ADD_REG_RDN(void *inst);
T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm); T16_ADD_REG_RDN(RegisterA32 &rdn, RegisterA32 &rm);
...@@ -455,13 +415,11 @@ namespace SandHook { ...@@ -455,13 +415,11 @@ namespace SandHook {
DEFINE_IS(ADD_REG_RDN) DEFINE_IS(ADD_REG_RDN)
DEFINE_INST_CODE(ADD_REG_RDN) bool PcRelate() override;
bool pcRelate() override;
void decode(T16_STRUCT_ADD_REG_RDN *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
RegisterA32* rdn; RegisterA32* rdn;
...@@ -475,6 +433,7 @@ namespace SandHook { ...@@ -475,6 +433,7 @@ namespace SandHook {
#undef DEFINE_IS #undef DEFINE_IS
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST
#undef DEFINE_INST_EXT
#endif //SANDHOOK_INST_T16_H #undef DEFINE_INST_EXT_
#undef DEFINE_INST_PCREL
\ No newline at end of file
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
#include "inst_struct_t32.h" #include "inst_struct_t32.h"
#define SET_BASE_OPCODE(X) get()->opcode_base = OPCODE_T32(X) #define SET_BASE_OPCODE(X) Get()->opcode_base = OPCODE_T32(X)
#define SET_OPCODE(X) get()->opcode = OPCODE_T32(X) #define SET_OPCODE(X) Get()->opcode = OPCODE_T32(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_T32(X##_##INDEX) #define SET_OPCODE_MULTI(X, INDEX) Get()->opcode##INDEX = OPCODE_T32(X##_##INDEX)
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::AsmA32; using namespace SandHook::AsmA32;
...@@ -18,240 +18,224 @@ using namespace SandHook::AsmA32; ...@@ -18,240 +18,224 @@ using namespace SandHook::AsmA32;
//Unknow //Unknow
T32_UNKNOW::T32_UNKNOW(STRUCT_T32(UNKNOW) &inst) : InstructionT32(&inst) { T32_UNKNOW::T32_UNKNOW(void *inst) : InstructionT32(inst) {
decode(&inst);
} }
void T32_UNKNOW::decode(T32_STRUCT_UNKNOW *inst) {
inst_backup = *inst;
}
void T32_UNKNOW::assembler() {
set(inst_backup);
}
T32_B32::T32_B32(T32_STRUCT_B32 *inst) : T32_INST_PC_REL(inst) { T32_B32::T32_B32(void *inst) : T32_INST_PC_REL(inst) {
decode(inst);
} }
T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Off offset) : op(op), x(x), offset(offset) {} T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Off offset) : op(op), x(x), offset(offset) {}
T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Label &label) : op(op), x(x) { T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Label *label) : op(op), x(x) {
bindLabel(label); BindLabel(label);
} }
Off T32_B32::getImmPCOffset() { Off T32_B32::GetImmPCOffset() {
U32 S = get()->S; U32 S = Get()->S;
U32 imm21 = COMBINE(get()->imm10, get()->imm11, 11); U32 imm21 = COMBINE(Get()->imm10, Get()->imm11, 11);
if (get()->X == 0 && op == BL) { if (Get()->X == 0 && op == BL) {
imm21 &= ~(1 << 0); imm21 &= ~(1 << 0);
} }
U32 i1 = !(get()->J1 ^ S); U32 i1 = !(Get()->J1 ^ S);
U32 i2 = !(get()->J2 ^ S); U32 i2 = !(Get()->J2 ^ S);
U32 i1i2 = COMBINE(i1, i2, 1); U32 i1i2 = COMBINE(i1, i2, 1);
U32 Si1i2 = COMBINE(-S, i1i2, 2); U32 Si1i2 = COMBINE(-S, i1i2, 2);
return signExtend32(25, COMBINE(Si1i2, imm21, 21) << 1); return SignExtend32(25, COMBINE(Si1i2, imm21, 21) << 1);
} }
void T32_B32::decode(T32_STRUCT_B32 *inst) { void T32_B32::Disassemble() {
DECODE_OP; DECODE_OP;
x = X(inst->X); x = X(Get()->X);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T32_B32::assembler() { void T32_B32::Assemble() {
SET_OPCODE(B32); SET_OPCODE(B32);
ENCODE_OP; ENCODE_OP;
get()->X = x; Get()->X = x;
U32 imm24 = TruncateToUint25(offset) >> 1; U32 imm24 = TruncateToUint25(offset) >> 1;
get()->imm11 = BITS(imm24, 0, 10); Get()->imm11 = BITS(imm24, 0, 10);
get()->imm10 = BITS(imm24, 11, 20); Get()->imm10 = BITS(imm24, 11, 20);
if (get()->X == 0) { if (Get()->X == 0) {
get()->imm11 |= (1 << 0); Get()->imm11 |= (1 << 0);
} }
get()->S = BIT(imm24, 23); Get()->S = BIT(imm24, 23);
U32 i1 = BIT(imm24, 22); U32 i1 = BIT(imm24, 22);
U32 i2 = BIT(imm24, 21); U32 i2 = BIT(imm24, 21);
if (i1 == 1) { if (i1 == 1) {
get()->J1 = get()->S; Get()->J1 = Get()->S;
} else { } else {
get()->J1 = !get()->S; Get()->J1 = !Get()->S;
} }
if (i2 == 1) { if (i2 == 1) {
get()->J2 = get()->S; Get()->J2 = Get()->S;
} else { } else {
get()->J2 = !get()->S; Get()->J2 = !Get()->S;
} }
} }
Addr T32_B32::getImmPCOffsetTarget() { Addr T32_B32::GetImmPCOffsetTarget() {
if (x == arm && op == BL) { if (x == arm && op == BL) {
void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4)); void* base = reinterpret_cast<void *>(ALIGN((Addr) GetPC(), 4));
return offset + reinterpret_cast<Addr>(base); return offset + reinterpret_cast<Addr>(base);
} else { } else {
return T32_INST_PC_REL::getImmPCOffsetTarget(); return T32_INST_PC_REL::GetImmPCOffsetTarget();
} }
} }
T32_LDR_UIMM::T32_LDR_UIMM(T32_STRUCT_LDR_UIMM *inst) : InstructionT32(inst) {} T32_LDR_UIMM::T32_LDR_UIMM(void *inst) : InstructionT32(inst) {}
T32_LDR_UIMM::T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset) : rt(&rt), rn(&rn), T32_LDR_UIMM::T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset) : rt(&rt), rn(&rn),
offset(offset) {} offset(offset) {}
void T32_LDR_UIMM::decode(T32_STRUCT_LDR_UIMM *inst) { void T32_LDR_UIMM::Disassemble() {
DECODE_RN(Reg); DECODE_RN(Reg);
DECODE_RT(Reg); DECODE_RT(Reg);
INST_ASSERT(rn == &PC); INST_ASSERT(rn == &PC);
offset = inst->imm12; offset = Get()->imm12;
} }
void T32_LDR_UIMM::assembler() { void T32_LDR_UIMM::Assemble() {
SET_OPCODE(LDR_UIMM); SET_OPCODE(LDR_UIMM);
ENCODE_RN; ENCODE_RN;
ENCODE_RT; ENCODE_RT;
INST_ASSERT(rn == &PC); INST_ASSERT(rn == &PC);
get()->imm12 = offset; Get()->imm12 = offset;
} }
T32_LDR_LIT::T32_LDR_LIT() {} T32_LDR_LIT::T32_LDR_LIT(void *inst) : T32_INST_PC_REL(inst) {
T32_LDR_LIT::T32_LDR_LIT(T32_STRUCT_LDR_LIT *inst) : T32_INST_PC_REL(inst) {
decode(inst);
} }
T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset) : op(op), s(s), rt(&rt), offset(offset) {} T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset) : op(op), s(s), rt(&rt), offset(offset) {}
T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label) : op(op), s(s), rt(&rt) { T32_LDR_LIT::T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label* label) : op(op), s(s), rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off T32_LDR_LIT::getImmPCOffset() { Off T32_LDR_LIT::GetImmPCOffset() {
return get()->U == add ? get()->imm12 : -get()->imm12; return Get()->U == add ? Get()->imm12 : -Get()->imm12;
} }
void T32_LDR_LIT::onOffsetApply(Off offset) { void T32_LDR_LIT::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
if (offset >= 0) { if (offset >= 0) {
get()->U = add; Get()->U = add;
get()->imm12 = static_cast<InstT32>(offset); Get()->imm12 = static_cast<InstT32>(offset);
} else { } else {
get()->U = cmp; Get()->U = cmp;
get()->imm12 = static_cast<InstT32>(-offset); Get()->imm12 = static_cast<InstT32>(-offset);
} }
} }
void T32_LDR_LIT::decode(T32_STRUCT_LDR_LIT *inst) { void T32_LDR_LIT::Disassemble() {
DECODE_OP; DECODE_OP;
DECODE_RT(Reg); DECODE_RT(Reg);
s = S(inst->S); s = S(Get()->S);
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void T32_LDR_LIT::assembler() { void T32_LDR_LIT::Assemble() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->S = s; Get()->S = s;
if (offset >= 0) { if (offset >= 0) {
get()->U = add; Get()->U = add;
get()->imm12 = static_cast<InstT32>(offset); Get()->imm12 = static_cast<InstT32>(offset);
} else { } else {
get()->U = cmp; Get()->U = cmp;
get()->imm12 = static_cast<InstT32>(-offset); Get()->imm12 = static_cast<InstT32>(-offset);
} }
} }
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM() {}
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst) : InstructionT32(inst) { T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(void *inst) : InstructionT32(inst) {
decode(inst);
} }
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_MOV_MOVT_IMM::OP op, RegisterA32 &rd, U16 imm16) : op(op), T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_MOV_MOVT_IMM::OP op, RegisterA32 &rd, U16 imm16) : op(op),
rd(&rd), rd(&rd),
imm16(imm16) {} imm16(imm16) {}
void T32_MOV_MOVT_IMM::decode(T32_STRUCT_MOV_MOVT_IMM *inst) { void T32_MOV_MOVT_IMM::Disassemble() {
DECODE_OP; DECODE_OP;
DECODE_RD(Reg); DECODE_RD(Reg);
U16 imm4i = COMBINE(inst->imm4, inst->i, 1); U16 imm4i = COMBINE(Get()->imm4, Get()->i, 1);
U16 imm38 = COMBINE(inst->imm3, inst->imm8, 8); U16 imm38 = COMBINE(Get()->imm3, Get()->imm8, 8);
imm16 = COMBINE(imm4i, imm38, 11); imm16 = COMBINE(imm4i, imm38, 11);
} }
void T32_MOV_MOVT_IMM::assembler() { void T32_MOV_MOVT_IMM::Assemble() {
SET_OPCODE_MULTI(MOV_MOVT_IMM, 1); SET_OPCODE_MULTI(MOV_MOVT_IMM, 1);
SET_OPCODE_MULTI(MOV_MOVT_IMM, 2); SET_OPCODE_MULTI(MOV_MOVT_IMM, 2);
ENCODE_OP; ENCODE_OP;
ENCODE_RD; ENCODE_RD;
get()->imm8 = BITS(imm16, 0, 7); Get()->imm8 = BITS(imm16, 0, 7);
get()->imm3 = BITS(imm16, 8 ,10); Get()->imm3 = BITS(imm16, 8 ,10);
get()->i = BIT(imm16, 11); Get()->i = BIT(imm16, 11);
get()->imm4 = BITS(imm16, 12, 15); Get()->imm4 = BITS(imm16, 12, 15);
} }
T32_LDR_IMM::T32_LDR_IMM(T32_STRUCT_LDR_IMM *inst) : InstructionT32(inst) { T32_LDR_IMM::T32_LDR_IMM(void *inst) : InstructionT32(inst) {
decode(inst);
} }
T32_LDR_IMM::T32_LDR_IMM(T32_LDR_IMM::OP op, RegisterA32 &rt, const MemOperand &operand) : op(op), T32_LDR_IMM::T32_LDR_IMM(T32_LDR_IMM::OP op, RegisterA32 &rt, const MemOperand &operand) : op(op),
rt(&rt), rt(&rt),
operand(operand) {} operand(operand) {}
void T32_LDR_IMM::decode(T32_STRUCT_LDR_IMM *inst) { void T32_LDR_IMM::Disassemble() {
DECODE_OP; DECODE_OP;
DECODE_RT(Reg); DECODE_RT(Reg);
operand.rn = Reg(static_cast<U8>(inst->rn)); operand.rn = Reg(static_cast<U8>(Get()->rn));
if (inst->P == 1 && inst->U == 0 && inst->W == 0) { if (Get()->P == 1 && Get()->U == 0 && Get()->W == 0) {
operand.addr_mode = Offset; operand.addr_mode = Offset;
} else if (inst->P == 0 && inst->W == 1) { } else if (Get()->P == 0 && Get()->W == 1) {
operand.addr_mode = PostIndex; operand.addr_mode = PostIndex;
} else if (inst->P == 1 && inst->W == 1) { } else if (Get()->P == 1 && Get()->W == 1) {
operand.addr_mode = PreIndex; operand.addr_mode = PreIndex;
} else { } else {
valid = false; valid_ = false;
} }
operand.offset = inst->U == 0 ? -inst->imm8 : inst->imm8; operand.offset = Get()->U == 0 ? -Get()->imm8 : Get()->imm8;
} }
void T32_LDR_IMM::assembler() { void T32_LDR_IMM::Assemble() {
SET_OPCODE_MULTI(LDR_IMM, 1); SET_OPCODE_MULTI(LDR_IMM, 1);
SET_OPCODE_MULTI(LDR_IMM, 2); SET_OPCODE_MULTI(LDR_IMM, 2);
ENCODE_OP; ENCODE_OP;
get()->rn = operand.rn->getCode(); Get()->rn = operand.rn->Code();
if (operand.offset < 0) { if (operand.offset < 0) {
get()->imm8 = static_cast<InstT32>(-operand.offset); Get()->imm8 = static_cast<InstT32>(-operand.offset);
get()->U = 0; Get()->U = 0;
} else { } else {
get()->imm8 = static_cast<InstT32>(operand.offset); Get()->imm8 = static_cast<InstT32>(operand.offset);
get()->U = 1; Get()->U = 1;
} }
switch (operand.addr_mode) { switch (operand.addr_mode) {
case Offset: case Offset:
get()->P = 1; Get()->P = 1;
get()->U = 0; Get()->U = 0;
get()->W = 0; Get()->W = 0;
break; break;
case PostIndex: case PostIndex:
get()->P = 0; Get()->P = 0;
get()->W = 1; Get()->W = 1;
break; break;
case PreIndex: case PreIndex:
get()->P = 1; Get()->P = 1;
get()->W = 1; Get()->W = 1;
break; break;
default: default:
valid = false; valid_ = false;
} }
} }
T32_SUB_IMM::T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst) : InstructionT32(inst) { T32_SUB_IMM::T32_SUB_IMM(void *inst) : InstructionT32(inst) {
decode(inst);
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_INST_T32_H #pragma once
#define SANDHOOK_INST_T32_H
#include "arm_base.h" #include "arm_base.h"
#include "arm32_base.h" #include "arm32_base.h"
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
#define INST_T32(X) T32_##X #define INST_T32(X) T32_##X
#define IS_OPCODE_T32(RAW,OP) INST_T32(OP)::is(RAW) #define IS_OPCODE_T32(RAW,OP) INST_T32(OP)::Is(RAW)
#define DEFINE_IS_EXT(X, COND) \ #define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstT32& inst) { \ inline static bool Is(InstT32& inst) { \
union { \ union { \
InstT32 raw; \ InstT32 raw; \
STRUCT_T32(X) inst; \ STRUCT_T32(X) inst; \
...@@ -34,10 +34,14 @@ return COND; \ ...@@ -34,10 +34,14 @@ return COND; \
#define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_T32(X##_##INDEX) #define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_T32(X##_##INDEX)
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST(X) class INST_T32(X) : public InstructionT32<STRUCT_T32(X), ENUM_VALUE(InstCodeT32, InstCodeT32::X)>
inline U32 instCode() override { \
return ENUM_VALUE(InstCodeT32, InstCodeT32::X); \ #define DEFINE_INST_EXT(X,P) class INST_T32(X) : public INST_T32(P)
}
#define DEFINE_INST_EXT_(X,P) class INST_T32(X) : public P<STRUCT_T32(X), ENUM_VALUE(InstCodeT32, InstCodeT32::X)>
#define DEFINE_INST_PCREL(X) class INST_T32(X) : public T32_INST_PC_REL<STRUCT_T32(X), ENUM_VALUE(InstCodeT32, InstCodeT32::X)>
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -45,89 +49,73 @@ namespace SandHook { ...@@ -45,89 +49,73 @@ namespace SandHook {
namespace AsmA32 { namespace AsmA32 {
template<typename Inst> template<typename S,U32 C>
class InstructionT32 : public Instruction<Inst> { class InstructionT32 : public Instruction<S,C> {
public: public:
InstructionT32() {} InstructionT32() {}
InstructionT32(Inst *inst) : Instruction<Inst>(inst) {} InstructionT32(void *inst) : Instruction<S,C>(inst) {}
Inst mask(Inst raw) { U32 Size() override {
return raw & *(this->get());
}
U32 size() override {
return 4; return 4;
} }
void *getPC() override { void *GetPC() override {
return reinterpret_cast<void *>((Addr) Instruction<Inst>::getPC() + 2 * 2); return reinterpret_cast<void *>((Addr) Instruction<S,C>::GetPC() + 2 * 2);
} }
Addr getVPC() override { Addr GetVPC() override {
return Instruction<Inst>::getVPC() + 2 * 2; return Instruction<S,C>::GetVPC() + 2 * 2;
} }
static inline S32 signExtend32(unsigned int bits, U32 value) { InstType InstType() override {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
InstType instType() override {
return thumb32; return thumb32;
} }
Arch arch() override { Arch Arch() override {
return arm32; return arm32;
} }
}; };
template <typename Inst> template <typename S,U32 C>
class T32_INST_PC_REL : public InstructionT32<Inst> { class T32_INST_PC_REL : public InstructionT32<S,C> {
public: public:
T32_INST_PC_REL() {}; T32_INST_PC_REL() {}
T32_INST_PC_REL(Inst *inst) : InstructionT32<Inst>(inst) {}; T32_INST_PC_REL(void *inst) : InstructionT32<S,C>(inst) {};
virtual Off getImmPCOffset() { virtual Off GetImmPCOffset() {
return 0; return 0;
}; };
virtual Addr getImmPCOffsetTarget() { virtual Addr GetImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset(); return (Addr) this->GetPC() + GetImmPCOffset();
}; };
inline bool pcRelate() override { inline bool PcRelate() override {
return true; return true;
}; };
}; };
class INST_T32(UNKNOW) : public InstructionT32<STRUCT_T32(UNKNOW)> { DEFINE_INST(UNKNOW) {
public: public:
T32_UNKNOW(STRUCT_T32(UNKNOW) &inst); T32_UNKNOW(void* inst);
DEFINE_INST_CODE(UNKNOW)
inline bool unknow() override { inline bool Unknow() override {
return true; return true;
} }
void decode(T32_STRUCT_UNKNOW *inst) override;
void assembler() override;
private:
STRUCT_T32(UNKNOW) inst_backup;
}; };
class INST_T32(B32) : public T32_INST_PC_REL<STRUCT_T32(B32)> { DEFINE_INST_PCREL(B32) {
public: public:
enum OP { enum OP {
...@@ -140,23 +128,21 @@ namespace SandHook { ...@@ -140,23 +128,21 @@ namespace SandHook {
thumb = 0b1 thumb = 0b1
}; };
T32_B32(T32_STRUCT_B32 *inst); T32_B32(void *inst);
T32_B32(OP op, X x, Off offset); T32_B32(OP op, X x, Off offset);
T32_B32(OP op, X x, Label& label); T32_B32(OP op, X x, Label* label);
DEFINE_INST_CODE(B32)
DEFINE_IS_EXT(B32, TEST_INST_FIELD(opcode, OPCODE_T32(B32)) && (TEST_INST_FIELD(op, B) || TEST_INST_FIELD(op, BL))) DEFINE_IS_EXT(B32, TEST_INST_FIELD(opcode, OPCODE_T32(B32)) && (TEST_INST_FIELD(op, B) || TEST_INST_FIELD(op, BL)))
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(T32_STRUCT_B32 *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -164,19 +150,18 @@ namespace SandHook { ...@@ -164,19 +150,18 @@ namespace SandHook {
Off offset; Off offset;
}; };
class INST_T32(LDR_UIMM) : public InstructionT32<STRUCT_T32(LDR_UIMM)> { DEFINE_INST(LDR_UIMM) {
public: public:
T32_LDR_UIMM(T32_STRUCT_LDR_UIMM *inst);
T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset); T32_LDR_UIMM(void *inst);
DEFINE_INST_CODE(LDR_UIMM) T32_LDR_UIMM(RegisterA32 &rt, RegisterA32 &rn, U32 offset);
DEFINE_IS(LDR_UIMM) DEFINE_IS(LDR_UIMM)
void decode(T32_STRUCT_LDR_UIMM *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
RegisterA32* rt; RegisterA32* rt;
...@@ -185,7 +170,7 @@ namespace SandHook { ...@@ -185,7 +170,7 @@ namespace SandHook {
}; };
class INST_T32(LDR_LIT) : public T32_INST_PC_REL<STRUCT_T32(LDR_LIT)> { DEFINE_INST_PCREL(LDR_LIT) {
public: public:
enum OP { enum OP {
...@@ -204,25 +189,21 @@ namespace SandHook { ...@@ -204,25 +189,21 @@ namespace SandHook {
Sign = 0b1 Sign = 0b1
}; };
T32_LDR_LIT(); T32_LDR_LIT(void *inst);
T32_LDR_LIT(T32_STRUCT_LDR_LIT *inst);
T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset); T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Off offset);
T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label); T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label* label);
DEFINE_IS_EXT(LDR_LIT, TEST_INST_FIELD(opcode, OPCODE_T32(LDR_LIT)) && (TEST_INST_FIELD(op, LDR) || TEST_INST_FIELD(op, LDRB) || TEST_INST_FIELD(op, LDRH))) DEFINE_IS_EXT(LDR_LIT, TEST_INST_FIELD(opcode, OPCODE_T32(LDR_LIT)) && (TEST_INST_FIELD(op, LDR) || TEST_INST_FIELD(op, LDRB) || TEST_INST_FIELD(op, LDRH)))
DEFINE_INST_CODE(LDR_LIT) Off GetImmPCOffset() override;
Off getImmPCOffset() override; void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; void Disassemble() override;
void decode(T32_STRUCT_LDR_LIT *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -232,7 +213,7 @@ namespace SandHook { ...@@ -232,7 +213,7 @@ namespace SandHook {
}; };
class INST_T32(MOV_MOVT_IMM) : public InstructionT32<STRUCT_T32(MOV_MOVT_IMM)> { DEFINE_INST(MOV_MOVT_IMM) {
public: public:
enum OP { enum OP {
...@@ -240,19 +221,15 @@ namespace SandHook { ...@@ -240,19 +221,15 @@ namespace SandHook {
MOVT = 0b101100 MOVT = 0b101100
}; };
T32_MOV_MOVT_IMM(); T32_MOV_MOVT_IMM(void *inst);
T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst);
T32_MOV_MOVT_IMM(OP op, RegisterA32 &rd, U16 imm16); T32_MOV_MOVT_IMM(OP op, RegisterA32 &rd, U16 imm16);
DEFINE_IS_EXT(MOV_MOVT_IMM, TEST_INST_OPCODE(MOV_MOVT_IMM, 1) && TEST_INST_OPCODE(MOV_MOVT_IMM, 2) && (TEST_INST_FIELD(op, MOV) || TEST_INST_FIELD(op, MOVT))) DEFINE_IS_EXT(MOV_MOVT_IMM, TEST_INST_OPCODE(MOV_MOVT_IMM, 1) && TEST_INST_OPCODE(MOV_MOVT_IMM, 2) && (TEST_INST_FIELD(op, MOV) || TEST_INST_FIELD(op, MOVT)))
DEFINE_INST_CODE(MOV_MOVT_IMM) void Disassemble() override;
void decode(T32_STRUCT_MOV_MOVT_IMM *inst) override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -261,7 +238,7 @@ namespace SandHook { ...@@ -261,7 +238,7 @@ namespace SandHook {
}; };
class INST_T32(LDR_IMM) : public InstructionT32<STRUCT_T32(LDR_IMM)> { DEFINE_INST(LDR_IMM) {
public: public:
enum OP { enum OP {
...@@ -272,17 +249,15 @@ namespace SandHook { ...@@ -272,17 +249,15 @@ namespace SandHook {
LDRSH = 0b0011 LDRSH = 0b0011
}; };
T32_LDR_IMM(T32_STRUCT_LDR_IMM *inst); T32_LDR_IMM(void *inst);
T32_LDR_IMM(OP op, RegisterA32 &rt, const MemOperand &operand); T32_LDR_IMM(OP op, RegisterA32 &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDR_IMM, TEST_INST_OPCODE(LDR_IMM, 1) && TEST_INST_OPCODE(LDR_IMM, 2)) DEFINE_IS_EXT(LDR_IMM, TEST_INST_OPCODE(LDR_IMM, 1) && TEST_INST_OPCODE(LDR_IMM, 2))
DEFINE_INST_CODE(LDR_IMM) void Disassemble() override;
void decode(T32_STRUCT_LDR_IMM *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -291,7 +266,7 @@ namespace SandHook { ...@@ -291,7 +266,7 @@ namespace SandHook {
}; };
class INST_T32(SUB_IMM) : public InstructionT32<STRUCT_T32(SUB_IMM)> { DEFINE_INST(SUB_IMM) {
public: public:
enum OP { enum OP {
...@@ -299,11 +274,10 @@ namespace SandHook { ...@@ -299,11 +274,10 @@ namespace SandHook {
T4 = 0b10101 T4 = 0b10101
}; };
T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst); T32_SUB_IMM(void *inst);
DEFINE_IS_EXT(SUB_IMM, TEST_INST_OPCODE(SUB_IMM, 1) && TEST_INST_OPCODE(SUB_IMM, 2) && (TEST_INST_FIELD(op, T3) || TEST_INST_FIELD(op, T4))) DEFINE_IS_EXT(SUB_IMM, TEST_INST_OPCODE(SUB_IMM, 1) && TEST_INST_OPCODE(SUB_IMM, 2) && (TEST_INST_FIELD(op, T3) || TEST_INST_FIELD(op, T4)))
DEFINE_INST_CODE(SUB_IMM)
}; };
} }
...@@ -314,6 +288,7 @@ namespace SandHook { ...@@ -314,6 +288,7 @@ namespace SandHook {
#undef DEFINE_IS #undef DEFINE_IS
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST
#undef DEFINE_INST_EXT
#endif //SANDHOOK_INST_T32_H #undef DEFINE_INST_EXT_
#undef DEFINE_INST_PCREL
\ No newline at end of file
...@@ -14,7 +14,7 @@ SandHook::Asm::RegisterA32::RegisterA32() { ...@@ -14,7 +14,7 @@ SandHook::Asm::RegisterA32::RegisterA32() {
} }
U8 SandHook::Asm::RegisterA32::getWide() { U8 SandHook::Asm::RegisterA32::Wide() {
return 4; return 4;
} }
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_REGISTER_A32_H #pragma once
#define SANDHOOK_NH_REGISTER_A32_H
#include "base.h" #include "base.h"
#include "register.h" #include "register.h"
...@@ -33,10 +32,10 @@ namespace SandHook { ...@@ -33,10 +32,10 @@ namespace SandHook {
RegisterA32(U8 code); RegisterA32(U8 code);
U8 getWide() override; U8 Wide() override;
virtual bool isUnkonw () { virtual bool isUnkonw () {
return getCode() == 38; return Code() == 38;
} }
static RegisterA32* get(U8 code) { static RegisterA32* get(U8 code) {
...@@ -48,5 +47,3 @@ namespace SandHook { ...@@ -48,5 +47,3 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_A32_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_REGISTER_LIST_A32_H #pragma once
#define SANDHOOK_NH_REGISTER_LIST_A32_H
#include "register_arm32.h" #include "register_arm32.h"
...@@ -31,5 +30,3 @@ namespace RegistersA32 { ...@@ -31,5 +30,3 @@ namespace RegistersA32 {
extern RegisterA32 UnknowRegiser; extern RegisterA32 UnknowRegiser;
}} }}
#define Reg(N) RegisterA32::get(N) #define Reg(N) RegisterA32::get(N)
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_LIST_A32_H
...@@ -20,59 +20,59 @@ case ENUM_VALUE(InstCode##T, InstCode##T::X): \ ...@@ -20,59 +20,59 @@ case ENUM_VALUE(InstCode##T, InstCode##T::X): \
relocate_##T##_##X(reinterpret_cast<INST_##T(X)*>(instruction), toPc); \ relocate_##T##_##X(reinterpret_cast<INST_##T(X)*>(instruction), toPc); \
break; break;
CodeRelocateA32::CodeRelocateA32(AssemblerA32 &assembler) : CodeRelocate(assembler.codeContainer) { CodeRelocateA32::CodeRelocateA32(AssemblerA32 &assembler) : CodeRelocate(assembler.code_container) {
this->assemblerA32 = &assembler; this->assemblerA32 = &assembler;
} }
bool CodeRelocateA32::visit(Unit<Base> *unit, void *pc) { bool CodeRelocateA32::Visit(BaseUnit *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC()); Relocate(reinterpret_cast<BaseInst *>(unit), __ GetPC());
curOffset += unit->size(); cur_offset += unit->Size();
if (unit->refcount() == 0) { if (unit->RefCount() == 0) {
delete unit; delete unit;
} }
return true; return true;
} }
void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) { void* CodeRelocateA32::Relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) {
AutoLock autoLock(relocateLock); AutoLock autoLock(relocate_lock);
startAddr = reinterpret_cast<Addr>(startPc); start_addr = reinterpret_cast<Addr>(startPc);
if (isThumbCode(startAddr)) { if (IsThumbCode(start_addr)) {
startAddr = reinterpret_cast<Addr>(getThumbCodeAddress(startPc)); start_addr = reinterpret_cast<Addr>(GetThumbCodeAddress(startPc));
} }
length = len; length = len;
curOffset = 0; cur_offset = 0;
__ allocBufferFirst(static_cast<U32>(len * 8)); __ AllocBufferFirst(static_cast<U32>(len * 8));
void* curPc = __ getPC(); void* curPc = __ GetPC();
if (toPc == nullptr) { if (toPc == nullptr) {
Disassembler::get()->decode(startPc, len, *this, true); Disassembler::Get()->Disassemble(startPc, len, *this, true);
} else { } else {
//TODO //TODO
} }
return curPc; return curPc;
} }
void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA32::Relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = __ getPC(); void* cur_pc = __ GetPC();
//insert later bind labels //insert later AddBind labels
__ Emit(getLaterBindLabel(curOffset)); __ Emit(GetLaterBindLabel(cur_offset));
if (!instruction->pcRelate()) { if (!instruction->PcRelate()) {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
return curPc; return cur_pc;
} }
if (instruction->instType() == thumb32) { if (instruction->InstType() == thumb32) {
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(T32, B32) CASE(T32, B32)
CASE(T32, LDR_LIT) CASE(T32, LDR_LIT)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
} else if (instruction->instType() == thumb16) { } else if (instruction->InstType() == thumb16) {
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(T16, B) CASE(T16, B)
CASE(T16, B_COND) CASE(T16, B_COND)
CASE(T16, BX_BLX) CASE(T16, BX_BLX)
...@@ -82,31 +82,31 @@ void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -82,31 +82,31 @@ void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) thro
CASE(T16, ADD_REG_RDN) CASE(T16, ADD_REG_RDN)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
} else { } else {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
return curPc; return cur_pc;
} }
IMPL_RELOCATE(T16, B_COND) { IMPL_RELOCATE(T16, B_COND) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (InRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
__ B(inst->condition, getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); __ B(inst->condition, GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
if (inst->condition == al) { if (inst->condition == al) {
Label* target_label = new Label; Label* target_label = new Label;
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_label); __ Ldr(PC, target_label);
__ Emit(target_label); __ Emit(target_label);
__ Emit(targetAddr); __ Emit(target_addr);
} else { } else {
Label* true_label = new Label(); Label* true_label = new Label();
Label* false_label = new Label(); Label* false_label = new Label();
...@@ -117,7 +117,7 @@ IMPL_RELOCATE(T16, B_COND) { ...@@ -117,7 +117,7 @@ IMPL_RELOCATE(T16, B_COND) {
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_label); __ Ldr(PC, target_label);
__ Emit(target_label); __ Emit(target_label);
__ Emit(targetAddr); __ Emit(target_addr);
__ Emit(false_label); __ Emit(false_label);
} }
...@@ -125,96 +125,96 @@ IMPL_RELOCATE(T16, B_COND) { ...@@ -125,96 +125,96 @@ IMPL_RELOCATE(T16, B_COND) {
IMPL_RELOCATE(T16, B) { IMPL_RELOCATE(T16, B) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (InRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
__ B(getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); __ B(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
Label* target_label = new Label(); Label* target_label = new Label();
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_label); __ Ldr(PC, target_label);
__ Emit(target_label); __ Emit(target_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(targetAddr))); __ Emit((Addr) GetThumbPC(reinterpret_cast<void *>(target_addr)));
} }
IMPL_RELOCATE(T16, BX_BLX) { IMPL_RELOCATE(T16, BX_BLX) {
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
inst->ref(); inst->Ref();
} }
IMPL_RELOCATE(T16, CBZ_CBNZ) { IMPL_RELOCATE(T16, CBZ_CBNZ) {
inst->ref(); inst->Ref();
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (InRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
Label* true_label = new Label; Label* true_label = new Label;
Label* false_label = new Label; Label* false_label = new Label;
Label* target_label = new Label(); Label* target_label = new Label();
inst->bindLabel(*true_label); inst->BindLabel(true_label);
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
__ B(false_label); __ B(false_label);
__ Emit(true_label); __ Emit(true_label);
ALIGN_FOR_LDR ALIGN_FOR_LDR
__ Ldr(PC, target_label); __ Ldr(PC, target_label);
__ Emit(target_label); __ Emit(target_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(targetAddr))); __ Emit((Addr) GetThumbPC(reinterpret_cast<void *>(target_addr)));
__ Emit(false_label); __ Emit(false_label);
} }
IMPL_RELOCATE(T16, LDR_LIT) { IMPL_RELOCATE(T16, LDR_LIT) {
if (inRelocateRange(CODE_OFFSET(inst), inst->rt->getWide())) { if (InRelocateRange(CODE_OFFSET(inst), inst->rt->Wide())) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rt, targetAddr); __ Mov(*inst->rt, target_addr);
__ Ldr(*inst->rt, MemOperand(inst->rt, 0)); __ Ldr(*inst->rt, MemOperand(inst->rt, 0));
} }
IMPL_RELOCATE(T16, ADR) { IMPL_RELOCATE(T16, ADR) {
if (inRelocateRange(CODE_OFFSET(inst), inst->rd->getWide())) { if (InRelocateRange(CODE_OFFSET(inst), inst->rd->Wide())) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rd, targetAddr); __ Mov(*inst->rd, target_addr);
} }
IMPL_RELOCATE(T16, ADD_REG_RDN) { IMPL_RELOCATE(T16, ADD_REG_RDN) {
if (*inst->rm != PC) { if (*inst->rm != PC) {
inst->ref(); inst->Ref();
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
RegisterA32& tmpReg = *inst->rdn != R0 ? R0 : R1; RegisterA32& tmpReg = *inst->rdn != R0 ? R0 : R1;
__ Push(tmpReg); __ Push(tmpReg);
__ Mov(tmpReg,(Addr)inst->getPC()); __ Mov(tmpReg,(Addr)inst->GetPC());
__ Add(*inst->rdn, *inst->rdn, tmpReg); __ Add(*inst->rdn, *inst->rdn, tmpReg);
__ Pop(tmpReg); __ Pop(tmpReg);
...@@ -222,21 +222,21 @@ IMPL_RELOCATE(T16, ADD_REG_RDN) { ...@@ -222,21 +222,21 @@ IMPL_RELOCATE(T16, ADD_REG_RDN) {
IMPL_RELOCATE(T32, B32) { IMPL_RELOCATE(T32, B32) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (InRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base> *>(inst)); __ Emit(reinterpret_cast<BaseInst *>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
if (inst->x == T32_B32::thumb) { if (inst->x == T32_B32::thumb) {
//Thumb mode //Thumb mode
targetAddr = reinterpret_cast<Addr>(getThumbPC(reinterpret_cast<void *>(targetAddr))); target_addr = reinterpret_cast<Addr>(GetThumbPC(reinterpret_cast<void *>(target_addr)));
} }
__ Mov(IP, targetAddr); __ Mov(IP, target_addr);
if (inst->op == T32_B32::BL) { if (inst->op == T32_B32::BL) {
__ Blx(IP); __ Blx(IP);
} else { } else {
...@@ -247,16 +247,16 @@ IMPL_RELOCATE(T32, B32) { ...@@ -247,16 +247,16 @@ IMPL_RELOCATE(T32, B32) {
IMPL_RELOCATE(T32, LDR_LIT) { IMPL_RELOCATE(T32, LDR_LIT) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(Addr))) { if (InRelocateRange(CODE_OFFSET(inst), sizeof(Addr))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->BindLabel(GetLaterBindLabel(CODE_OFFSET(inst) + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
__ Mov(*inst->rt, targetAddr); __ Mov(*inst->rt, target_addr);
switch (inst->op) { switch (inst->op) {
case T32_LDR_LIT::LDR: case T32_LDR_LIT::LDR:
__ Ldr(*inst->rt, MemOperand(inst->rt, 0)); __ Ldr(*inst->rt, MemOperand(inst->rt, 0));
...@@ -276,8 +276,8 @@ IMPL_RELOCATE(T32, LDR_LIT) { ...@@ -276,8 +276,8 @@ IMPL_RELOCATE(T32, LDR_LIT) {
} }
break; break;
default: default:
inst->ref(); inst->Ref();
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
} }
} }
\ No newline at end of file
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_CODE_RELOCATE_ARM32_H #pragma once
#define SANDHOOK_CODE_RELOCATE_ARM32_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -23,11 +22,11 @@ namespace SandHook { ...@@ -23,11 +22,11 @@ namespace SandHook {
public: public:
CodeRelocateA32(AssemblerA32 &assembler); CodeRelocateA32(AssemblerA32 &assembler);
void* relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override; void* Relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) override;
void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override; void* Relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override;
bool visit(Unit<Base> *unit, void *pc) override; bool Visit(BaseUnit *unit, void *pc) override;
DEFINE_RELOCATE(T16, B_COND) DEFINE_RELOCATE(T16, B_COND)
...@@ -56,5 +55,3 @@ namespace SandHook { ...@@ -56,5 +55,3 @@ namespace SandHook {
} }
#undef DEFINE_RELOCATE #undef DEFINE_RELOCATE
\ No newline at end of file
#endif //SANDHOOK_CODE_RELOCATE_ARM32_H
...@@ -9,42 +9,42 @@ using namespace SandHook::RegistersA64; ...@@ -9,42 +9,42 @@ using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64; using namespace SandHook::AsmA64;
AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) { AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer); code_container.SetCodeBuffer(codeBuffer);
} }
void *AssemblerA64::getPC() { void *AssemblerA64::GetPC() {
return reinterpret_cast<void *>(codeContainer.curPc); return reinterpret_cast<void *>(code_container.cur_pc);
} }
void *AssemblerA64::getStartPC() { void *AssemblerA64::GetStartPC() {
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(code_container.start_pc);
} }
void AssemblerA64::allocBufferFirst(U32 size) { void AssemblerA64::AllocBufferFirst(U32 size) {
codeContainer.allocBufferFirst(size); code_container.AllocBufferFirst(size);
} }
void *AssemblerA64::finish() { void *AssemblerA64::Finish() {
codeContainer.commit(); code_container.Commit();
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(code_container.start_pc);
} }
void AssemblerA64::Emit(U64 data64) { void AssemblerA64::Emit(U64 data64) {
Emit(reinterpret_cast<Unit<Base>*>(new Data64(data64))); Emit(reinterpret_cast<BaseUnit*>(new Data64(data64)));
} }
void AssemblerA64::Emit(U32 data32) { void AssemblerA64::Emit(U32 data32) {
Emit(reinterpret_cast<Unit<Base>*>(new Data32(data32))); Emit(reinterpret_cast<BaseUnit*>(new Data32(data32)));
} }
void AssemblerA64::Emit(Unit<Base> *unit) { void AssemblerA64::Emit(BaseUnit *unit) {
codeContainer.append(unit); code_container.Append(unit);
} }
void AssemblerA64::MoveWide(RegisterA64 &rd, INST_A64(MOV_WIDE)::OP op, U64 imme, void AssemblerA64::MoveWide(RegisterA64 &rd, INST_A64(MOV_WIDE)::OP op, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) { INST_A64(MOV_WIDE)::Shift shift) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(MOV_WIDE)(op, &rd, imme, shift))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(MOV_WIDE)(op, &rd, imme, shift)));
} }
void AssemblerA64::Mov(WRegister &rd, U32 imme) { void AssemblerA64::Mov(WRegister &rd, U32 imme) {
...@@ -83,106 +83,106 @@ void AssemblerA64::Movn(RegisterA64 &rd, U64 imme, ...@@ -83,106 +83,106 @@ void AssemblerA64::Movn(RegisterA64 &rd, U64 imme,
} }
void AssemblerA64::Br(XRegister &rn) { void AssemblerA64::Br(XRegister &rn) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(BR_BLR_RET)(INST_A64(BR_BLR_RET)::BR, rn))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(BR_BLR_RET)(INST_A64(BR_BLR_RET)::BR, rn)));
} }
void AssemblerA64::Blr(XRegister &rn) { void AssemblerA64::Blr(XRegister &rn) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(BR_BLR_RET)(INST_A64(BR_BLR_RET)::BLR, rn))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(BR_BLR_RET)(INST_A64(BR_BLR_RET)::BLR, rn)));
} }
void AssemblerA64::B(Off offset) { void AssemblerA64::B(Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, offset))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, offset)));
} }
void AssemblerA64::B(Label *label) { void AssemblerA64::B(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, *label))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, label)));
} }
void AssemblerA64::Bl(Off offset) { void AssemblerA64::Bl(Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, offset))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, offset)));
} }
void AssemblerA64::Bl(Label *label) { void AssemblerA64::Bl(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, *label))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, label)));
} }
void AssemblerA64::B(Condition condition, Off offset) { void AssemblerA64::B(Condition condition, Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, offset))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_COND)(condition, offset)));
} }
void AssemblerA64::B(Condition condition, Label *label) { void AssemblerA64::B(Condition condition, Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, *label))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(B_COND)(condition, label)));
} }
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Label *label) { void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, *label)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, label))));
} }
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Off offset) { void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, offset)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, offset))));
} }
void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Off offset) { void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, offset)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, offset))));
} }
void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Label *label) { void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, *label)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, label))));
} }
void AssemblerA64::Cbz(RegisterA64 &rt, Off offset) { void AssemblerA64::Cbz(RegisterA64 &rt, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, offset, rt)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, offset, rt))));
} }
void AssemblerA64::Cbz(RegisterA64 &rt, Label *label) { void AssemblerA64::Cbz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, *label, rt)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, label, rt))));
} }
void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) { void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, offset, rt)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, offset, rt))));
} }
void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) { void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, *label, rt)))); Emit((reinterpret_cast<BaseUnit *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, label, rt))));
} }
void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) { void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) { if (memOperand.addr_mode_ == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_UIMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(STR_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_IMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(STR_IMM)(rt, memOperand)));
} }
} }
void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) { void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) {
if (memOperand.addr_mode == Offset && memOperand.offset >= 0) { if (memOperand.addr_mode_ == Offset && memOperand.offset_ >= 0) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_UIMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDR_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_IMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDR_IMM)(rt, memOperand)));
} }
} }
void AssemblerA64::Ldr(RegisterA64 &rt, Label* label) { void AssemblerA64::Ldr(RegisterA64 &rt, Label* label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(rt.isX() ? INST_A64(LDR_LIT)::LDR_X : INST_A64(LDR_LIT)::LDR_W, rt, *label))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDR_LIT)(rt.isX() ? INST_A64(LDR_LIT)::LDR_X : INST_A64(LDR_LIT)::LDR_W, rt, label)));
} }
void AssemblerA64::Ldrsw(RegisterA64 &rt, Label* label) { void AssemblerA64::Ldrsw(RegisterA64 &rt, Label* label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(INST_A64(LDR_LIT)::LDR_SW, rt, *label))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDR_LIT)(INST_A64(LDR_LIT)::LDR_SW, rt, label)));
} }
void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) { void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) { if (memOperand.addr_mode_ == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDRSW_UIMM)(rt, memOperand)));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_IMM)(rt, memOperand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(LDRSW_IMM)(rt, memOperand)));
} }
} }
// If the current stack pointer is sp, then it must be aligned to 16 bytes // If the current stack pointer is sp, then it must be aligned to 16 bytes
// on entry and the total size of the specified registers must also be a // on entry and the total Size of the specified registers must also be a
// multiple of 16 bytes. // multiple of 16 bytes.
void AssemblerA64::Pop(RegisterA64 &rd) { void AssemblerA64::Pop(RegisterA64 &rd) {
if (rd.isX()) { if (rd.isX()) {
...@@ -193,7 +193,7 @@ void AssemblerA64::Pop(RegisterA64 &rd) { ...@@ -193,7 +193,7 @@ void AssemblerA64::Pop(RegisterA64 &rd) {
} }
// If the current stack pointer is sp, then it must be aligned to 16 bytes // If the current stack pointer is sp, then it must be aligned to 16 bytes
// on entry and the total size of the specified registers must also be a // on entry and the total Size of the specified registers must also be a
// multiple of 16 bytes. // multiple of 16 bytes.
void AssemblerA64::Push(RegisterA64 &rt) { void AssemblerA64::Push(RegisterA64 &rt) {
if (rt.isX()) { if (rt.isX()) {
...@@ -208,55 +208,55 @@ void AssemblerA64::Cmp(RegisterA64 &rn, const Operand &operand) { ...@@ -208,55 +208,55 @@ void AssemblerA64::Cmp(RegisterA64 &rn, const Operand &operand) {
} }
void AssemblerA64::Subs(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand) { void AssemblerA64::Subs(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(SUB_EXT_REG)(rd, rn, operand, SetFlags))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(SUB_EXT_REG)(rd, rn, operand, SetFlags)));
} }
void AssemblerA64::Stp(RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand operand) { void AssemblerA64::Stp(RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STP_LDP)(INST_A64(STP_LDP)::STP, rt1, rt2, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(STP_LDP)(INST_A64(STP_LDP)::STP, rt1, rt2, operand)));
} }
void AssemblerA64::Ldp(RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand operand) { void AssemblerA64::Ldp(RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STP_LDP)(INST_A64(STP_LDP)::LDP, rt1, rt2, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(STP_LDP)(INST_A64(STP_LDP)::LDP, rt1, rt2, operand)));
} }
void AssemblerA64::Add(RegisterA64 &rd, const Operand &operand) { void AssemblerA64::Add(RegisterA64 &rd, const Operand &operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::ADD, INST_A64(ADD_SUB_IMM)::UnSign, rd, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::ADD, INST_A64(ADD_SUB_IMM)::UnSign, rd, operand)));
} }
void AssemblerA64::Adds(RegisterA64 &rd, const Operand &operand) { void AssemblerA64::Adds(RegisterA64 &rd, const Operand &operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::ADD, INST_A64(ADD_SUB_IMM)::Sign, rd, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::ADD, INST_A64(ADD_SUB_IMM)::Sign, rd, operand)));
} }
void AssemblerA64::Sub(RegisterA64 &rd, const Operand &operand) { void AssemblerA64::Sub(RegisterA64 &rd, const Operand &operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::SUB, INST_A64(ADD_SUB_IMM)::UnSign, rd, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::SUB, INST_A64(ADD_SUB_IMM)::UnSign, rd, operand)));
} }
void AssemblerA64::Subs(RegisterA64 &rd, const Operand &operand) { void AssemblerA64::Subs(RegisterA64 &rd, const Operand &operand) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::SUB, INST_A64(ADD_SUB_IMM)::Sign, rd, operand))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(ADD_SUB_IMM)(INST_A64(ADD_SUB_IMM)::SUB, INST_A64(ADD_SUB_IMM)::Sign, rd, operand)));
} }
void AssemblerA64::Mrs(SystemRegister &sysReg, RegisterA64 &rt) { void AssemblerA64::Mrs(SystemRegister &sys_reg, RegisterA64 &rt) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(MSR_MRS)(INST_A64(MSR_MRS)::MRS, sysReg, rt))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(MSR_MRS)(INST_A64(MSR_MRS)::MRS, sys_reg, rt)));
} }
void AssemblerA64::Msr(SystemRegister &sysReg, RegisterA64 &rt) { void AssemblerA64::Msr(SystemRegister &sysReg, RegisterA64 &rt) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(MSR_MRS)(INST_A64(MSR_MRS)::MSR, sysReg, rt))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(MSR_MRS)(INST_A64(MSR_MRS)::MSR, sysReg, rt)));
} }
void AssemblerA64::Mov(RegisterA64 &rd, RegisterA64& rt) { void AssemblerA64::Mov(RegisterA64 &rd, RegisterA64& rt) {
if (rd == SP || rt == SP) { if (rd == SP || rt == SP) {
Add(rd, Operand(&rt, 0)); Add(rd, Operand(&rt, 0));
} else { } else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(MOV_REG)(rd, rt))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(MOV_REG)(rd, rt)));
} }
} }
void AssemblerA64::Svc(U16 imm) { void AssemblerA64::Svc(U16 imm) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(SVC)(imm))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(SVC)(imm)));
} }
void AssemblerA64::Hvc(U16 imm) { void AssemblerA64::Hvc(U16 imm) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(EXCEPTION_GEN)(INST_A64(EXCEPTION_GEN)::XXC, EL2, imm))); Emit(reinterpret_cast<BaseUnit *>(new INST_A64(EXCEPTION_GEN)(INST_A64(EXCEPTION_GEN)::XXC, EL2, imm)));
} }
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_ASSEMBLER_A64_H #pragma once
#define SANDHOOK_NH_ASSEMBLER_A64_H
#include "assembler.h" #include "assembler.h"
#include "register_arm64.h" #include "register_arm64.h"
...@@ -19,14 +18,14 @@ namespace SandHook { ...@@ -19,14 +18,14 @@ namespace SandHook {
public: public:
AssemblerA64(CodeBuffer* codeBuffer); AssemblerA64(CodeBuffer* codeBuffer);
void allocBufferFirst(U32 size); void AllocBufferFirst(U32 size);
void* getStartPC(); void* GetStartPC();
void* getPC(); void* GetPC();
void* finish(); void* Finish();
void Emit(U32 data32); void Emit(U32 data32);
void Emit(U64 data64); void Emit(U64 data64);
void Emit(Unit<Base>* unit); void Emit(BaseUnit* unit);
void MoveWide(RegisterA64& rd, INST_A64(MOV_WIDE)::OP op, U64 imme, INST_A64(MOV_WIDE)::Shift shift); void MoveWide(RegisterA64& rd, INST_A64(MOV_WIDE)::OP op, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
...@@ -85,7 +84,7 @@ namespace SandHook { ...@@ -85,7 +84,7 @@ namespace SandHook {
void Subs(RegisterA64& rd, const Operand& operand); void Subs(RegisterA64& rd, const Operand& operand);
void Msr(SystemRegister &sysReg, RegisterA64& rt); void Msr(SystemRegister &sysReg, RegisterA64& rt);
void Mrs(SystemRegister &sysReg, RegisterA64& rt); void Mrs(SystemRegister &sys_reg, RegisterA64& rt);
void Mov(RegisterA64& rd, RegisterA64& rt); void Mov(RegisterA64& rd, RegisterA64& rt);
...@@ -95,10 +94,8 @@ namespace SandHook { ...@@ -95,10 +94,8 @@ namespace SandHook {
public: public:
CodeContainer codeContainer = CodeContainer(nullptr); CodeContainer code_container = CodeContainer(nullptr);
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ASSEMBLER_A64_H
...@@ -10,18 +10,18 @@ using namespace SandHook::AsmA64; ...@@ -10,18 +10,18 @@ using namespace SandHook::AsmA64;
#define CASE(X) \ #define CASE(X) \
if (IS_OPCODE_A64(*pc, X)) { \ if (IS_OPCODE_A64(*pc, X)) { \
STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \ unit = reinterpret_cast<BaseUnit*>(new INST_A64(X)(pc)); \
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \
goto label_matched; \ goto label_matched; \
} }
Arm64Decoder* Arm64Decoder::instant = new Arm64Decoder(); Arm64Decoder* Arm64Decoder::instant = new Arm64Decoder();
void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) { void Arm64Decoder::Disassemble(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) {
InstA64 *pc = reinterpret_cast<InstA64 *>(codeStart); InstA64 *pc = reinterpret_cast<InstA64 *>(codeStart);
Addr endAddr = (Addr) codeStart + codeLen; Addr end_addr = (Addr) codeStart + codeLen;
Unit<Base>* unit = nullptr; BaseUnit* unit = nullptr;
while((Addr) pc < endAddr) { while((Addr) pc < end_addr) {
// pc relate insts // pc relate insts
CASE(B_BL) CASE(B_BL)
CASE(B_COND) CASE(B_COND)
...@@ -48,12 +48,13 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b ...@@ -48,12 +48,13 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
label_matched: label_matched:
if (unit == nullptr) { if (unit == nullptr) {
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(UNKNOW)(*reinterpret_cast<STRUCT_A64(UNKNOW) *>(pc))); unit = reinterpret_cast<BaseUnit*>(new INST_A64(UNKNOW)(pc));
} }
if (!visitor.visit(unit, pc)) { reinterpret_cast<BaseInst*>(unit)->Disassemble();
if (!visitor.Visit(unit, pc)) {
break; break;
} }
pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->size()); pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->Size());
unit = nullptr; unit = nullptr;
} }
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_DECODER_ARM64_H #pragma once
#define SANDHOOK_NH_DECODER_ARM64_H
#include "decoder.h" #include "decoder.h"
...@@ -12,12 +11,11 @@ namespace SandHook { ...@@ -12,12 +11,11 @@ namespace SandHook {
class Arm64Decoder : public InstDecoder { class Arm64Decoder : public InstDecoder {
public: public:
void decode(void *codeStart, Addr codeLen, InstVisitor &visitor, bool onlyPcRelInst) override; void Disassemble(void *codeStart, Addr codeLen, InstVisitor &visitor,
bool onlyPcRelInst) override;
public: public:
static Arm64Decoder* instant; static Arm64Decoder* instant;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_DECODER_ARM64_H
...@@ -15,18 +15,18 @@ using namespace SandHook::Utils; ...@@ -15,18 +15,18 @@ using namespace SandHook::Utils;
#include "assembler_arm64.h" #include "assembler_arm64.h"
#include "code_relocate_arm64.h" #include "code_relocate_arm64.h"
using namespace SandHook::RegistersA64; using namespace SandHook::RegistersA64;
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { void *InlineHookArm64Android::Hook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hook_lock);
void* backup = nullptr; void* backup = nullptr;
AssemblerA64 assemblerBackup(backupBuffer); AssemblerA64 assembler_backup(backup_buffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin)); StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin));
AssemblerA64 assemblerInline(&inlineBuffer); AssemblerA64 assembler_inline(&inline_buffer);
CodeContainer* codeContainerInline = &assemblerInline.codeContainer; CodeContainer* code_container_inline = &assembler_inline.code_container;
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assembler_inline.
Label* target_addr_label = new Label(); Label* target_addr_label = new Label();
__ Ldr(IP1, target_addr_label); __ Ldr(IP1, target_addr_label);
__ Br(IP1); __ Br(IP1);
...@@ -35,48 +35,48 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { ...@@ -35,48 +35,48 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
#undef __ #undef __
//build backup method //build backup method
CodeRelocateA64 relocate = CodeRelocateA64(assemblerBackup); CodeRelocateA64 relocate = CodeRelocateA64(assembler_backup);
backup = relocate.relocate(origin, codeContainerInline->size(), nullptr); backup = relocate.Relocate(origin, code_container_inline->Size(), nullptr);
#define __ assemblerBackup. #define __ assembler_backup.
Label* origin_addr_label = new Label(); Label* origin_addr_label = new Label();
__ Ldr(IP1, origin_addr_label); __ Ldr(IP1, origin_addr_label);
__ Br(IP1); __ Br(IP1);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) origin + codeContainerInline->size()); __ Emit((Addr) origin + code_container_inline->Size());
__ finish(); __ Finish();
#undef __ #undef __
//commit inline trampoline //commit inline trampoline
assemblerInline.finish(); assembler_inline.Finish();
return backup; return backup;
} }
bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[])) { bool InlineHookArm64Android::BreakPoint(void *point, void (*callback)(REG regs[])) {
AutoLock lock(hookLock); AutoLock lock(hook_lock);
void* backup = nullptr; void* backup = nullptr;
AssemblerA64 assemblerBackup(backupBuffer); AssemblerA64 assembler_backup(backup_buffer);
AssemblerA64 assemblerTrampoline(backupBuffer); AssemblerA64 assembler_trampoline(backup_buffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(point)); StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast<Addr>(point));
AssemblerA64 assemblerInline(&inlineBuffer); AssemblerA64 assembler_inline(&inline_buffer);
//build backup inst //build backup inst
CodeRelocateA64 relocate = CodeRelocateA64(assemblerBackup); CodeRelocateA64 relocate = CodeRelocateA64(assembler_backup);
backup = relocate.relocate(point, 4 * 4, nullptr); backup = relocate.Relocate(point, 4 * 4, nullptr);
#define __ assemblerBackup. #define __ assembler_backup.
Label* origin_addr_label = new Label(); Label* origin_addr_label = new Label();
__ Ldr(IP1, origin_addr_label); __ Ldr(IP1, origin_addr_label);
__ Br(IP1); __ Br(IP1);
__ Emit(origin_addr_label); __ Emit(origin_addr_label);
__ Emit((Addr) point + 4 * 4); __ Emit((Addr) point + 4 * 4);
__ finish(); __ Finish();
#undef __ #undef __
//build shell code //build shell code
#define __ assemblerTrampoline. #define __ assembler_trampoline.
//backup NZCV //backup NZCV
__ Sub(SP, Operand(&SP, 0x20)); __ Sub(SP, Operand(&SP, 0x20));
...@@ -114,19 +114,19 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[] ...@@ -114,19 +114,19 @@ bool InlineHookArm64Android::breakPoint(void *point, void (*callback)(REG regs[]
__ Mov(IP1, (Addr) backup); __ Mov(IP1, (Addr) backup);
__ Br(IP1); __ Br(IP1);
__ finish(); __ Finish();
#undef __ #undef __
void* secondTrampoline = assemblerTrampoline.getStartPC(); void* second_trampoline = assembler_trampoline.GetStartPC();
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assembler_inline.
Label* target_addr_label = new Label(); Label* target_addr_label = new Label();
__ Ldr(IP1, target_addr_label); __ Ldr(IP1, target_addr_label);
__ Br(IP1); __ Br(IP1);
__ Emit(target_addr_label); __ Emit(target_addr_label);
__ Emit((Addr) secondTrampoline); __ Emit((Addr) second_trampoline);
__ finish(); __ Finish();
#undef __ #undef __
return true; return true;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_HOOK_ARM64_H #pragma once
#define SANDHOOK_HOOK_ARM64_H
#include "hook.h" #include "hook.h"
...@@ -11,20 +10,8 @@ namespace SandHook { ...@@ -11,20 +10,8 @@ namespace SandHook {
namespace Hook { namespace Hook {
class InlineHookArm64Android : public InlineHook { class InlineHookArm64Android : public InlineHook {
public: public:
inline InlineHookArm64Android() { void *Hook(void *origin, void *replace) override;
hookLock = new std::mutex(); bool BreakPoint(void *point, void (*callback)(REG[])) override;
};
inline ~InlineHookArm64Android() {
delete hookLock;
}
void *inlineHook(void *origin, void *replace) override;
bool breakPoint(void *point, void (*callback)(REG[])) override;
protected:
std::mutex* hookLock;
}; };
} }
} }
#endif //SANDHOOK_HOOK_ARM64_H
...@@ -4,121 +4,95 @@ ...@@ -4,121 +4,95 @@
#include "inst_arm64.h" #include "inst_arm64.h"
#define SET_OPCODE(X) get()->opcode = OPCODE_A64(X) #define SET_OPCODE(X) Get()->opcode = OPCODE_A64(X)
#define SET_OPCODE_MULTI(X, INDEX) get()->opcode##INDEX = OPCODE_A64(X##_##INDEX) #define SET_OPCODE_MULTI(X, INDEX) Get()->opcode##INDEX = OPCODE_A64(X##_##INDEX)
#define DECODE_OFFSET(bits, ext) signExtend64(bits + ext, COMBINE(get()->imm##bits, 0, ext)) #define DECODE_OFFSET(bits, ext) SignExtend64(bits + ext, COMBINE(Get()->imm##bits, 0, ext))
#define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext) #define ENCODE_OFFSET(bits, ext) Get()->imm##bits = TruncateToUint##bits(offset >> ext)
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::AsmA64; using namespace SandHook::AsmA64;
template<typename InstStruct> //PC Rel Inst
U32 InstructionA64<InstStruct>::size() {
return sizeof(InstA64);
}
//Unknow
A64_UNKNOW::A64_UNKNOW(STRUCT_A64(UNKNOW) &inst) : InstructionA64(&inst) {
decode(&inst);
}
void A64_UNKNOW::decode(A64_STRUCT_UNKNOW *inst) {
inst_backup = *inst;
}
void A64_UNKNOW::assembler() { template<typename S,U32 C>
set(inst_backup); Addr A64_INST_PC_REL<S,C>::GetImmPCOffsetTarget() {
return this->GetImmPCOffset() + reinterpret_cast<Addr>(this->GetPC());
} }
//PC Rel Inst template<typename S,U32 C>
bool A64_INST_PC_REL<S,C>::PcRelate() {
template<typename Inst> return true;
A64_INST_PC_REL<Inst>::A64_INST_PC_REL(Inst *inst):InstructionA64<Inst>(inst) {
} }
template<typename Inst> template<typename S, U32 C>
A64_INST_PC_REL<Inst>::A64_INST_PC_REL() {} A64_INST_PC_REL<S, C>::A64_INST_PC_REL() {}
template<typename Inst> template<typename S, U32 C>
Addr A64_INST_PC_REL<Inst>::getImmPCOffsetTarget() { A64_INST_PC_REL<S, C>::A64_INST_PC_REL(void *inst) : InstructionA64<S,C>(inst) {
return this->getImmPCOffset() + reinterpret_cast<Addr>(this->getPC());
}
template<typename Inst>
bool A64_INST_PC_REL<Inst>::pcRelate() {
return true;
} }
//ADR ADRP //ADR ADRP
A64_ADR_ADRP::A64_ADR_ADRP() {}
A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst) { A64_ADR_ADRP::A64_ADR_ADRP(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, S64 offset) : op(op), rd(&rd), A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, S64 offset) : op(op), rd(&rd),
offset(offset) { offset(offset) {
} }
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, Label &label) { A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, Label *label) {
bindLabel(label); BindLabel(label);
} }
Off A64_ADR_ADRP::getImmPCOffset() { Off A64_ADR_ADRP::GetImmPCOffset() {
U32 hi = get()->immhi; U32 hi = Get()->immhi;
U32 lo = get()->immlo; U32 lo = Get()->immlo;
U64 imm = COMBINE(hi, lo, IMM_LO_W); U64 imm = COMBINE(hi, lo, IMM_LO_W);
if (isADRP()) { if (IsADRP()) {
return signExtend64(IMM_HI_W + IMM_LO_W + PAGE_OFFSET, imm << PAGE_OFFSET); return SignExtend64(IMM_HI_W + IMM_LO_W + PAGE_OFFSET, imm << PAGE_OFFSET);
} else { } else {
return signExtend64(IMM_HI_W + IMM_LO_W, imm); return SignExtend64(IMM_HI_W + IMM_LO_W, imm);
} }
} }
Addr A64_ADR_ADRP::getImmPCOffsetTarget() { Addr A64_ADR_ADRP::GetImmPCOffsetTarget() {
void* base = AlignDown(getPC(), P_SIZE); void* base = AlignDown(GetPC(), P_SIZE);
return offset + reinterpret_cast<Addr>(base); return offset + reinterpret_cast<Addr>(base);
} }
void A64_ADR_ADRP::assembler() { void A64_ADR_ADRP::Assemble() {
SET_OPCODE(ADR_ADRP); SET_OPCODE(ADR_ADRP);
} }
void A64_ADR_ADRP::decode(STRUCT_A64(ADR_ADRP) *inst) { void A64_ADR_ADRP::Disassemble() {
offset = getImmPCOffset(); offset = GetImmPCOffset();
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_OP; DECODE_OP;
} }
//Mov Wide //Mov Wide
A64_MOV_WIDE::A64_MOV_WIDE() {} A64_MOV_WIDE::A64_MOV_WIDE(void* inst) : InstructionA64(inst) {}
A64_MOV_WIDE::A64_MOV_WIDE(STRUCT_A64(MOV_WIDE) &inst) : InstructionA64(&inst) {
decode(&inst);
}
A64_MOV_WIDE::A64_MOV_WIDE(A64_MOV_WIDE::OP op,RegisterA64* rd, U16 imme, U8 shift) A64_MOV_WIDE::A64_MOV_WIDE(A64_MOV_WIDE::OP op,RegisterA64* rd, U16 imme, U8 shift)
: shift(shift), op(op), imme(imme), rd(rd) {} : shift(shift), op(op), imme(imme), rd(rd) {}
void A64_MOV_WIDE::assembler() { void A64_MOV_WIDE::Assemble() {
SET_OPCODE(MOV_WIDE); SET_OPCODE(MOV_WIDE);
get()->imm16 = imme; Get()->imm16 = imme;
get()->hw = static_cast<InstA64>(shift / 16); Get()->hw = static_cast<InstA64>(shift / 16);
ENCODE_OP; ENCODE_OP;
get()->sf = rd->isX() ? 1 : 0; Get()->sf = rd->isX() ? 1 : 0;
ENCODE_RD; ENCODE_RD;
} }
void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { void A64_MOV_WIDE::Disassemble() {
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(Get()->imm16);
shift = static_cast<U8>(inst->hw * 16); shift = static_cast<U8>(Get()->hw * 16);
op = OP(inst->op); op = OP(Get()->op);
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
} else { } else {
DECODE_RD(WReg); DECODE_RD(WReg);
...@@ -129,34 +103,31 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { ...@@ -129,34 +103,31 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) {
//B BL //B BL
A64_B_BL::A64_B_BL() {} A64_B_BL::A64_B_BL(void *inst) : A64_INST_PC_REL(inst) {
A64_B_BL::A64_B_BL(STRUCT_A64(B_BL) &inst) : A64_INST_PC_REL(&inst) {
decode(&inst);
} }
A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) { A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) {
} }
A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label &l) : op(op) { A64_B_BL::A64_B_BL(A64_B_BL::OP op, Label *l) : op(op) {
bindLabel(l); BindLabel(l);
} }
Off A64_B_BL::getImmPCOffset() { Off A64_B_BL::GetImmPCOffset() {
return DECODE_OFFSET(26, 2); return DECODE_OFFSET(26, 2);
} }
void A64_B_BL::onOffsetApply(Off offset) { void A64_B_BL::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(26, 2); ENCODE_OFFSET(26, 2);
} }
void A64_B_BL::decode(STRUCT_A64(B_BL) *inst) { void A64_B_BL::Disassemble() {
DECODE_OP; DECODE_OP;
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void A64_B_BL::assembler() { void A64_B_BL::Assemble() {
SET_OPCODE(B_BL); SET_OPCODE(B_BL);
ENCODE_OP; ENCODE_OP;
ENCODE_OFFSET(26, 2); ENCODE_OFFSET(26, 2);
...@@ -166,44 +137,41 @@ void A64_B_BL::assembler() { ...@@ -166,44 +137,41 @@ void A64_B_BL::assembler() {
//CBZ CBNZ //CBZ CBNZ
A64_CBZ_CBNZ::A64_CBZ_CBNZ() {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst) { A64_CBZ_CBNZ::A64_CBZ_CBNZ(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 &rt) : op(op), A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 &rt) : op(op),
offset(offset), offset(offset),
rt(&rt) {} rt(&rt) {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) : op(op), A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label *label, RegisterA64 &rt) : op(op),
rt(&rt) { rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off A64_CBZ_CBNZ::getImmPCOffset() { Off A64_CBZ_CBNZ::GetImmPCOffset() {
return DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_CBZ_CBNZ::decode(STRUCT_A64(CBZ_CBNZ) *inst) { void A64_CBZ_CBNZ::Disassemble() {
DECODE_OP; DECODE_OP;
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RT(XReg); DECODE_RT(XReg);
} else { } else {
DECODE_RT(WReg); DECODE_RT(WReg);
} }
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void A64_CBZ_CBNZ::assembler() { void A64_CBZ_CBNZ::Assemble() {
SET_OPCODE(CBZ_CBNZ); SET_OPCODE(CBZ_CBNZ);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->sf = rt->isX() ? 1 : 0; Get()->sf = rt->isX() ? 1 : 0;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
void A64_CBZ_CBNZ::onOffsetApply(Off offset) { void A64_CBZ_CBNZ::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
...@@ -211,34 +179,32 @@ void A64_CBZ_CBNZ::onOffsetApply(Off offset) { ...@@ -211,34 +179,32 @@ void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
//B.Cond //B.Cond
A64_B_COND::A64_B_COND() {} A64_B_COND::A64_B_COND(void *inst) : A64_INST_PC_REL(inst) {}
A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
A64_B_COND::A64_B_COND(STRUCT_A64(B_COND) &inst) : A64_INST_PC_REL(&inst) { A64_B_COND::A64_B_COND(Condition condition, Label *label) {
decode(&inst); BindLabel(label);
} }
A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
Off A64_B_COND::getImmPCOffset() { Off A64_B_COND::GetImmPCOffset() {
return DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_B_COND::decode(STRUCT_A64(B_COND) *inst) { void A64_B_COND::Disassemble() {
DECODE_COND; DECODE_COND;
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void A64_B_COND::assembler() { void A64_B_COND::Assemble() {
SET_OPCODE(B_COND); SET_OPCODE(B_COND);
ENCODE_COND; ENCODE_COND;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
A64_B_COND::A64_B_COND(Condition condition, Label &label) { void A64_B_COND::OnOffsetApply(Off offset) {
bindLabel(label);
}
void A64_B_COND::onOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
...@@ -246,82 +212,74 @@ void A64_B_COND::onOffsetApply(Off offset) { ...@@ -246,82 +212,74 @@ void A64_B_COND::onOffsetApply(Off offset) {
//TBZ TBNZ //TBZ TBNZ
A64_TBZ_TBNZ::A64_TBZ_TBNZ() {}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst) : A64_INST_PC_REL(&inst) { A64_TBZ_TBNZ::A64_TBZ_TBNZ(void *inst) : A64_INST_PC_REL(inst) {}
decode(&inst);
}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op), A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op),
rt(&rt), rt(&rt),
bit(bit), bit(bit),
offset(offset) {} offset(offset) {}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label &label) : op(op), A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label *label) : op(op),
rt(&rt), rt(&rt),
bit(bit) { bit(bit) {
bindLabel(label); BindLabel(label);
} }
Off A64_TBZ_TBNZ::getImmPCOffset() { Off A64_TBZ_TBNZ::GetImmPCOffset() {
return DECODE_OFFSET(14, 2); return DECODE_OFFSET(14, 2);
} }
void A64_TBZ_TBNZ::decode(STRUCT_A64(TBZ_TBNZ) *inst) { void A64_TBZ_TBNZ::Disassemble() {
bit = COMBINE(inst->b5, inst->b40, 5); bit = COMBINE(Get()->b5, Get()->b40, 5);
if (inst->b5 == 1) { if (Get()->b5 == 1) {
DECODE_RT(XReg); DECODE_RT(XReg);
} else { } else {
DECODE_RT(WReg); DECODE_RT(WReg);
} }
DECODE_OP; DECODE_OP;
offset = getImmPCOffset(); offset = GetImmPCOffset();
} }
void A64_TBZ_TBNZ::assembler() { void A64_TBZ_TBNZ::Assemble() {
SET_OPCODE(TBZ_TBNZ); SET_OPCODE(TBZ_TBNZ);
ENCODE_OP; ENCODE_OP;
get()->b5 = rt->isX() ? 1 : 0; Get()->b5 = rt->isX() ? 1 : 0;
ENCODE_RT; ENCODE_RT;
get()->b40 = static_cast<InstA64>(BITS(bit, sizeof(InstA64) - 5, sizeof(InstA64))); Get()->b40 = static_cast<InstA64>(BITS(bit, sizeof(InstA64) - 5, sizeof(InstA64)));
ENCODE_OFFSET(14, 2); ENCODE_OFFSET(14, 2);
} }
void A64_TBZ_TBNZ::onOffsetApply(Off offset) { void A64_TBZ_TBNZ::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
get()->imm14 = TruncateToUint14(offset >> 2); Get()->imm14 = TruncateToUint14(offset >> 2);
} }
// LDR(literal) // LDR(literal)
A64_LDR_LIT::A64_LDR_LIT() {} A64_LDR_LIT::A64_LDR_LIT(void *inst) : A64_INST_PC_REL(inst) {}
A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&inst) {
decode(&inst);
}
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Off offset) : op(op), rt(&rt), A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Off offset) : op(op), rt(&rt),
offset(offset) {} offset(offset) {}
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Label& label) : op(op), rt(&rt) { A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Label *label) : op(op), rt(&rt) {
bindLabel(label); BindLabel(label);
} }
Off A64_LDR_LIT::getImmPCOffset() { Off A64_LDR_LIT::GetImmPCOffset() {
return DECODE_OFFSET(19, 2); return DECODE_OFFSET(19, 2);
} }
void A64_LDR_LIT::onOffsetApply(Off offset) { void A64_LDR_LIT::OnOffsetApply(Off offset) {
this->offset = offset; this->offset = offset;
ENCODE_OFFSET(19, 2); ENCODE_OFFSET(19, 2);
} }
void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { void A64_LDR_LIT::Disassemble() {
DECODE_OP; DECODE_OP;
offset = getImmPCOffset(); offset = GetImmPCOffset();
ENCODE_OFFSET(19, 2);
if (op == LDR_W) { if (op == LDR_W) {
DECODE_RT(WReg); DECODE_RT(WReg);
} else { } else {
...@@ -329,7 +287,7 @@ void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { ...@@ -329,7 +287,7 @@ void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) {
} }
} }
void A64_LDR_LIT::assembler() { void A64_LDR_LIT::Assemble() {
SET_OPCODE(LDR_LIT); SET_OPCODE(LDR_LIT);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
...@@ -337,21 +295,18 @@ void A64_LDR_LIT::assembler() { ...@@ -337,21 +295,18 @@ void A64_LDR_LIT::assembler() {
} }
//BR BLR RET
A64_BR_BLR_RET::A64_BR_BLR_RET() {} A64_BR_BLR_RET::A64_BR_BLR_RET(void *inst) : InstructionA64(inst) {}
A64_BR_BLR_RET::A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst) : InstructionA64(&inst) {
decode(&inst);
}
A64_BR_BLR_RET::A64_BR_BLR_RET(A64_BR_BLR_RET::OP op, XRegister &rn) : op(op), rn(&rn) {} A64_BR_BLR_RET::A64_BR_BLR_RET(A64_BR_BLR_RET::OP op, XRegister &rn) : op(op), rn(&rn) {}
void A64_BR_BLR_RET::decode(A64_STRUCT_BR_BLR_RET *inst) { void A64_BR_BLR_RET::Disassemble() {
DECODE_RN(XReg); DECODE_RN(XReg);
DECODE_OP; DECODE_OP;
} }
void A64_BR_BLR_RET::assembler() { void A64_BR_BLR_RET::Assemble() {
SET_OPCODE_MULTI(BR_BLR_RET, 1); SET_OPCODE_MULTI(BR_BLR_RET, 1);
SET_OPCODE_MULTI(BR_BLR_RET, 2); SET_OPCODE_MULTI(BR_BLR_RET, 2);
SET_OPCODE_MULTI(BR_BLR_RET, 3); SET_OPCODE_MULTI(BR_BLR_RET, 3);
...@@ -359,141 +314,132 @@ void A64_BR_BLR_RET::assembler() { ...@@ -359,141 +314,132 @@ void A64_BR_BLR_RET::assembler() {
ENCODE_OP; ENCODE_OP;
} }
A64_STR_IMM::A64_STR_IMM() {}
A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) &inst) : A64LoadAndStoreImm(&inst) { //STR IMM
decode(&inst);
}
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) { A64_STR_IMM::A64_STR_IMM(void *inst) : A64LoadAndStoreImm(inst) {}
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
} }
void A64_STR_IMM::decode(STRUCT_A64(STR_IMM) *inst) { void A64_STR_IMM::Disassemble() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
valid = false; valid_ = false;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
} }
void A64_STR_IMM::assembler() { void A64_STR_IMM::Assemble() {
SET_OPCODE(STR_IMM); SET_OPCODE(STR_IMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
get()->addrmode = Offset; Get()->addrmode = Offset;
valid = false; valid_ = false;
} }
} }
A64_STR_UIMM::A64_STR_UIMM() {}
A64_STR_UIMM::A64_STR_UIMM(STRUCT_A64(STR_UIMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) { A64_STR_UIMM::A64_STR_UIMM(void *inst) : A64LoadAndStoreImm(inst) {}
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
} }
void A64_STR_UIMM::decode(STRUCT_A64(STR_UIMM) *inst) { void A64_STR_UIMM::Disassemble() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << regSize; offset = Get()->imm12 << regSize;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_STR_UIMM::assembler() { void A64_STR_UIMM::Assemble() {
SET_OPCODE(STR_UIMM); SET_OPCODE(STR_UIMM);
ENCODE_RT; ENCODE_RT;
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
get()->imm12 = operand.offset >> get()->size; Get()->imm12 = operand.offset_ >> Get()->size;
} }
A64_MOV_REG::A64_MOV_REG(void *inst) : InstructionA64(inst) {
A64_MOV_REG::A64_MOV_REG() {}
A64_MOV_REG::A64_MOV_REG(STRUCT_A64(MOV_REG) &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_MOV_REG::A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm) : rd(&rd), rm(&rm) { A64_MOV_REG::A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm) : rd(&rd), rm(&rm) {
} }
void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) { void A64_MOV_REG::Disassemble() {
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_RM(XReg); DECODE_RM(XReg);
} else { } else {
...@@ -502,418 +448,391 @@ void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) { ...@@ -502,418 +448,391 @@ void A64_MOV_REG::decode(A64_STRUCT_MOV_REG *inst) {
} }
} }
void A64_MOV_REG::assembler() { void A64_MOV_REG::Assemble() {
SET_OPCODE_MULTI(MOV_REG, 1); SET_OPCODE_MULTI(MOV_REG, 1);
SET_OPCODE_MULTI(MOV_REG, 2); SET_OPCODE_MULTI(MOV_REG, 2);
get()->sf = rd->isX() ? 1 : 0; Get()->sf = rd->isX() ? 1 : 0;
ENCODE_RD; ENCODE_RD;
ENCODE_RM; ENCODE_RM;
} }
A64_SUB_EXT_REG::A64_SUB_EXT_REG(void *inst) : InstructionA64(inst) {}
A64_SUB_EXT_REG::A64_SUB_EXT_REG() {}
A64_SUB_EXT_REG::A64_SUB_EXT_REG(STRUCT_A64(SUB_EXT_REG) &inst) : InstructionA64(&inst) {
decode(&inst);
}
A64_SUB_EXT_REG::A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand, A64_SUB_EXT_REG::A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand,
FlagsUpdate flagsUpdate) : rd(&rd), rn(&rn), operand(operand), FlagsUpdate flagsUpdate) : rd(&rd), rn(&rn), operand(operand),
flagsUpdate(flagsUpdate) {} flagsUpdate(flagsUpdate) {}
void A64_SUB_EXT_REG::decode(STRUCT_A64(SUB_EXT_REG) *inst) { void A64_SUB_EXT_REG::Disassemble() {
flagsUpdate = FlagsUpdate(inst->S); flagsUpdate = FlagsUpdate(Get()->S);
if (inst->sf == 1) { if (Get()->sf == 1) {
DECODE_RD(XReg); DECODE_RD(XReg);
DECODE_RN(XReg); DECODE_RN(XReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg_ = XReg(static_cast<U8>(Get()->rm));
} else { } else {
DECODE_RD(WReg); DECODE_RD(WReg);
DECODE_RN(WReg); DECODE_RN(WReg);
operand.reg = XReg(static_cast<U8>(inst->rm)); operand.reg_ = XReg(static_cast<U8>(Get()->rm));
} }
operand.extend = Extend(inst->option); operand.extend_ = Extend(Get()->option);
INST_ASSERT(inst->imm3 > 4); INST_ASSERT(Get()->imm3 > 4);
operand.shift = Shift(inst->imm3); operand.shift_ = Shift(Get()->imm3);
} }
void A64_SUB_EXT_REG::assembler() { void A64_SUB_EXT_REG::Assemble() {
SET_OPCODE_MULTI(SUB_EXT_REG, 1); SET_OPCODE_MULTI(SUB_EXT_REG, 1);
SET_OPCODE_MULTI(SUB_EXT_REG, 2); SET_OPCODE_MULTI(SUB_EXT_REG, 2);
get()->S = flagsUpdate; Get()->S = flagsUpdate;
get()->sf = rd->isX() ? 1 : 0; Get()->sf = rd->isX() ? 1 : 0;
get()->option = operand.extend; Get()->option = operand.extend_;
get()->imm3 = operand.shift; Get()->imm3 = operand.shift_;
get()->rm = operand.reg->getCode(); Get()->rm = operand.reg_->Code();
ENCODE_RN; ENCODE_RN;
ENCODE_RD; ENCODE_RD;
} }
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(void* inst) : InstructionA64(inst) {
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN() {}
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(STRUCT_A64(EXCEPTION_GEN) &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el, U16 imme) : op( A64_EXCEPTION_GEN::A64_EXCEPTION_GEN(A64_EXCEPTION_GEN::OP op, ExceptionLevel el, U16 imme) : op(
op), el(el), imme(imme) {} op), el(el), imme(imme) {}
void A64_EXCEPTION_GEN::decode(STRUCT_A64(EXCEPTION_GEN) *inst) { void A64_EXCEPTION_GEN::Disassemble() {
DECODE_OP; DECODE_OP;
el = ExceptionLevel(inst->ll); el = ExceptionLevel(Get()->ll);
imme = static_cast<U16>(inst->imm16); imme = static_cast<U16>(Get()->imm16);
} }
void A64_EXCEPTION_GEN::assembler() { void A64_EXCEPTION_GEN::Assemble() {
SET_OPCODE_MULTI(EXCEPTION_GEN, 1); SET_OPCODE_MULTI(EXCEPTION_GEN, 1);
SET_OPCODE_MULTI(EXCEPTION_GEN, 2); SET_OPCODE_MULTI(EXCEPTION_GEN, 2);
ENCODE_OP; ENCODE_OP;
get()->ll = el; Get()->ll = el;
get()->imm16 = imme; Get()->imm16 = imme;
} }
A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {} A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {}
A64_SVC::A64_SVC() {} A64_SVC::A64_SVC(void *inst) : A64_EXCEPTION_GEN(inst) {}
A64_SVC::A64_SVC(STRUCT_A64(SVC) &inst) : A64_EXCEPTION_GEN(inst) {}
A64_LDR_IMM::A64_LDR_IMM(void *inst) : A64LoadAndStoreImm(inst) {
A64_LDR_IMM::A64_LDR_IMM() {}
A64_LDR_IMM::A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
} }
A64_LDR_IMM::A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, A64_LDR_IMM::A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {} operand) {}
void A64_LDR_IMM::decode(STRUCT_A64(LDR_IMM) *inst) { void A64_LDR_IMM::Disassemble() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
valid = false; valid_ = false;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDR_IMM::assembler() { void A64_LDR_IMM::Assemble() {
SET_OPCODE(LDR_IMM); SET_OPCODE(LDR_IMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
get()->addrmode = Offset; Get()->addrmode = Offset;
valid = false; valid_ = false;
} }
} }
A64_LDR_UIMM::A64_LDR_UIMM() {}
A64_LDR_UIMM::A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64LoadAndStoreImm(&inst) { A64_LDR_UIMM::A64_LDR_UIMM(void *inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
} }
A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {} operand) {}
void A64_LDR_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) { void A64_LDR_UIMM::Disassemble() {
regSize = Size(inst->size); regSize = RegSize(Get()->size);
switch (regSize) { switch (regSize) {
case Size64: case Size64:
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
break; break;
case Size32: case Size32:
rt = WReg(static_cast<U8>(inst->rt)); rt = WReg(static_cast<U8>(Get()->rt));
operand.base = WReg(static_cast<U8>(inst->rn)); operand.base_ = WReg(static_cast<U8>(Get()->rn));
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << regSize; offset = Get()->imm12 << regSize;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDR_UIMM::assembler() { void A64_LDR_UIMM::Assemble() {
SET_OPCODE(LDR_UIMM); SET_OPCODE(LDR_UIMM);
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
if (rt->isX()) { if (rt->isX()) {
get()->size = Size64; Get()->size = Size64;
} else if (rt->isW()) { } else if (rt->isW()) {
get()->size = Size32; Get()->size = Size32;
} else { } else {
valid = false; valid_ = false;
return; return;
} }
get()->imm12 = static_cast<InstA64>(operand.offset >> get()->size); Get()->imm12 = static_cast<InstA64>(operand.offset_ >> Get()->size);
} }
A64_LDRSW_IMM::A64_LDRSW_IMM() {}
A64_LDRSW_IMM::A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst) : A64_LDR_IMM(inst) {} A64_LDRSW_IMM::A64_LDRSW_IMM(void *inst) : A64_LDR_IMM(inst) {}
A64_LDRSW_IMM::A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand) : A64_LDR_IMM(rt, A64_LDRSW_IMM::A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand) : A64_LDR_IMM(rt,
operand) {} operand) {}
void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) { void A64_LDRSW_IMM::Disassemble() {
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
addrMode = AdMod(inst->addrmode); addrMode = AdMod(Get()->addrmode);
switch (addrMode) { switch (addrMode) {
case PostIndex: case PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = signExtend64(9, inst->imm9); offset = SignExtend64(9, Get()->imm9);
operand.offset = offset; operand.offset_ = offset;
rt = XReg(static_cast<U8>(inst->rt)); rt = XReg(static_cast<U8>(Get()->rt));
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
} }
void A64_LDRSW_IMM::assembler() { void A64_LDRSW_IMM::Assemble() {
SET_OPCODE(LDRSW_IMM); SET_OPCODE(LDRSW_IMM);
get()->size = Size32; Get()->size = Size32;
get()->rt = rt->getCode(); Get()->rt = rt->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm9 = TruncateToUint9(operand.offset); Get()->imm9 = TruncateToUint9(operand.offset_);
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case AddrMode::PostIndex: case AddrMode::PostIndex:
wback = true; wback = true;
postindex = true; postindex = true;
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
wback = true; wback = true;
postindex = false; postindex = false;
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
return; return;
} }
} }
A64_LDRSW_UIMM::A64_LDRSW_UIMM(void *inst) : A64_LDR_UIMM(inst) {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM() {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64_LDR_UIMM(inst) {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_LDR_UIMM(rt, A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_LDR_UIMM(rt,
operand) {} operand) {}
void A64_LDRSW_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) { void A64_LDRSW_UIMM::Disassemble() {
DECODE_RT(XReg); DECODE_RT(XReg);
operand.base = XReg(static_cast<U8>(inst->rn)); operand.base_ = XReg(static_cast<U8>(Get()->rn));
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
scale = static_cast<U8>(inst->size); scale = static_cast<U8>(Get()->size);
offset = inst->imm12 << Size32; offset = Get()->imm12 << Size32;
operand.offset = offset; operand.offset_ = offset;
} }
void A64_LDRSW_UIMM::assembler() { void A64_LDRSW_UIMM::Assemble() {
SET_OPCODE(LDRSW_UIMM); SET_OPCODE(LDRSW_UIMM);
get()->size = Size32; Get()->size = Size32;
ENCODE_RT; ENCODE_RT;
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
get()->imm12 = operand.offset >> Size32; Get()->imm12 = operand.offset_ >> Size32;
} }
A64_STP_LDP::A64_STP_LDP(A64_STRUCT_STP_LDP &inst) : InstructionA64(&inst) { A64_STP_LDP::A64_STP_LDP(void *inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_STP_LDP::A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand) : op(op), rt1(&rt1), A64_STP_LDP::A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand) : op(op), rt1(&rt1),
rt2(&rt2), rt2(&rt2),
operand(operand) {} operand(operand) {}
void A64_STP_LDP::decode(A64_STRUCT_STP_LDP *inst) { void A64_STP_LDP::Disassemble() {
DECODE_OP; DECODE_OP;
Size s = Size(inst->size); RegSize s = RegSize(Get()->size);
if (s == Size64) { if (s == Size64) {
rt1 = XReg(inst->rt); rt1 = XReg(Get()->rt);
rt2 = XReg(inst->rt2); rt2 = XReg(Get()->rt2);
operand.offset = signExtend64(7, inst->imm7) << 3; operand.offset_ = SignExtend64(7, Get()->imm7) << 3;
} else { } else {
rt1 = WReg(inst->rt); rt1 = WReg(Get()->rt);
rt2 = WReg(inst->rt2); rt2 = WReg(Get()->rt2);
operand.offset = signExtend64(7, inst->imm7) << 2; operand.offset_ = SignExtend64(7, Get()->imm7) << 2;
} }
operand.base = XReg(inst->rn); operand.base_ = XReg(Get()->rn);
AdMod adMod = AdMod(inst->addrmode); AdMod adMod = AdMod(Get()->addrmode);
switch (adMod) { switch (adMod) {
case SignOffset: case SignOffset:
operand.addr_mode = AddrMode::Offset; operand.addr_mode_ = AddrMode::Offset;
break; break;
case PostIndex: case PostIndex:
operand.addr_mode = AddrMode::PostIndex; operand.addr_mode_ = AddrMode::PostIndex;
break; break;
case PreIndex: case PreIndex:
operand.addr_mode = AddrMode::PreIndex; operand.addr_mode_ = AddrMode::PreIndex;
break; break;
} }
} }
void A64_STP_LDP::assembler() { void A64_STP_LDP::Assemble() {
SET_OPCODE(STP_LDP); SET_OPCODE(STP_LDP);
ENCODE_OP; ENCODE_OP;
get()->size = rt1->isX() ? Size64 : Size32; Get()->size = rt1->isX() ? Size64 : Size32;
get()->rt = rt1->getCode(); Get()->rt = rt1->Code();
get()->rt2 = rt2->getCode(); Get()->rt2 = rt2->Code();
get()->rn = operand.base->getCode(); Get()->rn = operand.base_->Code();
switch (operand.addr_mode) { switch (operand.addr_mode_) {
case Offset: case Offset:
get()->addrmode = SignOffset; Get()->addrmode = SignOffset;
break; break;
case AddrMode::PostIndex: case AddrMode::PostIndex:
get()->addrmode = PostIndex; Get()->addrmode = PostIndex;
break; break;
case AddrMode::PreIndex: case AddrMode::PreIndex:
get()->addrmode = PreIndex; Get()->addrmode = PreIndex;
break; break;
default: default:
valid = false; valid_ = false;
} }
get()->imm7 = TruncateToUint7(operand.offset >> (rt1->isX() ? 3 : 2)); Get()->imm7 = TruncateToUint7(operand.offset_ >> (rt1->isX() ? 3 : 2));
} }
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(void *inst) : InstructionA64(&inst) {
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM() {}
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_STRUCT_ADD_SUB_IMM &inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_ADD_SUB_IMM::OP op, A64_ADD_SUB_IMM::S sign, RegisterA64 &rd, A64_ADD_SUB_IMM::A64_ADD_SUB_IMM(A64_ADD_SUB_IMM::OP op, A64_ADD_SUB_IMM::S sign, RegisterA64 &rd,
const Operand &operand) : op(op), sign(sign), rd(&rd), operand(operand) {} const Operand &operand) : op(op), sign(sign), rd(&rd), operand(operand) {}
void A64_ADD_SUB_IMM::decode(A64_STRUCT_ADD_SUB_IMM *inst) { void A64_ADD_SUB_IMM::Disassemble() {
DECODE_OP; DECODE_OP;
if (inst->sf == Size64) { if (Get()->sf == Size64) {
DECODE_RD(XReg); DECODE_RD(XReg);
operand.reg = XReg(inst->rn); operand.reg_ = XReg(Get()->rn);
} else { } else {
DECODE_RD(XReg); DECODE_RD(XReg);
operand.reg = WReg(inst->rn); operand.reg_ = WReg(Get()->rn);
} }
sign = S(inst->S); sign = S(Get()->S);
DECODE_SHIFT; DECODE_SHIFT;
if (operand.shift == LSL) { if (operand.shift_ == LSL) {
operand.shift_extend_imm = get()->imm12; operand.shift_extend_imm_ = Get()->imm12;
} else if (operand.shift == LSR) { } else if (operand.shift_ == LSR) {
operand.shift_extend_imm = get()->imm12 << 12; operand.shift_extend_imm_ = Get()->imm12 << 12;
} else { } else {
valid = false; valid_ = false;
} }
} }
void A64_ADD_SUB_IMM::assembler() { void A64_ADD_SUB_IMM::Assemble() {
SET_OPCODE(ADD_SUB_IMM); SET_OPCODE(ADD_SUB_IMM);
ENCODE_OP; ENCODE_OP;
ENCODE_RD; ENCODE_RD;
get()->rn = operand.reg->getCode(); Get()->rn = operand.reg_->Code();
get()->sf = rd->isX() ? Size64 : Size32; Get()->sf = rd->isX() ? Size64 : Size32;
get()->S = sign; Get()->S = sign;
ENCODE_SHIFT; ENCODE_SHIFT;
if (operand.shift == LSL) { if (operand.shift_ == LSL) {
get()->imm12 = operand.shift_extend_imm; Get()->imm12 = operand.shift_extend_imm_;
} else if (operand.shift == LSR) { } else if (operand.shift_ == LSR) {
get()->imm12 = operand.shift_extend_imm >> 12; Get()->imm12 = operand.shift_extend_imm_ >> 12;
} else { } else {
valid = false; valid_ = false;
} }
} }
A64_MSR_MRS::A64_MSR_MRS(A64_STRUCT_MSR_MRS &inst) : InstructionA64(&inst) { A64_MSR_MRS::A64_MSR_MRS(void *inst) : InstructionA64(&inst) {
decode(&inst);
} }
A64_MSR_MRS::A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt) : op(op), systemRegister( A64_MSR_MRS::A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt) : op(op), system_reg(
&systemRegister), rt(&rt) {} &systemRegister), rt(&rt) {}
void A64_MSR_MRS::decode(A64_STRUCT_MSR_MRS *inst) { void A64_MSR_MRS::Disassemble() {
DECODE_OP; DECODE_OP;
DECODE_RT(XReg); DECODE_RT(XReg);
//TODO system_reg->value = static_cast<U16>(Get()->sysreg);
} }
void A64_MSR_MRS::assembler() { void A64_MSR_MRS::Assemble() {
SET_OPCODE(MSR_MRS); SET_OPCODE(MSR_MRS);
ENCODE_OP; ENCODE_OP;
ENCODE_RT; ENCODE_RT;
get()->sysreg = systemRegister->value(); Get()->sysreg = system_reg->value;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_INST_ARM64_H #pragma once
#define SANDHOOK_NH_INST_ARM64_H
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
#include "instruction.h" #include "instruction.h"
...@@ -13,10 +12,10 @@ ...@@ -13,10 +12,10 @@
#define INST_A64(X) A64_##X #define INST_A64(X) A64_##X
#define IS_OPCODE_A64(RAW,OP) INST_A64(OP)::is(RAW) #define IS_OPCODE_A64(RAW,OP) INST_A64(OP)::Is(RAW)
#define DEFINE_IS_EXT(X, COND) \ #define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstA64& inst) { \ inline static bool Is(InstA64& inst) { \
union { \ union { \
InstA64 raw; \ InstA64 raw; \
STRUCT_A64(X) inst; \ STRUCT_A64(X) inst; \
...@@ -31,12 +30,13 @@ return COND; \ ...@@ -31,12 +30,13 @@ return COND; \
#define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_A64(X##_##INDEX) #define TEST_INST_OPCODE(X, INDEX) inst_test.inst.opcode##INDEX == OPCODE_A64(X##_##INDEX)
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
inline U32 instCode() override { \
return ENUM_VALUE(InstCodeA64, InstCodeA64::X); \ #define DEFINE_INST_EXT(X,P) class INST_A64(X) : public INST_A64(P)
}
#define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X)> #define DEFINE_INST_EXT_(X,P) class INST_A64(X) : public P<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
#define DEFINE_INST_PCREL(X) class INST_A64(X) : public A64_INST_PC_REL<STRUCT_A64(X), ENUM_VALUE(InstCodeA64, InstCodeA64::X)>
#define CAST_A64(X,V) reinterpret_cast<SandHook::AsmA64::INST_A64(X) *>(V) #define CAST_A64(X,V) reinterpret_cast<SandHook::AsmA64::INST_A64(X) *>(V)
...@@ -47,33 +47,23 @@ namespace SandHook { ...@@ -47,33 +47,23 @@ namespace SandHook {
namespace AsmA64 { namespace AsmA64 {
template<typename Inst> template<typename S, U32 C>
class InstructionA64 : public Instruction<Inst> { class InstructionA64 : public Instruction<S, C> {
public: public:
InstructionA64() {} InstructionA64() {}
InstructionA64(Inst *inst) : Instruction<Inst>(inst) {} InstructionA64(void *inst) : Instruction<S, C>(inst) {}
Inst mask(Inst raw) {
return raw & *(this->get());
}
U32 size() override;
static inline S64 signExtend64(unsigned int bits, U64 value) {
return ExtractSignedBitfield64(bits - 1, 0, value);
}
static inline S32 signExtend32(unsigned int bits, U32 value) { U32 Size() override {
return ExtractSignedBitfield32(bits - 1, 0, value); return 4;
} };
InstType instType() override { InstType InstType() override {
return A64; return A64;
} }
Arch arch() override { Arch Arch() override {
return arm64; return arm64;
} }
...@@ -102,117 +92,108 @@ namespace SandHook { ...@@ -102,117 +92,108 @@ namespace SandHook {
public: public:
inline explicit Operand(){}; inline explicit Operand(){};
inline explicit Operand(S64 imm) inline explicit Operand(S64 imm)
: immediate(imm), reg(&UnknowRegiser), shift(NO_SHIFT), extend(NO_EXTEND), shift_extend_imm(0) {} : immediate_(imm), reg_(&UnknowRegiser), shift_(NO_SHIFT), extend_(NO_EXTEND), shift_extend_imm_(0) {}
inline explicit Operand(RegisterA64* reg, int32_t imm = 0, Shift shift = LSL) inline explicit Operand(RegisterA64* reg, int32_t imm = 0, Shift shift = LSL)
: immediate(0), reg(reg), shift(shift), extend(NO_EXTEND), shift_extend_imm(imm) {} : immediate_(0), reg_(reg), shift_(shift), extend_(NO_EXTEND), shift_extend_imm_(imm) {}
inline explicit Operand(RegisterA64* reg, Extend extend, int32_t imm = 0) inline explicit Operand(RegisterA64* reg, Extend extend, int32_t imm = 0)
: immediate(0), reg(reg), shift(NO_SHIFT), extend(extend), shift_extend_imm(imm) {} : immediate_(0), reg_(reg), shift_(NO_SHIFT), extend_(extend), shift_extend_imm_(imm) {}
// ===== // =====
bool IsImmediate() const { return reg->is(UnknowRegiser); } bool IsImmediate() const { return *reg_ == UnknowRegiser; }
bool IsShiftedRegister() const { return (shift != NO_SHIFT); } bool IsShiftedRegister() const { return (shift_ != NO_SHIFT); }
bool IsExtendedRegister() const { return (extend != NO_EXTEND); } bool IsExtendedRegister() const { return (extend_ != NO_EXTEND); }
public: public:
S64 immediate; S64 immediate_;
RegisterA64* reg; RegisterA64* reg_;
Shift shift; Shift shift_;
Extend extend; Extend extend_;
int32_t shift_extend_imm; int32_t shift_extend_imm_;
}; };
class MemOperand { class MemOperand {
public: public:
inline explicit MemOperand() {} inline explicit MemOperand() {}
inline explicit MemOperand(RegisterA64* base, Off offset = 0, AddrMode addr_mode = Offset) inline explicit MemOperand(RegisterA64* base, Off offset = 0, AddrMode addr_mode = Offset)
: base(base), reg_offset(&UnknowRegiser), offset(offset), addr_mode(addr_mode), shift(NO_SHIFT), : base_(base), reg_offset_(&UnknowRegiser), offset_(offset), addr_mode_(addr_mode), shift_(NO_SHIFT),
extend(NO_EXTEND), shift_extend_imm(0) {} extend_(NO_EXTEND), shift_extend_imm_(0) {}
inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Extend extend, unsigned extend_imm) inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Extend extend, unsigned extend_imm)
: base(base), reg_offset(reg_offset), offset(0), addr_mode(Offset), shift(NO_SHIFT), extend(extend), : base_(base), reg_offset_(reg_offset), offset_(0), addr_mode_(Offset), shift_(NO_SHIFT), extend_(extend),
shift_extend_imm(extend_imm) {} shift_extend_imm_(extend_imm) {}
inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Shift shift = LSL, unsigned shift_imm = 0) inline explicit MemOperand(RegisterA64* base, RegisterA64* reg_offset, Shift shift = LSL, unsigned shift_imm = 0)
: base(base), reg_offset(reg_offset), offset(0), addr_mode(Offset), shift(shift), extend(NO_EXTEND), : base_(base), reg_offset_(reg_offset), offset_(0), addr_mode_(Offset), shift_(shift), extend_(NO_EXTEND),
shift_extend_imm(shift_imm) {} shift_extend_imm_(shift_imm) {}
inline explicit MemOperand(RegisterA64* base, const Operand &offset, AddrMode addr_mode = Offset) inline explicit MemOperand(RegisterA64* base, const Operand &offset, AddrMode addr_mode = Offset)
: base(base), reg_offset(&UnknowRegiser), addr_mode(addr_mode) { : base_(base), reg_offset_(&UnknowRegiser), addr_mode_(addr_mode) {
if (offset.IsShiftedRegister()) { if (offset.IsShiftedRegister()) {
reg_offset = offset.reg; reg_offset_ = offset.reg_;
shift = offset.shift; shift_ = offset.shift_;
shift_extend_imm = offset.shift_extend_imm; shift_extend_imm_ = offset.shift_extend_imm_;
extend = NO_EXTEND; extend_ = NO_EXTEND;
this->offset = 0; this->offset_ = 0;
} else if (offset.IsExtendedRegister()) { } else if (offset.IsExtendedRegister()) {
reg_offset = offset.reg; reg_offset_ = offset.reg_;
extend = offset.extend; extend_ = offset.extend_;
shift_extend_imm = offset.shift_extend_imm; shift_extend_imm_ = offset.shift_extend_imm_;
shift = NO_SHIFT; shift_ = NO_SHIFT;
this->offset = 0; this->offset_ = 0;
} }
} }
// ===== // =====
bool IsImmediateOffset() const { return (addr_mode == Offset); } bool IsImmediateOffset() const { return (addr_mode_ == Offset); }
bool IsRegisterOffset() const { return (addr_mode == Offset); } bool IsRegisterOffset() const { return (addr_mode_ == Offset); }
bool IsPreIndex() const { return addr_mode == PreIndex; } bool IsPreIndex() const { return addr_mode_ == PreIndex; }
bool IsPostIndex() const { return addr_mode == PostIndex; } bool IsPostIndex() const { return addr_mode_ == PostIndex; }
public: public:
RegisterA64* base; RegisterA64* base_;
RegisterA64* reg_offset; RegisterA64* reg_offset_;
Off offset; Off offset_;
AddrMode addr_mode; AddrMode addr_mode_;
Shift shift; Shift shift_;
Extend extend; Extend extend_;
S32 shift_extend_imm; S32 shift_extend_imm_;
}; };
class INST_A64(UNKNOW) : public InstructionA64<STRUCT_A64(UNKNOW)> { DEFINE_INST(UNKNOW) {
public: public:
A64_UNKNOW(STRUCT_A64(UNKNOW) &inst); A64_UNKNOW(void *inst) : InstructionA64(inst) {}
DEFINE_INST_CODE(UNKNOW) INLINE bool Unknow() override {
inline bool unknow() override {
return true; return true;
} }
void decode(A64_STRUCT_UNKNOW *inst) override;
void assembler() override;
private:
STRUCT_A64(UNKNOW) inst_backup;
}; };
template <typename Inst> template <typename S,U32 C>
class A64_INST_PC_REL : public InstructionA64<Inst> { class A64_INST_PC_REL : public InstructionA64<S, C> {
public: public:
A64_INST_PC_REL(); A64_INST_PC_REL();
A64_INST_PC_REL(Inst *inst); A64_INST_PC_REL(void *inst);
virtual Off getImmPCOffset() = 0; virtual Off GetImmPCOffset() = 0;
virtual Addr getImmPCOffsetTarget(); virtual Addr GetImmPCOffsetTarget();
bool pcRelate() override; bool PcRelate() override;
}; };
class INST_A64(ADR_ADRP) : public A64_INST_PC_REL<STRUCT_A64(ADR_ADRP)> { DEFINE_INST_PCREL(ADR_ADRP) {
public: public:
enum OP { enum OP {
...@@ -220,29 +201,25 @@ namespace SandHook { ...@@ -220,29 +201,25 @@ namespace SandHook {
ADRP = 0b1, ADRP = 0b1,
}; };
A64_ADR_ADRP(); A64_ADR_ADRP(void *inst);
A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst);
A64_ADR_ADRP(OP op, XRegister &rd, S64 offset); A64_ADR_ADRP(OP op, XRegister &rd, S64 offset);
A64_ADR_ADRP(OP op, XRegister &rd, Label &label); A64_ADR_ADRP(OP op, XRegister &rd, Label *label);
DEFINE_IS(ADR_ADRP) DEFINE_IS(ADR_ADRP)
DEFINE_INST_CODE(ADR_ADRP) bool IsADRP() {
return Get()->op == OP::ADRP;
bool isADRP() {
return get()->op == OP::ADRP;
} }
Off getImmPCOffset() override; Off GetImmPCOffset() override;
Addr getImmPCOffsetTarget() override; Addr GetImmPCOffsetTarget() override;
void decode(A64_STRUCT_ADR_ADRP *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -252,7 +229,7 @@ namespace SandHook { ...@@ -252,7 +229,7 @@ namespace SandHook {
class INST_A64(MOV_WIDE) : public InstructionA64<STRUCT_A64(MOV_WIDE)> { DEFINE_INST(MOV_WIDE) {
public: public:
enum OP { enum OP {
...@@ -271,23 +248,19 @@ namespace SandHook { ...@@ -271,23 +248,19 @@ namespace SandHook {
Shift3 = 48 Shift3 = 48
}; };
A64_MOV_WIDE(); A64_MOV_WIDE(void* inst);
A64_MOV_WIDE(STRUCT_A64(MOV_WIDE) &inst);
A64_MOV_WIDE(A64_MOV_WIDE::OP op, RegisterA64* rd, U16 imme, U8 shift); A64_MOV_WIDE(A64_MOV_WIDE::OP op, RegisterA64* rd, U16 imme, U8 shift);
DEFINE_IS(MOV_WIDE) DEFINE_IS(MOV_WIDE)
DEFINE_INST_CODE(MOV_WIDE) void Assemble() override;
void assembler() override; void Disassemble() override;
void decode(STRUCT_A64(MOV_WIDE) *decode) override;
public: public:
//can be 16/32/64/128 //can be 16/32/64/128
//hw = shift / 16 //hw = shift_ / 16
U8 shift; U8 shift;
OP op; OP op;
U16 imme; U16 imme;
...@@ -296,7 +269,7 @@ namespace SandHook { ...@@ -296,7 +269,7 @@ namespace SandHook {
class INST_A64(B_BL) : public A64_INST_PC_REL<STRUCT_A64(B_BL)> { DEFINE_INST_PCREL(B_BL) {
public: public:
enum OP { enum OP {
...@@ -304,13 +277,11 @@ namespace SandHook { ...@@ -304,13 +277,11 @@ namespace SandHook {
BL = 0b1 BL = 0b1
}; };
A64_B_BL(); A64_B_BL(void *inst) ;
A64_B_BL(STRUCT_A64(B_BL) &inst);
A64_B_BL(OP op, Off offset); A64_B_BL(OP op, Off offset);
A64_B_BL(OP op, Label &l); A64_B_BL(OP op, Label *l);
DEFINE_IS(B_BL) DEFINE_IS(B_BL)
...@@ -322,15 +293,13 @@ namespace SandHook { ...@@ -322,15 +293,13 @@ namespace SandHook {
return op; return op;
} }
DEFINE_INST_CODE(B_BL) Off GetImmPCOffset() override;
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_A64(B_BL) *decode) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
...@@ -339,7 +308,7 @@ namespace SandHook { ...@@ -339,7 +308,7 @@ namespace SandHook {
}; };
class INST_A64(CBZ_CBNZ) : public A64_INST_PC_REL<STRUCT_A64(CBZ_CBNZ)> { DEFINE_INST_PCREL(CBZ_CBNZ) {
public: public:
enum OP { enum OP {
...@@ -347,25 +316,21 @@ namespace SandHook { ...@@ -347,25 +316,21 @@ namespace SandHook {
CBNZ = 1 CBNZ = 1
}; };
A64_CBZ_CBNZ(); A64_CBZ_CBNZ(void *inst);
A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst);
A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 &rt); A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 &rt);
A64_CBZ_CBNZ(OP op, Label& label, RegisterA64 &rt); A64_CBZ_CBNZ(OP op, Label *label, RegisterA64 &rt);
DEFINE_IS(CBZ_CBNZ) DEFINE_IS(CBZ_CBNZ)
DEFINE_INST_CODE(CBZ_CBNZ) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off GetImmPCOffset() override;
void decode(STRUCT_A64(CBZ_CBNZ) *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -374,27 +339,24 @@ namespace SandHook { ...@@ -374,27 +339,24 @@ namespace SandHook {
}; };
class INST_A64(B_COND) : public A64_INST_PC_REL<STRUCT_A64(B_COND)> { DEFINE_INST_PCREL(B_COND) {
public: public:
A64_B_COND();
A64_B_COND(STRUCT_A64(B_COND) &inst); A64_B_COND(void *inst);
A64_B_COND(Condition condition, Off offset); A64_B_COND(Condition condition, Off offset);
A64_B_COND(Condition condition, Label& label); A64_B_COND(Condition condition, Label *label);
DEFINE_IS(B_COND) DEFINE_IS(B_COND)
DEFINE_INST_CODE(B_COND) Off GetImmPCOffset() override;
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_A64(B_COND) *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
Condition condition; Condition condition;
...@@ -402,7 +364,7 @@ namespace SandHook { ...@@ -402,7 +364,7 @@ namespace SandHook {
}; };
class INST_A64(TBZ_TBNZ) : public A64_INST_PC_REL<STRUCT_A64(TBZ_TBNZ)> { DEFINE_INST_PCREL(TBZ_TBNZ) {
public: public:
enum OP { enum OP {
...@@ -410,25 +372,22 @@ namespace SandHook { ...@@ -410,25 +372,22 @@ namespace SandHook {
TBNZ = 1 TBNZ = 1
}; };
A64_TBZ_TBNZ();
A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst); A64_TBZ_TBNZ(void *inst);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Off offset); A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Off offset);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Label& label); A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Label* label);
DEFINE_IS(TBZ_TBNZ) DEFINE_IS(TBZ_TBNZ)
DEFINE_INST_CODE(TBZ_TBNZ) void OnOffsetApply(Off offset) override;
void onOffsetApply(Off offset) override; Off GetImmPCOffset() override;
Off getImmPCOffset() override; void Disassemble() override;
void decode(STRUCT_A64(TBZ_TBNZ) *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -438,7 +397,7 @@ namespace SandHook { ...@@ -438,7 +397,7 @@ namespace SandHook {
}; };
class INST_A64(LDR_LIT) : public A64_INST_PC_REL<STRUCT_A64(LDR_LIT)> { DEFINE_INST_PCREL(LDR_LIT) {
public: public:
enum OP { enum OP {
...@@ -448,25 +407,21 @@ namespace SandHook { ...@@ -448,25 +407,21 @@ namespace SandHook {
LDR_PRFM = 0b11 LDR_PRFM = 0b11
}; };
A64_LDR_LIT(); A64_LDR_LIT(void *inst);
A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst);
A64_LDR_LIT(OP op, RegisterA64 &rt, Off offset); A64_LDR_LIT(OP op, RegisterA64 &rt, Off offset);
A64_LDR_LIT(OP op, RegisterA64 &rt, Label& label); A64_LDR_LIT(OP op, RegisterA64 &rt, Label* label);
DEFINE_IS(LDR_LIT) DEFINE_IS(LDR_LIT)
DEFINE_INST_CODE(LDR_LIT) Off GetImmPCOffset() override;
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void OnOffsetApply(Off offset) override;
void decode(STRUCT_A64(LDR_LIT) *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -484,19 +439,15 @@ namespace SandHook { ...@@ -484,19 +439,15 @@ namespace SandHook {
RET = 0b11 RET = 0b11
}; };
A64_BR_BLR_RET(); A64_BR_BLR_RET(void *inst);
A64_BR_BLR_RET(STRUCT_A64(BR_BLR_RET) &inst);
A64_BR_BLR_RET(OP op, XRegister &rn); A64_BR_BLR_RET(OP op, XRegister &rn);
DEFINE_IS_EXT(BR_BLR_RET, TEST_INST_OPCODE(BR_BLR_RET, 1) && TEST_INST_OPCODE(BR_BLR_RET, 2) && TEST_INST_OPCODE(BR_BLR_RET,3)) DEFINE_IS_EXT(BR_BLR_RET, TEST_INST_OPCODE(BR_BLR_RET, 1) && TEST_INST_OPCODE(BR_BLR_RET, 2) && TEST_INST_OPCODE(BR_BLR_RET,3))
DEFINE_INST_CODE(BR_BLR_RET) void Disassemble() override;
void decode(A64_STRUCT_BR_BLR_RET *inst) override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -504,8 +455,8 @@ namespace SandHook { ...@@ -504,8 +455,8 @@ namespace SandHook {
}; };
template <typename Inst> template <typename S, U32 C>
class A64LoadAndStoreImm : public InstructionA64<Inst> { class A64LoadAndStoreImm : public InstructionA64<S,C> {
public: public:
enum AdMod { enum AdMod {
...@@ -514,14 +465,12 @@ namespace SandHook { ...@@ -514,14 +465,12 @@ namespace SandHook {
PreIndex = 0b11 PreIndex = 0b11
}; };
enum Size { enum RegSize {
Size32 = 0b10, Size32 = 0b10,
Size64 = 0b11 Size64 = 0b11
}; };
A64LoadAndStoreImm() {} A64LoadAndStoreImm(void *inst) : InstructionA64<S,C>(inst) {}
A64LoadAndStoreImm(Inst *inst) : InstructionA64<Inst>(inst) {}
A64LoadAndStoreImm(RegisterA64 *rt, const MemOperand &operand) : rt(rt), A64LoadAndStoreImm(RegisterA64 *rt, const MemOperand &operand) : rt(rt),
operand(operand) {} operand(operand) {}
...@@ -529,70 +478,58 @@ namespace SandHook { ...@@ -529,70 +478,58 @@ namespace SandHook {
RegisterA64* rt; RegisterA64* rt;
MemOperand operand = MemOperand(); MemOperand operand = MemOperand();
protected: protected:
Off offset;
AdMod addrMode; AdMod addrMode;
Size regSize; RegSize regSize;
U8 scale; U8 scale;
bool wback; bool wback;
bool postindex; bool postindex;
Off offset;
}; };
class INST_A64(STR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_IMM)> { DEFINE_INST_EXT_(STR_IMM, A64LoadAndStoreImm) {
public: public:
A64_STR_IMM(); A64_STR_IMM(void *inst);
A64_STR_IMM(STRUCT_A64(STR_IMM)& inst);
A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand); A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(STR_IMM) DEFINE_IS(STR_IMM)
DEFINE_INST_CODE(STR_IMM) void Disassemble() override;
void decode(STRUCT_A64(STR_IMM) *inst) override;
void assembler() override; void Assemble() override;
}; };
class INST_A64(STR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_UIMM)> { DEFINE_INST_EXT_(STR_UIMM, A64LoadAndStoreImm) {
public: public:
A64_STR_UIMM(); A64_STR_UIMM(void *inst);
A64_STR_UIMM(STRUCT_A64(STR_UIMM)& inst);
A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand); A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(STR_UIMM) DEFINE_IS(STR_UIMM)
DEFINE_INST_CODE(STR_UIMM) void Disassemble() override;
void decode(STRUCT_A64(STR_UIMM) *inst) override;
void assembler() override; void Assemble() override;
}; };
DEFINE_INST(MOV_REG) { DEFINE_INST(MOV_REG) {
public: public:
A64_MOV_REG(); A64_MOV_REG(void *inst);
A64_MOV_REG(STRUCT_A64(MOV_REG) &inst);
A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm); A64_MOV_REG(RegisterA64 &rd, RegisterA64 &rm);
DEFINE_IS_EXT(MOV_REG, TEST_INST_OPCODE(MOV_REG, 1) && TEST_INST_OPCODE(MOV_REG, 2)) DEFINE_IS_EXT(MOV_REG, TEST_INST_OPCODE(MOV_REG, 1) && TEST_INST_OPCODE(MOV_REG, 2))
DEFINE_INST_CODE(MOV_REG) void Disassemble() override;
void decode(A64_STRUCT_MOV_REG *inst) override;
void assembler() override; void Assemble() override;
public: public:
RegisterA64* rd; RegisterA64* rd;
...@@ -603,20 +540,16 @@ namespace SandHook { ...@@ -603,20 +540,16 @@ namespace SandHook {
DEFINE_INST(SUB_EXT_REG) { DEFINE_INST(SUB_EXT_REG) {
public: public:
A64_SUB_EXT_REG(); A64_SUB_EXT_REG(void *inst);
A64_SUB_EXT_REG(STRUCT_A64(SUB_EXT_REG) &inst);
A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand, A64_SUB_EXT_REG(RegisterA64 &rd, RegisterA64 &rn, const Operand &operand,
FlagsUpdate flagsUpdate); FlagsUpdate flagsUpdate);
DEFINE_IS_EXT(SUB_EXT_REG, TEST_INST_OPCODE(SUB_EXT_REG, 1) && TEST_INST_OPCODE(SUB_EXT_REG, 2)) DEFINE_IS_EXT(SUB_EXT_REG, TEST_INST_OPCODE(SUB_EXT_REG, 1) && TEST_INST_OPCODE(SUB_EXT_REG, 2))
DEFINE_INST_CODE(SUB_EXT_REG) void Disassemble() override;
void decode(A64_STRUCT_SUB_EXT_REG *inst) override;
void assembler() override; void Assemble() override;
public: public:
...@@ -637,19 +570,15 @@ namespace SandHook { ...@@ -637,19 +570,15 @@ namespace SandHook {
DCP = 0b101 DCP = 0b101
}; };
A64_EXCEPTION_GEN(); A64_EXCEPTION_GEN(void *inst);
A64_EXCEPTION_GEN(STRUCT_A64(EXCEPTION_GEN) &inst);
A64_EXCEPTION_GEN(OP op, ExceptionLevel el, U16 imme); A64_EXCEPTION_GEN(OP op, ExceptionLevel el, U16 imme);
DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2)) DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2))
DEFINE_INST_CODE(EXCEPTION_GEN) void Disassemble() override;
void decode(STRUCT_A64(EXCEPTION_GEN) *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -658,89 +587,77 @@ namespace SandHook { ...@@ -658,89 +587,77 @@ namespace SandHook {
}; };
class INST_A64(SVC) : public INST_A64(EXCEPTION_GEN) { DEFINE_INST_EXT(SVC, EXCEPTION_GEN) {
public: public:
A64_SVC(U16 imme);
A64_SVC(); A64_SVC(U16 imme);
A64_SVC(STRUCT_A64(SVC) &inst); A64_SVC(void *inst);
DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1)) DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1))
DEFINE_INST_CODE(SVC)
}; };
class INST_A64(LDR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_IMM)> { DEFINE_INST_EXT_(LDR_IMM, A64LoadAndStoreImm) {
public: public:
A64_LDR_IMM();
A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst); A64_LDR_IMM(void *inst);
A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand); A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_IMM) DEFINE_IS(LDR_IMM)
DEFINE_INST_CODE(LDR_IMM) void Disassemble() override;
void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override; void Assemble() override;
}; };
class INST_A64(LDR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_UIMM)> { DEFINE_INST_EXT_(LDR_UIMM, A64LoadAndStoreImm) {
public: public:
A64_LDR_UIMM();
A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst); A64_LDR_UIMM(void *inst);
A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand); A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_UIMM) DEFINE_IS(LDR_UIMM)
DEFINE_INST_CODE(LDR_UIMM) void Disassemble() override;
void decode(STRUCT_A64(LDR_UIMM) *inst) override; void Assemble() override;
void assembler() override;
}; };
DEFINE_INST_EXT(LDRSW_IMM, LDR_IMM) {
class INST_A64(LDRSW_IMM) : public INST_A64(LDR_IMM) {
public: public:
A64_LDRSW_IMM();
A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst); A64_LDRSW_IMM(void *inst);
A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand); A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) && TEST_INST_FIELD(size, Size32)) DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) &&
TEST_INST_FIELD(size , Size32))
DEFINE_INST_CODE(LDRSW_IMM)
void decode(STRUCT_A64(LDR_IMM) *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
}; };
class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) { DEFINE_INST_EXT(LDRSW_UIMM, LDR_UIMM) {
public: public:
A64_LDRSW_UIMM(); A64_LDRSW_UIMM();
A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst); A64_LDRSW_UIMM(void *inst);
A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand); A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_UIMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_UIMM)) && TEST_INST_FIELD(size, Size32)) DEFINE_IS_EXT(LDRSW_UIMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_UIMM)) &&
TEST_INST_FIELD(size, Size32))
DEFINE_INST_CODE(LDRSW_UIMM) void Disassemble() override;
void decode(STRUCT_A64(LDR_UIMM) *inst) override; void Assemble() override;
void assembler() override;
}; };
...@@ -757,22 +674,20 @@ namespace SandHook { ...@@ -757,22 +674,20 @@ namespace SandHook {
PreIndex = 0b11 PreIndex = 0b11
}; };
enum Size { enum RegSize {
Size32 = 0b00, Size32 = 0b00,
Size64 = 0b10 Size64 = 0b10
}; };
A64_STP_LDP(A64_STRUCT_STP_LDP &inst); A64_STP_LDP(void *inst);
A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand); A64_STP_LDP(OP op, RegisterA64 &rt1, RegisterA64 &rt2, const MemOperand &operand);
DEFINE_IS(STP_LDP) DEFINE_IS(STP_LDP)
DEFINE_INST_CODE(STP_LDP) void Disassemble() override;
void decode(A64_STRUCT_STP_LDP *inst) override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
...@@ -795,24 +710,20 @@ namespace SandHook { ...@@ -795,24 +710,20 @@ namespace SandHook {
UnSign = 0b0 UnSign = 0b0
}; };
enum Size { enum RegSize {
Size32 = 0b0, Size32 = 0b0,
Size64 = 0b1 Size64 = 0b1
}; };
A64_ADD_SUB_IMM(); A64_ADD_SUB_IMM(void *inst);
A64_ADD_SUB_IMM(A64_STRUCT_ADD_SUB_IMM &inst);
A64_ADD_SUB_IMM(OP op, S sign, RegisterA64 &rd, const Operand &operand); A64_ADD_SUB_IMM(OP op, S sign, RegisterA64 &rd, const Operand &operand);
DEFINE_IS(ADD_SUB_IMM) DEFINE_IS(ADD_SUB_IMM)
DEFINE_INST_CODE(ADD_SUB_IMM) void Disassemble() override;
void decode(A64_STRUCT_ADD_SUB_IMM *inst) override; void Assemble() override;
void assembler() override;
public: public:
OP op; OP op;
...@@ -830,21 +741,19 @@ namespace SandHook { ...@@ -830,21 +741,19 @@ namespace SandHook {
MRS = 1 MRS = 1
}; };
A64_MSR_MRS(A64_STRUCT_MSR_MRS &inst); A64_MSR_MRS(void *inst);
A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt); A64_MSR_MRS(OP op, SystemRegister &systemRegister, RegisterA64 &rt);
DEFINE_INST_CODE(MSR_MRS)
DEFINE_IS(MSR_MRS) DEFINE_IS(MSR_MRS)
void decode(A64_STRUCT_MSR_MRS *inst) override; void Disassemble() override;
void assembler() override; void Assemble() override;
public: public:
OP op; OP op;
SystemRegister* systemRegister; SystemRegister* system_reg;
RegisterA64* rt; RegisterA64* rt;
}; };
...@@ -857,6 +766,7 @@ namespace SandHook { ...@@ -857,6 +766,7 @@ namespace SandHook {
#undef DEFINE_IS #undef DEFINE_IS
#undef TEST_INST_FIELD #undef TEST_INST_FIELD
#undef TEST_INST_OPCODE #undef TEST_INST_OPCODE
#undef DEFINE_INST_CODE #undef DEFINE_INST
#undef DEFINE_INST_EXT
#endif //SANDHOOK_NH_INST_ARM64_H #undef DEFINE_INST_EXT_
#undef DEFINE_INST_PCREL
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_INST_CODE_ARM64_H #pragma once
#define SANDHOOK_NH_INST_CODE_ARM64_H
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
enum class InstCodeA64 { enum class InstCodeA64 : InstCode {
UNKNOW, UNKNOW,
MOV_WIDE, MOV_WIDE,
MOV_REG, MOV_REG,
...@@ -31,5 +30,3 @@ enum class InstCodeA64 { ...@@ -31,5 +30,3 @@ enum class InstCodeA64 {
ADD_SUB_IMM, ADD_SUB_IMM,
MSR_MRS MSR_MRS
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_CODE_ARM64_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/5. // Created by swift on 2019/5/5.
// //
#ifndef SANDHOOK_NH_INST_AARCH64_H #pragma once
#define SANDHOOK_NH_INST_AARCH64_H
#include "instruction.h" #include "instruction.h"
...@@ -39,7 +38,7 @@ enum FieldWide { ...@@ -39,7 +38,7 @@ enum FieldWide {
WideReg = 5, WideReg = 5,
}; };
//unknow inst //Unknow inst
DEFINE_STRUCT_A64(UNKNOW) { DEFINE_STRUCT_A64(UNKNOW) {
InstA64 raw; InstA64 raw;
}; };
...@@ -234,5 +233,3 @@ DEFINE_STRUCT_A64(MSR_MRS) { ...@@ -234,5 +233,3 @@ DEFINE_STRUCT_A64(MSR_MRS) {
InstA64 op:1; InstA64 op:1;
InstA64 opcode:10; InstA64 opcode:10;
}; };
\ No newline at end of file
#endif //SANDHOOK_NH_INST_AARCH64_H
...@@ -26,7 +26,7 @@ XRegister::XRegister(U8 code) : RegisterA64(code) {} ...@@ -26,7 +26,7 @@ XRegister::XRegister(U8 code) : RegisterA64(code) {}
XRegister::XRegister() {} XRegister::XRegister() {}
U8 XRegister::getWide() { U8 XRegister::Wide() {
return Reg64Bit; return Reg64Bit;
} }
...@@ -43,6 +43,6 @@ WRegister::WRegister(U8 code) : RegisterA64(code) {} ...@@ -43,6 +43,6 @@ WRegister::WRegister(U8 code) : RegisterA64(code) {}
WRegister::WRegister() {} WRegister::WRegister() {}
U8 WRegister::getWide() { U8 WRegister::Wide() {
return Reg32Bit; return Reg32Bit;
} }
// //
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#pragma once
#ifndef SANDHOOK_NH_REGISTER_A64_H
#define SANDHOOK_NH_REGISTER_A64_H
#include "register.h" #include "register.h"
...@@ -62,7 +60,7 @@ namespace SandHook { ...@@ -62,7 +60,7 @@ namespace SandHook {
XRegister(); XRegister();
XRegister(U8 code); XRegister(U8 code);
U8 getWide() override; U8 Wide() override;
static XRegister* get(U8 code) { static XRegister* get(U8 code) {
return registers[code]; return registers[code];
...@@ -75,9 +73,10 @@ namespace SandHook { ...@@ -75,9 +73,10 @@ namespace SandHook {
class WRegister : public RegisterA64 { class WRegister : public RegisterA64 {
public: public:
WRegister(); WRegister();
WRegister(U8 code); WRegister(U8 code);
U8 getWide() override; U8 Wide() override;
static WRegister* get(U8 code) { static WRegister* get(U8 code) {
return registers[code]; return registers[code];
...@@ -87,6 +86,8 @@ namespace SandHook { ...@@ -87,6 +86,8 @@ namespace SandHook {
static WRegister* registers[]; static WRegister* registers[];
}; };
class SystemRegister { class SystemRegister {
public: public:
...@@ -98,34 +99,31 @@ namespace SandHook { ...@@ -98,34 +99,31 @@ namespace SandHook {
U16 op0:2; U16 op0:2;
}; };
SystemRegister(U16 value) : value(value) {}
SystemRegister(U16 op0, U16 op1, U16 crn, U16 crm, U16 op2) { SystemRegister(U16 op0, U16 op1, U16 crn, U16 crm, U16 op2) {
reg.op0 = op0; reg.op0 = op0;
reg.op1 = op1; reg.op1 = op1;
reg.CRn = crn; reg.CRn = crn;
reg.CRm = crm; reg.CRm = crm;
reg.op2 = op2; reg.op2 = op2;
value = ForceCast<U16>(reg);
} }
U16 value() { bool operator==(const SystemRegister &rhs) const {
return value == rhs.value;
union { }
U16 raw;
SystemReg reg;
} ret;
ret.reg = reg;
return ret.raw; bool operator!=(const SystemRegister &rhs) const {
return !(rhs == *this);
} }
public: public:
U16 value;
SystemReg reg; SystemReg reg;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_A64_H
...@@ -18,7 +18,7 @@ namespace SandHook { ...@@ -18,7 +18,7 @@ namespace SandHook {
XRegister IP0 = X16; XRegister IP0 = X16;
XRegister IP1 = X17; XRegister IP1 = X17;
XRegister LR = X30; XRegister LR = X30;
//zero reg //zero reg_
XRegister XZR = X31; XRegister XZR = X31;
WRegister WZR = W31; WRegister WZR = W31;
RegisterA64 UnknowRegiser = RegisterA64(38); RegisterA64 UnknowRegiser = RegisterA64(38);
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/8. // Created by swift on 2019/5/8.
// //
#ifndef SANDHOOK_NH_REGISTER_LIST_A64_H #pragma once
#define SANDHOOK_NH_REGISTER_LIST_A64_H
#include "register_arm64.h" #include "register_arm64.h"
#include "base.h" #include "base.h"
...@@ -34,7 +33,7 @@ namespace SandHook { ...@@ -34,7 +33,7 @@ namespace SandHook {
extern XRegister IP0; extern XRegister IP0;
extern XRegister IP1; extern XRegister IP1;
extern XRegister LR; extern XRegister LR;
//zero reg //zero reg_
extern XRegister XZR; extern XRegister XZR;
extern WRegister WZR; extern WRegister WZR;
extern RegisterA64 UnknowRegiser; extern RegisterA64 UnknowRegiser;
...@@ -59,5 +58,3 @@ namespace SandHook { ...@@ -59,5 +58,3 @@ namespace SandHook {
#define XReg(N) XRegister::get(N) #define XReg(N) XRegister::get(N)
#define WReg(N) WRegister::get(N) #define WReg(N) WRegister::get(N)
\ No newline at end of file
#endif //SANDHOOK_NH_REGISTER_LIST_A64_H
...@@ -20,46 +20,46 @@ case ENUM_VALUE(InstCodeA64, InstCodeA64::X): \ ...@@ -20,46 +20,46 @@ case ENUM_VALUE(InstCodeA64, InstCodeA64::X): \
relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \ relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \
break; break;
CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembler.codeContainer) { CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembler.code_container) {
assemblerA64 = &assembler; assemblerA64 = &assembler;
} }
bool CodeRelocateA64::visit(Unit<Base> *unit, void *pc) { bool CodeRelocateA64::Visit(BaseUnit *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC()); Relocate(reinterpret_cast<BaseInst *>(unit), __ GetPC());
curOffset += unit->size(); cur_offset += unit->Size();
if (unit->refcount() == 0) { if (unit->RefCount() == 0) {
delete unit; delete unit;
} }
return true; return true;
} }
void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) { void* CodeRelocateA64::Relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) {
AutoLock autoLock(relocateLock); AutoLock autoLock(relocate_lock);
startAddr = reinterpret_cast<Addr>(startPc); start_addr = reinterpret_cast<Addr>(startPc);
length = len; length = len;
curOffset = 0; cur_offset = 0;
__ allocBufferFirst(static_cast<U32>(len * 8)); __ AllocBufferFirst(static_cast<U32>(len * 8));
void* curPc = __ getPC(); void* cur_pc = __ GetPC();
if (toPc == nullptr) { if (toPc == nullptr) {
Disassembler::get()->decode(startPc, len, *this, true); Disassembler::Get()->Disassemble(startPc, len, *this, true);
} else { } else {
//TODO //TODO
} }
return curPc; return cur_pc;
} }
void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA64::Relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = __ getPC(); void* cur_pc = __ GetPC();
//insert later bind labels //insert later AddBind labels
__ Emit(getLaterBindLabel(curOffset)); __ Emit(GetLaterBindLabel(cur_offset));
if (!instruction->pcRelate()) { if (!instruction->PcRelate()) {
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
return curPc; return cur_pc;
} }
switch (instruction->instCode()) { switch (instruction->InstCode()) {
CASE(B_BL) CASE(B_BL)
CASE(B_COND) CASE(B_COND)
CASE(TBZ_TBNZ) CASE(TBZ_TBNZ)
...@@ -68,21 +68,21 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -68,21 +68,21 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro
CASE(ADR_ADRP) CASE(ADR_ADRP)
default: default:
__ Emit(instruction); __ Emit(instruction);
instruction->ref(); instruction->Ref();
} }
return curPc; return cur_pc;
} }
IMPL_RELOCATE(B_BL) { IMPL_RELOCATE(B_BL) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (InRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(GetLaterBindLabel(inst->offset + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
if (inst->op == inst->BL) { if (inst->op == inst->BL) {
Addr lr = reinterpret_cast<Addr>(toPc); Addr lr = reinterpret_cast<Addr>(toPc);
...@@ -91,20 +91,20 @@ IMPL_RELOCATE(B_BL) { ...@@ -91,20 +91,20 @@ IMPL_RELOCATE(B_BL) {
lr += 4; // Br lr += 4; // Br
__ Mov(LR, lr); __ Mov(LR, lr);
} }
__ Mov(IP1, targetAddr); __ Mov(IP1, target_addr);
__ Br(IP1); __ Br(IP1);
} }
IMPL_RELOCATE(B_COND) { IMPL_RELOCATE(B_COND) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (InRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(GetLaterBindLabel(inst->offset + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -113,7 +113,7 @@ IMPL_RELOCATE(B_COND) { ...@@ -113,7 +113,7 @@ IMPL_RELOCATE(B_COND) {
__ B(false_label); __ B(false_label);
__ Emit(true_label); __ Emit(true_label);
__ Mov(IP1, targetAddr); __ Mov(IP1, target_addr);
__ Br(IP1); __ Br(IP1);
__ Emit(false_label); __ Emit(false_label);
...@@ -121,14 +121,14 @@ IMPL_RELOCATE(B_COND) { ...@@ -121,14 +121,14 @@ IMPL_RELOCATE(B_COND) {
IMPL_RELOCATE(TBZ_TBNZ) { IMPL_RELOCATE(TBZ_TBNZ) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (InRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(GetLaterBindLabel(inst->offset + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -141,7 +141,7 @@ IMPL_RELOCATE(TBZ_TBNZ) { ...@@ -141,7 +141,7 @@ IMPL_RELOCATE(TBZ_TBNZ) {
__ B(false_label); __ B(false_label);
__ Emit(true_label); __ Emit(true_label);
__ Mov(IP1, targetAddr); __ Mov(IP1, target_addr);
__ Br(IP1); __ Br(IP1);
__ Emit(false_label); __ Emit(false_label);
...@@ -149,14 +149,14 @@ IMPL_RELOCATE(TBZ_TBNZ) { ...@@ -149,14 +149,14 @@ IMPL_RELOCATE(TBZ_TBNZ) {
IMPL_RELOCATE(CBZ_CBNZ) { IMPL_RELOCATE(CBZ_CBNZ) {
if (inRelocateRange(inst->offset, sizeof(InstA64))) { if (InRelocateRange(inst->offset, sizeof(InstA64))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(GetLaterBindLabel(inst->offset + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
Label *true_label = new Label(); Label *true_label = new Label();
Label *false_label = new Label(); Label *false_label = new Label();
...@@ -170,40 +170,40 @@ IMPL_RELOCATE(CBZ_CBNZ) { ...@@ -170,40 +170,40 @@ IMPL_RELOCATE(CBZ_CBNZ) {
__ B(false_label); __ B(false_label);
__ Emit(true_label); __ Emit(true_label);
__ Mov(IP1, targetAddr); __ Mov(IP1, target_addr);
__ Br(IP1); __ Br(IP1);
__ Emit(false_label); __ Emit(false_label);
} }
IMPL_RELOCATE(LDR_LIT) { IMPL_RELOCATE(LDR_LIT) {
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr target_addr = inst->GetImmPCOffsetTarget();
XRegister* rtX = XReg(inst->rt->getCode()); XRegister* rtX = XReg(inst->rt->Code());
WRegister* rtW = WReg(inst->rt->getCode()); WRegister* rtW = WReg(inst->rt->Code());
if (inRelocateRange(inst->offset, sizeof(Addr))) { if (InRelocateRange(inst->offset, sizeof(Addr))) {
inst->ref(); inst->Ref();
inst->bindLabel(*getLaterBindLabel(inst->offset + curOffset)); inst->BindLabel(GetLaterBindLabel(inst->offset + cur_offset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<BaseInst*>(inst));
return; return;
} }
switch (inst->op) { switch (inst->op) {
case INST_A64(LDR_LIT)::LDR_X: case INST_A64(LDR_LIT)::LDR_X:
__ Mov(*rtX, targetAddr); __ Mov(*rtX, target_addr);
__ Ldr(*rtX, MemOperand(rtX, 0, Offset)); __ Ldr(*rtX, MemOperand(rtX, 0, Offset));
break; break;
case INST_A64(LDR_LIT)::LDR_W: case INST_A64(LDR_LIT)::LDR_W:
__ Mov(*rtX, targetAddr); __ Mov(*rtX, target_addr);
__ Ldr(*rtW, MemOperand(rtX, 0, Offset)); __ Ldr(*rtW, MemOperand(rtX, 0, Offset));
break; break;
case INST_A64(LDR_LIT)::LDR_SW: case INST_A64(LDR_LIT)::LDR_SW:
__ Mov(*rtX, targetAddr); __ Mov(*rtX, target_addr);
__ Ldrsw(*rtX, MemOperand(rtX, 0, Offset)); __ Ldrsw(*rtX, MemOperand(rtX, 0, Offset));
break; break;
case INST_A64(LDR_LIT)::LDR_PRFM: case INST_A64(LDR_LIT)::LDR_PRFM:
__ Push(X0); __ Push(X0);
__ Mov(X0, targetAddr); __ Mov(X0, target_addr);
__ Ldrsw(X0, MemOperand(rtX, 0, Offset)); __ Ldrsw(X0, MemOperand(rtX, 0, Offset));
__ Pop(X0); __ Pop(X0);
break; break;
...@@ -211,5 +211,5 @@ IMPL_RELOCATE(LDR_LIT) { ...@@ -211,5 +211,5 @@ IMPL_RELOCATE(LDR_LIT) {
} }
IMPL_RELOCATE(ADR_ADRP) { IMPL_RELOCATE(ADR_ADRP) {
__ Mov(*inst->rd, inst->getImmPCOffsetTarget()); __ Mov(*inst->rd, inst->GetImmPCOffsetTarget());
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_CODE_RELOCATE_A64_H #pragma once
#define SANDHOOK_NH_CODE_RELOCATE_A64_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -23,11 +22,11 @@ namespace SandHook { ...@@ -23,11 +22,11 @@ namespace SandHook {
public: public:
CodeRelocateA64(AssemblerA64 &assembler); CodeRelocateA64(AssemblerA64 &assembler);
void* relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override; void* Relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) override;
void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override; void* Relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override;
bool visit(Unit<Base> *unit, void *pc) override; bool Visit(BaseUnit *unit, void *pc) override;
DEFINE_RELOCATE(B_BL) DEFINE_RELOCATE(B_BL)
...@@ -50,5 +49,3 @@ namespace SandHook { ...@@ -50,5 +49,3 @@ namespace SandHook {
} }
#undef DEFINE_RELOCATE #undef DEFINE_RELOCATE
\ No newline at end of file
#endif //SANDHOOK_NH_CODE_RELOCATE_A64_H
...@@ -2,30 +2,29 @@ ...@@ -2,30 +2,29 @@
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#ifndef SANDHOOK_ARM_BASE_H #pragma once
#define SANDHOOK_ARM_BASE_H
// Condition codes. // Condition codes.
enum Condition { enum Condition {
eq = 0, // Z set Equal. eq = 0, // Z Set Equal.
ne = 1, // Z clear Not equal. ne = 1, // Z clear Not equal.
cs = 2, // C set Carry set. cs = 2, // C Set Carry Set.
cc = 3, // C clear Carry clear. cc = 3, // C clear Carry clear.
mi = 4, // N set Negative. mi = 4, // N Set Negative.
pl = 5, // N clear Positive or zero. pl = 5, // N clear Positive or zero.
vs = 6, // V set Overflow. vs = 6, // V Set Overflow.
vc = 7, // V clear No overflow. vc = 7, // V clear No overflow.
hi = 8, // C set, Z clear Unsigned higher. hi = 8, // C Set, Z clear Unsigned higher.
ls = 9, // C clear or Z set Unsigned lower or same. ls = 9, // C clear or Z Set Unsigned lower or same.
ge = 10, // N == V Greater or equal. ge = 10, // N == V Greater or equal.
lt = 11, // N != V Less than. lt = 11, // N != V Less than.
gt = 12, // Z clear, N == V Greater than. gt = 12, // Z clear, N == V Greater than.
le = 13, // Z set or N != V Less then or equal le = 13, // Z Set or N != V Less then or equal
al = 14, // Always. al = 14, // Always.
nv = 15, // Behaves as always/al. nv = 15, // Behaves as always/al.
// Aliases. // Aliases.
hs = cs, // C set Unsigned higher or same. hs = cs, // C Set Unsigned higher or same.
lo = cc // C clear Unsigned lower. lo = cc // C clear Unsigned lower.
}; };
...@@ -42,31 +41,29 @@ enum Shift { ...@@ -42,31 +41,29 @@ enum Shift {
enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode}; enum AddrMode { Offset, PreIndex, PostIndex, NonAddrMode};
//decode field & encode field //Disassembler field & encode field
//condition //condition
#define DECODE_COND condition = Condition(inst->cond) #define DECODE_COND condition = Condition(Get()->cond)
#define ENCODE_COND get()->cond = condition #define ENCODE_COND Get()->cond = condition
//reg //reg_
#define DECODE_RD(Type) rd = Type(static_cast<U8>(get()->rd)) #define DECODE_RD(Type) rd = Type(static_cast<U8>(Get()->rd))
#define ENCODE_RD get()->rd = rd->getCode() #define ENCODE_RD Get()->rd = rd->Code()
#define DECODE_RT(Type) rt = Type(static_cast<U8>(get()->rt)) #define DECODE_RT(Type) rt = Type(static_cast<U8>(Get()->rt))
#define ENCODE_RT get()->rt = rt->getCode() #define ENCODE_RT Get()->rt = rt->Code()
#define DECODE_RM(Type) rm = Type(static_cast<U8>(get()->rm)) #define DECODE_RM(Type) rm = Type(static_cast<U8>(Get()->rm))
#define ENCODE_RM get()->rm = rm->getCode() #define ENCODE_RM Get()->rm = rm->Code()
#define DECODE_RN(Type) rn = Type(static_cast<U8>(get()->rn)) #define DECODE_RN(Type) rn = Type(static_cast<U8>(Get()->rn))
#define ENCODE_RN get()->rn = rn->getCode() #define ENCODE_RN Get()->rn = rn->Code()
//op //op
#define DECODE_OP op = OP(inst->op) #define DECODE_OP op = OP(Get()->op)
#define ENCODE_OP get()->op = op #define ENCODE_OP Get()->op = op
#define DECODE_SHIFT operand.shift = Shift(inst->shift) #define DECODE_SHIFT operand.shift_ = Shift(Get()->shift)
#define ENCODE_SHIFT get()->shift = operand.shift #define ENCODE_SHIFT Get()->shift = operand.shift_
\ No newline at end of file
#endif //SANDHOOK_ARM_BASE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/6/1. // Created by swift on 2019/6/1.
// //
#ifndef SANDHOOK_SHELL_CODE_ARM_H #pragma once
#define SANDHOOK_SHELL_CODE_ARM_H
//for shell code //for shell code
#define FUNCTION_START(x) \ #define FUNCTION_START(x) \
...@@ -30,5 +29,3 @@ extern "C" void x##_END(); ...@@ -30,5 +29,3 @@ extern "C" void x##_END();
#define IMPORT_LABEL(X,T) extern T X; #define IMPORT_LABEL(X,T) extern T X;
#define SHELLCODE_LEN(x) (Addr)x##_END - (Addr)x #define SHELLCODE_LEN(x) (Addr)x##_END - (Addr)x
\ No newline at end of file
#endif //SANDHOOK_SHELL_CODE_ARM_H
// //
// Created by swift on 2019/5/16. // Created by swift on 2019/5/16.
// //
#pragma once
#ifndef SANDHOOK_PLACE_HOLDER_H
#define SANDHOOK_PLACE_HOLDER_H
#endif //SANDHOOK_PLACE_HOLDER_H
// //
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#pragma once
#ifndef SANDHOOK_CPU_H
#define SANDHOOK_CPU_H
#include "register.h" #include "register.h"
...@@ -17,4 +15,3 @@ namespace SandHook { ...@@ -17,4 +15,3 @@ namespace SandHook {
} }
} }
#endif //SANDHOOK_CPU_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_DATA_H #pragma once
#define SANDHOOK_NH_DATA_H
#include "unit.h" #include "unit.h"
...@@ -21,15 +20,22 @@ public: \ ...@@ -21,15 +20,22 @@ public: \
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename DType> template <typename D>
class Data : public Unit<DType> { class Data : public Unit<D> {
public: public:
Data(DType raw) : Unit<DType>() {
this->set(raw); Data(D raw) : backup_(raw) {}
}
inline UnitType unitType() override { INLINE UnitTypeDef UnitType() override {
return UnitType::UnitData; return UnitTypeDef::UnitData;
}; };
void Move(D *dest) override {
*dest = backup_;
}
private:
D backup_;
}; };
...@@ -53,5 +59,3 @@ namespace SandHook { ...@@ -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 @@ ...@@ -2,9 +2,9 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_INSTRUCTION_H #pragma once
#define SANDHOOK_INSTRUCTION_H
#include <memory>
#include "unit.h" #include "unit.h"
#include "label.h" #include "label.h"
...@@ -23,84 +23,87 @@ typedef U32 InstRaw; ...@@ -23,84 +23,87 @@ typedef U32 InstRaw;
#define INST_CHECK(X,V) \ #define INST_CHECK(X,V) \
CHECK(X,V, valid = false;) CHECK(X,V, valid_ = false;)
#define INST_DCHECK(X,V) \ #define INST_DCHECK(X,V) \
DCHECK(X,V, valid = false;) DCHECK(X,V, valid_ = false;)
#define INST_ASSERT(COND) \ #define INST_ASSERT(COND) \
if (COND) { \ if (COND) { \
valid = false; \ valid_ = false; \
} }
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename Inst> template <typename S, U32 C>
class Instruction : public Unit<Inst>, public LabelBinder { class Instruction : public Unit<S>, public LabelBinder {
public: public:
Instruction() {} Instruction() {}
Instruction(Inst *inst) : Unit<Inst>(inst) {} Instruction(void *inst) : Unit<S>(inst) {}
Instruction(S *inst) : Unit<S>(inst) {}
UnitType unitType() override { UnitTypeDef UnitType() override {
return UnitType::UnitInst; return UnitTypeDef::UnitInst;
}; };
virtual InstType instType() { virtual InstType InstType() {
return unknowInst; return unknowInst;
} }
virtual Arch arch() { virtual Arch Arch() {
return unknowArch; return unknowArch;
} }
virtual U32 instCode() { virtual U32 InstCode() {
return 0; return C;
}; };
virtual bool pcRelate() { virtual bool PcRelate() {
return false; return false;
} }
virtual bool unknow() { virtual bool Unknow() {
return false; return false;
} }
inline bool isValid() const { inline bool Valid() const {
return valid; return valid_;
} }
virtual void onOffsetApply(Off offset) {} virtual void OnOffsetApply(Off offset) {}
void onLabelApply(Addr pc) override { void OnLabelApply(Addr pc) override {
onOffsetApply(pc - this->getVPC()); OnOffsetApply(pc - this->GetVPC());
} }
inline void bindLabel(Label &l) { INLINE void BindLabel(Label *label) {
label = &l; label_ = label;
l.addBinder(this); label->AddBind(this);
} }
virtual void decode(Inst* inst) { virtual void Disassemble() {
inst_backup = *inst; backup_ = *this->pc_;
} }
virtual void assembler() { virtual void Assemble() {
this->set(inst_backup); *this->pc_ = backup_;
} }
protected: protected:
bool valid = true; bool valid_ = true;
Label* label = nullptr; Label* label_ = nullptr;
Inst inst_backup; S backup_;
}; };
class Void : public Unit<Base> { class Void : public BaseUnit {
public: public:
Void(U32 size) : size_(size) {} Void(U32 size) : size_(size) {}
U32 size() override { U32 Size() override {
return size_; return size_;
} }
...@@ -108,7 +111,8 @@ namespace SandHook { ...@@ -108,7 +111,8 @@ namespace SandHook {
U32 size_; U32 size_;
}; };
using BaseInst = Instruction<Base,0>;
using BaseInstRef = std::shared_ptr<BaseInst>;
} }
} }
#endif //SANDHOOK_INSTRUCTION_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_LABEL_H #pragma once
#define SANDHOOK_NH_LABEL_H
#include "unit.h" #include "unit.h"
#include <list> #include <list>
...@@ -13,53 +12,42 @@ namespace SandHook { ...@@ -13,53 +12,42 @@ namespace SandHook {
class LabelBinder { class LabelBinder {
public: public:
virtual void onLabelApply(Addr pc) = 0; virtual void OnLabelApply(Addr pc) = 0;
}; };
class Label : public Unit<Base> { class Label : public BaseUnit {
public: public:
Label() {} Label() {}
Label(void *pc) : pc(pc) {} Label(void *pc) : BaseUnit(pc) {}
inline UnitType unitType() override { enum UnitTypeDef UnitType() override {
return UnitType::UnitLabel; return UnitTypeDef::UnitLabel;
} }
inline U32 size() override { INLINE U32 Size() override {
return 0; return 0;
} }
inline void setPC(void* pc) { INLINE void AddBind(LabelBinder *binder) {
this->pc = pc;
}
inline void *getPC() override {
return pc;
}
inline void addBinder(LabelBinder* binder) {
binders.push_back(binder); binders.push_back(binder);
} }
inline void removeBinder(LabelBinder* binder) { INLINE void RemoveBind(LabelBinder *binder) {
binders.push_back(binder); binders.push_back(binder);
} }
inline void bindLabel() { INLINE void BindLabel() {
std::list<LabelBinder*>::iterator binder; std::list<LabelBinder*>::iterator binder;
for(binder = binders.begin();binder != binders.end(); ++binder) { for(binder = binders.begin();binder != binders.end(); ++binder) {
(*binder)->onLabelApply(getVPC()); (*binder)->OnLabelApply(GetVPC());
} }
} }
private: private:
void* pc;
std::list<LabelBinder*> binders = std::list<LabelBinder*>(); std::list<LabelBinder*> binders = std::list<LabelBinder*>();
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_LABEL_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#ifndef SANDHOOK_MEMORY_H #pragma once
#define SANDHOOK_MEMORY_H
namespace SandHook { namespace SandHook {
namespace VM { namespace VM {
...@@ -12,5 +11,3 @@ namespace SandHook { ...@@ -12,5 +11,3 @@ namespace SandHook {
}; };
} }
} }
#endif //SANDHOOK_MEMORY_H
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_REGISTER_H #pragma once
#define SANDHOOK_REGISTER_H
#include "../includes/base.h" #include "base.h"
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
...@@ -23,61 +22,55 @@ namespace SandHook { ...@@ -23,61 +22,55 @@ namespace SandHook {
Register() {} Register() {}
Register(U8 code) : code(code) {} Register(U8 code) : code_(code) {}
inline U8 getCode() { inline U8 Code() {
return code; return code_;
} }
virtual bool isFP() { virtual bool IsFP() {
return false; return false;
}; };
virtual U8 getWide() { virtual U8 Wide() {
return 0; return 0;
}; };
inline U8 getWideInBytes() { INLINE U8 WideInBytes() {
return static_cast<U8>(getWide() / BITS_OF_BYTE); return static_cast<U8>(Wide() / BITS_OF_BYTE);
}; };
inline bool is32Bit() { INLINE bool is32Bit() {
return getWide() == Reg32Bit; return Wide() == Reg32Bit;
} }
inline bool is64Bit() { INLINE bool is64Bit() {
return getWide() == Reg64Bit; return Wide() == Reg64Bit;
} }
inline bool is128Bit() { INLINE bool is128Bit() {
return getWide() == Reg128Bit; return Wide() == Reg128Bit;
}
virtual bool is(const Register &rhs) {
return rhs.code == code;
} }
bool operator==(const Register &rhs) const { bool operator==(const Register &rhs) const {
return code == rhs.code; return code_ == rhs.code_;
} }
bool operator!=(const Register &rhs) const { bool operator!=(const Register &rhs) const {
return code != rhs.code; return code_ != rhs.code_;
} }
virtual void setData(Data data) { virtual void SetData(Data data) {
this->data = data; data_ = data;
} }
virtual Data& getData() { virtual Data& GetData() {
return data; return data_;
} }
private: private:
U8 code; U8 code_;
Data data; Data data_;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_REGISTER_H
...@@ -2,110 +2,86 @@ ...@@ -2,110 +2,86 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_UNIT_H #pragma once
#define SANDHOOK_NH_UNIT_H
#include <malloc.h> #include <malloc.h>
#include "../includes/base.h" #include <memory>
#include "base.h"
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
template <typename Raw> template <typename S>
class Unit { class Unit {
public: public:
Unit() { Unit() {}
if (unitType() != UnitVoid) {
raw = reinterpret_cast<Raw *>(malloc(size()));
memset(raw, 0, size());
auto_alloc = true;
}
}
Unit<Raw>(Raw *raw) : raw(raw) {} Unit<S>(S *pc) : pc_(pc) {}
Unit<Raw>(Raw raw) { Unit<S>(void *pc) : pc_(ForceCast<S*>(pc)) {}
Unit();
*this->raw = raw;
}
virtual void* getPC() { virtual void* GetPC() {
return auto_alloc ? nullptr : raw; return pc_;
} }
virtual Addr getVPC() { virtual Addr GetVPC() {
return vPos; return virtual_pc_;
} }
inline void setVPos(Addr vPos) { INLINE void SetVPC(Addr vPos) {
this->vPos = vPos; virtual_pc_ = vPos;
} }
inline Raw* get() const { INLINE S* Get() {
return raw; return pc_;
} }
inline void set(Raw raw) const { INLINE void Set(S raw) {
*this->raw = raw; *pc_ = raw;
} }
inline void set(Raw* raw) { INLINE void Set(S *raw) {
if (auto_alloc) { pc_ = raw;
free(this->raw);
auto_alloc = false;
}
this->raw = raw;
} }
inline void copy(void* dest) { INLINE void Copy(S *dest) {
memcpy(dest, getPC(), size()); *dest = *pc_;
} }
virtual void Move(S *dest) {
inline void move(Raw* dest) { *dest = *pc_;
memcpy(dest, raw, size()); pc_ = dest;
if (auto_alloc) {
free(raw);
auto_alloc = false;
}
raw = dest;
} }
virtual UnitType unitType() { virtual UnitTypeDef UnitType() {
return UnitType::UnitUnknow; return UnitTypeDef::UnitUnknow;
}; };
virtual U32 size() { virtual U32 Size() {
return sizeof(Raw); return sizeof(S);
} }
inline U8 ref() { INLINE U8 Ref() {
return ++ref_count; return ++ref_count_;
} }
inline U8 release() { INLINE U8 Release() {
return --ref_count; return --ref_count_;
} }
inline U8 refcount() { INLINE U8 RefCount() {
return ref_count; return ref_count_;
} }
virtual ~Unit() { protected:
if (auto_alloc) { S* pc_ = nullptr;
free(raw); Addr virtual_pc_ = 0;
} U8 ref_count_ = 0;
}
private:
Raw* raw = nullptr;
Addr vPos = 0;
bool auto_alloc = false;
U8 ref_count = 0;
}; };
using BaseUnit = Unit<Base>;
using BaseUnitRef = std::shared_ptr<BaseUnit>;
} }
} }
#endif //SANDHOOK_NH_UNIT_H
...@@ -8,76 +8,76 @@ ...@@ -8,76 +8,76 @@
using namespace SandHook::Assembler; using namespace SandHook::Assembler;
using namespace SandHook::Asm; using namespace SandHook::Asm;
CodeContainer::CodeContainer(CodeBuffer *codeBuffer) : codeBuffer(codeBuffer) {} CodeContainer::CodeContainer(CodeBuffer *codeBuffer) : code_buffer(codeBuffer) {}
void CodeContainer::setCodeBuffer(CodeBuffer *codeBuffer) { void CodeContainer::SetCodeBuffer(CodeBuffer *codeBuffer) {
this->codeBuffer = codeBuffer; this->code_buffer = codeBuffer;
} }
void CodeContainer::append(Unit<Base> *unit) { void CodeContainer::Append(BaseUnit *unit) {
units.push_back(unit); units.push_back(unit);
unit->setVPos(curPc); unit->SetVPC(cur_pc);
switch (unit->unitType()) { switch (unit->UnitType()) {
case UnitLabel: case UnitLabel:
labels.push_back((Label*)unit); labels.push_back((Label*)unit);
break; break;
default: default:
curPc += unit->size(); cur_pc += unit->Size();
} }
} }
void CodeContainer::commit() { void CodeContainer::Commit() {
U32 bufferSize = static_cast<U32>(curPc - startPc); U32 bufferSize = static_cast<U32>(cur_pc - start_pc);
void* bufferStart; void* bufferStart;
if (startPc > 0) { if (start_pc > 0) {
bufferStart = reinterpret_cast<void *>(startPc); bufferStart = reinterpret_cast<void *>(start_pc);
codeBuffer->resetLastBufferSize(bufferSize); code_buffer->ResetLastBufferSize(bufferSize);
} else { } else {
bufferStart = codeBuffer->getBuffer(bufferSize); bufferStart = code_buffer->GetBuffer(bufferSize);
} }
Addr pcNow = reinterpret_cast<Addr>(bufferStart); Addr pcNow = reinterpret_cast<Addr>(bufferStart);
//commit to code buffer & assembler inst //commit to code buffer & Assembler inst
std::list<Unit<Base>*>::iterator unit; std::list<BaseUnit*>::iterator unit;
for(unit = units.begin();unit != units.end(); ++unit) { for(unit = units.begin();unit != units.end(); ++unit) {
if ((*unit)->unitType() == UnitData) { if ((*unit)->UnitType() == UnitData) {
(*unit)->move(reinterpret_cast<Base *>(pcNow)); (*unit)->Move(reinterpret_cast<Base*>(pcNow));
} else if ((*unit)->unitType() != UnitLabel) { } else if ((*unit)->UnitType() != UnitLabel) {
(*unit)->set(reinterpret_cast<Base *>(pcNow)); (*unit)->Set(reinterpret_cast<Base*>(pcNow));
} }
if ((*unit)->unitType() == UnitInst) { if ((*unit)->UnitType() == UnitInst) {
reinterpret_cast<Instruction<Base>*>(*unit)->assembler(); reinterpret_cast<BaseInst*>(*unit)->Assemble();
} }
pcNow += (*unit)->size(); pcNow += (*unit)->Size();
} }
//bind labels //AddBind labels
std::list<Label*>::iterator label; std::list<Label*>::iterator label;
for(label = labels.begin();label != labels.end(); ++label) { for(label = labels.begin();label != labels.end(); ++label) {
(*label)->bindLabel(); (*label)->BindLabel();
} }
//flush I cache //flush I cache
flushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart)); FlushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart));
//set pc //Set pc
startPc = reinterpret_cast<Addr>(bufferStart); start_pc = reinterpret_cast<Addr>(bufferStart);
curPc = pcNow; cur_pc = pcNow;
} }
void CodeContainer::allocBufferFirst(U32 size) { void CodeContainer::AllocBufferFirst(U32 size) {
startPc = reinterpret_cast<Addr>(codeBuffer->getBuffer(size)); start_pc = reinterpret_cast<Addr>(code_buffer->GetBuffer(size));
curPc = startPc; cur_pc = start_pc;
} }
CodeContainer::~CodeContainer() { CodeContainer::~CodeContainer() {
std::list<Unit<Base>*>::iterator unit; std::list<BaseUnit*>::iterator unit;
for(unit = units.begin();unit != units.end(); ++unit) { for(unit = units.begin();unit != units.end(); ++unit) {
delete (*unit); delete (*unit);
} }
} }
Addr CodeContainer::size() { Addr CodeContainer::Size() {
return curPc - startPc; return cur_pc - start_pc;
} }
...@@ -11,31 +11,31 @@ ...@@ -11,31 +11,31 @@
using namespace SandHook::Assembler; using namespace SandHook::Assembler;
using namespace SandHook::Utils; using namespace SandHook::Utils;
void *AndroidCodeBuffer::getBuffer(U32 size) { void *AndroidCodeBuffer::GetBuffer(U32 size) {
AutoLock autoLock(allocSpaceLock); AutoLock autoLock(alloc_space_lock);
void* mmapRes; void* mmapRes;
Addr exeSpace = 0; Addr exeSpace = 0;
if (executeSpaceList.size() == 0) { if (execute_space_list.size() == 0) {
goto label_alloc_new_space; goto label_alloc_new_space;
} else if (executePageOffset + size + 4> currentExecutePageSize) { } else if (execute_page_offset + size + 4> current_execute_page_size) {
goto label_alloc_new_space; goto label_alloc_new_space;
} else { } else {
exeSpace = reinterpret_cast<Addr>(executeSpaceList.back()); exeSpace = reinterpret_cast<Addr>(execute_space_list.back());
//4 字节对齐 //4 字节对齐
Addr retSpace = RoundUp(exeSpace + executePageOffset, 4); Addr retSpace = RoundUp(exeSpace + execute_page_offset, 4);
executePageOffset = retSpace + size - exeSpace; execute_page_offset = retSpace + size - exeSpace;
return reinterpret_cast<void *>(retSpace); return reinterpret_cast<void *>(retSpace);
} }
label_alloc_new_space: label_alloc_new_space:
currentExecutePageSize = static_cast<U32>(FIT(size, P_SIZE)); current_execute_page_size = static_cast<U32>(FIT(size, P_SIZE));
mmapRes = mmap(NULL, currentExecutePageSize, PROT_READ | PROT_WRITE | PROT_EXEC, mmapRes = mmap(NULL, current_execute_page_size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0); MAP_ANON | MAP_PRIVATE, -1, 0);
if (mmapRes == MAP_FAILED) { if (mmapRes == MAP_FAILED) {
return 0; return 0;
} }
memset(mmapRes, 0, currentExecutePageSize); memset(mmapRes, 0, current_execute_page_size);
executeSpaceList.push_back(mmapRes); execute_space_list.push_back(mmapRes);
executePageOffset = size; execute_page_offset = size;
return mmapRes; return mmapRes;
} }
...@@ -43,24 +43,24 @@ AndroidCodeBuffer::AndroidCodeBuffer() {} ...@@ -43,24 +43,24 @@ AndroidCodeBuffer::AndroidCodeBuffer() {}
StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {} StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {}
void *StaticCodeBuffer::getBuffer(U32 bufferSize) { void *StaticCodeBuffer::GetBuffer(U32 bufferSize) {
if (!memUnprotect(pc, bufferSize)) { if (!MemUnprotect(pc, bufferSize)) {
LOGE("error memUnprotect!"); LOGE("error MemUnprotect!");
} }
return reinterpret_cast<void *>(pc); return reinterpret_cast<void *>(pc);
} }
void AndroidRellocBufferUnsafe::resetLastBufferSize(U32 size) { void AndroidReSizableBufferUnsafe::ResetLastBufferSize(U32 size) {
if (executePageOffset + (size - lastAllocSize) <= currentExecutePageSize) { if (execute_page_offset + (size - last_alloc_size) <= current_execute_page_size) {
executePageOffset += size - lastAllocSize; execute_page_offset += size - last_alloc_size;
lastAllocSize = size; last_alloc_size = size;
} }
} }
void *AndroidRellocBufferUnsafe::getBuffer(U32 bufferSize) { void *AndroidReSizableBufferUnsafe::GetBuffer(U32 bufferSize) {
void* res = AndroidCodeBuffer::getBuffer(bufferSize); void* res = AndroidCodeBuffer::GetBuffer(bufferSize);
if (res) { if (res) {
lastAllocSize = bufferSize; last_alloc_size = bufferSize;
} }
return res; return res;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_CODE_BUFFER_H #pragma once
#define SANDHOOK_NH_CODE_BUFFER_H
#include <mutex> #include <mutex>
#include "assembler.h" #include "assembler.h"
...@@ -15,25 +14,25 @@ namespace SandHook { ...@@ -15,25 +14,25 @@ namespace SandHook {
AndroidCodeBuffer(); AndroidCodeBuffer();
void *getBuffer(U32 bufferSize) override; void *GetBuffer(U32 bufferSize) override;
protected: protected:
std::list<void*> executeSpaceList = std::list<void*>(); std::list<void*> execute_space_list = std::list<void*>();
std::mutex allocSpaceLock; std::mutex alloc_space_lock;
Addr executePageOffset = 0; Addr execute_page_offset = 0;
U32 currentExecutePageSize = 0; U32 current_execute_page_size = 0;
}; };
//thread unsafe //thread unsafe
class AndroidRellocBufferUnsafe : public AndroidCodeBuffer { class AndroidReSizableBufferUnsafe : public AndroidCodeBuffer {
public: public:
public: public:
void resetLastBufferSize(U32 size) override; void ResetLastBufferSize(U32 size) override;
void *getBuffer(U32 bufferSize) override; void *GetBuffer(U32 bufferSize) override;
private: private:
U32 lastAllocSize; U32 last_alloc_size;
}; };
class StaticCodeBuffer : public CodeBuffer { class StaticCodeBuffer : public CodeBuffer {
...@@ -41,12 +40,10 @@ namespace SandHook { ...@@ -41,12 +40,10 @@ namespace SandHook {
StaticCodeBuffer(Addr pc); StaticCodeBuffer(Addr pc);
void *getBuffer(U32 bufferSize) override; void *GetBuffer(U32 bufferSize) override;
private: private:
Addr pc; Addr pc;
}; };
} }
} }
#endif //SANDHOOK_NH_CODE_BUFFER_H
...@@ -11,27 +11,27 @@ ...@@ -11,27 +11,27 @@
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
bool DefaultVisitor::visit(Unit<Base> *unit, void *pc) { bool DefaultVisitor::Visit(BaseUnit *unit, void *pc) {
bool res = visitor(unit, pc); bool res = visitor(unit, pc);
delete unit; delete unit;
return res; return res;
} }
DefaultVisitor::DefaultVisitor(bool (*visitor)(Unit<Base> *, void *)) : visitor(visitor) {} DefaultVisitor::DefaultVisitor(bool (*visitor)(BaseUnit *, void *)) : visitor(visitor) {}
//do not support now //do not support now
InstDecoder* Disassembler::get(Arch arch) { InstDecoder* Disassembler::Get(Arch arch) {
switch (arch) { switch (arch) {
case arm32: case arm32:
return get(); return Get();
case arm64: case arm64:
return get(); return Get();
default: default:
return nullptr; return nullptr;
} }
} }
InstDecoder *Disassembler::get() { InstDecoder *Disassembler::Get() {
#if defined(__arm__) #if defined(__arm__)
return Arm32Decoder::instant; return Arm32Decoder::instant;
#elif defined(__aarch64__) #elif defined(__aarch64__)
......
...@@ -9,11 +9,16 @@ ...@@ -9,11 +9,16 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <elf.h>
#include "log.h" #include "log.h"
using namespace SandHook::Elf; using namespace SandHook::Elf;
TextSegment::TextSegment(void *start, void *end) : start(start), end(end) {}
ElfImg::ElfImg(const char *elf) { ElfImg::ElfImg(const char *elf) {
this->elf = elf; this->elf = elf;
//load elf //load elf
...@@ -84,8 +89,8 @@ ElfImg::ElfImg(const char *elf) { ...@@ -84,8 +89,8 @@ ElfImg::ElfImg(const char *elf) {
LOGW("can't find symtab from sections\n"); LOGW("can't find symtab from sections\n");
} }
//load module base //load module rang
base = getModuleBase(elf); baseInRam = getModuleBase(elf);
} }
ElfImg::~ElfImg() { ElfImg::~ElfImg() {
...@@ -136,8 +141,8 @@ Elf_Addr ElfImg::getSymbOffset(const char *name) { ...@@ -136,8 +141,8 @@ Elf_Addr ElfImg::getSymbOffset(const char *name) {
Elf_Addr ElfImg::getSymbAddress(const char *name) { Elf_Addr ElfImg::getSymbAddress(const char *name) {
Elf_Addr offset = getSymbOffset(name); Elf_Addr offset = getSymbOffset(name);
if (offset > 0 && base != nullptr) { if (offset > 0 && baseInRam != nullptr) {
return static_cast<Elf_Addr>((size_t) base + offset - bias); return static_cast<Elf_Addr>((size_t) baseInRam + offset - bias);
} else { } else {
return 0; return 0;
} }
...@@ -167,7 +172,47 @@ void *ElfImg::getModuleBase(const char *name) { ...@@ -167,7 +172,47 @@ void *ElfImg::getModuleBase(const char *name) {
fclose(maps); fclose(maps);
LOGD("get module base %s: %lu", name, load_addr); LOGD("Get module baseInRam %s: %lu", name, load_addr);
return reinterpret_cast<void *>(load_addr); return reinterpret_cast<void *>(load_addr);
} }
bool isRXPerm(const char *perm) {
bool r = false, x = false;
for (int i = 0; i < 5; ++i) {
if (perm[i] == 'r') {
r = true;
}
if (perm[i] == 'x') {
x = true;
}
}
return r && x;
}
void ElfImg::searchMaps() {
FILE *f;
if ((f = fopen("/proc/self/maps", "r")) == NULL) {
return;
}
char buf[PATH_MAX], perm[12] = {'\0'}, dev[12] = {'\0'}, mapname[PATH_MAX] = {'\0'};
Addr begin, end, inode, foo;
while (!feof(f)) {
if (fgets(buf, sizeof(buf), f) == 0)
break;
mapname[0] = '\0';
sscanf(buf, "%lx-%lx %s %lx %s %ld %s", &begin, &end, perm,
&foo, dev, &inode, mapname);
if (strstr(buf, elf)) {
if (baseInRam == nullptr) {
baseInRam = reinterpret_cast<void *>(begin);
}
endInRam = reinterpret_cast<void *>(end);
if (isRXPerm(perm)) {
textSegments.emplace_back((void*)begin, (void*)end);
}
}
}
fclose(f);
}
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
using namespace SandHook::Hook; using namespace SandHook::Hook;
CodeBuffer* InlineHook::backupBuffer = new AndroidCodeBuffer(); CodeBuffer* InlineHook::backup_buffer = new AndroidCodeBuffer();
#if defined(__arm__) #if defined(__arm__)
InlineHook* InlineHook::instance = new InlineHookArm32Android(); InlineHook* InlineHook::instance = new InlineHookArm32Android();
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/7. // Created by swift on 2019/5/7.
// //
#ifndef SANDHOOK_NH_ASSEMBLER_H #pragma once
#define SANDHOOK_NH_ASSEMBLER_H
#include "label.h" #include "label.h"
#include "instruction.h" #include "instruction.h"
...@@ -22,14 +21,14 @@ namespace SandHook { ...@@ -22,14 +21,14 @@ namespace SandHook {
class CodeBuffer { class CodeBuffer {
public: public:
virtual void* getBuffer(U32 size) = 0; virtual void* GetBuffer(U32 size) = 0;
virtual void resetLastBufferSize(U32 size){}; virtual void ResetLastBufferSize(U32 size){};
virtual void* copy(void* start, U32 size) { virtual void* Copy(void* start, U32 size) {
void* bufferStart = getBuffer(size); void* bufferStart = GetBuffer(size);
if (bufferStart == nullptr) if (bufferStart == nullptr)
return nullptr; return nullptr;
memcpy(bufferStart, start, size); memcpy(bufferStart, start, size);
flushCache((Addr)bufferStart, size); FlushCache((Addr) bufferStart, size);
return bufferStart; return bufferStart;
}; };
}; };
...@@ -39,31 +38,29 @@ namespace SandHook { ...@@ -39,31 +38,29 @@ namespace SandHook {
CodeContainer(CodeBuffer *codeBuffer); CodeContainer(CodeBuffer *codeBuffer);
void setCodeBuffer(CodeBuffer *codeBuffer); void SetCodeBuffer(CodeBuffer *codeBuffer);
//allow code relocate to get new pc first //allow code Relocate to Get new pc first
void allocBufferFirst(U32 size); void AllocBufferFirst(U32 size);
void append(Unit<Base>* unit); void Append(BaseUnit *unit);
void commit(); void Commit();
Addr size(); Addr Size();
virtual ~CodeContainer(); virtual ~CodeContainer();
public: public:
//before commit is virtual address so = 0, after commit is real address //before commit is virtual address so = 0, after commit is real address
Addr startPc = 0; Addr start_pc = 0;
Addr curPc = 0; Addr cur_pc = 0;
private: private:
Addr maxSize = 0; Addr max_size = 0;
std::list<Unit<Base>*> units = std::list<Unit<Base>*>(); std::list<BaseUnit*> units = std::list<BaseUnit*>();
std::list<Label*> labels = std::list<Label*>(); std::list<Label*> labels = std::list<Label*>();
CodeBuffer* codeBuffer = nullptr; CodeBuffer* code_buffer = nullptr;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ASSEMBLER_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_BASE_H #pragma once
#define SANDHOOK_BASE_H
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
...@@ -22,6 +21,8 @@ typedef int64_t S64; ...@@ -22,6 +21,8 @@ typedef int64_t S64;
typedef size_t Addr; typedef size_t Addr;
using InstCode = U32;
//32bit //32bit
#if defined(__i386__) || defined(__arm__) #if defined(__i386__) || defined(__arm__)
typedef S32 Off; typedef S32 Off;
...@@ -30,8 +31,6 @@ typedef S32 Off; ...@@ -30,8 +31,6 @@ typedef S32 Off;
typedef S64 Off; typedef S64 Off;
#endif #endif
const int PTR_BYTE = sizeof(void*);
#define PAGE_OFFSET 12 #define PAGE_OFFSET 12
const int BITS_OF_BYTE = 8; const int BITS_OF_BYTE = 8;
...@@ -44,7 +43,7 @@ enum Arch { ...@@ -44,7 +43,7 @@ enum Arch {
unknowArch unknowArch
}; };
enum UnitType { enum UnitTypeDef {
UnitInst, UnitInst,
UnitData, UnitData,
UnitLabel, UnitLabel,
...@@ -79,12 +78,17 @@ struct Unsigned<64> { ...@@ -79,12 +78,17 @@ struct Unsigned<64> {
}; };
struct Base {}; struct Base {
};
#define INLINE __always_inline
template <typename T> template <typename T>
T AlignDown(T pointer, T AlignDown(T pointer,
typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type alignment) { typename Unsigned<sizeof(T) * BITS_OF_BYTE>::type alignment) {
// Use C-style casts to get static_cast behaviour for integral types (T), and // Use C-style casts to Get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types. // reinterpret_cast behaviour for other types.
typename Unsigned<sizeof(T)* BITS_OF_BYTE>::type pointer_raw = typename Unsigned<sizeof(T)* BITS_OF_BYTE>::type pointer_raw =
...@@ -181,26 +185,26 @@ INT_1_TO_32_LIST(DECLARE_TRUNCATE_TO_UINT_32) ...@@ -181,26 +185,26 @@ INT_1_TO_32_LIST(DECLARE_TRUNCATE_TO_UINT_32)
//位提取 //位提取
// Bit field extraction. // Bit field extraction.
inline uint64_t ExtractUnsignedBitfield64(int msb, int lsb, uint64_t x) { inline U64 ExtractUnsignedBitfield64(int msb, int lsb, U64 x) {
if ((msb == 63) && (lsb == 0)) return x; if ((msb == 63) && (lsb == 0)) return x;
return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1); return (x >> lsb) & ((static_cast<U64>(1) << (1 + msb - lsb)) - 1);
} }
inline int64_t ExtractSignedBitfield64(int msb, int lsb, U64 x) { inline S64 ExtractSignedBitfield64(int msb, int lsb, U64 x) {
uint64_t temp = ExtractUnsignedBitfield64(msb, lsb, x); U64 temp = ExtractUnsignedBitfield64(msb, lsb, x);
// If the highest extracted bit is set, sign extend. // If the highest extracted bit is Set, sign extend_.
if ((temp >> (msb - lsb)) == 1) { if ((temp >> (msb - lsb)) == 1) {
temp |= ~UINT64_C(0) << (msb - lsb); temp |= ~UINT64_C(0) << (msb - lsb);
} }
int64_t result; S64 result;
memcpy(&result, &temp, sizeof(result)); memcpy(&result, &temp, sizeof(result));
return result; return result;
} }
inline int32_t ExtractSignedBitfield32(int msb, int lsb, U32 x) { inline int32_t ExtractSignedBitfield32(int msb, int lsb, U32 x) {
uint32_t temp = TruncateToUint32(ExtractSignedBitfield64(msb, lsb, x)); U32 temp = TruncateToUint32(ExtractSignedBitfield64(msb, lsb, x));
int32_t result; S32 result;
memcpy(&result, &temp, sizeof(result)); memcpy(&result, &temp, sizeof(result));
return result; return result;
} }
...@@ -216,25 +220,17 @@ inline T SignExtend(T val, int bitSize) { ...@@ -216,25 +220,17 @@ inline T SignExtend(T val, int bitSize) {
} }
inline U16 BITS16L(U32 value) { #define BITS16L(value) static_cast<U16>(value & 0xffff)
return static_cast<U16>(value & 0xffff);
}
inline U16 BITS16H(U32 value) { #define BITS16H(value) static_cast<U16>(value >> 16)
return static_cast<U16>(value >> 16);
}
inline U32 BITS32L(U64 value) { #define BITS32L(value) static_cast<U32>(value)
return static_cast<U32>(value);
}
inline U32 BITS32H(U64 value) { #define BITS32H(value) static_cast<U32>(value >> 32)
return static_cast<U32>(value >> 32);
}
#define COMBINE(hi, lo, lowide) (hi << lowide) | lo #define COMBINE(hi, lo, lowide) (hi << lowide) | lo
/* borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h */ /* borrow from gdb, refer: binutils-gdb/gdb/Arch/arm.h */
#define SUB_MASK(x) ((1L << ((x) + 1)) - 1) #define SUB_MASK(x) ((1L << ((x) + 1)) - 1)
#define BITS(obj, st, fn) (((obj) >> (st)) & SUB_MASK((fn) - (st))) #define BITS(obj, st, fn) (((obj) >> (st)) & SUB_MASK((fn) - (st)))
#define BIT(obj, st) (((obj) >> (st)) & 1) #define BIT(obj, st) (((obj) >> (st)) & 1)
...@@ -254,4 +250,21 @@ if (X != V) { \ ...@@ -254,4 +250,21 @@ if (X != V) { \
#define ENUM_VALUE(Type, Value) static_cast<std::underlying_type<Type>::type>(Value) #define ENUM_VALUE(Type, Value) static_cast<std::underlying_type<Type>::type>(Value)
#endif //SANDHOOK_BASE_H static inline S64 SignExtend64(unsigned int bits, U64 value) {
return ExtractSignedBitfield64(bits - 1, 0, value);
}
static inline S32 SignExtend32(unsigned int bits, U32 value) {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
template<typename U, typename T>
U ForceCast(T *x) {
return (U) (uintptr_t) x;
}
template<typename U, typename T>
U ForceCast(T &x) {
return *(U *) &x;
}
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_CODE_RELOCATE_H #pragma once
#define SANDHOOK_NH_CODE_RELOCATE_H
#include <mutex> #include <mutex>
#include <map> #include <map>
...@@ -21,30 +20,28 @@ namespace SandHook { ...@@ -21,30 +20,28 @@ namespace SandHook {
class CodeRelocate : public InstVisitor { class CodeRelocate : public InstVisitor {
public: public:
CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {} CodeRelocate(CodeContainer &codeContainer) : code_container(&codeContainer) {}
virtual void* relocate(Instruction<Base> *instruction, void* toPc) throw(ErrorCodeException) = 0; virtual void* Relocate(BaseInst *instruction, void *toPc) throw(ErrorCodeException) = 0;
virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0; virtual void* Relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0;
bool inRelocateRange(Off targetOffset, Addr targetLen); bool InRelocateRange(Off targetOffset, Addr targetLen);
Label* getLaterBindLabel(Addr offset); Label* GetLaterBindLabel(Addr offset);
virtual ~CodeRelocate() { virtual ~CodeRelocate() {
delete relocateLock; delete relocate_lock;
delete laterBindlabels; delete later_bind_labels;
} }
public: public:
CodeContainer* codeContainer; CodeContainer* code_container;
std::mutex* relocateLock = new std::mutex(); std::mutex* relocate_lock = new std::mutex();
std::map<Addr, Label*>* laterBindlabels = new std::map<Addr, Label*>(); std::map<Addr, Label*>* later_bind_labels = new std::map<Addr, Label*>();
Addr startAddr = 0; Addr start_addr = 0;
Addr length = 0; Addr length = 0;
Addr curOffset = 0; Addr cur_offset = 0;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_CODE_RELOCATE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_COMPILER_H #pragma once
#define SANDHOOK_NH_COMPILER_H
// Helper to check whether the version of GCC used is greater than the specified // Helper to check whether the version of GCC used is greater than the specified
// requirement. // requirement.
...@@ -58,5 +57,3 @@ ...@@ -58,5 +57,3 @@
// clang-format on // clang-format on
#endif #endif
\ No newline at end of file
#endif //SANDHOOK_NH_COMPILER_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#ifndef SANDHOOK_NH_DECODER_H #pragma once
#define SANDHOOK_NH_DECODER_H
#include "base.h" #include "base.h"
#include "instruction.h" #include "instruction.h"
...@@ -16,7 +15,7 @@ namespace SandHook { ...@@ -16,7 +15,7 @@ namespace SandHook {
class InstVisitor { class InstVisitor {
public: public:
//need free unit //need free unit
virtual bool visit(Unit<Base>* unit, void* pc) { virtual bool Visit(BaseUnit *unit, void *pc) {
delete unit; delete unit;
return false; return false;
}; };
...@@ -24,29 +23,29 @@ namespace SandHook { ...@@ -24,29 +23,29 @@ namespace SandHook {
class DefaultVisitor : public InstVisitor { class DefaultVisitor : public InstVisitor {
public: public:
DefaultVisitor(bool (*visitor)(Unit<Base> *, void *)); DefaultVisitor(bool (*visitor)(BaseUnit *, void *));
bool visit(Unit<Base> *unit, void *pc) override; bool Visit(BaseUnit *unit, void *pc) override;
private: private:
bool (*visitor)(Unit<Base>*, void*); bool (*visitor)(BaseUnit*, void*);
}; };
class InstDecoder { class InstDecoder {
public: public:
virtual void decode(void* codeStart, Addr codeLen, InstVisitor& visitor, bool onlyPcRelInst = false) = 0; virtual void Disassemble(void *code_start, Addr code_len, InstVisitor &visitor,
inline void decode(void* codeStart, Addr codeLen, bool (*visitor)(Unit<Base>*, void*), bool onlyPcRelInst = false) { bool only_pc_rel = false) = 0;
inline void Disassemble(void *codeStart, Addr codeLen,
bool (*visitor)(BaseUnit *, void *), bool only_pc_rel = false) {
InstVisitor vis = DefaultVisitor(visitor); InstVisitor vis = DefaultVisitor(visitor);
decode(codeStart, codeLen, vis, onlyPcRelInst); Disassemble(codeStart, codeLen, vis, only_pc_rel);
}; };
}; };
class Disassembler { class Disassembler {
public: public:
static InstDecoder* get(Arch arch); static InstDecoder* Get(Arch arch);
static InstDecoder* get(); static InstDecoder* Get();
}; };
} }
} }
#endif //SANDHOOK_NH_DECODER_H
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#ifndef SANDHOOK_NH_ELF_H #pragma once
#define SANDHOOK_NH_ELF_H
#include <linux/elf.h> #include <linux/elf.h>
#include <list>
#include "base.h" #include "base.h"
#if defined(__LP64__) #if defined(__LP64__)
...@@ -32,6 +32,13 @@ typedef Elf32_Off Elf_Off; ...@@ -32,6 +32,13 @@ typedef Elf32_Off Elf_Off;
namespace SandHook { namespace SandHook {
namespace Elf { namespace Elf {
struct TextSegment {
TextSegment(void *start, void *end);
void* start;
void* end;
};
class ElfImg { class ElfImg {
public: public:
...@@ -45,9 +52,14 @@ namespace SandHook { ...@@ -45,9 +52,14 @@ namespace SandHook {
~ElfImg(); ~ElfImg();
private:
void searchMaps();
private: private:
const char* elf = nullptr; const char* elf = nullptr;
void* base = nullptr; void* baseInRam = nullptr;
void* endInRam = nullptr;
std::list<TextSegment> textSegments = std::list<TextSegment>();
char* buffer = nullptr; char* buffer = nullptr;
off_t size = 0; off_t size = 0;
off_t bias = -4396; off_t bias = -4396;
...@@ -70,5 +82,3 @@ namespace SandHook { ...@@ -70,5 +82,3 @@ namespace SandHook {
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_ELF_H
// //
// Created by swift on 2019/5/10. // Created by swift on 2019/5/10.
// //
#pragma once
#include "exception" #include "exception"
#ifndef SANDHOOK_NH_EXCEPTION_H
#define SANDHOOK_NH_EXCEPTION_H
namespace SandHook { namespace SandHook {
namespace Asm { namespace Asm {
...@@ -25,5 +24,3 @@ namespace SandHook { ...@@ -25,5 +24,3 @@ namespace SandHook {
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_EXCEPTION_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/14. // Created by swift on 2019/5/14.
// //
#ifndef SANDHOOK_NH_HOOK_H #pragma once
#define SANDHOOK_NH_HOOK_H
#include <mutex> #include <mutex>
...@@ -20,17 +19,16 @@ namespace SandHook { ...@@ -20,17 +19,16 @@ namespace SandHook {
class InlineHook { class InlineHook {
public: public:
//return == backup method //return == backup method
virtual void* inlineHook(void* origin, void* replace) = 0; virtual void *Hook(void *origin, void *replace) = 0;
virtual bool breakPoint(void* point, void (*callback)(REG[])) { virtual bool BreakPoint(void *point, void (*callback)(REG[])) {
return false; return false;
}; };
protected: protected:
static CodeBuffer* backupBuffer; static CodeBuffer* backup_buffer;
std::mutex hook_lock;
public: public:
static InlineHook* instance; static InlineHook* instance;
}; };
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_HOOK_H
...@@ -6,22 +6,22 @@ ...@@ -6,22 +6,22 @@
using namespace SandHook::Asm; using namespace SandHook::Asm;
//in range of copy //in range of Copy
bool CodeRelocate::inRelocateRange(Off targetOffset, Addr targetLen) { bool CodeRelocate::InRelocateRange(Off targetOffset, Addr targetLen) {
Off startP = curOffset + targetOffset; Off startP = cur_offset + targetOffset;
Off endP = startP + targetLen; Off endP = startP + targetLen;
return startP >= 0 && endP <= length; return startP >= 0 && endP <= length;
} }
Label *CodeRelocate::getLaterBindLabel(Addr offset) { Label *CodeRelocate::GetLaterBindLabel(Addr offset) {
Label* label_per_unit = nullptr; Label* label_per_unit = nullptr;
std::map<Addr,Label*>::iterator it = laterBindlabels->find(offset); std::map<Addr,Label*>::iterator it = later_bind_labels->find(offset);
if (it != laterBindlabels->end()) { if (it != later_bind_labels->end()) {
label_per_unit = it->second; label_per_unit = it->second;
} }
if (label_per_unit == nullptr) { if (label_per_unit == nullptr) {
label_per_unit = new Label(); label_per_unit = new Label();
laterBindlabels->insert(std::map<Addr, Label*>::value_type(offset, label_per_unit)); later_bind_labels->insert(std::map<Addr, Label*>::value_type(offset, label_per_unit));
} }
return label_per_unit; return label_per_unit;
} }
\ No newline at end of file
...@@ -19,7 +19,7 @@ EXPORT void* SandGetSym(const char* so, const char* symb) { ...@@ -19,7 +19,7 @@ EXPORT void* SandGetSym(const char* so, const char* symb) {
extern "C" extern "C"
EXPORT void* SandInlineHook(void* origin, void* replace) { EXPORT void* SandInlineHook(void* origin, void* replace) {
return InlineHook::instance->inlineHook(origin, replace); return InlineHook::instance->Hook(origin, replace);
} }
extern "C" extern "C"
...@@ -29,10 +29,10 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace) ...@@ -29,10 +29,10 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace)
if (origin == nullptr) if (origin == nullptr)
return nullptr; return nullptr;
return InlineHook::instance->inlineHook(origin, replace); return InlineHook::instance->Hook(origin, replace);
} }
extern "C" extern "C"
EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])) { EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])) {
return InlineHook::instance->breakPoint(origin, callback); return InlineHook::instance->BreakPoint(origin, callback);
} }
\ No newline at end of file
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/4/15. // Created by SwiftGan on 2019/4/15.
// //
#ifndef SANDHOOK_SANDHOOK_NATIVE_H #pragma once
#define SANDHOOK_SANDHOOK_NATIVE_H
typedef size_t REG; typedef size_t REG;
...@@ -20,5 +19,3 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace); ...@@ -20,5 +19,3 @@ EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace);
extern "C" extern "C"
EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])); EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[]));
\ No newline at end of file
#endif //SANDHOOK_SANDHOOK_NATIVE_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_LOCK_H #pragma once
#define SANDHOOK_NH_LOCK_H
#include <mutex> #include <mutex>
...@@ -22,5 +21,3 @@ namespace SandHook { ...@@ -22,5 +21,3 @@ namespace SandHook {
} }
} }
\ No newline at end of file
#endif //SANDHOOK_NH_LOCK_H
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Created by SwiftGan on 2019/2/15. // Created by SwiftGan on 2019/2/15.
// //
#ifndef SANDHOOK_LOG_H #pragma once
#define SANDHOOK_LOG_H
#include "android/log.h" #include "android/log.h"
...@@ -12,5 +11,3 @@ ...@@ -12,5 +11,3 @@
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
\ No newline at end of file
#endif //SANDHOOK_LOG_H
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "platform.h" #include "platform.h"
bool flushCache(Addr addr, Off len) { bool FlushCache(Addr addr, Off len) {
#if defined(__arm__) #if defined(__arm__)
int i = cacheflush(addr, addr + len, 0); int i = cacheflush(addr, addr + len, 0);
if (i == -1) { if (i == -1) {
...@@ -21,7 +21,7 @@ bool flushCache(Addr addr, Off len) { ...@@ -21,7 +21,7 @@ bool flushCache(Addr addr, Off len) {
} }
extern "C" bool memUnprotect(Addr addr, Addr len) { extern "C" bool MemUnprotect(Addr addr, Addr len) {
long pagesize = P_SIZE; long pagesize = P_SIZE;
unsigned alignment = (unsigned)((unsigned long long)addr % pagesize); unsigned alignment = (unsigned)((unsigned long long)addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len), int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
......
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
// Created by swift on 2019/5/11. // Created by swift on 2019/5/11.
// //
#ifndef SANDHOOK_NH_PLATFORM_H #pragma once
#define SANDHOOK_NH_PLATFORM_H
#include "base.h" #include "base.h"
extern "C" bool flushCache(Addr addr, Off len); extern "C" bool FlushCache(Addr addr, Off len);
extern "C" bool memUnprotect(Addr addr, Addr len); extern "C" bool MemUnprotect(Addr addr, Addr len);
\ No newline at end of file
#endif //SANDHOOK_NH_PLATFORM_H
include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook', ':xposedcompat_new' include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook'
...@@ -34,7 +34,6 @@ add_library( # Sets the name of the library. ...@@ -34,7 +34,6 @@ add_library( # Sets the name of the library.
src/main/cpp/art_jni_trampoline.cpp src/main/cpp/art_jni_trampoline.cpp
# Provides a relative path to your source file(s). # Provides a relative path to your source file(s).
src/main/cpp/libffi/closures.c src/main/cpp/libffi/closures.c
src/main/cpp/libffi/closures.c
src/main/cpp/libffi/debug.c src/main/cpp/libffi/debug.c
src/main/cpp/libffi/dlmalloc.c src/main/cpp/libffi/dlmalloc.c
src/main/cpp/libffi/java_raw_api.c src/main/cpp/libffi/java_raw_api.c
......
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