Commit 933b513a authored by swift_gan's avatar swift_gan Committed by swift_gan

finish mov assembler

parent d68629c6
......@@ -19,6 +19,7 @@ add_library( # Sets the name of the library.
# Provides a relative path to your source file(s).
src/main/cpp/sandhook_native.cpp
src/main/cpp/decoder/decoder.cpp
src/main/cpp/archs/arm64/assembler/assembler_a64.cpp
src/main/cpp/archs/arm64/inst/inst_arm64.cpp
src/main/cpp/archs/arm64/register/register_a64.cpp
src/main/cpp/archs/arm64/register/register_list_a64.cpp
......
//
// Created by swift on 2019/5/11.
//
#include "assembler_a64.h"
SandHook::Assembler::AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer);
}
void *SandHook::Assembler::AssemblerA64::finish() {
codeContainer.commit();
return reinterpret_cast<void *>(codeContainer.startPc);
}
void
SandHook::Assembler::AssemblerA64::MoveWide(RegisterA64 &rd, INST_A64(MOV_WIDE)::OP op, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
codeContainer.append(reinterpret_cast<Unit<Base> *>(new INST_A64(MOV_WIDE)(op, &rd, imme, shift)));
}
void SandHook::Assembler::AssemblerA64::Mov(WRegister &rd, U32 imme) {
const U16 h0 = BITS16L(imme);
const U16 h1 = BITS16H(imme);
Movz(rd, h0, INST_A64(MOV_WIDE)::Shift0);
Movk(rd, h1, INST_A64(MOV_WIDE)::Shift1);
}
void SandHook::Assembler::AssemblerA64::Mov(XRegister &rd, U64 imme) {
const U32 wl = BITS32L(imme);
const U32 wh = BITS32H(imme);
const U16 h0 = BITS16L(wl);
const U16 h1 = BITS16H(wl);
const U16 h2 = BITS16L(wh);
const U16 h3 = BITS16H(wh);
Movz(rd, h0, INST_A64(MOV_WIDE)::Shift0);
Movk(rd, h1, INST_A64(MOV_WIDE)::Shift1);
Movk(rd, h2, INST_A64(MOV_WIDE)::Shift2);
Movk(rd, h3, INST_A64(MOV_WIDE)::Shift3);
}
void SandHook::Assembler::AssemblerA64::Movz(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_Z, imme, shift);
}
void SandHook::Assembler::AssemblerA64::Movk(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_K, imme, shift);
}
void SandHook::Assembler::AssemblerA64::Movn(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_N, imme, shift);
}
//
// Created by swift on 2019/5/11.
//
#ifndef SANDHOOK_NH_ASSEMBLER_A64_H
#define SANDHOOK_NH_ASSEMBLER_A64_H
#include <assembler.h>
#include "register_a64.h"
#include "inst_arm64.h"
namespace SandHook {
namespace Assembler {
class AssemblerA64 {
public:
AssemblerA64(CodeBuffer* codeBuffer);
void* finish();
void MoveWide(RegisterA64& rd, INST_A64(MOV_WIDE)::OP op, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Movz(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Movk(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Movn(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Mov(WRegister& rd, U32 imme);
void Mov(XRegister& rd, U64 imme);
private:
CodeContainer codeContainer = CodeContainer(nullptr);
};
}
}
#endif //SANDHOOK_NH_ASSEMBLER_A64_H
......@@ -234,6 +234,13 @@ namespace SandHook {
MOV_WideOp_N = 0b11,
};
enum Shift {
Shift0 = 0,
Shift1 = 16,
Shift2 = 32,
Shift3 = 48
};
A64_MOV_WIDE();
A64_MOV_WIDE(STRUCT_A64(MOV_WIDE) &inst);
......
......@@ -8,6 +8,12 @@
using namespace SandHook::Assembler;
using namespace SandHook::Asm;
CodeContainer::CodeContainer(CodeBuffer *codeBuffer) : codeBuffer(codeBuffer) {}
void CodeContainer::setCodeBuffer(CodeBuffer *codeBuffer) {
this->codeBuffer = codeBuffer;
}
void CodeContainer::append(Unit<Base> *unit) {
units.push_back(unit);
switch (unit->unitType()) {
......@@ -21,10 +27,12 @@ void CodeContainer::append(Unit<Base> *unit) {
}
void CodeContainer::commit() {
std::list<Unit<Base>*>::iterator unit;
U32 bufferSize = static_cast<U32>(curPc - startPc);
void* bufferStart = codeBuffer->getBuffer(bufferSize);
Addr pcNow = reinterpret_cast<Addr>(bufferStart);
//commit to code buffer & assembler inst
std::list<Unit<Base>*>::iterator unit;
for(unit = units.begin();unit != units.end(); ++unit) {
if ((*unit)->unitType() == UnitData) {
(*unit)->move(reinterpret_cast<Base *>(pcNow));
......@@ -36,9 +44,18 @@ void CodeContainer::commit() {
}
pcNow += (*unit)->size();
}
//bind labels
std::list<Label*>::iterator label;
for(label = labels.begin();label != labels.end(); ++label) {
(*label)->bindLabel();
}
//flush I cache
flushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart));
//set pc
startPc = reinterpret_cast<Addr>(bufferStart);
curPc = pcNow;
}
......@@ -3,6 +3,7 @@
//
#include <sys/mman.h>
#include <platform.h>
#include "code_buffer.h"
#include "lock.h"
......@@ -42,5 +43,6 @@ label_alloc_new_space:
StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {}
void *StaticCodeBuffer::getBuffer(U32 bufferSize) {
memUnprotect(pc, bufferSize);
return reinterpret_cast<void *>(pc);
}
......@@ -26,11 +26,19 @@ namespace SandHook {
class CodeContainer {
public:
CodeContainer(CodeBuffer *codeBuffer);
void setCodeBuffer(CodeBuffer *codeBuffer);
void append(Unit<Base>* unit);
void commit();
private:
public:
//before commit is virtual address so = 0, after commit is real address
Addr startPc = 0;
Addr curPc = 0;
private:
Addr maxSize = 0;
std::list<Unit<Base>*> units = std::list<Unit<Base>*>();
std::list<Label*> labels = std::list<Label*>();
......
......@@ -3,6 +3,7 @@
//
#include <unistd.h>
#include <sys/mman.h>
#include "platform.h"
bool flushCache(Addr addr, Off len) {
......@@ -17,4 +18,13 @@ bool flushCache(Addr addr, Off len) {
__builtin___clear_cache(begin, begin + len);
#endif
return true;
}
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),
PROT_READ | PROT_WRITE | PROT_EXEC);
return i != -1;
}
\ No newline at end of file
......@@ -9,4 +9,6 @@
extern "C" bool flushCache(Addr addr, Off len);
extern "C" bool memUnprotect(Addr addr, Addr len);
#endif //SANDHOOK_NH_PLATFORM_H
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