private static void Example1() { const int valueToReturn = 1; FasmNet fasmNet = new FasmNet(); fasmNet.AddLine("use32"); //Tell FASM.Net to use x86 (32bit) mode fasmNet.AddLine("mov eax, {0}", valueToReturn); // copy "1" to eax fasmNet.AddLine("ret"); // in cdecl calling convention, return value is stored in eax; so this will return 1 byte[] assembledCode = fasmNet.Assemble(); var allocatedCodeMemory = _currentProcess.MemoryFactory.Allocate( name: "Example1", // only used for debugging; not really needed size: assembledCode.Length, protection: MemoryProtectionFlags.ExecuteReadWrite /* It is important to mark the memory as executeable or we will get exceptions from DEP */ ); allocatedCodeMemory.Write(0, assembledCode); var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer <AssemblyConstantValueFunction>(allocatedCodeMemory.BaseAddress); var returnValue = myAssemblyFunction(); // Warning: Potential memory leak! // Do not forget to dispose the allocated code memory after usage. allocatedCodeMemory.Dispose(); Console.WriteLine($"Example1 return value: {returnValue}, expected: {valueToReturn}"); // Prints 1 }
private static void Example2() { FasmNet fasmNet = new FasmNet(); fasmNet.AddLine("use32"); //Tell FASM.Net to use x86 (32bit) mode fasmNet.AddLine("mov eax, [ebp+4]"); // Set return value to ebp+4 (return address) fasmNet.AddLine("ret"); // in cdecl calling convention, return value is stored in eax; so this will return the return address byte[] assembledCode = fasmNet.Assemble(); var allocatedCodeMemory = _currentProcess.MemoryFactory.Allocate( name: "Example2", // only used for debugging; not really needed size: assembledCode.Length, protection: MemoryProtectionFlags.ExecuteReadWrite /* It is important to mark the memory as executeable or we will get exceptions from DEP */ ); allocatedCodeMemory.Write(0, assembledCode); var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer <AssemblyReadRegistersFunction>(allocatedCodeMemory.BaseAddress); var returnValue = myAssemblyFunction(); // Warning: Potential memory leak! // Do not forget to dispose the allocated code memory after usage. allocatedCodeMemory.Dispose(); Console.WriteLine($"Example2 return value: 0x{returnValue.ToInt32():X}"); // Prints this methods JIT'ed address }
public byte[] Compile(IntPtr OverrideAddress, params object[] statements) { var asm = new FasmNet(); if (framework == TargetFramework.x86) { asm.AddLine("use32"); } else { asm.AddLine("use64"); } foreach (object op in statements) { if (op.GetType() == typeof(Operation)) { asm.AddLine(((Operation)op).op); Console.WriteLine(((Operation)op).op); } else if (op.GetType() == typeof(string)) { asm.AddLine((string)op); Console.WriteLine((string)op); } else { throw new InvalidOperationException("Unsupported object in Compile"); } } return(asm.Assemble(OverrideAddress)); }
public void ObjectMnemonics() { // Arrange var fasm = new FasmNet(); // Act fasm.AddLine("push eax"); fasm.AddLine("retn"); // Assert Assert.AreEqual(String.Format("push eax{0}retn{0}", Environment.NewLine), fasm.Mnemonics); }
public void ObjectAssembleWithOrigin() { // Arrange var fasm = new FasmNet(); // Act fasm.AddLine("use32"); fasm.AddLine("jmp {0}", 0x2000); var asm = fasm.Assemble(new IntPtr(0x1000)); // Assert CollectionAssert.AreEqual(new byte[] { 0xE9, 0xfb, 0x0f, 0x00, 0x00 }, asm); }
public void ObjectAddAndInsertLines() { // Arrange var fasm = new FasmNet(); // Act fasm.AddLine("push eax"); fasm.AddLine("pop {0}", "eax"); fasm.InsertLine(0, "use32"); var asm = fasm.Assemble(); // Assert CollectionAssert.AreEqual(new byte[] { 0x50, 0x58 }, asm); }
private static void Example3() { FasmNet fasmNet = new FasmNet(); fasmNet.AddLine("use32"); //Tell FASM.Net to use x86 (32bit) mode fasmNet.AddLine("push ebp"); // init stack frame fasmNet.AddLine("mov eax, [ebp+8]"); // set eax to second param (remember, in cdecl calling convention, params are pushed right-to-left) fasmNet.AddLine("mov edx, [ebp+12]"); // set edx to first param fasmNet.AddLine("add eax, edx"); //add edx (first param) to eax (second param) fasmNet.AddLine("pop ebp"); // leave stack frame fasmNet.AddLine("ret"); // in cdecl calling convention, return value is stored in eax; so this will return both params added up byte[] assembledCode = fasmNet.Assemble(); var allocatedCodeMemory = _currentProcess.MemoryFactory.Allocate( name: "Example3", // only used for debugging; not really needed size: assembledCode.Length, protection: MemoryProtectionFlags.ExecuteReadWrite /* It is important to mark the memory as executeable or we will get exceptions from DEP */ ); allocatedCodeMemory.Write(0, assembledCode); var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer <AssemblyAddFunction>(allocatedCodeMemory.BaseAddress); var returnValue = myAssemblyFunction(10, -15); // Warning: Potential memory leak! // Do not forget to dispose the allocated code memory after usage. allocatedCodeMemory.Dispose(); Console.WriteLine($"Example3 return value: {returnValue}, expected: -5"); // Prints -5 }
//[Obfuscation(Feature = "virtualization", Exclude = false)] internal static IntPtr InjectAsm(string[] parInstructions, string parPatchName) { if (Asm == null) { Asm = new FasmNet(); } Asm.Clear(); Asm.AddLine("use32"); foreach (var x in parInstructions) { Asm.AddLine(x); } var byteCode = new byte[0]; try { byteCode = Asm.Assemble(); } catch (FasmAssemblerException ex) { MessageBox.Show( $"Error definition: {ex.ErrorCode}; Error code: {(int) ex.ErrorCode}; Error line: {ex.ErrorLine}; Error offset: {ex.ErrorOffset}; Mnemonics: {ex.Mnemonics}"); } var start = Reader.Alloc(byteCode.Length); Asm.Clear(); Asm.AddLine("use32"); foreach (var x in parInstructions) { Asm.AddLine(x); } byteCode = Asm.Assemble(start); HookWardenMemScan.RemoveHack(start); HookWardenMemScan.RemoveHack(parPatchName); var originalBytes = Reader.ReadBytes(start, byteCode.Length); if (parPatchName != "") { var parHack = new Hack(start, byteCode, originalBytes, parPatchName); HookWardenMemScan.AddHack(parHack); parHack.Apply(); } else { Reader.WriteBytes(start, byteCode); } return(start); }
public virtual int GenerateStub(WindowsAssembly pE, ProtectionOptions options) { try { FasmNet fasmNet = new FasmNet(memorySize, 10); // if compilcation fails increase memorySize parameter fasmNet.AddLine(Code); generatedStub = fasmNet.Assemble(NextSectionRVA(pE.NtHeaders.OptionalHeader.SectionAlignment, pE.SectionHeaders.Last()) + (uint)pE.NtHeaders.OptionalHeader.ImageBase); return(generatedStub.Length); } catch { } return(-1); }
public byte[] Compile(params object[] statements) { var asm = new FasmNet(100000, 100); if (framework == TargetFramework.x86) { asm.AddLine("use32"); } else { asm.AddLine("use64"); } if (statements.Length == 0) { foreach (object op in operations) { if (op.GetType() == typeof(Operation)) { asm.AddLine(((Operation)op).op); } else if (op.GetType() == typeof(string)) { asm.AddLine((string)op); } else { throw new InvalidOperationException("Unsupported object in Compile"); } } return(asm.Assemble(Address)); } foreach (object op in statements) { if (op.GetType() == typeof(Operation)) { asm.AddLine(((Operation)op).op); } else if (op.GetType() == typeof(string)) { asm.AddLine((string)op); } else { throw new InvalidOperationException("Unsupported object in Compile"); } } return(asm.Assemble(Address)); }
public void ObjectClear() { // Arrange var fasm = new FasmNet(); // Act fasm.AddLine("retn"); fasm.Clear(); fasm.AddLine("push eax"); fasm.AddLine("pop {0}", "eax"); fasm.InsertLine(0, "use32"); var asm = fasm.Assemble(); // Assert CollectionAssert.AreEqual(new byte[] { 0x50, 0x58 }, asm); }