Commit 62dc8d9a authored by swift_gan's avatar swift_gan Committed by swift_gan

[NativeHook]TWEAK CODE

parent 04992943
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef SANDHOOK_ARM32_BASE_H #ifndef SANDHOOK_ARM32_BASE_H
#define SANDHOOK_ARM32_BASE_H #define SANDHOOK_ARM32_BASE_H
#include <ostream>
#include "arm_base.h" #include "arm_base.h"
#include "register_list_a32.h" #include "register_list_a32.h"
...@@ -47,6 +48,97 @@ namespace SandHook { ...@@ -47,6 +48,97 @@ namespace SandHook {
int shift_imm; // valid if rm_ != no_reg && rs_ == no_reg int shift_imm; // valid if rm_ != no_reg && rs_ == no_reg
AddrMode addr_mode; // bits P, U, and W AddrMode addr_mode; // bits P, U, and W
}; };
class RegisterList {
public:
RegisterList() : list_(0) {}
RegisterList(RegisterA32& reg) // NOLINT(runtime/explicit)
: list_(RegisterToList(reg)) {}
RegisterList(RegisterA32& reg1, RegisterA32& reg2)
: list_(RegisterToList(reg1) | RegisterToList(reg2)) {}
RegisterList(RegisterA32& reg1, RegisterA32& reg2, RegisterA32& reg3)
: list_(RegisterToList(reg1) | RegisterToList(reg2) |
RegisterToList(reg3)) {}
RegisterList(RegisterA32& reg1, RegisterA32& reg2, RegisterA32& reg3, RegisterA32& reg4)
: list_(RegisterToList(reg1) | RegisterToList(reg2) |
RegisterToList(reg3) | RegisterToList(reg4)) {}
explicit RegisterList(uint32_t list) : list_(list) {}
uint32_t GetList() const { return list_; }
void SetList(uint32_t list) { list_ = list; }
bool Includes(RegisterA32& reg) const {
return (list_ & RegisterToList(reg)) != 0;
}
void Combine(RegisterList& other) { list_ |= other.GetList(); }
void Combine(RegisterA32& reg) { list_ |= RegisterToList(reg); }
void Remove(RegisterList& other) { list_ &= ~other.GetList(); }
void Remove(RegisterA32& reg) { list_ &= ~RegisterToList(reg); }
bool Overlaps(RegisterList& other) const {
return (list_ & other.list_) != 0;
}
bool IsR0toR7orPC() const {
// True if all the registers from the list are not from r8-r14.
return (list_ & 0x7f00) == 0;
}
bool IsR0toR7orLR() const {
// True if all the registers from the list are not from r8-r13 nor from r15.
return (list_ & 0xbf00) == 0;
}
Register GetFirstAvailableRegister() const;
bool IsEmpty() const { return list_ == 0; }
static RegisterList Union(const RegisterList& list_1,
const RegisterList& list_2) {
return RegisterList(list_1.list_ | list_2.list_);
}
static RegisterList Union(const RegisterList& list_1,
const RegisterList& list_2,
const RegisterList& list_3) {
return Union(list_1, Union(list_2, list_3));
}
static RegisterList Union(const RegisterList& list_1,
const RegisterList& list_2,
const RegisterList& list_3,
const RegisterList& list_4) {
return Union(Union(list_1, list_2), Union(list_3, list_4));
}
static RegisterList Intersection(const RegisterList& list_1,
const RegisterList& list_2) {
return RegisterList(list_1.list_ & list_2.list_);
}
static RegisterList Intersection(const RegisterList& list_1,
const RegisterList& list_2,
const RegisterList& list_3) {
return Intersection(list_1, Intersection(list_2, list_3));
}
static RegisterList Intersection(const RegisterList& list_1,
const RegisterList& list_2,
const RegisterList& list_3,
const RegisterList& list_4) {
return Intersection(Intersection(list_1, list_2),
Intersection(list_3, list_4));
}
private:
static uint32_t RegisterToList(RegisterA32& reg) {
if (reg.getCode() == UnknowRegiser.getCode()) {
return 0;
} else {
return UINT32_C(1) << reg.getCode();
}
}
// Bitfield representation of all registers in the list
// (1 for r0, 2 for r1, 4 for r2, ...).
uint32_t list_;
};
inline uint32_t GetRegisterListEncoding(const RegisterList& registers,
int first,
int count) {
return (registers.GetList() >> first) & ((1 << count) - 1);
}
std::ostream& operator<<(std::ostream& os, RegisterList registers);
} }
} }
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
#ifndef SANDHOOK_INST_CODE_ARM32_H #ifndef SANDHOOK_INST_CODE_ARM32_H
#define SANDHOOK_INST_CODE_ARM32_H #define SANDHOOK_INST_CODE_ARM32_H
enum InstCodeA32 { enum class InstCodeA32 {
}; };
enum InstCodeT16 { enum class InstCodeT16 {
BASE_SASMC, BASE_SASMC,
DATA_PROC, DATA_PROC,
SPDIABE, SPDIABE,
...@@ -27,8 +27,8 @@ enum InstCodeT16 { ...@@ -27,8 +27,8 @@ enum InstCodeT16 {
MOV_REG MOV_REG
}; };
enum InstCodeT32 { enum class InstCodeT32 {
B32,
}; };
#endif //SANDHOOK_INST_CODE_ARM32_H #endif //SANDHOOK_INST_CODE_ARM32_H
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Created by swift on 2019/5/12. // Created by swift on 2019/5/12.
// //
#ifndef SANDHOOK_NH_INST_STRUCT_T16_H #ifndef SANDHOOK_NH_INST_STRUCT_T32_H
#define SANDHOOK_NH_INST_STRUCT_T16_H #define SANDHOOK_NH_INST_STRUCT_T32_H
#include "instruction.h" #include "instruction.h"
...@@ -14,9 +14,17 @@ ...@@ -14,9 +14,17 @@
#define DEFINE_STRUCT_T32(X) struct STRUCT_T32(X) : public Base #define DEFINE_STRUCT_T32(X) struct STRUCT_T32(X) : public Base
DEFINE_OPCODE_T32(B, 0b010) DEFINE_OPCODE_T32(B32, 0b11110)
DEFINE_STRUCT_T32(B) { DEFINE_STRUCT_T32(B32) {
InstT32 imm11:11;
InstT32 J2:1;
InstT32 X:1;
InstT32 J1:1;
InstT32 op:2;
InstT32 imm10:10;
InstT32 S:1;
InstT32 opcode:5;
}; };
#endif //SANDHOOK_NH_INST_STRUCT_T16_H #endif //SANDHOOK_NH_INST_STRUCT_T32_H
...@@ -34,7 +34,7 @@ return COND; \ ...@@ -34,7 +34,7 @@ return COND; \
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST_CODE(X) \
inline U32 instCode() override { \ inline U32 instCode() override { \
return InstCodeT16::X; \ return ENUM_VALUE(InstCodeT16, InstCodeT16::X); \
} }
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
...@@ -59,6 +59,10 @@ namespace SandHook { ...@@ -59,6 +59,10 @@ namespace SandHook {
return 2; return 2;
} }
void onLabelApply(Addr pc) override {
this->onOffsetApply(pc - this->getVPC() - 2 * size());
}
static inline U32 zeroExtend32(unsigned int bits, U32 value) { static inline U32 zeroExtend32(unsigned int bits, U32 value) {
return value << (32 - bits); return value << (32 - bits);
} }
......
...@@ -4,3 +4,36 @@ ...@@ -4,3 +4,36 @@
#include "inst_t32.h" #include "inst_t32.h"
#include "inst_struct_t32.h" #include "inst_struct_t32.h"
#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)
using namespace SandHook::Asm;
using namespace SandHook::AsmA32;
T32_B32::T32_B32(T32_STRUCT_B32 *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);
}
Off T32_B32::getImmPCOffset() {
//U16 immhi =
}
void T32_B32::decode(T32_STRUCT_B32 *inst) {
DECODE_OP;
x = X(inst->X);
}
void T32_B32::assembler() {
SET_OPCODE(B32);
ENCODE_OP;
get()->X = x;
}
...@@ -5,6 +5,135 @@ ...@@ -5,6 +5,135 @@
#ifndef SANDHOOK_INST_T32_H #ifndef SANDHOOK_INST_T32_H
#define SANDHOOK_INST_T32_H #define SANDHOOK_INST_T32_H
#include "arm_base.h"
#include "register_list_a32.h"
#include "inst_struct_t16.h"
#include "inst_code_arm32.h"
#include "inst_struct_t32.h"
#define INST_T32(X) T32_##X
#define IS_OPCODE_T16(RAW,OP) INST_T32(OP)::is(RAW)
#define DEFINE_IS_EXT(X, COND) \
inline static bool is(InstT16& inst) { \
union { \
InstT32 raw; \
STRUCT_T32(X) inst; \
} inst_test; \
inst_test.raw = inst; \
return COND; \
}
#define DEFINE_IS(X) DEFINE_IS_EXT(X, TEST_INST_FIELD(opcode,OPCODE_T32(X)))
#define TEST_INST_FIELD(F,V) inst_test.inst.F == V
#define INST_FIELD(F) inst_test.inst.F
#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 InstCodeT32::X; \
}
using namespace SandHook::RegistersA32;
namespace SandHook {
namespace AsmA32 {
template<typename Inst>
class InstructionT32 : public Instruction<Inst> {
public:
InstructionT32() {}
InstructionT32(Inst *inst) : Instruction<Inst>(inst) {}
Inst mask(Inst raw) {
return raw & *(this->get());
}
U32 size() override {
return 4;
}
void onLabelApply(Addr pc) override {
this->onOffsetApply(pc - this->getVPC() - 2 * size());
}
static inline S32 signExtend32(unsigned int bits, U32 value) {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
InstType instType() override {
return thumb32;
}
Arch arch() override {
return arm32;
}
};
template <typename Inst>
class T32_INST_PC_REL : public InstructionT32<Inst> {
public:
T32_INST_PC_REL() {};
T32_INST_PC_REL(Inst *inst) : InstructionT32<Inst>(inst) {};
virtual Off getImmPCOffset() {
return 0;
};
virtual Addr getImmPCOffsetTarget() {
return (Addr) this->getPC() + getImmPCOffset();
};
inline bool pcRelate() override {
return true;
};
};
class INST_T32(B32) : public T32_INST_PC_REL<STRUCT_T32(B32)> {
public:
enum OP {
B = 0b10,
BL = 0b11
};
enum X {
arm = 0b0,
thumb = 0b1
};
T32_B32(T32_STRUCT_B32 *inst);
T32_B32(OP op, X x, Off offset);
T32_B32(OP op, X x, Label& label);
Off getImmPCOffset() override;
void decode(T32_STRUCT_B32 *inst) override;
void assembler() override;
public:
OP op;
X x;
Off offset;
};
}
}
#endif //SANDHOOK_INST_T32_H #endif //SANDHOOK_INST_T32_H
...@@ -22,6 +22,10 @@ namespace SandHook { ...@@ -22,6 +22,10 @@ namespace SandHook {
U8 getWide() override; U8 getWide() override;
virtual bool isUnkonw () {
return getCode() == 38;
}
static RegisterA32* get(U8 code) { static RegisterA32* get(U8 code) {
return registers[code]; return registers[code];
} }
......
...@@ -33,7 +33,7 @@ return COND; \ ...@@ -33,7 +33,7 @@ return COND; \
#define DEFINE_INST_CODE(X) \ #define DEFINE_INST_CODE(X) \
inline U32 instCode() override { \ inline U32 instCode() override { \
return InstCodeA64::X; \ return ENUM_VALUE(InstCodeA64, InstCodeA64::X); \
} }
using namespace SandHook::RegistersA64; using namespace SandHook::RegistersA64;
...@@ -57,10 +57,6 @@ namespace SandHook { ...@@ -57,10 +57,6 @@ namespace SandHook {
U32 size() override; U32 size() override;
static inline U32 zeroExtend32(unsigned int bits, U32 value) {
return value << (32 - bits);
}
static inline S64 signExtend64(unsigned int bits, U64 value) { static inline S64 signExtend64(unsigned int bits, U64 value) {
return ExtractSignedBitfield64(bits - 1, 0, value); return ExtractSignedBitfield64(bits - 1, 0, value);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "inst_struct_aarch64.h" #include "inst_struct_aarch64.h"
enum InstCodeA64 { enum class InstCodeA64 {
UNKNOW, UNKNOW,
MOV_WIDE, MOV_WIDE,
MOV_REG, MOV_REG,
......
...@@ -13,7 +13,7 @@ using namespace SandHook::AsmA64; ...@@ -13,7 +13,7 @@ using namespace SandHook::AsmA64;
#define IMPL_RELOCATE(X) void CodeRelocateA64::relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException) #define IMPL_RELOCATE(X) void CodeRelocateA64::relocate_##X (INST_A64(X)* inst, void* toPc) throw(ErrorCodeException)
#define CASE(X) \ #define CASE(X) \
case InstCodeA64::X: \ case ENUM_VALUE(InstCodeA64, InstCodeA64::X): \
relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \ relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \
break; break;
......
...@@ -34,7 +34,10 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) { ...@@ -34,7 +34,10 @@ void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assemblerInline.
Label* target_addr_label = new Label(); Label* target_addr_label = new Label();
__ Push(X0);
__ Ldr(IP1, *target_addr_label); __ Ldr(IP1, *target_addr_label);
__ Ldr(IP1, *target_addr_label);
__ Pop(X0);
__ Br(IP1); __ Br(IP1);
__ Emit(target_addr_label); __ Emit(target_addr_label);
__ Emit(reinterpret_cast<Addr>(replace)); __ Emit(reinterpret_cast<Addr>(replace));
......
...@@ -240,4 +240,6 @@ if (X != V) { \ ...@@ -240,4 +240,6 @@ if (X != V) { \
ACTION \ ACTION \
} }
#define ENUM_VALUE(Type, Value) static_cast<std::underlying_type<Type>::type>(Value)
#endif //SANDHOOK_BASE_H #endif //SANDHOOK_BASE_H
...@@ -51,8 +51,10 @@ void do5() { ...@@ -51,8 +51,10 @@ void do5() {
} }
void do4() { void do4() {
do5(); int a = 1 + 1;
LOGE("x = %d", 6); int b = a + 1;
int d = a + 1;
int e = a + 1;
LOGE("x = %d", 7); LOGE("x = %d", 7);
} }
......
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