24 #include "IPCVector.h"
31 using namespace blackbone;
40 template <
typename ElemT,
typename IntPtrT>
41 IPCVector<ElemT, IntPtrT>::IPCVector()
42 : process(nullptr), injected(false), remAPI(nullptr), code(nullptr)
47 template <
typename ElemT,
typename IntPtrT>
48 IPCVector<ElemT, IntPtrT>::~IPCVector()
54 template <
typename ElemT,
typename IntPtrT>
55 typename IPCVector<ElemT, IntPtrT>::VectorPtr IPCVector<ElemT, IntPtrT>::vectorNew(uint32_t cap)
58 return *remAPI->vectorNew.Call({cap}, process->remote().getWorker());
60 return localApi.vectorNew(cap);
65 template <
typename ElemT,
typename IntPtrT>
66 void IPCVector<ElemT, IntPtrT>::vectorFree(VectorPtr v)
69 remAPI->vectorFree.Call({v}, process->remote().getWorker());
71 localApi.vectorFree(v);
76 template <
typename ElemT,
typename IntPtrT>
77 void IPCVector<ElemT, IntPtrT>::vectorAdd(VectorPtr v, ElemT elem)
80 remAPI->vectorAdd.Call({v, elem}, process->remote().getWorker());
82 localApi.vectorAdd(v, elem);
87 template <
typename ElemT,
typename IntPtrT>
88 void IPCVector<ElemT, IntPtrT>::vectorClear(VectorPtr v)
91 remAPI->vectorClear.Call({v}, process->remote().getWorker());
93 localApi.vectorClear(v);
98 template <
typename ElemT,
typename IntPtrT>
99 uint32_t IPCVector<ElemT, IntPtrT>::vectorLength(VectorPtr v)
102 return *remAPI->vectorLength.Call({v}, process->remote().getWorker());
104 return localApi.vectorLength(v);
109 template <
typename ElemT,
typename IntPtrT>
110 uint32_t IPCVector<ElemT, IntPtrT>::vectorCapacity(VectorPtr v)
113 return *remAPI->vectorCapacity.Call({v}, process->remote().getWorker());
115 return localApi.vectorCapacity(v);
120 template <
typename ElemT,
typename IntPtrT>
121 typename IPCVector<ElemT, IntPtrT>::DataPtr IPCVector<ElemT, IntPtrT>::vectorData(VectorPtr v)
124 return *remAPI->vectorData.Call({v}, process->remote().getWorker());
126 return localApi.vectorData(v);
131 template <
typename ElemT,
typename IntPtrT>
132 void IPCVector<ElemT, IntPtrT>::vectorGrow(VectorPtr v, uint32_t cap)
135 remAPI->vectorGrow.Call({v, cap}, process->remote().getWorker());
137 localApi.vectorGrow(v, cap);
142 template <
typename ElemT,
typename IntPtrT>
143 typename IPCVector<ElemT, IntPtrT>::VectorPtr IPCVector<ElemT, IntPtrT>::create(
const std::vector<ElemT>& data)
145 VectorPtr v = vectorNew((uint32_t) data.size());
146 for (
const ElemT& e : data) {
153 template <
typename ElemT,
typename IntPtrT>
154 void IPCVector<ElemT, IntPtrT>::read(VectorPtr v, std::vector<ElemT>& out)
156 uint32_t len = vectorLength(v);
160 ProcessMemory& mem = process->memory();
161 mem.Read((ptr_t) vectorData(v), len*
sizeof(ElemT), out.data());
163 memcpy(out.data(), (
void*) (uintptr_t) vectorData(v), len*
sizeof(ElemT));
168 template <
typename ElemT,
typename IntPtrT>
169 void IPCVector<ElemT, IntPtrT>::inject(Process* process)
171 using namespace asmjit;
172 using namespace asmjit::host;
179 this->process = process;
181 ProcessModules* modules = process ? &process->modules() :
nullptr;
182 ProcessMemory* mem = process ? &process->memory() :
nullptr;
184 bool x64 = (
sizeof(IntPtrT) == 8);
186 RMonoLogVerbose(
"Assembling IPCVector functions for %s", x64 ?
"x64" :
"x86");
188 auto asmPtr = AsmFactory::GetAssembler(!x64);
192 Label lVectorGrow = a->newLabel();
193 Label lVectorNew = a->newLabel();
194 Label lVectorFree = a->newLabel();
195 Label lVectorAdd = a->newLabel();
196 Label lVectorClear = a->newLabel();
197 Label lVectorLength = a->newLabel();
198 Label lVectorCapacity = a->newLabel();
199 Label lVectorData = a->newLabel();
204 ptr_t pGetProcessHeap;
207 auto k32 = modules->GetModule(L
"kernel32.dll");
209 pHeapAlloc = modules->GetExport(k32,
"HeapAlloc")->procAddress;
210 pHeapReAlloc = modules->GetExport(k32,
"HeapReAlloc")->procAddress;
211 pHeapFree = modules->GetExport(k32,
"HeapFree")->procAddress;
212 pGetProcessHeap = modules->GetExport(k32,
"GetProcessHeap")->procAddress;
214 pHeapAlloc = (ptr_t) &HeapAlloc;
215 pHeapReAlloc = (ptr_t) &HeapReAlloc;
216 pHeapFree = (ptr_t) &HeapFree;
217 pGetProcessHeap = (ptr_t) &GetProcessHeap;
230 Label lVectorGrowRet = a->newLabel();
231 Label lVectorGrowPow2Loop = a->newLabel();
232 Label lVectorGrowPow2LoopEnd = a->newLabel();
234 a->bind(lVectorGrow);
238 a->mov(a->zbx, a->zcx);
239 a->mov(a->zsi, a->zdx);
243 a->sub(edx, ptr(a->zbx, offsetof(Vector, cap)));
244 a->jbe(lVectorGrowRet);
252 a->bind(lVectorGrowPow2Loop);
253 a->mov(a->zdx, a->zcx);
254 a->sub(a->zdx, a->zsi);
255 a->jae(lVectorGrowPow2LoopEnd);
257 a->jmp(lVectorGrowPow2Loop);
258 a->bind(lVectorGrowPow2LoopEnd);
259 a->mov(a->zsi, a->zcx);
260 a->mov(ptr(a->zbx, offsetof(Vector, cap)), ecx);
264 a->mov(a->zax, pGetProcessHeap);
269 a->mov(a->zax, pGetProcessHeap);
272 a->mov(a->zdi, a->zax);
275 a->shl(a->zsi, static_ilog2(
sizeof(ElemT)));
276 a.GenCall(pHeapReAlloc, {a->zdi, 0, ptr(a->zbx, offsetof(Vector, data), a->zbx.getSize()), a->zsi}, cc_stdcall);
277 a->mov(ptr(a->zbx, offsetof(Vector, data)), a->zax);
279 a->bind(lVectorGrowRet);
293 a->mov(a->zdi, a->zcx);
297 a->mov(a->zax, pGetProcessHeap);
302 a->mov(a->zax, pGetProcessHeap);
305 a->mov(a->zsi, a->zax);
308 a.GenCall(pHeapAlloc, {a->zsi, 0,
sizeof(Vector)}, cc_stdcall);
309 a->mov(a->zbx, a->zax);
314 a->mov(ptr(a->zbx, offsetof(Vector, len)), ecx);
315 a->mov(ptr(a->zbx, offsetof(Vector, cap)), edi);
318 a->shl(a->zdi, static_ilog2(
sizeof(ElemT)));
319 a.GenCall(pHeapAlloc, {a->zsi, 0, a->zdi}, cc_stdcall);
320 a->mov(ptr(a->zbx, offsetof(Vector, data)), a->zax);
323 a->mov(a->zax, a->zbx);
333 a->bind(lVectorFree);
337 a->mov(a->zbx, a->zcx);
341 a->mov(a->zax, pGetProcessHeap);
346 a->mov(a->zax, pGetProcessHeap);
349 a->mov(a->zsi, a->zax);
352 a.GenCall(pHeapFree, {a->zsi, 0, ptr(a->zbx, offsetof(Vector, data), a->zbx.getSize())}, cc_stdcall);
355 a.GenCall(pHeapFree, {a->zsi, 0, a->zbx}, cc_stdcall);
370 a->mov(a->zbx, a->zcx);
371 a->mov(a->zsi, a->zdx);
374 a->mov(edx, ptr(a->zcx, offsetof(Vector, len)));
378 a->call(lVectorGrow);
381 a->call(lVectorGrow);
385 a->mov(ecx, ptr(a->zbx, offsetof(Vector, len)));
386 a->mov(a->zax, ptr(a->zbx, offsetof(Vector, data)));
387 a->mov(ptr(a->zax, a->zcx, static_ilog2(
sizeof(ElemT))), a->zsi);
390 a->inc(ptr(a->zbx, offsetof(Vector, len)));
401 a->bind(lVectorClear);
402 a->mov(dword_ptr(a->zcx, offsetof(Vector, len)), 0);
409 a->bind(lVectorLength);
410 a->mov(eax, ptr(a->zcx, offsetof(Vector, len)));
417 a->bind(lVectorCapacity);
418 a->mov(eax, ptr(a->zcx, offsetof(Vector, cap)));
425 a->bind(lVectorData);
426 a->mov(a->zax, ptr(a->zcx, offsetof(Vector, data)));
434 remoteCode = std::move(mem->Allocate(a->getCodeSize()).result());
436 code = malloc(a->getCodeSize());
439 mem->Write(remoteCode.ptr(), a->getCodeSize(), code);
444 codeBaseAddr = remoteCode.ptr();
446 code = VirtualAlloc(NULL, a->getCodeSize(), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
448 codeBaseAddr = (ptr_t) code;
451 api.vectorNew = codeBaseAddr + a->getLabelOffset(lVectorNew);
452 api.vectorFree = codeBaseAddr + a->getLabelOffset(lVectorFree);
453 api.vectorAdd = codeBaseAddr + a->getLabelOffset(lVectorAdd);
454 api.vectorClear = codeBaseAddr + a->getLabelOffset(lVectorClear);
455 api.vectorLength = codeBaseAddr + a->getLabelOffset(lVectorLength);
456 api.vectorCapacity = codeBaseAddr + a->getLabelOffset(lVectorCapacity);
457 api.vectorData = codeBaseAddr + a->getLabelOffset(lVectorData);
459 api.vectorGrow = codeBaseAddr + a->getLabelOffset(lVectorGrow);
462 remAPI =
new VectorRemoteAPI {
463 RemoteFunctionFastcall<VECTOR_NEW>(*process, api.vectorNew),
464 RemoteFunctionFastcall<VECTOR_FREE>(*process, api.vectorFree),
465 RemoteFunctionFastcall<VECTOR_ADD>(*process, api.vectorAdd),
466 RemoteFunctionFastcall<VECTOR_CLEAR>(*process, api.vectorClear),
467 RemoteFunctionFastcall<VECTOR_LENGTH>(*process, api.vectorLength),
468 RemoteFunctionFastcall<VECTOR_CAPACITY>(*process, api.vectorCapacity),
469 RemoteFunctionFastcall<VECTOR_DATA>(*process, api.vectorData),
471 RemoteFunctionFastcall<VECTOR_GROW>(*process, api.vectorGrow)
474 localApi.vectorNew = (VECTOR_NEW) api.vectorNew;
475 localApi.vectorFree = (VECTOR_FREE) api.vectorFree;
476 localApi.vectorAdd = (VECTOR_ADD) api.vectorAdd;
477 localApi.vectorClear = (VECTOR_CLEAR) api.vectorClear;
478 localApi.vectorLength = (VECTOR_LENGTH) api.vectorLength;
479 localApi.vectorCapacity = (VECTOR_CAPACITY) api.vectorCapacity;
480 localApi.vectorData = (VECTOR_DATA) api.vectorData;
482 localApi.vectorGrow = (VECTOR_GROW) api.vectorGrow;
489 template <
typename ElemT,
typename IntPtrT>
490 void IPCVector<ElemT, IntPtrT>::uninject()
500 remoteCode = MemBlock();
505 VirtualFree(code, 0, MEM_RELEASE);