public void CallCustomX86(Action <X86Writer> writeX86) { if (CodeHandle.IsClosed || CodeHandle.IsInvalid) { CompletelyReInitializeAndInjectCodeInNewLocation(); } Kernel.CheckAddress(CodeHandle.GetHandle().ToInt64(), FUNCTION_CALL_ASM_BUFFER_SIZE, "execute function"); Buffer_ParamPointerList.Clear(); AsmBuffer.Position = 0; X86Writer asm = new X86Writer(AsmBuffer, CodeHandle.GetHandle()); writeX86.Invoke(asm); if (WriteAsm((uint)CodeHandle.GetHandle(), AsmBuffer.ToArray(), (int)AsmBuffer.Position)) { var threadHandle = new SafeRemoteThreadHandle(CodeHandle); if (!threadHandle.IsClosed & !threadHandle.IsInvalid) { Kernel.WaitForSingleObject(threadHandle.GetHandle(), MAX_WAIT); } threadHandle.Close(); threadHandle.Dispose(); threadHandle = null; } }
protected override void BuildCustomRemoteCode(X86Writer w, MemoryStream ms) { RecordedValueHandle?.Dispose(); RecordedValueHandle = new SafeRemoteHandle(sizeof(int)); //Move address in Register into the value of RecordedValueHandle // // e.g. with RecordedValueHandle = 7777 and Register = X86Register32.EAX: // mov [7777],eax w.Mov32(new X86Address(X86Register32.None, RecordedValueHandle.GetHandle().ToInt32()), Register); }
private void _buildAsmArrays() { if (OriginalLocalCode == null) { OriginalLocalCode = RBytes(OriginalLocalCodeStartOffset.ToInt64(), OriginalLocalCodeLength); } using (var _customRemoteCodeMemoryStream = new MemoryStream(OriginalLocalCodeLength)) { //Start building wrapped user code at the location immediately after the copy of the original //code ends (unless OriginalCodeAtEnd is defined, in which case, it's at the beginning of CustomRemoteCodeHandle) : var customRemoteCodeCodeBuilder = new X86Writer(_customRemoteCodeMemoryStream, (IntPtr)(CustomRemoteCodeHandle.GetHandle().ToInt64())); //If OriginalCodeAtEnd is not defined, write the original code at the start of the custom remote code: if (!OriginalCodeAtEnd) { _customRemoteCodeMemoryStream.Write(OriginalLocalCode, 0, OriginalLocalCodeLength); } BuildCustomRemoteCode(customRemoteCodeCodeBuilder, _customRemoteCodeMemoryStream); //If OriginalCodeAtEnd is defined, write the original code at the end of the custom remote code: if (OriginalCodeAtEnd) { _customRemoteCodeMemoryStream.Write(OriginalLocalCode, 0, OriginalLocalCodeLength); } //Jump to return offset at end of wrapped function: customRemoteCodeCodeBuilder.Jmp(CustomRemoteCodeReturnDestinationOffset); //Copy the bytes of the ASM to our array before exiting the "using" statement and disposing the MemoryStream: CustomRemoteCode = _customRemoteCodeMemoryStream.ToArray(); } using (var _customLocalCodeMemoryStream = new MemoryStream(OriginalLocalCodeLength)) { var customLocalCodeCodeBuilder = new X86Writer(_customLocalCodeMemoryStream, OriginalLocalCodeStartOffset); // Jump to our wrapped code instead of doing the original code: customLocalCodeCodeBuilder.Jmp(CustomRemoteCodeHandle.GetHandle()); // Fill in the rest of the original instructions with NOP's: while (_customLocalCodeMemoryStream.Position < OriginalLocalCodeLength) { customLocalCodeCodeBuilder.Nop(); } CustomLocalCode = _customLocalCodeMemoryStream.ToArray(); } }
private void InitAsmBuffer(int funcAddr, IEnumerable <dynamic> parameters, List <SafeRemoteHandle> allocPtrList, dynamic eax = null, dynamic ecx = null, dynamic edx = null, dynamic ebx = null, dynamic esp = null, dynamic esi = null, dynamic edi = null) { var args = parameters.ToArray(); AsmBuffer.Position = 0; X86Writer asm = new X86Writer(AsmBuffer, CodeHandle.GetHandle()); //ASM START: asm.Push32(Reg32.EBP); asm.Mov32(Reg32.EBP, Reg32.ESP); asm.Push32(Reg32.EAX); for (int i = args.Length - 1; i >= 0; i += -1) { asm.Mov32(Reg32.EAX, SquashIntoDword(ref allocPtrList, args[i])); asm.Push32(Reg32.EAX); } if (eax != null) { asm.Mov32(Reg32.EAX, SquashIntoDword(ref allocPtrList, eax)); } if (ecx != null) { asm.Mov32(Reg32.ECX, SquashIntoDword(ref allocPtrList, ecx)); } if (edx != null) { asm.Mov32(Reg32.EDX, SquashIntoDword(ref allocPtrList, edx)); } if (ebx != null) { asm.Mov32(Reg32.EBX, SquashIntoDword(ref allocPtrList, ebx)); } if (esp != null) { asm.Mov32(Reg32.ESP, SquashIntoDword(ref allocPtrList, esp)); } if (esi != null) { asm.Mov32(Reg32.ESI, SquashIntoDword(ref allocPtrList, esi)); } if (edi != null) { asm.Mov32(Reg32.EDI, SquashIntoDword(ref allocPtrList, edi)); } //CALL LUA FUNCTION: asm.Call(new IntPtr(funcAddr)); AsmLocAfterLuaFunctionCall = new MoveableAddressOffset(this, asm.Position); //SET RETURN POS: asm.Mov32(Reg32.EBX, CodeHandle.GetHandle().ToInt32() + FUNC_RETURN_ADDR_OFFSET); asm.Mov32(new Addr(Reg32.EBX, 0), Reg32.EAX); //mov [ebx], eax asm.Pop32(Reg32.EAX); for (int i = args.Length - 1; i >= 0; i += -1) { asm.Pop32(Reg32.EAX); } asm.Mov32(Reg32.ESP, Reg32.EBP); asm.Pop32(Reg32.EBP); asm.Retn(); }
protected abstract void BuildCustomRemoteCode(X86Writer w, MemoryStream ms);