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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook', ':xposedcompat_new'
include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook'
This diff is collapsed.
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