From ff1f0a5c1a8efd2edec6a36fb420a8041e1e35fb Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Fri, 14 Oct 2022 16:57:46 +0200 Subject: [PATCH 1/4] dotnet: Refactor .NET bindings for .NET5.0 --- .../dotnet/UnicornManaged/AssemblyInfo.fs | 41 ---- .../UnicornManaged/Binding/BindingFactory.fs | 4 +- bindings/dotnet/UnicornManaged/Unicorn.fs | 103 ++++----- .../UnicornManaged/UnicornManaged.fsproj | 94 +++----- bindings/dotnet/UnicornSamples/App.config | 6 - bindings/dotnet/UnicornSamples/Program.cs | 4 +- .../UnicornSamples/Properties/AssemblyInfo.cs | 36 --- .../dotnet/UnicornSamples/ShellcodeSample.cs | 87 ++++--- .../UnicornSamples/UnicornSamples.csproj | 93 ++------ bindings/dotnet/UnicornSamples/Utils.cs | 28 +-- bindings/dotnet/UnicornSamples/X86Sample32.cs | 218 ++++++++---------- .../dotnet/UnicornSamples/packages.config | 4 - 12 files changed, 251 insertions(+), 467 deletions(-) delete mode 100644 bindings/dotnet/UnicornManaged/AssemblyInfo.fs delete mode 100644 bindings/dotnet/UnicornSamples/App.config delete mode 100644 bindings/dotnet/UnicornSamples/Properties/AssemblyInfo.cs delete mode 100644 bindings/dotnet/UnicornSamples/packages.config diff --git a/bindings/dotnet/UnicornManaged/AssemblyInfo.fs b/bindings/dotnet/UnicornManaged/AssemblyInfo.fs deleted file mode 100644 index 16d8c919..00000000 --- a/bindings/dotnet/UnicornManaged/AssemblyInfo.fs +++ /dev/null @@ -1,41 +0,0 @@ -namespace UnicornManaged.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[] -[] -[] -[] -[] -[] -[] -[] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [] -[] -[] - -do - () \ No newline at end of file diff --git a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs b/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs index f55f72ec..6ea0b183 100644 --- a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs +++ b/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs @@ -1,13 +1,11 @@ namespace UnicornManaged.Binding -open System module BindingFactory = let mutable _instance = NativeBinding.instance let setDefaultBinding(binding: IBinding) = _instance <- binding - + let getDefault() = _instance - diff --git a/bindings/dotnet/UnicornManaged/Unicorn.fs b/bindings/dotnet/UnicornManaged/Unicorn.fs index 0a05d30d..31decbcd 100644 --- a/bindings/dotnet/UnicornManaged/Unicorn.fs +++ b/bindings/dotnet/UnicornManaged/Unicorn.fs @@ -1,7 +1,6 @@ namespace UnicornManaged - + open System -open System.Threading open System.Collections.Generic open System.Runtime.InteropServices open System.Linq @@ -20,7 +19,7 @@ and OutHook = delegate of Unicorn * Int32 * Int32 * Int32 * Object -> unit and SyscallHook = delegate of Unicorn * Object -> unit // the managed unicorn engine -and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = +and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = // hook callback list let _codeHooks = new List<(CodeHook * Object)>() @@ -43,24 +42,24 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = (UC_HOOK_MEM_WRITE_PROT, UC_MEM_WRITE_PROT) (UC_HOOK_MEM_FETCH_PROT, UC_MEM_FETCH_PROT) ] |> dict - + let mutable _eng = [|UIntPtr.Zero|] - + let checkResult(errCode: Int32, errMsg: String) = if errCode <> Common.UC_ERR_OK then raise(ApplicationException(String.Format("{0}. Error: {1}", errMsg, errCode))) - + let hookDel(callbacks: List<'a * Object>) (callback: 'a)= // TODO: invoke the native function in order to not call the trampoline anymore callbacks |> Seq.tryFind(fun item -> match item with | (c, _) -> c = callback) |> (fun k -> if k.IsSome then callbacks.Remove(k.Value) |> ignore) - + let allocate(size: Int32) = let mem = Marshal.AllocHGlobal(size) _disposablePointers.Add(mem) mem.ToPointer() - do + do // initialize event list _eventMemMap |> Seq.map(fun kv -> kv.Key) @@ -72,7 +71,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = checkResult(err, "Unable to open the Unicorn Engine") new(arch, mode) = new Unicorn(arch, mode, BindingFactory.getDefault()) - + member private this.CheckResult(errorCode: Int32) = // return the exception instead of raising it in order to have a more meaningful stack trace if errorCode <> Common.UC_ERR_OK then @@ -82,43 +81,43 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.MemMap(address: Int64, size: Int64, perm: Int32) = let size = new UIntPtr(uint64 size) - match binding.MemMap(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with + match binding.MemMap(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with | Some e -> raise e | None -> () member this.MemMapPtr(address: Int64, size: Int64, perm: Int32, ptr: IntPtr) = let size = new UIntPtr(uint64 size) let ptr = new UIntPtr(ptr.ToPointer()) - match binding.MemMapPtr(_eng.[0], uint64 address, size, uint32 perm, ptr) |> this.CheckResult with - | Some e -> raise e | None -> () - + match binding.MemMapPtr(_eng.[0], uint64 address, size, uint32 perm, ptr) |> this.CheckResult with + | Some e -> raise e | None -> () + member this.MemUnmap(address: Int64, size: Int64) = let size = new UIntPtr(uint64 size) - match binding.MemUnmap(_eng.[0], uint64 address, size) |> this.CheckResult with - | Some e -> raise e | None -> () + match binding.MemUnmap(_eng.[0], uint64 address, size) |> this.CheckResult with + | Some e -> raise e | None -> () member this.MemProtect(address: Int64, size: Int64, ?perm: Int32) = let size = new UIntPtr(uint64 size) let perm = defaultArg perm Common.UC_PROT_ALL - match binding.MemProtect(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with - | Some e -> raise e | None -> () - + match binding.MemProtect(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with + | Some e -> raise e | None -> () + member this.MemWrite(address: Int64, value: Byte array) = - match binding.MemWrite(_eng.[0], uint64 address, value, new UIntPtr(uint32 value.Length)) |> this.CheckResult with + match binding.MemWrite(_eng.[0], uint64 address, value, new UIntPtr(uint32 value.Length)) |> this.CheckResult with | Some e -> raise e | None -> () member this.MemRead(address: Int64, memValue: Byte array) = - match binding.MemRead(_eng.[0], uint64 address, memValue, new UIntPtr(uint32 memValue.Length)) |> this.CheckResult with + match binding.MemRead(_eng.[0], uint64 address, memValue, new UIntPtr(uint32 memValue.Length)) |> this.CheckResult with | Some e -> raise e | None -> () member this.RegWrite(regId: Int32, value: Byte array) = - match binding.RegWrite(_eng.[0], regId, value) |> this.CheckResult with + match binding.RegWrite(_eng.[0], regId, value) |> this.CheckResult with | Some e -> raise e | None -> () member this.RegWrite(regId: Int32, value: Int64) = this.RegWrite(regId, int64ToBytes value) member this.RegRead(regId: Int32, regValue: Byte array) = - match binding.RegRead(_eng.[0], regId, regValue) |> this.CheckResult with + match binding.RegRead(_eng.[0], regId, regValue) |> this.CheckResult with | Some e -> raise e | None -> () member this.RegRead(regId: Int32) = @@ -127,15 +126,15 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = bytesToInt64 buffer member this.EmuStart(beginAddr: Int64, untilAddr: Int64, timeout: Int64, count: Int64) = - match binding.EmuStart(_eng.[0], uint64 beginAddr, uint64 untilAddr, uint64 timeout, uint64 count) |> this.CheckResult with + match binding.EmuStart(_eng.[0], uint64 beginAddr, uint64 untilAddr, uint64 timeout, uint64 count) |> this.CheckResult with | Some e -> raise e | None -> () member this.EmuStop() = - match binding.EmuStop(_eng.[0]) |> this.CheckResult with + match binding.EmuStop(_eng.[0]) |> this.CheckResult with | Some e -> raise e | None -> () - + member this.Close() = - match binding.Close(_eng.[0]) |> this.CheckResult with + match binding.Close(_eng.[0]) |> this.CheckResult with | Some e -> raise e | None -> () member this.ArchSupported(arch: Int32) = @@ -148,15 +147,15 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let errorStringPointer = binding.Strerror(errorNo) Marshal.PtrToStringAnsi(errorStringPointer) - member this.AddCodeHook(callback: CodeHook, userData: Object, beginAddr: Int64, endAddr: Int64) = + member this.AddCodeHook(callback: CodeHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = _codeHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) - + if _codeHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new CodeHookInternal(trampoline)) + let funcPointer = Marshal.GetFunctionPointerForDelegate(new CodeHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_CODE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_CODE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () _codeHooks.Add(callback, userData) @@ -167,7 +166,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.HookDel(callback: CodeHook) = hookDel _codeHooks callback - member this.AddBlockHook(callback: BlockHook, userData: Object, beginAddr: Int64, endAddr: Int64) = + member this.AddBlockHook(callback: BlockHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = _blockHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) @@ -175,7 +174,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = if _blockHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new BlockHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_BLOCK, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_BLOCK, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () _blockHooks.Add(callback, userData) @@ -183,15 +182,15 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.HookDel(callback: BlockHook) = hookDel _blockHooks callback - member this.AddInterruptHook(callback: InterruptHook, userData: Object, hookBegin: UInt64, hookEnd : UInt64) = + member this.AddInterruptHook(callback: InterruptHook, userData: Object, hookBegin: UInt64, hookEnd : UInt64) = let trampoline(u: IntPtr) (intNumber: Int32) (user: IntPtr) = _interruptHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, intNumber, userData)) - + if _interruptHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new InterruptHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_INTR, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, hookBegin, hookEnd) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_INTR, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, hookBegin, hookEnd) |> this.CheckResult with | Some e -> raise e | None -> () _interruptHooks.Add(callback, userData) @@ -202,7 +201,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.HookDel(callback: InterruptHook) = hookDel _interruptHooks callback - member this.AddMemReadHook(callback: MemReadHook, userData: Object, beginAddr: Int64, endAddr: Int64) = + member this.AddMemReadHook(callback: MemReadHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = _memReadHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) @@ -210,7 +209,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = if _memReadHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new MemReadHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_READ, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_READ, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () _memReadHooks.Add(callback, userData) @@ -218,15 +217,15 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.HookDel(callback: MemReadHook) = hookDel _memReadHooks callback - member this.AddMemWriteHook(callback: MemWriteHook, userData: Object, beginAddr: Int64, endAddr: Int64) = + member this.AddMemWriteHook(callback: MemWriteHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = _memWriteHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, value, userData)) - + if _memWriteHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new MemWriteHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_WRITE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_WRITE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () _memWriteHooks.Add(callback, userData) @@ -235,7 +234,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = hookDel _memWriteHooks callback member this.AddEventMemHook(callback: EventMemHook, eventType: Int32, userData: Object) = - let trampoline(u: IntPtr) (eventType: Int32) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = + let trampoline(u: IntPtr) (eventType: Int32) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = _memEventHooks.Keys |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) |> Seq.map(fun eventflag -> _memEventHooks.[eventflag]) @@ -249,12 +248,12 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.filter(fun eventFlag -> _memEventHooks.[eventFlag] |> Seq.isEmpty) |> Seq.iter(fun eventFlag -> let funcPointer = Marshal.GetFunctionPointerForDelegate(new EventMemHookInternal(trampoline)) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0) |> this.CheckResult with + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0) |> this.CheckResult with | Some e -> raise e | None -> () ) - // register the callbacks + // register the callbacks _memEventHooks.Keys |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) |> Seq.iter(fun eventFlag -> _memEventHooks.[eventFlag].Add((callback, userData))) @@ -271,11 +270,11 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = _inHooks |> Seq.map(fun (callback, userData) -> callback.Invoke(this, port, size, userData)) |> Seq.last - + if _inHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new InHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with | Some e -> raise e | None -> () _inHooks.Add(callback, userData) @@ -287,11 +286,11 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let trampoline(u: IntPtr) (port: Int32) (size: Int32) (value: Int32) (user: IntPtr) = _outHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, port, size, value, userData)) - + if _outHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new OutHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with | Some e -> raise e | None -> () _outHooks.Add(callback, userData) @@ -303,18 +302,18 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let trampoline(u: IntPtr) (user: IntPtr) = _syscallHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, userData)) - + if _syscallHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new SyscallHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with | Some e -> raise e | None -> () _syscallHooks.Add(callback, userData) member this.AddSyscallHook(callback: SyscallHook) = this.AddSyscallHook(callback, null) - + member this.Version() = let (major, minor) = (new UIntPtr(), new UIntPtr()) let combined = binding.Version(major, minor) @@ -340,4 +339,4 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = interface IDisposable with member this.Dispose() = - this.Dispose() \ No newline at end of file + this.Dispose() diff --git a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj index e10cd735..864e4e96 100644 --- a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj +++ b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj @@ -1,56 +1,45 @@ - - - + - Debug - AnyCPU - 2.0 - 0c21f1c1-2725-4a46-9022-1905f85822a5 - Library + net5.0 UnicornManaged UnicornManaged - v4.5 - 4.3.1.0 + Copyright © Antonio Parata 2016 + https://github.com/unicorn-engine/unicorn + 2.0.0 + 0c21f1c1-2725-4a46-9022-1905f85822a5 true - UnicornManaged - + true + + + 3 + + - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - bin\Debug\UnicornManaged.XML - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - bin\Release\UnicornManaged.XML - + true + full + false + false + DEBUG;TRACE + + + pdbonly + true + true + TRACE + + - - - True - - - - - - - + + + + @@ -61,27 +50,4 @@ - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - - \ No newline at end of file + diff --git a/bindings/dotnet/UnicornSamples/App.config b/bindings/dotnet/UnicornSamples/App.config deleted file mode 100644 index d1428ad7..00000000 --- a/bindings/dotnet/UnicornSamples/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/bindings/dotnet/UnicornSamples/Program.cs b/bindings/dotnet/UnicornSamples/Program.cs index 41cfb19c..f961708a 100644 --- a/bindings/dotnet/UnicornSamples/Program.cs +++ b/bindings/dotnet/UnicornSamples/Program.cs @@ -2,9 +2,9 @@ namespace UnicornSamples { - class Program + internal static class Program { - static void Main(string[] args) + private static void Main(string[] args) { // X86 tests 32bit X86Sample32.X86Code32(); diff --git a/bindings/dotnet/UnicornSamples/Properties/AssemblyInfo.cs b/bindings/dotnet/UnicornSamples/Properties/AssemblyInfo.cs deleted file mode 100644 index aacf2f82..00000000 --- a/bindings/dotnet/UnicornSamples/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("UnicornSamples")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("UnicornSamples")] -[assembly: AssemblyCopyright("Copyright © Antonio Parata 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b80b5987-1e24-4309-8bf9-c4f91270f21c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs index be654d6f..7982e5e4 100644 --- a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs +++ b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs @@ -1,24 +1,20 @@ using Gee.External.Capstone; using Gee.External.Capstone.X86; using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Reflection; using System.Text; -using System.Threading.Tasks; using UnicornManaged; using UnicornManaged.Const; namespace UnicornSamples { - internal class ShellcodeSample + internal static class ShellcodeSample { - private const Int64 ADDRESS = 0x1000000; + private const long ADDRESS = 0x1000000; public static void X86Code32Self() { - Byte[] X86_CODE32_SELF = + byte[] X86_CODE32_SELF = { 0xeb, 0x1c, 0x5a, 0x89, 0xd6, 0x8b, 0x02, 0x66, 0x3d, 0xca, 0x7d, 0x75, 0x06, 0x66, 0x05, 0x03, 0x03, 0x89, 0x02, 0xfe, 0xc2, 0x3d, 0x41, 0x41, 0x41, 0x41, 0x75, 0xe9, 0xff, 0xe6, 0xe8, 0xdf, 0xff, 0xff, @@ -31,7 +27,7 @@ namespace UnicornSamples public static void X86Code32() { - Byte[] X86_CODE32 = + byte[] X86_CODE32 = { 0xeb, 0x19, 0x31, 0xc0, 0x31, 0xdb, 0x31, 0xd2, 0x31, 0xc9, 0xb0, 0x04, 0xb3, 0x01, 0x59, 0xb2, 0x05, 0xcd, 0x80, 0x31, 0xc0, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80, 0xe8, 0xe2, 0xff, 0xff, 0xff, 0x68, 0x65, @@ -41,39 +37,39 @@ namespace UnicornSamples Run(X86_CODE32); } - private static void Run(Byte[] code) + private static void Run(byte[] code) { Console.WriteLine(); var stackTrace = new StackTrace(); var stackFrame = stackTrace.GetFrames()[1]; var methodName = stackFrame.GetMethod().Name; - Console.WriteLine("*** Start: " + methodName); + Console.WriteLine($"*** Start: {methodName}"); RunTest(code, ADDRESS); - Console.WriteLine("*** End: " + methodName); + Console.WriteLine($"*** End: {methodName}"); Console.WriteLine(); } - private static void RunTest(Byte[] code, Int64 address) + private static void RunTest(byte[] code, long address) { try { using (var u = new Unicorn(Common.UC_ARCH_X86, Common.UC_MODE_32)) - using(var disassembler = CapstoneDisassembler.CreateX86Disassembler(DisassembleMode.Bit32)) + using(var disassembler = CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit32)) { - Console.WriteLine("Unicorn version: {0}", u.Version()); - + Console.WriteLine($"Unicorn version: {u.Version()}"); + // map 2MB of memory for this emulation u.MemMap(address, 2 * 1024 * 1024, Common.UC_PROT_ALL); // write machine code to be emulated to memory u.MemWrite(address, code); - + // initialize machine registers u.RegWrite(X86.UC_X86_REG_ESP, Utils.Int64ToBytes(address + 0x200000)); - var regv = new Byte[4]; + var regv = new byte[4]; u.RegRead(X86.UC_X86_REG_ESP, regv); // tracing all instructions by having @begin > @end @@ -84,7 +80,7 @@ namespace UnicornSamples // handle SYSCALL u.AddSyscallHook(SyscallHookCallback); - + Console.WriteLine(">>> Start tracing code"); // emulate machine code in infinite time @@ -98,44 +94,44 @@ namespace UnicornSamples Console.Error.WriteLine("Emulation FAILED! " + ex.Message); } } - - private static void CodeHookCallback( - CapstoneDisassembler disassembler, - Unicorn u, - Int64 addr, - Int32 size, - Object userData) - { - Console.Write("[+] 0x{0}: ", addr.ToString("X")); - var eipBuffer = new Byte[4]; + private static void CodeHookCallback( + CapstoneX86Disassembler disassembler, + Unicorn u, + long addr, + int size, + object userData) + { + Console.Write($"[+] 0x{addr:X}: "); + + var eipBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EIP, eipBuffer); var effectiveSize = Math.Min(16, size); - var tmp = new Byte[effectiveSize]; + var tmp = new byte[effectiveSize]; u.MemRead(addr, tmp); var sb = new StringBuilder(); foreach (var t in tmp) { - sb.AppendFormat("{0} ", (0xFF & t).ToString("X")); + sb.AppendFormat($"{(0xFF & t):X} "); } - Console.Write("{0,-20}", sb); + Console.Write($"{sb,-20}"); Console.WriteLine(Utils.Disassemble(disassembler, tmp)); } - private static void SyscallHookCallback(Unicorn u, Object userData) + private static void SyscallHookCallback(Unicorn u, object userData) { - var eaxBuffer = new Byte[4]; + var eaxBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EAX, eaxBuffer); var eax = Utils.ToInt(eaxBuffer); - Console.WriteLine("[!] Syscall EAX = 0x{0}", eax.ToString("X")); + Console.WriteLine($"[!] Syscall EAX = 0x{eax:X}"); u.EmuStop(); } - private static void InterruptHookCallback(Unicorn u, Int32 intNumber, Object userData) + private static void InterruptHookCallback(Unicorn u, int intNumber, object userData) { // only handle Linux syscall if (intNumber != 0x80) @@ -143,8 +139,8 @@ namespace UnicornSamples return; } - var eaxBuffer = new Byte[4]; - var eipBuffer = new Byte[4]; + var eaxBuffer = new byte[4]; + var eipBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EAX, eaxBuffer); u.RegRead(X86.UC_X86_REG_EIP, eipBuffer); @@ -155,19 +151,19 @@ namespace UnicornSamples switch (eax) { default: - Console.WriteLine("[!] Interrupt 0x{0} num {1}, EAX=0x{2}", eip.ToString("X"), intNumber.ToString("X"), eax.ToString("X")); + Console.WriteLine($"[!] Interrupt 0x{eip:X} num {intNumber:X}, EAX=0x{eax:X}"); break; case 1: // sys_exit - Console.WriteLine("[!] Interrupt 0x{0} num {1}, SYS_EXIT", eip.ToString("X"), intNumber.ToString("X")); + Console.WriteLine($"[!] Interrupt 0x{eip:X} num {intNumber:X}, SYS_EXIT"); u.EmuStop(); break; case 4: // sys_write // ECX = buffer address - var ecxBuffer = new Byte[4]; + var ecxBuffer = new byte[4]; // EDX = buffer size - var edxBuffer = new Byte[4]; + var edxBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_ECX, ecxBuffer); u.RegRead(X86.UC_X86_REG_EDX, edxBuffer); @@ -177,16 +173,11 @@ namespace UnicornSamples // read the buffer in var size = Math.Min(256, edx); - var buffer = new Byte[size]; + var buffer = new byte[size]; u.MemRead(ecx, buffer); var content = Encoding.Default.GetString(buffer); - Console.WriteLine( - "[!] Interrupt 0x{0}: num {1}, SYS_WRITE. buffer = 0x{2}, size = , content = '{3}'", - eip.ToString("X"), - ecx.ToString("X"), - edx.ToString("X"), - content); + Console.WriteLine($"[!] Interrupt 0x{eip:X}: num {ecx:X}, SYS_WRITE. buffer = 0x{edx:X}, size = {size:X}, content = '{content}'"); break; } diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index 3a087b03..d7464c04 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -1,43 +1,28 @@ - - - + - Debug - AnyCPU - {B80B5987-1E24-4309-8BF9-C4F91270F21C} + net5.0 Exe - Properties UnicornSamples UnicornSamples - v4.5 - 512 + Copyright © Antonio Parata 2016 + https://github.com/unicorn-engine/unicorn + 2.0.0 + {B80B5987-1E24-4309-8BF9-C4F91270F21C} + true - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true + + + prompt + 4 + + - x86 true full false bin\Debug\ DEBUG;TRACE - prompt - 4 false false @@ -47,62 +32,16 @@ true bin\Release\ TRACE - prompt - 4 - - - ..\packages\Gee.External.Capstone.1.2.2\lib\net45\Gee.External.Capstone.dll - True - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.5 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - + {0c21f1c1-2725-4a46-9022-1905f85822a5} UnicornManaged + - - + - - \ No newline at end of file diff --git a/bindings/dotnet/UnicornSamples/Utils.cs b/bindings/dotnet/UnicornSamples/Utils.cs index 1f4d287a..aff34d50 100644 --- a/bindings/dotnet/UnicornSamples/Utils.cs +++ b/bindings/dotnet/UnicornSamples/Utils.cs @@ -1,45 +1,41 @@ -using Gee.External.Capstone; -using Gee.External.Capstone.X86; +using Gee.External.Capstone.X86; using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace UnicornSamples { internal static class Utils { - public static Int64 ToInt(Byte[] val) + public static long ToInt(byte[] val) { - UInt64 res = 0; + ulong res = 0; for (var i = 0; i < val.Length; i++) { var v = val[i] & 0xFF; - res += (UInt64)(v << (i * 8)); + res += (ulong)(v << (i * 8)); } - return (Int64)res; + return (long)res; } - public static Byte[] Int64ToBytes(Int64 intVal) + public static byte[] Int64ToBytes(long intVal) { - var res = new Byte[8]; - var uval = (UInt64)intVal; + var res = new byte[8]; + var uval = (ulong)intVal; for (var i = 0; i < res.Length; i++) { - res[i] = (Byte)(uval & 0xff); + res[i] = (byte)(uval & 0xff); uval = uval >> 8; } return res; } - public static String Disassemble(CapstoneDisassembler disassembler, Byte[] code) + public static string Disassemble(CapstoneX86Disassembler disassembler, byte[] code) { var sb = new StringBuilder(); - var instructions = disassembler.DisassembleAll(code); + var instructions = disassembler.Disassemble(code); foreach (var instruction in instructions) { - sb.AppendFormat("{0} {1}{2}", instruction.Mnemonic, instruction.Operand, Environment.NewLine); + sb.AppendFormat($"{instruction.Mnemonic} {instruction.Operand}{Environment.NewLine}"); } return sb.ToString().Trim(); } diff --git a/bindings/dotnet/UnicornSamples/X86Sample32.cs b/bindings/dotnet/UnicornSamples/X86Sample32.cs index 6bcd8309..24333839 100644 --- a/bindings/dotnet/UnicornSamples/X86Sample32.cs +++ b/bindings/dotnet/UnicornSamples/X86Sample32.cs @@ -1,34 +1,30 @@ using Gee.External.Capstone; using Gee.External.Capstone.X86; using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Reflection; using System.Text; -using System.Threading.Tasks; using UnicornManaged; using UnicornManaged.Const; namespace UnicornSamples { - internal class X86Sample32 + internal static class X86Sample32 { - private const Int64 ADDRESS = 0x1000000; + private const long ADDRESS = 0x1000000; public static void X86Code32() { - Byte[] X86_CODE32 = + byte[] X86_CODE32 = { // INC ecx; DEC edx 0x41, 0x4a }; Run(X86_CODE32); } - + public static void X86Code32InvalidMemRead() { - Byte[] X86_CODE32_MEM_READ = + byte[] X86_CODE32_MEM_READ = { // mov ecx,[0xaaaaaaaa]; INC ecx; DEC edx 0x8B, 0x0D, 0xAA, 0xAA, 0xAA, 0xAA, 0x41, 0x4a @@ -38,7 +34,7 @@ namespace UnicornSamples public static void X86Code32InvalidMemWriteWithRuntimeFix() { - Byte[] X86_CODE32_MEM_WRITE = + byte[] X86_CODE32_MEM_WRITE = { // mov [0xaaaaaaaa], ecx; INC ecx; DEC edx 0x89, 0x0D, 0xAA, 0xAA, 0xAA, 0xAA, 0x41, 0x4a @@ -48,7 +44,7 @@ namespace UnicornSamples public static void X86Code32InOut() { - Byte[] X86_CODE32_INOUT = + byte[] X86_CODE32_INOUT = { // INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx 0x41, 0xE4, 0x3F, 0x4a, 0xE6, 0x46, 0x43 @@ -57,14 +53,14 @@ namespace UnicornSamples } - private static void Run(Byte[] code, Boolean raiseException = false) + private static void Run(byte[] code, bool raiseException = false) { Console.WriteLine(); var stackTrace = new StackTrace(); var stackFrame = stackTrace.GetFrames()[1]; - var methodName = stackFrame.GetMethod().Name; + var methodName = stackFrame.GetMethod()?.Name; - Console.WriteLine("*** Start: " + methodName); + Console.WriteLine($"*** Start: {methodName}"); Exception e = null; try { @@ -84,93 +80,88 @@ namespace UnicornSamples Console.WriteLine(); } - private static void RunTest(Byte[] code, Int64 address, Int32 mode) + private static void RunTest(byte[] code, long address, int mode) { - using (var u = new Unicorn(Common.UC_ARCH_X86, mode)) - using (var disassembler = CapstoneDisassembler.CreateX86Disassembler(DisassembleMode.Bit32)) - { - Console.WriteLine("Unicorn version: {0}", u.Version()); + using var u = new Unicorn(Common.UC_ARCH_X86, mode); + using var disassembler = CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit32); + Console.WriteLine($"Unicorn version: {u.Version()}"); - // map 2MB of memory for this emulation - u.MemMap(address, 2 * 1024 * 1024, Common.UC_PROT_ALL); + // map 2MB of memory for this emulation + u.MemMap(address, 2 * 1024 * 1024, Common.UC_PROT_ALL); - // initialize machine registers - u.RegWrite(X86.UC_X86_REG_EAX, 0x1234); - u.RegWrite(X86.UC_X86_REG_ECX, 0x1234); - u.RegWrite(X86.UC_X86_REG_EDX, 0x7890); + // initialize machine registers + u.RegWrite(X86.UC_X86_REG_EAX, 0x1234); + u.RegWrite(X86.UC_X86_REG_ECX, 0x1234); + u.RegWrite(X86.UC_X86_REG_EDX, 0x7890); - // write machine code to be emulated to memory - u.MemWrite(address, code); + // write machine code to be emulated to memory + u.MemWrite(address, code); - // initialize machine registers - u.RegWrite(X86.UC_X86_REG_ESP, Utils.Int64ToBytes(address + 0x200000)); + // initialize machine registers + u.RegWrite(X86.UC_X86_REG_ESP, Utils.Int64ToBytes(address + 0x200000)); - // handle IN & OUT instruction - u.AddInHook(InHookCallback); - u.AddOutHook(OutHookCallback); + // handle IN & OUT instruction + u.AddInHook(InHookCallback); + u.AddOutHook(OutHookCallback); - // tracing all instructions by having @begin > @end - u.AddCodeHook((uc, addr, size, userData) => CodeHookCallback(disassembler, uc, addr, size, userData), 1, 0); + // tracing all instructions by having @begin > @end + u.AddCodeHook((uc, addr, size, userData) => CodeHookCallback(disassembler, uc, addr, size, userData), 1, 0); - // handle interrupt ourself - u.AddInterruptHook(InterruptHookCallback); + // handle interrupt ourself + u.AddInterruptHook(InterruptHookCallback); - // handle SYSCALL - u.AddSyscallHook(SyscallHookCallback); + // handle SYSCALL + u.AddSyscallHook(SyscallHookCallback); - // intercept invalid memory events - u.AddEventMemHook(MemMapHookCallback, Common.UC_HOOK_MEM_READ_UNMAPPED | Common.UC_HOOK_MEM_WRITE_UNMAPPED); + // intercept invalid memory events + u.AddEventMemHook(MemMapHookCallback, Common.UC_HOOK_MEM_READ_UNMAPPED | Common.UC_HOOK_MEM_WRITE_UNMAPPED); - Console.WriteLine(">>> Start tracing code"); + Console.WriteLine(">>> Start tracing code"); - // emulate machine code in infinite time - u.EmuStart(address, address + code.Length, 0u, 0u); + // emulate machine code in infinite time + u.EmuStart(address, address + code.Length, 0u, 0u); - // print registers - var ecx = u.RegRead(X86.UC_X86_REG_ECX); - var edx = u.RegRead(X86.UC_X86_REG_EDX); - var eax = u.RegRead(X86.UC_X86_REG_EAX); - Console.WriteLine("[!] EAX = {0}", eax.ToString("X")); - Console.WriteLine("[!] ECX = {0}", ecx.ToString("X")); - Console.WriteLine("[!] EDX = {0}", edx.ToString("X")); + // print registers + var ecx = u.RegRead(X86.UC_X86_REG_ECX); + var edx = u.RegRead(X86.UC_X86_REG_EDX); + var eax = u.RegRead(X86.UC_X86_REG_EAX); + Console.WriteLine($"[!] EAX = {eax:X}"); + Console.WriteLine($"[!] ECX = {ecx:X}"); + Console.WriteLine($"[!] EDX = {edx:X}"); - Console.WriteLine(">>> Emulation Done!"); - } + Console.WriteLine(">>> Emulation Done!"); } - private static Int32 InHookCallback(Unicorn u, Int32 port, Int32 size, Object userData) + private static int InHookCallback(Unicorn u, int port, int size, object userData) { - var eip = u.RegRead(X86.UC_X86_REG_EIP); - Console.WriteLine("[!] Reading from port 0x{0}, size: {1}, address: 0x{2}", port.ToString("X"), size.ToString("X"), eip.ToString("X")); - var res = 0; - switch (size) + var eip = u.RegRead(X86.UC_X86_REG_EIP); + Console.WriteLine($"[!] Reading from port 0x{port:X}, size: {size:X}, address: 0x{eip:X}"); + var res = size switch { - case 1: + 1 => // read 1 byte to AL - res = 0xf1; - break; - case 2: + 0xf1, + 2 => // read 2 byte to AX - res = 0xf2; - break; - case 4: + 0xf2, + 4 => // read 4 byte to EAX - res = 0xf4; - break; - } + 0xf4, + _ => 0 + }; - Console.WriteLine("[!] Return value: {0}", res.ToString("X")); + Console.WriteLine($"[!] Return value: {res:X}"); return res; } - private static void OutHookCallback(Unicorn u, Int32 port, Int32 size, Int32 value, Object userData) + private static void OutHookCallback(Unicorn u, int port, int size, int value, object userData) { var eip = u.RegRead(X86.UC_X86_REG_EIP); - Console.WriteLine("[!] Writing to port 0x{0}, size: {1}, value: 0x{2}, address: 0x{3}", port.ToString("X"), size.ToString("X"), value.ToString("X"), eip.ToString("X")); + Console.WriteLine($"[!] Writing to port 0x{port:X}, size: {size:X}, value: 0x{value:X}, address: 0x{eip:X}"); // confirm that value is indeed the value of AL/ AX / EAX var v = 0L; - var regName = String.Empty; + var regName = string.Empty; switch (size) { case 1: @@ -190,85 +181,81 @@ namespace UnicornSamples break; } - Console.WriteLine("[!] Register {0}: {1}", regName, v.ToString("X")); + Console.WriteLine("[!] Register {0}: {1:X}", regName, v); } - private static Boolean MemMapHookCallback(Unicorn u, Int32 eventType, Int64 address, Int32 size, Int64 value, Object userData) + private static bool MemMapHookCallback(Unicorn u, int eventType, long address, int size, long value, object userData) { - if (eventType == Common.UC_MEM_WRITE_UNMAPPED) - { - Console.WriteLine("[!] Missing memory is being WRITE at 0x{0}, data size = {1}, data value = 0x{2}. Map memory.", address.ToString("X"), size.ToString("X"), value.ToString("X")); - u.MemMap(0xaaaa0000, 2 * 1024 * 1024, Common.UC_PROT_ALL); - return true; - } - else - { - return false; - } + if (eventType != Common.UC_MEM_WRITE_UNMAPPED) return false; + + Console.WriteLine($"[!] Missing memory is being WRITE at 0x{address:X}, data size = {size:X}, data value = 0x{value:X}. Map memory."); + u.MemMap(0xaaaa0000, 2 * 1024 * 1024, Common.UC_PROT_ALL); + + return true; } private static void CodeHookCallback1( - CapstoneDisassembler disassembler, + CapstoneX86Disassembler disassembler, Unicorn u, - Int64 addr, - Int32 size, - Object userData) + long addr, + int size, + object userData) { - Console.Write("[+] 0x{0}: ", addr.ToString("X")); + Console.Write($"[+] 0x{addr:X}: "); - var eipBuffer = new Byte[4]; + var eipBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EIP, eipBuffer); var effectiveSize = Math.Min(16, size); - var tmp = new Byte[effectiveSize]; + var tmp = new byte[effectiveSize]; u.MemRead(addr, tmp); var sb = new StringBuilder(); foreach (var t in tmp) { - sb.AppendFormat("{0} ", (0xFF & t).ToString("X")); + sb.AppendFormat($"{(0xFF & t):X} "); } - Console.Write("{0,-20}", sb); + Console.Write($"{sb,-20}"); Console.WriteLine(Utils.Disassemble(disassembler, tmp)); } private static void CodeHookCallback( - CapstoneDisassembler disassembler, + CapstoneX86Disassembler disassembler, Unicorn u, - Int64 addr, - Int32 size, - Object userData) + long addr, + int size, + object userData) { - Console.Write("[+] 0x{0}: ", addr.ToString("X")); + Console.Write($"[+] 0x{addr:X}: "); - var eipBuffer = new Byte[4]; + var eipBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EIP, eipBuffer); var effectiveSize = Math.Min(16, size); - var tmp = new Byte[effectiveSize]; + var tmp = new byte[effectiveSize]; u.MemRead(addr, tmp); var sb = new StringBuilder(); foreach (var t in tmp) { - sb.AppendFormat("{0} ", (0xFF & t).ToString("X")); + sb.AppendFormat($"{(0xFF & t):X} "); } - Console.Write("{0,-20}", sb); + Console.Write($"{sb,-20}"); Console.WriteLine(Utils.Disassemble(disassembler, tmp)); } - private static void SyscallHookCallback(Unicorn u, Object userData) + private static void SyscallHookCallback(Unicorn u, object userData) { - var eaxBuffer = new Byte[4]; + var eaxBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EAX, eaxBuffer); var eax = Utils.ToInt(eaxBuffer); - Console.WriteLine("[!] Syscall EAX = 0x{0}", eax.ToString("X")); + Console.WriteLine($"[!] Syscall EAX = 0x{eax:X}"); u.EmuStop(); } - private static void InterruptHookCallback(Unicorn u, Int32 intNumber, Object userData) + private static void InterruptHookCallback(Unicorn u, int intNumber, object userData) { // only handle Linux syscall if (intNumber != 0x80) @@ -276,8 +263,8 @@ namespace UnicornSamples return; } - var eaxBuffer = new Byte[4]; - var eipBuffer = new Byte[4]; + var eaxBuffer = new byte[4]; + var eipBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_EAX, eaxBuffer); u.RegRead(X86.UC_X86_REG_EIP, eipBuffer); @@ -288,19 +275,19 @@ namespace UnicornSamples switch (eax) { default: - Console.WriteLine("[!] Interrupt 0x{0} num {1}, EAX=0x{2}", eip.ToString("X"), intNumber.ToString("X"), eax.ToString("X")); + Console.WriteLine($"[!] Interrupt 0x{eip:X} num {intNumber:X}, EAX=0x{eax:X}"); break; case 1: // sys_exit - Console.WriteLine("[!] Interrupt 0x{0} num {1}, SYS_EXIT", eip.ToString("X"), intNumber.ToString("X")); + Console.WriteLine($"[!] Interrupt 0x{eip:X} num {intNumber:X}, SYS_EXIT"); u.EmuStop(); break; case 4: // sys_write // ECX = buffer address - var ecxBuffer = new Byte[4]; + var ecxBuffer = new byte[4]; // EDX = buffer size - var edxBuffer = new Byte[4]; + var edxBuffer = new byte[4]; u.RegRead(X86.UC_X86_REG_ECX, ecxBuffer); u.RegRead(X86.UC_X86_REG_EDX, edxBuffer); @@ -310,16 +297,11 @@ namespace UnicornSamples // read the buffer in var size = Math.Min(256, edx); - var buffer = new Byte[size]; + var buffer = new byte[size]; u.MemRead(ecx, buffer); var content = Encoding.Default.GetString(buffer); - Console.WriteLine( - "[!] Interrupt 0x{0}: num {1}, SYS_WRITE. buffer = 0x{2}, size = , content = '{3}'", - eip.ToString("X"), - ecx.ToString("X"), - edx.ToString("X"), - content); + Console.WriteLine($"[!] Interrupt 0x{eip:X}: num {ecx:X}, SYS_WRITE. buffer = 0x{edx:X}, size = {size:X}, content = '{content}'"); break; } diff --git a/bindings/dotnet/UnicornSamples/packages.config b/bindings/dotnet/UnicornSamples/packages.config deleted file mode 100644 index d4215eec..00000000 --- a/bindings/dotnet/UnicornSamples/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file From b1af49f72b5197e35fb5d35d6fbcfc0c4e0175a7 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Fri, 14 Oct 2022 17:16:57 +0200 Subject: [PATCH 2/4] dotnet: Adapt README.md to recent changes --- bindings/dotnet/README.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/bindings/dotnet/README.md b/bindings/dotnet/README.md index 77171645..e299649a 100644 --- a/bindings/dotnet/README.md +++ b/bindings/dotnet/README.md @@ -7,15 +7,19 @@ from source. 1. Compile the code - [Windows] - To compile the code open the UnicornSln.sln with Microsoft Visual - Studio 12 or with a newer version and just press Ctrl+Shift+B to build - the solution. - - You need to have installed at least version 4.5 of the .NET framework. - - [Linux] - TODO + You need to have at least version 5.0 of .NET installed. + + 1. Windows + + To compile the code open the UnicornSln.sln with Microsoft Visual + Studio 12 or with a newer version and just press Ctrl+Shift+B to build + the solution. + + 2. Linux + + To compile the code open a terminal in this directory + and enter the following command to build the solution: + `dotnet build` 2. Usage From 0522f728b6561ed65e5e86483b769464dbc5d0c0 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Thu, 20 Oct 2022 20:35:18 +0200 Subject: [PATCH 3/4] dotnet: Remove faulty property groups --- .../UnicornManaged/UnicornManaged.fsproj | 14 -------------- .../UnicornSamples/UnicornSamples.csproj | 18 ------------------ 2 files changed, 32 deletions(-) diff --git a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj index 864e4e96..2b076296 100644 --- a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj +++ b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj @@ -15,20 +15,6 @@ 3 - - true - full - false - false - DEBUG;TRACE - - - pdbonly - true - true - TRACE - - diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index d7464c04..37239526 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -8,7 +8,6 @@ https://github.com/unicorn-engine/unicorn 2.0.0 {B80B5987-1E24-4309-8BF9-C4F91270F21C} - true @@ -16,23 +15,6 @@ prompt 4 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - false - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - From 040146e059137a42b43475b31b67a15f3bc4ffcb Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Thu, 20 Oct 2022 21:31:46 +0200 Subject: [PATCH 4/4] dotnet: Target .NET 6.0 --- bindings/dotnet/UnicornManaged/UnicornManaged.fsproj | 2 +- bindings/dotnet/UnicornSamples/UnicornSamples.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj index 2b076296..1a66562a 100644 --- a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj +++ b/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 UnicornManaged UnicornManaged Copyright © Antonio Parata 2016 diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index 37239526..bd603441 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 Exe UnicornSamples UnicornSamples @@ -26,4 +26,4 @@ - \ No newline at end of file +