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