Commit d68629c6 authored by swift_gan's avatar swift_gan Committed by swift_gan

impl code buffer & code container

parent 746e516a
......@@ -26,6 +26,8 @@ add_library( # Sets the name of the library.
src/main/cpp/relocate/code_relocate.cpp
src/main/cpp/elf/elf.cpp
src/main/cpp/assembler/assembler.cpp
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp
)
......@@ -33,6 +35,7 @@ include_directories(
src/main/cpp/asm
src/main/cpp/decoder
src/main/cpp/elf
src/main/cpp/utils
src/main/cpp/includes
src/main/cpp/archs/arm64/inst
src/main/cpp/archs/arm64/register
......
......@@ -73,8 +73,8 @@ namespace SandHook {
virtual void onOffsetApply(Off offset) {}
void onLabelApply(void *pc) override {
onOffsetApply((Addr)pc - (Addr)this->getPC());
void onLabelApply(Addr pc) override {
onOffsetApply(pc - this->getVPC());
}
inline void bindLabel(Label &l) {
......
......@@ -13,7 +13,7 @@ namespace SandHook {
class LabelBinder {
public:
virtual void onLabelApply(void* pc) = 0;
virtual void onLabelApply(Addr pc) = 0;
};
class Label : public Unit<Base> {
......@@ -50,7 +50,7 @@ namespace SandHook {
inline void bindLabel() {
std::list<LabelBinder*>::iterator binder;
for(binder = binders.begin();binder != binders.end(); ++binder) {
(*binder)->onLabelApply(pc);
(*binder)->onLabelApply(getVPC());
}
}
......
......@@ -34,6 +34,14 @@ namespace SandHook {
return auto_alloc ? nullptr : raw;
}
inline Addr getVPC() {
return vPC;
}
inline void setVPC(Addr vPC) {
this->vPC = vPC;
}
inline Raw* get() const {
return raw;
}
......@@ -80,6 +88,7 @@ namespace SandHook {
private:
Raw* raw;
Addr vPC;
bool auto_alloc = false;
};
......
......@@ -3,12 +3,12 @@
//
#include <assembler.h>
#include <platform.h>
using namespace SandHook::Assembler;
using namespace SandHook::Asm;
void CodeContainer::append(Unit<Base> *unit) {
Label* l = dynamic_cast<Label *>(unit);
units.push_back(unit);
switch (unit->unitType()) {
case UnitLabel:
......@@ -17,20 +17,28 @@ void CodeContainer::append(Unit<Base> *unit) {
default:
curPc += unit->size();
}
if (unit->unitType() == UnitData) {
unit->move((Base*)codeBuffer->getBuffer(unit));
} else if (unit->unitType() != UnitLabel) {
unit->set((Base*)codeBuffer->getBuffer(unit));
}
unit->setVPC(curPc);
}
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);
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() == UnitInst) {
reinterpret_cast<Instruction<Base>*>(*unit)->assembler();
}
pcNow += (*unit)->size();
}
std::list<Label*>::iterator label;
for(label = labels.begin();label != labels.end(); ++label) {
(*label)->bindLabel();
}
}
void *CodeBuffer::getBuffer(Unit<Base> *unit) {
return nullptr;
flushCache(reinterpret_cast<Addr>(bufferStart), pcNow - reinterpret_cast<Addr>(bufferStart));
}
//
// Created by swift on 2019/5/11.
//
#include <sys/mman.h>
#include "code_buffer.h"
#include "lock.h"
using namespace SandHook::Assembler;
using namespace SandHook::Utils;
void *AndroidCodeBuffer::getBuffer(U32 size) {
AutoLock autoLock(allocSpaceLock);
void* mmapRes;
Addr exeSpace = 0;
if (executeSpaceList.size() == 0) {
goto label_alloc_new_space;
} else if (executePageOffset + size > currentExecutePageSize) {
goto label_alloc_new_space;
} else {
exeSpace = reinterpret_cast<Addr>(executeSpaceList.back());
Addr retSpace = exeSpace + executePageOffset;
executePageOffset += size;
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,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (mmapRes == MAP_FAILED) {
return 0;
}
memset(mmapRes, 0, currentExecutePageSize);
executeSpaceList.push_back(mmapRes);
executePageOffset = size;
return mmapRes;
}
StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {}
void *StaticCodeBuffer::getBuffer(U32 bufferSize) {
return reinterpret_cast<void *>(pc);
}
//
// Created by swift on 2019/5/11.
//
#ifndef SANDHOOK_NH_CODE_BUFFER_H
#define SANDHOOK_NH_CODE_BUFFER_H
#include <mutex>
#include "assembler.h"
namespace SandHook {
namespace Assembler {
class AndroidCodeBuffer : public CodeBuffer {
public:
void *getBuffer(U32 bufferSize) override;
private:
std::list<void*> executeSpaceList = std::list<void*>();
std::mutex allocSpaceLock;
Addr executePageOffset = 0;
U32 currentExecutePageSize = 0;
};
class StaticCodeBuffer : public CodeBuffer {
public:
StaticCodeBuffer(Addr pc);
void *getBuffer(U32 bufferSize) override;
private:
Addr pc;
};
}
}
#endif //SANDHOOK_NH_CODE_BUFFER_H
......@@ -21,7 +21,7 @@ namespace SandHook {
class CodeBuffer {
public:
void* getBuffer(Unit<Base>* unit);
virtual void* getBuffer(U32 size) = 0;
};
class CodeContainer {
......@@ -29,7 +29,7 @@ namespace SandHook {
void append(Unit<Base>* unit);
void commit();
private:
void* startPc = nullptr;
Addr startPc = 0;
Addr curPc = 0;
Addr maxSize = 0;
std::list<Unit<Base>*> units = std::list<Unit<Base>*>();
......
......@@ -86,6 +86,8 @@ T AlignDown(T pointer,
return (T)(pointer_raw & ~mask);
}
#define FIT(value, align) value <= align ? align : ((value / align) + align)
#define OFFSET(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
......
//
// Created by swift on 2019/5/11.
//
#ifndef SANDHOOK_NH_LOCK_H
#define SANDHOOK_NH_LOCK_H
#include <mutex>
namespace SandHook {
namespace Utils {
class AutoLock {
public:
inline AutoLock(std::mutex& mutex) : mLock(mutex) { mLock.lock(); }
inline AutoLock(std::mutex* mutex) : mLock(*mutex) { mLock.lock(); }
inline ~AutoLock() { mLock.unlock(); }
private:
std::mutex& mLock;
};
}
}
#endif //SANDHOOK_NH_LOCK_H
//
// Created by swift on 2019/5/11.
//
#include <unistd.h>
#include "platform.h"
bool flushCache(Addr addr, Off len) {
#if defined(__arm__)
int i = cacheflush(addr, addr + len, 0);
if (i == -1) {
return false;
}
return true;
#elif defined(__aarch64__)
char *begin = reinterpret_cast<char *>(addr);
__builtin___clear_cache(begin, begin + len);
#endif
return true;
}
\ No newline at end of file
//
// Created by swift on 2019/5/11.
//
#ifndef SANDHOOK_NH_PLATFORM_H
#define SANDHOOK_NH_PLATFORM_H
#include "base.h"
extern "C" bool flushCache(Addr addr, Off 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