From 1d12e8778bde982b6456efaabefa239d48d95096 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 22:56:44 +0100 Subject: [PATCH 01/35] bindings: Rename dotnet project to UnicornEngine Add a few more properties to prepare a nuget package --- bindings/const_generator.py | 4 ++-- bindings/dotnet/UnicornDotNet.sln | 2 +- .../Binding/BindingFactory.fs | 2 +- .../Binding/IBinding.fs | 2 +- .../Binding/MockBinding.fs | 2 +- .../Binding/NativeBinding.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Arm.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Arm64.fs | 2 +- .../Const/Common.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/M68k.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Mips.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Ppc.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Riscv.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/S390x.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Sparc.fs | 2 +- .../Const/TriCore.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/X86.fs | 2 +- .../ConvertUtility.fs | 2 +- .../InternalHooks.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Unicorn.fs | 6 +++--- .../UnicornEngine.fsproj} | 12 +++++++++--- .../UnicornEngineException.fs | 2 +- bindings/dotnet/UnicornSamples/ShellcodeSample.cs | 4 ++-- bindings/dotnet/UnicornSamples/UnicornSamples.csproj | 4 ++-- bindings/dotnet/UnicornSamples/X86Sample32.cs | 4 ++-- 25 files changed, 39 insertions(+), 33 deletions(-) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/BindingFactory.fs (84%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/IBinding.fs (97%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/MockBinding.fs (98%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/NativeBinding.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Arm.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Arm64.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Common.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/M68k.fs (97%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Mips.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Ppc.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Riscv.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/S390x.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Sparc.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/TriCore.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/X86.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/ConvertUtility.fs (94%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/InternalHooks.fs (98%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Unicorn.fs (99%) rename bindings/dotnet/{UnicornManaged/UnicornManaged.fsproj => UnicornEngine/UnicornEngine.fsproj} (79%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/UnicornEngineException.fs (83%) diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 2a74c864..6d529630 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -90,10 +90,10 @@ template = { 'comment_close': '', }, 'dotnet': { - 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\nnamespace UnicornManaged.Const\n\nopen System\n\n[]\nmodule %s =\n", + 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\nnamespace UnicornEngine.Const\n\nopen System\n\n[]\nmodule %s =\n", 'footer': "\n", 'line_format': ' let UC_%s = %s\n', - 'out_file': os.path.join('dotnet', 'UnicornManaged', 'Const', '%s.fs'), + 'out_file': os.path.join('dotnet', 'UnicornEngine', 'Const', '%s.fs'), # prefixes for constant filenames of all archs - case sensitive 'arm.h': 'Arm', 'arm64.h': 'Arm64', diff --git a/bindings/dotnet/UnicornDotNet.sln b/bindings/dotnet/UnicornDotNet.sln index 90aa5b60..abe168e9 100644 --- a/bindings/dotnet/UnicornDotNet.sln +++ b/bindings/dotnet/UnicornDotNet.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnicornSamples", "UnicornSamples\UnicornSamples.csproj", "{B80B5987-1E24-4309-8BF9-C4F91270F21C}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UnicornManaged", "UnicornManaged\UnicornManaged.fsproj", "{0C21F1C1-2725-4A46-9022-1905F85822A5}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UnicornEngine", "UnicornEngine\UnicornEngine.fsproj", "{0C21F1C1-2725-4A46-9022-1905F85822A5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs b/bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs similarity index 84% rename from bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs rename to bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs index 6ea0b183..30c7f821 100644 --- a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs +++ b/bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding module BindingFactory = diff --git a/bindings/dotnet/UnicornManaged/Binding/IBinding.fs b/bindings/dotnet/UnicornEngine/Binding/IBinding.fs similarity index 97% rename from bindings/dotnet/UnicornManaged/Binding/IBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/IBinding.fs index 7ef6d279..b6c3edc0 100644 --- a/bindings/dotnet/UnicornManaged/Binding/IBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/IBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System diff --git a/bindings/dotnet/UnicornManaged/Binding/MockBinding.fs b/bindings/dotnet/UnicornEngine/Binding/MockBinding.fs similarity index 98% rename from bindings/dotnet/UnicornManaged/Binding/MockBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/MockBinding.fs index 7b99c8e5..3eeefe89 100644 --- a/bindings/dotnet/UnicornManaged/Binding/MockBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/MockBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System diff --git a/bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs index 6be7b2f3..efaccc48 100644 --- a/bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System open System.Runtime.InteropServices diff --git a/bindings/dotnet/UnicornManaged/Const/Arm.fs b/bindings/dotnet/UnicornEngine/Const/Arm.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Arm.fs rename to bindings/dotnet/UnicornEngine/Const/Arm.fs index 08766baf..8a275261 100644 --- a/bindings/dotnet/UnicornManaged/Const/Arm.fs +++ b/bindings/dotnet/UnicornEngine/Const/Arm.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Arm64.fs b/bindings/dotnet/UnicornEngine/Const/Arm64.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Arm64.fs rename to bindings/dotnet/UnicornEngine/Const/Arm64.fs index 4c509d03..9e9878a7 100644 --- a/bindings/dotnet/UnicornManaged/Const/Arm64.fs +++ b/bindings/dotnet/UnicornEngine/Const/Arm64.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornEngine/Const/Common.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Common.fs rename to bindings/dotnet/UnicornEngine/Const/Common.fs index 72b5cb3a..73f9663c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornEngine/Const/Common.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/M68k.fs b/bindings/dotnet/UnicornEngine/Const/M68k.fs similarity index 97% rename from bindings/dotnet/UnicornManaged/Const/M68k.fs rename to bindings/dotnet/UnicornEngine/Const/M68k.fs index b9189d2d..768bc12b 100644 --- a/bindings/dotnet/UnicornManaged/Const/M68k.fs +++ b/bindings/dotnet/UnicornEngine/Const/M68k.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Mips.fs b/bindings/dotnet/UnicornEngine/Const/Mips.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Mips.fs rename to bindings/dotnet/UnicornEngine/Const/Mips.fs index 7f85a0cf..d4818783 100644 --- a/bindings/dotnet/UnicornManaged/Const/Mips.fs +++ b/bindings/dotnet/UnicornEngine/Const/Mips.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Ppc.fs b/bindings/dotnet/UnicornEngine/Const/Ppc.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Ppc.fs rename to bindings/dotnet/UnicornEngine/Const/Ppc.fs index 1727c157..54a18b3b 100644 --- a/bindings/dotnet/UnicornManaged/Const/Ppc.fs +++ b/bindings/dotnet/UnicornEngine/Const/Ppc.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Riscv.fs b/bindings/dotnet/UnicornEngine/Const/Riscv.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Riscv.fs rename to bindings/dotnet/UnicornEngine/Const/Riscv.fs index bf578024..fe61ec2c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Riscv.fs +++ b/bindings/dotnet/UnicornEngine/Const/Riscv.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/S390x.fs b/bindings/dotnet/UnicornEngine/Const/S390x.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/S390x.fs rename to bindings/dotnet/UnicornEngine/Const/S390x.fs index 97f7ec4b..c4bd76e6 100644 --- a/bindings/dotnet/UnicornManaged/Const/S390x.fs +++ b/bindings/dotnet/UnicornEngine/Const/S390x.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Sparc.fs b/bindings/dotnet/UnicornEngine/Const/Sparc.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Sparc.fs rename to bindings/dotnet/UnicornEngine/Const/Sparc.fs index 8eb8cc23..8350af5c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Sparc.fs +++ b/bindings/dotnet/UnicornEngine/Const/Sparc.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/TriCore.fs b/bindings/dotnet/UnicornEngine/Const/TriCore.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/TriCore.fs rename to bindings/dotnet/UnicornEngine/Const/TriCore.fs index 0c82fb97..b2c78e2e 100644 --- a/bindings/dotnet/UnicornManaged/Const/TriCore.fs +++ b/bindings/dotnet/UnicornEngine/Const/TriCore.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/X86.fs b/bindings/dotnet/UnicornEngine/Const/X86.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/X86.fs rename to bindings/dotnet/UnicornEngine/Const/X86.fs index 8d2fd5b3..5e115b9e 100644 --- a/bindings/dotnet/UnicornManaged/Const/X86.fs +++ b/bindings/dotnet/UnicornEngine/Const/X86.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/ConvertUtility.fs b/bindings/dotnet/UnicornEngine/ConvertUtility.fs similarity index 94% rename from bindings/dotnet/UnicornManaged/ConvertUtility.fs rename to bindings/dotnet/UnicornEngine/ConvertUtility.fs index 5e455bf7..a453c861 100644 --- a/bindings/dotnet/UnicornManaged/ConvertUtility.fs +++ b/bindings/dotnet/UnicornEngine/ConvertUtility.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System diff --git a/bindings/dotnet/UnicornManaged/InternalHooks.fs b/bindings/dotnet/UnicornEngine/InternalHooks.fs similarity index 98% rename from bindings/dotnet/UnicornManaged/InternalHooks.fs rename to bindings/dotnet/UnicornEngine/InternalHooks.fs index 36cfc3ce..d9e87954 100644 --- a/bindings/dotnet/UnicornManaged/InternalHooks.fs +++ b/bindings/dotnet/UnicornEngine/InternalHooks.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System open System.Runtime.InteropServices diff --git a/bindings/dotnet/UnicornManaged/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Unicorn.fs rename to bindings/dotnet/UnicornEngine/Unicorn.fs index 31decbcd..7d401300 100644 --- a/bindings/dotnet/UnicornManaged/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -1,11 +1,11 @@ -namespace UnicornManaged +namespace UnicornEngine open System open System.Collections.Generic open System.Runtime.InteropServices open System.Linq -open UnicornManaged.Const -open UnicornManaged.Binding +open UnicornEngine.Const +open UnicornEngine.Binding // exported hooks type CodeHook = delegate of Unicorn * Int64 * Int32 * Object -> unit diff --git a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj similarity index 79% rename from bindings/dotnet/UnicornManaged/UnicornManaged.fsproj rename to bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index 1a66562a..c117557c 100644 --- a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -1,11 +1,13 @@  net6.0 - UnicornManaged - UnicornManaged + UnicornEngine.Unicorn + UnicornEngine Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn - 2.0.0 + .NET bindings for unicorn + 2.0.0 + $(VersionSuffix) 0c21f1c1-2725-4a46-9022-1905f85822a5 true true @@ -15,6 +17,10 @@ 3 + + none + + diff --git a/bindings/dotnet/UnicornManaged/UnicornEngineException.fs b/bindings/dotnet/UnicornEngine/UnicornEngineException.fs similarity index 83% rename from bindings/dotnet/UnicornManaged/UnicornEngineException.fs rename to bindings/dotnet/UnicornEngine/UnicornEngineException.fs index fd582557..68622951 100644 --- a/bindings/dotnet/UnicornManaged/UnicornEngineException.fs +++ b/bindings/dotnet/UnicornEngine/UnicornEngineException.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System diff --git a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs index 7982e5e4..08ab59b1 100644 --- a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs +++ b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs @@ -3,8 +3,8 @@ using Gee.External.Capstone.X86; using System; using System.Diagnostics; using System.Text; -using UnicornManaged; -using UnicornManaged.Const; +using UnicornEngine; +using UnicornEngine.Const; namespace UnicornSamples { diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index bd603441..4ba2d49e 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -17,9 +17,9 @@ - + {0c21f1c1-2725-4a46-9022-1905f85822a5} - UnicornManaged + UnicornEngine diff --git a/bindings/dotnet/UnicornSamples/X86Sample32.cs b/bindings/dotnet/UnicornSamples/X86Sample32.cs index 24333839..bff69e79 100644 --- a/bindings/dotnet/UnicornSamples/X86Sample32.cs +++ b/bindings/dotnet/UnicornSamples/X86Sample32.cs @@ -3,8 +3,8 @@ using Gee.External.Capstone.X86; using System; using System.Diagnostics; using System.Text; -using UnicornManaged; -using UnicornManaged.Const; +using UnicornEngine; +using UnicornEngine.Const; namespace UnicornSamples { From 9928600584a51855e8c6f8bcfc6a7dc86aa2d1ba Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:43:04 +0100 Subject: [PATCH 02/35] gh: Publish Nuget for dotnet bindings --- .github/workflows/Nuget-publishing.yml | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/Nuget-publishing.yml diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml new file mode 100644 index 00000000..dfc6cd25 --- /dev/null +++ b/.github/workflows/Nuget-publishing.yml @@ -0,0 +1,51 @@ +name: Nuget 📦 Distribution + +on: + push: + branches: + - dev + - master + paths-ignore: + - ".gitignore" + - "docs/**" + - "README" + - "CREDITS.TXT" + - "COPYING_GLIB" + - "COPYING.LGPL2" + - "AUTHORS.TXT" + - "CHANGELOG" + - "COPYING" + +permissions: + packages: write + +jobs: + publish: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: bindings/dotnet/UnicornEngine + + steps: + - uses: actions/checkout@v3 + + - name: Get short sha + id: git_short_sha + run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + + - uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.x + + - name: Authenticate to Github Packages + run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" + + - name: Package .NET bindings + run: | + [[ "${{ github.ref_name }}" == "master" ]] \ + && dotnet pack -c Release \ + || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" + + - name: 📦 Publish to Github Packages + run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" From 5d41b3346f71f04933945a68864c70a478e69c32 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:50:53 +0100 Subject: [PATCH 03/35] gh: Publish new packages if bindings get modified --- .github/workflows/Nuget-publishing.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index dfc6cd25..463245db 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -5,16 +5,8 @@ on: branches: - dev - master - paths-ignore: - - ".gitignore" - - "docs/**" - - "README" - - "CREDITS.TXT" - - "COPYING_GLIB" - - "COPYING.LGPL2" - - "AUTHORS.TXT" - - "CHANGELOG" - - "COPYING" + paths: + - "bindings/dotnet/UnicornEngine/**" permissions: packages: write From 2e6a88805215a663250756e3ae5513635dcf369c Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 02:40:50 +0100 Subject: [PATCH 04/35] dotnet: Add native unicorn libraries to nuget package --- .github/workflows/Nuget-publishing.yml | 102 +++++++++++++++++- .../dotnet/UnicornEngine/UnicornEngine.fsproj | 4 + 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 463245db..ce5450bb 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -1,18 +1,21 @@ name: Nuget 📦 Distribution on: - push: + workflow_run: + workflows: + - "Build UC2" + types: + - completed branches: - dev - master - paths: - - "bindings/dotnet/UnicornEngine/**" permissions: packages: write jobs: publish: + if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest defaults: @@ -21,10 +24,99 @@ jobs: steps: - uses: actions/checkout@v3 + with: + ref: ${{ github.event.workflow_run.head_branch }} + + - name: 'Download and extract artifacts' + uses: actions/github-script@v6 + with: + script: | + let fs = require('fs'); + const options = {}; + options.cwd = './bindings/dotnet/UnicornEngine'; + + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + + let sourceDir = ""; + let sourceFile = ""; + let destDir = ""; + let destFile = ""; + for (const artifact of allArtifacts.data.artifacts) { + switch(artifact.name) { + case 'ubuntu-cmake-aarch64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-arm64/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-ppc64le.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-ppc64le/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-shared-x64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-x64/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-shared-x86.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-x86/native"; + destFile = "libunicorn.so"; + break; + case 'macos-cmake-shared-x64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.*.dylib"; + destDir = "runtimes/osx-x64/native"; + destFile = "libunicorn.dylib"; + break; + case 'windows_msvc64_shared.7z': + sourceDir = ""; + sourceFile = "unicorn.dll"; + destDir = "runtimes/win-x64/native"; + destFile = "unicorn.dll"; + break; + case 'windows_msvc32_shared.7z': + sourceDir = ""; + sourceFile = "unicorn.dll"; + destDir = "runtimes/win-x86/native"; + destFile = "unicorn.dll"; + break; + default: + continue; + } + console.log(`Creating destination directory: ${destDir}`); + await exec.exec("mkdir", ["-p", destDir], options); + + console.log(`Downloading artifact: ${artifact.name}.zip`); + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + fs.writeFileSync(`/tmp/${artifact.name}.zip`, Buffer.from(download.data)); + + console.log(`Unzipping: /tmp/${artifact.name}.zip`); + await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); + console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); + await exec.exec("7z", ["e", "-o", destDir, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + if (sourceFile != destFile) { + console.log(`Renaming library to: ${destFile}`); + await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); + } + } - name: Get short sha id: git_short_sha - run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + run: echo "result=$(git rev-parse --short "${{ github.event.workflow_run.head_sha }}")" >> $GITHUB_OUTPUT - uses: actions/setup-dotnet@v3 with: @@ -35,7 +127,7 @@ jobs: - name: Package .NET bindings run: | - [[ "${{ github.ref_name }}" == "master" ]] \ + [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" diff --git a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index c117557c..f2142473 100644 --- a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -42,4 +42,8 @@ + + + + From a810da70950363110650c6eb2101db231ae714b4 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 02:56:31 +0100 Subject: [PATCH 05/35] gha: List all native libs before packing .Net distribution --- .github/workflows/Nuget-publishing.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index ce5450bb..420a7026 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -27,7 +27,7 @@ jobs: with: ref: ${{ github.event.workflow_run.head_branch }} - - name: 'Download and extract artifacts' + - name: Download and extract artifacts uses: actions/github-script@v6 with: script: | @@ -125,7 +125,10 @@ jobs: - name: Authenticate to Github Packages run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - - name: Package .NET bindings + - name: List all native libraries + run: find ./runtimes -type f -print + + - name: Package .NET distribution run: | [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ From 9bb45741b032a98677580a65204c0dbc9d2cbb53 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 03:38:27 +0100 Subject: [PATCH 06/35] gha: Fix 7zip extraction arguments --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 420a7026..604dc778 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -107,7 +107,7 @@ jobs: console.log(`Unzipping: /tmp/${artifact.name}.zip`); await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); - await exec.exec("7z", ["e", "-o", destDir, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + await exec.exec("7z", ["e", `-o${destDir}`, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { console.log(`Renaming library to: ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); From 8275b05ff40f53876302850064340f8a38f1ff44 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 14:29:23 +0100 Subject: [PATCH 07/35] gha: Try to fix 7zip extraction errors --- .github/workflows/Nuget-publishing.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 604dc778..156f42ac 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -102,12 +102,12 @@ jobs: artifact_id: artifact.id, archive_format: 'zip', }); - fs.writeFileSync(`/tmp/${artifact.name}.zip`, Buffer.from(download.data)); + fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); - console.log(`Unzipping: /tmp/${artifact.name}.zip`); - await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); - console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); - await exec.exec("7z", ["e", `-o${destDir}`, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + console.log(`Unzipping: /home/runner/${artifact.name}.zip`); + await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`]); + console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); + await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { console.log(`Renaming library to: ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); From 331c11fea1b9d8052889fa673f4cf8e6eeec06f3 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 16:45:32 +0100 Subject: [PATCH 08/35] gha: Fix unzip extracting to the wrong directory --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 156f42ac..53e25218 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -105,7 +105,7 @@ jobs: fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); console.log(`Unzipping: /home/runner/${artifact.name}.zip`); - await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`]); + await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`, "-d", "/home/runner/"]); console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { From d5ea8f675000e70e4dfd9706418ffd0a385a653d Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 17:51:23 +0100 Subject: [PATCH 09/35] gha: Get correct file name before renaming --- .github/workflows/Nuget-publishing.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 53e25218..9aaff37e 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -45,6 +45,7 @@ jobs: let sourceFile = ""; let destDir = ""; let destFile = ""; + var output = {}; for (const artifact of allArtifacts.data.artifacts) { switch(artifact.name) { case 'ubuntu-cmake-aarch64.7z': @@ -109,7 +110,9 @@ jobs: console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { - console.log(`Renaming library to: ${destFile}`); + output = await exec.getExecOutput("ls", [destDir], options); + sourceFile = output.stdout.trim(); + console.log(`Renaming ${sourceFile} to ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); } } From dfea3f9e45d47419b5c94982452c7257392730bf Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Tue, 22 Nov 2022 17:48:54 +0100 Subject: [PATCH 10/35] nuget: Build native libraries in jobs --- .github/workflows/Nuget-publishing.yml | 486 ++++++++++++++++++++----- 1 file changed, 385 insertions(+), 101 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 9aaff37e..e0edb5f1 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -1,11 +1,17 @@ name: Nuget 📦 Distribution on: - workflow_run: - workflows: - - "Build UC2" - types: - - completed + push: + paths-ignore: + - ".gitignore" + - "docs/**" + - "README" + - "CREDITS.TXT" + - "COPYING_GLIB" + - "COPYING.LGPL2" + - "AUTHORS.TXT" + - "CHANGELOG" + - "COPYING" branches: - dev - master @@ -14,128 +20,406 @@ permissions: packages: write jobs: - publish: - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest + Windows: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} + strategy: + fail-fast: true + matrix: + config: + - { + os: windows-2019, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'windows-x64 MSVC 64bit shared', + msvc-arch: x64, + artifact: 'windows_msvc64_shared.7z', + shared: 'yes', + build_type: 'Release', + archiver: '7z a', + generators: 'Visual Studio 16 2019' + } + - { + os: windows-2019, + arch: x86, + python-arch: x86, + python-ver: '3.8', + name: 'windows-x86 MSVC 32bit shared', + msvc-arch: x86, + artifact: 'windows_msvc32_shared.7z', + shared: 'yes', + build_type: 'Release', + archiver: '7z a', + generators: 'Visual Studio 16 2019' + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 - defaults: - run: - working-directory: bindings/dotnet/UnicornEngine + - name: '🛠️ Win MSVC 64 setup' + if: contains(matrix.config.name, 'MSVC 64') + uses: microsoft/setup-msbuild@v1 + + - name: '🛠️ Win MSVC 64 dev cmd setup' + if: contains(matrix.config.name, 'MSVC 64') + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: '🚧 Win MSVC 64 build' + if: contains(matrix.config.name, 'MSVC 64') + shell: bash + run: | + choco install ninja cmake + ninja --version + cmake --version + mkdir build + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip --config ${{ matrix.config.build_type }} + ctest -VV -C ${{ matrix.config.build_type }} + mv Release instdir + + - name: '🛠️ Win MSVC 32 setup' + if: contains(matrix.config.name, 'MSVC 32') + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x86 + + - name: '🚧 Win MSVC 32 build' + if: contains(matrix.config.name, 'MSVC 32') + shell: bash + run: | + choco install ninja cmake + ninja --version + cmake --version + mkdir build + cmake \ + -S . \ + -B . \ + -A "win32" \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip --config ${{ matrix.config.build_type }} + ctest -VV -C ${{ matrix.config.build_type }} + mv Release instdir + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + Macos: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} - ${{ matrix.compiler }} + strategy: + fail-fast: true + matrix: + config: + - { + os: macos-latest, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'macos-x64 cmake shared', + shared: 'yes', + artifact: 'macos-cmake-shared-x64.7z', + build_type: 'Release', + archiver: '7za a', + generators: 'Ninja' + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 + + - name: '🚧 Mac build' + if: contains(matrix.config.name, 'macos-x64') + shell: bash + run: | + brew install p7zip cmake ninja + ninja --version + cmake --version + mkdir build + mkdir instdir + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + Linux: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} - ${{ matrix.compiler }} + strategy: + fail-fast: false + matrix: + config: + - { + os: ubuntu-latest, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'ubuntu-x64 cmake shared', + shared: 'yes', + artifact: 'ubuntu-cmake-shared-x64.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja' + } + - { + os: ubuntu-latest, + arch: x86, + python-arch: x86, + python-ver: '3.8', + name: 'ubuntu-x86 cmake shared', + shared: 'yes', + artifact: 'ubuntu-cmake-shared-x86.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja' + } + - { + os: ubuntu-latest, + arch: aarch64, + python-arch: aarch64, + python-ver: '3.8', + name: 'ubuntu-aarch64 cmake', + artifact: 'ubuntu-cmake-aarch64.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja', + distro: ubuntu20.04 + } + - { + os: ubuntu-latest, + arch: ppc64le, + python-arch: ppc, + python-ver: '3.8', + name: 'ubuntu-ppc64le cmake', + artifact: 'ubuntu-cmake-ppc64le.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja', + distro: ubuntu20.04 + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 + + - name: '🚧 Linux x64/x86 build' + if: contains(matrix.config.arch, 'x64') || contains(matrix.config.arch, 'x86') + shell: 'script -q -e -c "bash {0}"' + run: | + if [ ${{ matrix.config.arch }} == 'x64' ]; then + sudo apt install -q -y libcmocka-dev ninja-build + else + export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" + sudo dpkg --add-architecture i386 + sudo apt install -q -y lib32ncurses-dev lib32z1-dev lib32gcc-9-dev libc6-dev-i386 gcc-multilib \ + libcmocka-dev:i386 libcmocka0:i386 libc6:i386 libgcc-s1:i386 ninja-build + fi + mkdir build + mkdir instdir + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '🚧 Linux ppc64le/aarch64 build' + if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64') + uses: uraimo/run-on-arch-action@v2.0.5 + with: + arch: ${{ matrix.config.arch }} + distro: ${{ matrix.config.distro }} + setup: | + mkdir -p "${PWD}/instdir" + dockerRunArgs: | + --volume "${PWD}/instdir:/instdir" + shell: /bin/sh + install: | + apt-get update -q -y + apt-get install -q -y git cmake build-essential automake libcmocka-dev pkg-config ${{ matrix.compiler }} ninja-build + run: | + mkdir build + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=/instdir + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + publish: + needs: ["Windows", "Macos", "Linux"] + if: ${{ needs.Windows.result == 'success' && needs.Macos.result == 'success' && needs.Linux.result == 'success' }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - with: - ref: ${{ github.event.workflow_run.head_branch }} - - name: Download and extract artifacts - uses: actions/github-script@v6 + - name: Download artifacts + uses: actions/download-artifact@v3 with: - script: | - let fs = require('fs'); - const options = {}; - options.cwd = './bindings/dotnet/UnicornEngine'; - - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - let sourceDir = ""; - let sourceFile = ""; - let destDir = ""; - let destFile = ""; - var output = {}; - for (const artifact of allArtifacts.data.artifacts) { - switch(artifact.name) { - case 'ubuntu-cmake-aarch64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-arm64/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-ppc64le.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-ppc64le/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-shared-x64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-x64/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-shared-x86.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-x86/native"; - destFile = "libunicorn.so"; - break; - case 'macos-cmake-shared-x64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.*.dylib"; - destDir = "runtimes/osx-x64/native"; - destFile = "libunicorn.dylib"; - break; - case 'windows_msvc64_shared.7z': - sourceDir = ""; - sourceFile = "unicorn.dll"; - destDir = "runtimes/win-x64/native"; - destFile = "unicorn.dll"; - break; - case 'windows_msvc32_shared.7z': - sourceDir = ""; - sourceFile = "unicorn.dll"; - destDir = "runtimes/win-x86/native"; - destFile = "unicorn.dll"; - break; - default: - continue; - } - console.log(`Creating destination directory: ${destDir}`); - await exec.exec("mkdir", ["-p", destDir], options); - - console.log(`Downloading artifact: ${artifact.name}.zip`); - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); - - console.log(`Unzipping: /home/runner/${artifact.name}.zip`); - await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`, "-d", "/home/runner/"]); - console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); - await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); - if (sourceFile != destFile) { - output = await exec.getExecOutput("ls", [destDir], options); - sourceFile = output.stdout.trim(); - console.log(`Renaming ${sourceFile} to ${destFile}`); - await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); - } + path: artifacts + + - name: Extract artifacts + shell: python + run: | + import subprocess + import os + + artifactPath = os.path.join(os.getcwd(), "artifacts") + bindingsPath = os.path.join(os.getcwd(), "bindings", "dotnet", "UnicornEngine") + + ARTIFACT_CONFIG = { + "ubuntu-cmake-aarch64.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-arm64/native", + "destFile": "libunicorn.so" + }, + "ubuntu-cmake-ppc64le.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-ppc64le/native", + "destFile": "libunicorn.so" + }, + "ubuntu-cmake-shared-x86.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-x64/native", + "destFile": "libunicorn.so" + }, + "macos-cmake-shared-x64.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.*.dylib", + "destDir": "runtimes/osx-x64/native", + "destFile": "libunicorn.dylib" + }, + "windows_msvc64_shared.7z": { + "sourceDir": "", + "sourceFile": "unicorn.dll", + "destDir": "runtimes/win-x64/native", + "destFile": "unicorn.dll" + }, + "windows_msvc32_shared.7z": { + "sourceDir": "", + "sourceFile": "unicorn.dll", + "destDir": "runtimes/win-x86/native", + "destFile": "unicorn.dll" } + } + + if len(os.listdir(artifactPath)) < len(ARTIFACT_CONFIG.keys()): + print("Some artifacts are missing. Aborting.") + exit(1) + + for artifact in os.listdir(artifactPath): + if artifact in ARTIFACT_CONFIG.keys(): + print("Working on:", artifact) + config = ARTIFACT_CONFIG[artifact] + destDir = os.path.join(bindingsPath, config["destDir"]) + print("Creating dir:", destDir) + os.makedirs(destDir, exist_ok=True) + + print(f"Extracting library from 7z file to: {config['destDir']}/{config['sourceFile']}") + result = subprocess.run(["7z", "e", f"-o{destDir}/", os.path.join(artifactPath, artifact), f"{config['sourceDir']}{config['sourceFile']}"]) + result.check_returncode() + + if config["sourceFile"] != config["destFile"]: + output = subprocess.run(["ls", destDir], stdout=subprocess.PIPE) + sourceFile = output.stdout.decode().strip() + print(f"Renaming {sourceFile} to {config['destFile']}") + os.rename(os.path.join(destDir, sourceFile), os.path.join(destDir, config["destFile"])) + + print("Done!") - name: Get short sha id: git_short_sha - run: echo "result=$(git rev-parse --short "${{ github.event.workflow_run.head_sha }}")" >> $GITHUB_OUTPUT + run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT - uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.x - name: Authenticate to Github Packages + working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - name: List all native libraries + working-directory: bindings/dotnet/UnicornEngine run: find ./runtimes -type f -print - name: Package .NET distribution + working-directory: bindings/dotnet/UnicornEngine run: | [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" - name: 📦 Publish to Github Packages + working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" From 81baee2b1cd1443e986a4b19f7a404652c5a0ea0 Mon Sep 17 00:00:00 2001 From: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:24:53 +0100 Subject: [PATCH 11/35] gha: Fix master branch check --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index e0edb5f1..fe8b17de 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -416,7 +416,7 @@ jobs: - name: Package .NET distribution working-directory: bindings/dotnet/UnicornEngine run: | - [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ + [[ "${{ github.ref_name }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" From ca7449791101874ed72765f25da6e3e1e3869b0d Mon Sep 17 00:00:00 2001 From: deadash Date: Thu, 29 Dec 2022 14:43:54 +0800 Subject: [PATCH 12/35] Add arch list feature control in Rust Signed-off-by: deadash --- Cargo.toml | 15 +++++++++++++-- bindings/rust/build.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3d6d388d..46253df6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,5 +39,16 @@ cmake = { version = "0.1" } pkg-config = { version = "0.3" } [features] -default = [] -dynamic_linkage = [] \ No newline at end of file +default = ["arch_all"] +dynamic_linkage = [] +arch_all = ["arch_x86", "arch_arm", "arch_aarch64", "arch_riscv", "arch_mips", "arch_sparc", "arch_m68k", "arch_ppc", "arch_s390x", "arch_tricore"] +arch_x86 = [] +arch_arm = [] +arch_aarch64 = [] +arch_riscv = [] +arch_mips = [] +arch_sparc = [] +arch_m68k = [] +arch_ppc = [] +arch_s390x = [] +arch_tricore = [] \ No newline at end of file diff --git a/bindings/rust/build.rs b/bindings/rust/build.rs index 1f5e2251..04f5431a 100644 --- a/bindings/rust/build.rs +++ b/bindings/rust/build.rs @@ -84,6 +84,43 @@ fn build_with_cmake() { config.generator("Ninja"); } + let mut archs = String::new(); + + if std::env::var("CARGO_FEATURE_ARCH_X86").is_ok() { + archs.push_str("x86;"); + } + if std::env::var("CARGO_FEATURE_ARCH_ARM").is_ok() { + archs.push_str("arm;"); + } + if std::env::var("CARGO_FEATURE_ARCH_AARCH64").is_ok() { + archs.push_str("aarch64;"); + } + if std::env::var("CARGO_FEATURE_ARCH_RISCV").is_ok() { + archs.push_str("riscv;"); + } + if std::env::var("CARGO_FEATURE_ARCH_MIPS").is_ok() { + archs.push_str("mips;"); + } + if std::env::var("CARGO_FEATURE_ARCH_SPARC").is_ok() { + archs.push_str("sparc;"); + } + if std::env::var("CARGO_FEATURE_ARCH_M68K").is_ok() { + archs.push_str("m68k;"); + } + if std::env::var("CARGO_FEATURE_ARCH_PPC").is_ok() { + archs.push_str("ppc;"); + } + if std::env::var("CARGO_FEATURE_ARCH_S390X").is_ok() { + archs.push_str("s390x;"); + } + if std::env::var("CARGO_FEATURE_ARCH_TRICORE").is_ok() { + archs.push_str("tricore;"); + } + + if !archs.is_empty() { + archs.pop(); + } + // need to clear build target and append "build" to the path because // unicorn's CMakeLists.txt doesn't properly support 'install', so we use // the build artifacts from the build directory, which cmake crate sets @@ -91,6 +128,7 @@ fn build_with_cmake() { let dst = config .define("UNICORN_BUILD_TESTS", "OFF") .define("UNICORN_INSTALL", "OFF") + .define("UNICORN_ARCH", archs) .no_build_target(true) .build(); println!( From 549f34f098853c871c12240936909a7b41b84cc4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 5 Jan 2023 18:10:09 +0100 Subject: [PATCH 13/35] Fix warning for ./setup.py (#1756) --- bindings/python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 8c579ad3..e842db80 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -8,6 +8,7 @@ import subprocess import shutil import sys import platform +import setuptools from distutils import log from distutils.core import setup From 014cee5bd142f9211dbb86d93b104ef16b04e066 Mon Sep 17 00:00:00 2001 From: Luca Gladiator Date: Tue, 17 Jan 2023 13:49:27 +0100 Subject: [PATCH 14/35] Fix Rust binding memory leak --- bindings/rust/src/ffi.rs | 77 ++++++++++++++++++++++++++++------------ bindings/rust/src/lib.rs | 43 +++++++--------------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index a4624a02..1aea7c20 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -1,10 +1,11 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -use crate::Unicorn; +use crate::{Unicorn, UnicornInner}; use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query}; -use core::ffi::c_void; +use alloc::rc::Weak; +use core::{cell::UnsafeCell, ffi::c_void}; use libc::{c_char, c_int}; pub type uc_handle = *mut c_void; @@ -89,7 +90,7 @@ extern "C" { pub struct UcHook<'a, D: 'a, F: 'a> { pub callback: F, - pub uc: Unicorn<'a, D>, + pub uc: Weak>>, } pub trait IsUcHook<'a> {} @@ -106,8 +107,11 @@ where F: FnMut(&mut crate::Unicorn, u64, usize) -> u64, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size) } pub extern "C" fn mmio_write_callback_proxy( @@ -120,8 +124,11 @@ pub extern "C" fn mmio_write_callback_proxy( F: FnMut(&mut crate::Unicorn, u64, usize, u64), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size, value); } pub extern "C" fn code_hook_proxy( @@ -133,8 +140,11 @@ pub extern "C" fn code_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn block_hook_proxy( @@ -146,8 +156,11 @@ pub extern "C" fn block_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn mem_hook_proxy( @@ -162,8 +175,11 @@ where F: FnMut(&mut crate::Unicorn, MemType, u64, usize, i64) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, mem_type, address, size as usize, value) } pub extern "C" fn intr_hook_proxy(uc: uc_handle, value: u32, user_data: *mut UcHook) @@ -171,8 +187,11 @@ where F: FnMut(&mut crate::Unicorn, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, value); } pub extern "C" fn insn_in_hook_proxy( @@ -184,8 +203,11 @@ pub extern "C" fn insn_in_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize) -> u32, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size); } pub extern "C" fn insn_invalid_hook_proxy(uc: uc_handle, user_data: *mut UcHook) -> bool @@ -193,8 +215,11 @@ where F: FnMut(&mut crate::Unicorn) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc) } pub extern "C" fn insn_out_hook_proxy( @@ -207,8 +232,11 @@ pub extern "C" fn insn_out_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size, value); } pub extern "C" fn insn_sys_hook_proxy(uc: uc_handle, user_data: *mut UcHook) @@ -216,6 +244,9 @@ where F: FnMut(&mut crate::Unicorn), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc); } diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 7959e2d5..a71b9996 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -369,17 +369,13 @@ impl<'a, D> Unicorn<'a, D> { let mut read_data = read_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); let mut write_data = write_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); @@ -586,7 +582,8 @@ impl<'a, D> Unicorn<'a, D> { return Err(uc_error::ARCH); } - let err: uc_error = unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; + let err: uc_error = + unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; if err == uc_error::OK { boxed = value.into_boxed_slice(); @@ -622,9 +619,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -654,9 +649,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -697,9 +690,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -730,9 +721,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -763,9 +752,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -796,9 +783,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -830,9 +815,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -870,9 +853,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { From a490ece557606497db1b470d2371ec6a7891911f Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Wed, 18 Jan 2023 16:15:36 +0100 Subject: [PATCH 15/35] Do not search for the RAMBlock in split_region The MemoryRegion already contains a pointer to the RAMBlock. So it is not necesary to search for it. --- uc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/uc.c b/uc.c index 667f40ca..964137f8 100644 --- a/uc.c +++ b/uc.c @@ -1254,14 +1254,7 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, // Find the correct and large enough (which contains our target mr) // to create the content backup. - QLIST_FOREACH(block, &uc->ram_list.blocks, next) - { - // block->offset is the offset within ram_addr_t, not GPA - if (block->mr->addr <= mr->addr && - block->used_length + block->mr->addr >= mr->end) { - break; - } - } + block = mr->ram_block; if (block == NULL) { return false; @@ -2431,4 +2424,4 @@ void trace_end(uc_tracer *tracer, trace_loc loc, const char *fmt, ...) fprintf(stderr, "%.6fus\n", (double)(end - tracer->starts[loc]) / (double)(1000)); } -#endif \ No newline at end of file +#endif From aded30f5a87c07b33fbe6e9cff8cf47aa31ded31 Mon Sep 17 00:00:00 2001 From: Luca Gladiator Date: Sat, 21 Jan 2023 13:50:11 +0100 Subject: [PATCH 16/35] Fix insn_in_hook_proxy return type --- bindings/rust/src/ffi.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index 1aea7c20..b1c04f57 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -199,7 +199,8 @@ pub extern "C" fn insn_in_hook_proxy( port: u32, size: usize, user_data: *mut UcHook, -) where +) -> u32 +where F: FnMut(&mut crate::Unicorn, u32, usize) -> u32, { let user_data = unsafe { &mut *user_data }; @@ -207,7 +208,7 @@ pub extern "C" fn insn_in_hook_proxy( inner: user_data.uc.upgrade().unwrap(), }; debug_assert_eq!(uc, user_data_uc.get_handle()); - (user_data.callback)(&mut user_data_uc, port, size); + (user_data.callback)(&mut user_data_uc, port, size) } pub extern "C" fn insn_invalid_hook_proxy(uc: uc_handle, user_data: *mut UcHook) -> bool From ed9164e47ad2a62fd3f350f8bd5c2518c3a1c784 Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 23 Jan 2023 13:22:55 +0100 Subject: [PATCH 17/35] rust only add mmio callback funktion, if callback is requested The C function uc_mmio_map() allows to add seperate callback functions and userdata for read and write. When the callback functions are NULL unicorn don't try to call this functions. Previous this patch, when i.e. read_callback was None the callback was set to mmio_read_callback_proxy and the userdata was set to NULL. On a callback the mmio_read_callback_proxy then tried to dereference the userdata and caused a segfault. fixes #1762 --- bindings/rust/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 7959e2d5..2aac940d 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -388,12 +388,18 @@ impl<'a, D> Unicorn<'a, D> { self.get_handle(), address, size, - ffi::mmio_read_callback_proxy:: as _, + match read_data { + Some(_) => ffi::mmio_read_callback_proxy:: as _, + None => ptr::null_mut(), + }, match read_data { Some(ref mut d) => d.as_mut() as *mut _ as _, None => ptr::null_mut(), }, - ffi::mmio_write_callback_proxy:: as _, + match write_data { + Some(_) => ffi::mmio_write_callback_proxy:: as _, + None => ptr::null_mut(), + }, match write_data { Some(ref mut d) => d.as_mut() as *mut _ as _, None => ptr::null_mut(), From 12a79192ee6a4ec5b69130ff3481ac64d93a9b25 Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:04:43 +0100 Subject: [PATCH 18/35] Demand paging on Windows --- msvc/config-host.h | 7 +++++++ qemu/accel/tcg/translate-all.c | 18 ++++++++++++++++++ qemu/include/hw/core/cpu.h | 1 + qemu/include/tcg/tcg.h | 5 +++++ qemu/tcg/tcg.c | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/msvc/config-host.h b/msvc/config-host.h index 943d8593..bf750d2d 100644 --- a/msvc/config-host.h +++ b/msvc/config-host.h @@ -7,3 +7,10 @@ #define CONFIG_CMPXCHG128 1 // #define CONFIG_ATOMIC64 1 #define CONFIG_PLUGIN 1 + +// QEMU by default allocates (and commits) 1GB memory on Windows, and multiple Unicorn instances will result in OOM error easily. +// Unfortunately, Windows doesn't have a similar demand paging feature like mmap(), therefore a workaround is to use tcg regions mechanism. +// Note most Unicorn hacks (and even QEMU!) relies on the assumption that the translation memory won't run out and thus it might result +// in some unexpected errors. If that is case, define to align with QEMU and Unicorn <= 2.0.1 behavior. +// +// #define USE_STATIC_CODE_GEN_BUFFER \ No newline at end of file diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 91dd5ce7..aaebd4c5 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -869,6 +869,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return buf; } #elif defined(_WIN32) +#ifdef USE_STATIC_CODE_GEN_BUFFER static inline void *alloc_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; @@ -876,6 +877,23 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); } +#else +static inline void *alloc_code_gen_buffer(struct uc_struct *uc) +{ + TCGContext *tcg_ctx = uc->tcg_ctx; + size_t size = tcg_ctx->code_gen_buffer_size; + + void* ptr = VirtualAlloc(NULL, size, MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + + // for prolog init + VirtualAlloc(ptr, + uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT, + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + return ptr; +} +#endif void free_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; diff --git a/qemu/include/hw/core/cpu.h b/qemu/include/hw/core/cpu.h index d1b7c250..097a7f63 100644 --- a/qemu/include/hw/core/cpu.h +++ b/qemu/include/hw/core/cpu.h @@ -20,6 +20,7 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H +#include #include "exec/hwaddr.h" #include "exec/memattrs.h" #include "qemu/bitmap.h" diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index f3643fe3..c7eb23ef 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -35,6 +35,11 @@ #include "tcg-apple-jit.h" #include "qemu/int128.h" +// Unicorn: Default region size for win32 +#if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#define UC_TCG_REGION_PAGES_COUNT (128) +#endif + /* XXX: make safe guess about sizes */ #define MAX_OP_PER_INSTR 266 diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 4910c67c..d5fba106 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -23,6 +23,8 @@ */ /* define it to use liveness analysis (better code) */ +#include "tcg/tcg.h" +#include #define USE_TCG_OPTIMIZATIONS #include "qemu/osdep.h" @@ -406,6 +408,13 @@ static void tcg_region_assign(TCGContext *s, size_t curr_region) s->code_gen_buffer = start; s->code_gen_ptr = start; s->code_gen_buffer_size = (char *)end - (char *)start; +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + VirtualAlloc( + s->code_gen_buffer, + ROUND_UP(s->code_gen_buffer_size, s->uc->qemu_real_host_page_size), + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); +#endif memset(s->code_gen_buffer, 0x00, s->code_gen_buffer_size); s->code_gen_highwater = (char *)end - TCG_HIGHWATER; } @@ -500,7 +509,11 @@ void tcg_region_init(TCGContext *tcg_ctx) size_t n_regions; size_t i; +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + n_regions = size / (tcg_ctx->uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT); +#else n_regions = 1; +#endif /* The first region will be 'aligned - buf' bytes larger than the others */ aligned = (void *)QEMU_ALIGN_PTR_UP(buf, page_size); @@ -537,6 +550,11 @@ void tcg_region_init(TCGContext *tcg_ctx) } tcg_ctx->tree = g_tree_new(tb_tc_cmp); + +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + // Allocate a region immediately, or the highwater is not set correctly. + tcg_region_alloc(tcg_ctx); +#endif } /* From 513e797d46a958e64f6ef5118a8861d694b60a8a Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:10:39 +0100 Subject: [PATCH 19/35] Update comments of the page count --- qemu/include/tcg/tcg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index c7eb23ef..0b4f9a4c 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -37,7 +37,7 @@ // Unicorn: Default region size for win32 #if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) -#define UC_TCG_REGION_PAGES_COUNT (128) +#define UC_TCG_REGION_PAGES_COUNT (128) // Note less pages may cause unexpected and subtle errors. #endif /* XXX: make safe guess about sizes */ From a25adf84f0bdf82113c75d1c63baebe9d3ae994d Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:18:39 +0100 Subject: [PATCH 20/35] Rename flags to avoid confusion --- msvc/config-host.h | 4 ++-- qemu/accel/tcg/translate-all.c | 2 +- qemu/include/tcg/tcg.h | 2 +- qemu/tcg/tcg.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/msvc/config-host.h b/msvc/config-host.h index bf750d2d..a5e1e190 100644 --- a/msvc/config-host.h +++ b/msvc/config-host.h @@ -11,6 +11,6 @@ // QEMU by default allocates (and commits) 1GB memory on Windows, and multiple Unicorn instances will result in OOM error easily. // Unfortunately, Windows doesn't have a similar demand paging feature like mmap(), therefore a workaround is to use tcg regions mechanism. // Note most Unicorn hacks (and even QEMU!) relies on the assumption that the translation memory won't run out and thus it might result -// in some unexpected errors. If that is case, define to align with QEMU and Unicorn <= 2.0.1 behavior. +// in some unexpected errors. If that is case, define WIN32_QEMU_ALLOC_BUFFER to align with QEMU and Unicorn <= 2.0.1 behavior. // -// #define USE_STATIC_CODE_GEN_BUFFER \ No newline at end of file +// #define WIN32_QEMU_ALLOC_BUFFER \ No newline at end of file diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index aaebd4c5..56ddb35e 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -869,7 +869,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return buf; } #elif defined(_WIN32) -#ifdef USE_STATIC_CODE_GEN_BUFFER +#ifdef WIN32_QEMU_ALLOC_BUFFER static inline void *alloc_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index 0b4f9a4c..1134c75c 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -36,7 +36,7 @@ #include "qemu/int128.h" // Unicorn: Default region size for win32 -#if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(_WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) #define UC_TCG_REGION_PAGES_COUNT (128) // Note less pages may cause unexpected and subtle errors. #endif diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index d5fba106..cb76f31a 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -408,7 +408,7 @@ static void tcg_region_assign(TCGContext *s, size_t curr_region) s->code_gen_buffer = start; s->code_gen_ptr = start; s->code_gen_buffer_size = (char *)end - (char *)start; -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) VirtualAlloc( s->code_gen_buffer, ROUND_UP(s->code_gen_buffer_size, s->uc->qemu_real_host_page_size), @@ -509,7 +509,7 @@ void tcg_region_init(TCGContext *tcg_ctx) size_t n_regions; size_t i; -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) n_regions = size / (tcg_ctx->uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT); #else n_regions = 1; @@ -551,7 +551,7 @@ void tcg_region_init(TCGContext *tcg_ctx) tcg_ctx->tree = g_tree_new(tb_tc_cmp); -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) // Allocate a region immediately, or the highwater is not set correctly. tcg_region_alloc(tcg_ctx); #endif From cee8e6b5da3af9b699b4af44eb38e4b5ced2bb48 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sun, 29 Jan 2023 00:47:46 +0100 Subject: [PATCH 21/35] gha: Add steps to upload nupkg as artifact & publish to Nuget --- .github/workflows/Nuget-publishing.yml | 47 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index fe8b17de..75abbf67 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -124,7 +124,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -182,7 +182,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -251,9 +251,9 @@ jobs: shell: 'script -q -e -c "bash {0}"' run: | if [ ${{ matrix.config.arch }} == 'x64' ]; then - sudo apt install -q -y libcmocka-dev ninja-build + sudo apt install -q -y libcmocka-dev ninja-build else - export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" + export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" sudo dpkg --add-architecture i386 sudo apt install -q -y lib32ncurses-dev lib32z1-dev lib32gcc-9-dev libc6-dev-i386 gcc-multilib \ libcmocka-dev:i386 libcmocka0:i386 libc6:i386 libgcc-s1:i386 ninja-build @@ -307,7 +307,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -320,20 +320,20 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Download artifacts + - name: 🛠️ Download artifacts uses: actions/download-artifact@v3 with: path: artifacts - - name: Extract artifacts + - name: 🛠️ Extract artifacts shell: python run: | import subprocess import os - + artifactPath = os.path.join(os.getcwd(), "artifacts") bindingsPath = os.path.join(os.getcwd(), "bindings", "dotnet", "UnicornEngine") - + ARTIFACT_CONFIG = { "ubuntu-cmake-aarch64.7z": { "sourceDir": "lib/", @@ -372,11 +372,11 @@ jobs: "destFile": "unicorn.dll" } } - + if len(os.listdir(artifactPath)) < len(ARTIFACT_CONFIG.keys()): print("Some artifacts are missing. Aborting.") exit(1) - + for artifact in os.listdir(artifactPath): if artifact in ARTIFACT_CONFIG.keys(): print("Working on:", artifact) @@ -384,20 +384,20 @@ jobs: destDir = os.path.join(bindingsPath, config["destDir"]) print("Creating dir:", destDir) os.makedirs(destDir, exist_ok=True) - + print(f"Extracting library from 7z file to: {config['destDir']}/{config['sourceFile']}") result = subprocess.run(["7z", "e", f"-o{destDir}/", os.path.join(artifactPath, artifact), f"{config['sourceDir']}{config['sourceFile']}"]) result.check_returncode() - + if config["sourceFile"] != config["destFile"]: output = subprocess.run(["ls", destDir], stdout=subprocess.PIPE) sourceFile = output.stdout.decode().strip() print(f"Renaming {sourceFile} to {config['destFile']}") os.rename(os.path.join(destDir, sourceFile), os.path.join(destDir, config["destFile"])) - + print("Done!") - - name: Get short sha + - name: 🛠️ Get short sha id: git_short_sha run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT @@ -405,21 +405,32 @@ jobs: with: dotnet-version: 6.0.x - - name: Authenticate to Github Packages + - name: 🛠️ Authenticate to Github Packages working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - - name: List all native libraries + - name: 🛠️ List all native libraries working-directory: bindings/dotnet/UnicornEngine run: find ./runtimes -type f -print - - name: Package .NET distribution + - name: 🚧 Package .NET distribution working-directory: bindings/dotnet/UnicornEngine run: | [[ "${{ github.ref_name }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" + - name: '📤 Upload artifact' + uses: actions/upload-artifact@v2 + with: + path: ${{ github.workspace }}/bindings/dotnet/UnicornEngine/bin/Release/UnicornEngine.Unicorn.*.nupkg + - name: 📦 Publish to Github Packages working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" + + - name: 📦 Publish Nuget package + working-directory: bindings/dotnet/UnicornEngine + run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" -k "$NUGET_AUTH_TOKEN" -s https://api.nuget.org/v3/index.json + env: + NUGET_AUTH_TOKEN: ${{ secrets.NUGET_KEY }} From 6e9c6aea5fd79ba271a388eef114ee6410674da1 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 4 Feb 2023 13:00:58 +0800 Subject: [PATCH 22/35] bump version to 2.0.2 --- CMakeLists.txt | 2 +- Cargo.toml | 4 ++-- bindings/python/setup.py | 2 +- include/unicorn/unicorn.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4110ae53..d94bd464 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ set(CMAKE_C_STANDARD 11) set(UNICORN_VERSION_MAJOR 2) set(UNICORN_VERSION_MINOR 0) -set(UNICORN_VERSION_PATCH 1) +set(UNICORN_VERSION_PATCH 2) include(bundle_static.cmake) diff --git a/Cargo.toml b/Cargo.toml index 46253df6..6731d9e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unicorn-engine" -version = "2.0.1" +version = "2.0.2" authors = ["Ziqiao Kong", "Lukas Seidel"] documentation = "https://github.com/unicorn-engine/unicorn/wiki" edition = "2021" @@ -51,4 +51,4 @@ arch_sparc = [] arch_m68k = [] arch_ppc = [] arch_s390x = [] -arch_tricore = [] \ No newline at end of file +arch_tricore = [] diff --git a/bindings/python/setup.py b/bindings/python/setup.py index e842db80..b8cfbdfa 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -30,7 +30,7 @@ SRC_DIR = os.path.join(ROOT_DIR, 'src') UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..') BUILD_DIR = os.path.join(UC_DIR, 'build_python') -VERSION = "2.0.1.post1" +VERSION = "2.0.2" if SYSTEM == 'darwin': LIBRARY_FILE = "libunicorn.2.dylib" diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 4b169d76..54ffd251 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -72,9 +72,9 @@ typedef size_t uc_hook; // Unicorn API version #define UC_API_MAJOR 2 #define UC_API_MINOR 0 -#define UC_API_PATCH 1 +#define UC_API_PATCH 2 // Release candidate version, 255 means the official release. -#define UC_API_EXTRA 255 +#define UC_API_EXTRA 1 // Unicorn package version #define UC_VERSION_MAJOR UC_API_MAJOR From 7ca4769f2abfb8a0f6bb253ea9a735195d1a59cc Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 4 Feb 2023 13:01:33 +0800 Subject: [PATCH 23/35] bindings: update version to 2.0.2 --- bindings/dotnet/UnicornManaged/Const/Common.fs | 8 ++++---- bindings/go/unicorn/unicorn_const.go | 8 ++++---- bindings/java/unicorn/UnicornConst.java | 8 ++++---- bindings/pascal/unicorn/UnicornConst.pas | 8 ++++---- bindings/python/unicorn/unicorn_const.py | 8 ++++---- .../ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornManaged/Const/Common.fs index 72b5cb3a..d6b92eae 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornManaged/Const/Common.fs @@ -9,13 +9,13 @@ module Common = let UC_API_MAJOR = 2 let UC_API_MINOR = 0 - let UC_API_PATCH = 1 - let UC_API_EXTRA = 255 + let UC_API_PATCH = 2 + let UC_API_EXTRA = 1 let UC_VERSION_MAJOR = 2 let UC_VERSION_MINOR = 0 - let UC_VERSION_PATCH = 1 - let UC_VERSION_EXTRA = 255 + let UC_VERSION_PATCH = 2 + let UC_VERSION_EXTRA = 1 let UC_SECOND_SCALE = 1000000 let UC_MILISECOND_SCALE = 1000 let UC_ARCH_ARM = 1 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 19268ce5..34c97b4a 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -4,13 +4,13 @@ const ( API_MAJOR = 2 API_MINOR = 0 - API_PATCH = 1 - API_EXTRA = 255 + API_PATCH = 2 + API_EXTRA = 1 VERSION_MAJOR = 2 VERSION_MINOR = 0 - VERSION_PATCH = 1 - VERSION_EXTRA = 255 + VERSION_PATCH = 2 + VERSION_EXTRA = 1 SECOND_SCALE = 1000000 MILISECOND_SCALE = 1000 ARCH_ARM = 1 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 62759ba6..e63afb79 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -6,13 +6,13 @@ public interface UnicornConst { public static final int UC_API_MAJOR = 2; public static final int UC_API_MINOR = 0; - public static final int UC_API_PATCH = 1; - public static final int UC_API_EXTRA = 255; + public static final int UC_API_PATCH = 2; + public static final int UC_API_EXTRA = 1; public static final int UC_VERSION_MAJOR = 2; public static final int UC_VERSION_MINOR = 0; - public static final int UC_VERSION_PATCH = 1; - public static final int UC_VERSION_EXTRA = 255; + public static final int UC_VERSION_PATCH = 2; + public static final int UC_VERSION_EXTRA = 1; public static final int UC_SECOND_SCALE = 1000000; public static final int UC_MILISECOND_SCALE = 1000; public static final int UC_ARCH_ARM = 1; diff --git a/bindings/pascal/unicorn/UnicornConst.pas b/bindings/pascal/unicorn/UnicornConst.pas index 26896d13..2d75d4ae 100644 --- a/bindings/pascal/unicorn/UnicornConst.pas +++ b/bindings/pascal/unicorn/UnicornConst.pas @@ -7,13 +7,13 @@ interface const UC_API_MAJOR = 2; UC_API_MINOR = 0; - UC_API_PATCH = 1; - UC_API_EXTRA = 255; + UC_API_PATCH = 2; + UC_API_EXTRA = 1; UC_VERSION_MAJOR = 2; UC_VERSION_MINOR = 0; - UC_VERSION_PATCH = 1; - UC_VERSION_EXTRA = 255; + UC_VERSION_PATCH = 2; + UC_VERSION_EXTRA = 1; UC_SECOND_SCALE = 1000000; UC_MILISECOND_SCALE = 1000; UC_ARCH_ARM = 1; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index f491dd26..96f2949b 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -2,13 +2,13 @@ UC_API_MAJOR = 2 UC_API_MINOR = 0 -UC_API_PATCH = 1 -UC_API_EXTRA = 255 +UC_API_PATCH = 2 +UC_API_EXTRA = 1 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 -UC_VERSION_PATCH = 1 -UC_VERSION_EXTRA = 255 +UC_VERSION_PATCH = 2 +UC_VERSION_EXTRA = 1 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 UC_ARCH_ARM = 1 diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb index e317589e..6dbc46e0 100644 --- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb +++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb @@ -4,13 +4,13 @@ module UnicornEngine UC_API_MAJOR = 2 UC_API_MINOR = 0 - UC_API_PATCH = 1 - UC_API_EXTRA = 255 + UC_API_PATCH = 2 + UC_API_EXTRA = 1 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 - UC_VERSION_PATCH = 1 - UC_VERSION_EXTRA = 255 + UC_VERSION_PATCH = 2 + UC_VERSION_EXTRA = 1 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 UC_ARCH_ARM = 1 From eb118528b189ed6c4980fcb408636d84188b232e Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Mon, 6 Feb 2023 17:59:16 +0800 Subject: [PATCH 24/35] rename memory_mapping() to find_memory_region() and simplify mem_map() --- include/uc_priv.h | 2 +- qemu/accel/tcg/cputlb.c | 8 ++++---- uc.c | 38 ++++++++++++++++++-------------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 030fadce..66b6e83e 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -409,7 +409,7 @@ struct uc_context { }; // check if this address is mapped in (via uc_mem_map()) -MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address); +MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address); // We have to support 32bit system so we can't hold uint64_t on void* static inline void uc_add_exit(uc_engine *uc, uint64_t addr) diff --git a/qemu/accel/tcg/cputlb.c b/qemu/accel/tcg/cputlb.c index 04c892a2..d591e9d1 100644 --- a/qemu/accel/tcg/cputlb.c +++ b/qemu/accel/tcg/cputlb.c @@ -1436,7 +1436,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, bool handled; HOOK_FOREACH_VAR_DECLARE; struct uc_struct *uc = env->uc; - MemoryRegion *mr = memory_mapping(uc, addr); + MemoryRegion *mr = find_memory_region(uc, addr); // memory might be still unmapped while reading or fetching if (mr == NULL) { @@ -1480,7 +1480,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, if (handled) { uc->invalid_error = UC_ERR_OK; - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; cpu_exit(uc->cpu); @@ -2010,7 +2010,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, } // Load the latest memory mapping. - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); // Unicorn: callback on invalid memory if (mr == NULL) { @@ -2037,7 +2037,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, return; } else { uc->invalid_error = UC_ERR_OK; - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; cpu_exit(uc->cpu); diff --git a/uc.c b/uc.c index 964137f8..829dda95 100644 --- a/uc.c +++ b/uc.c @@ -552,7 +552,7 @@ static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size) size_t count = 0, len; while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { len = (size_t)MIN(size - count, mr->end - address); count += len; @@ -587,7 +587,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) // memory area can overlap adjacent memory blocks while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { len = (size_t)MIN(size - count, mr->end - address); if (uc->read_mem(&uc->address_space_memory, address, bytes, len) == @@ -632,7 +632,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, // memory area can overlap adjacent memory blocks while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { uint32_t operms = mr->perms; if (!(operms & UC_PROT_WRITE)) { // write protected @@ -976,8 +976,7 @@ static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size) } // common setup/error checking shared between uc_mem_map and uc_mem_map_ptr -static uc_err mem_map(uc_engine *uc, uint64_t address, size_t size, - uint32_t perms, MemoryRegion *block) +static uc_err mem_map(uc_engine *uc, MemoryRegion *block) { MemoryRegion **regions; int pos; @@ -1060,8 +1059,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) return res; } - return mem_map(uc, address, size, perms, - uc->memory_map(uc, address, size, perms)); + return mem_map(uc, uc->memory_map(uc, address, size, perms)); } UNICORN_EXPORT @@ -1085,8 +1083,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, return res; } - return mem_map(uc, address, size, UC_PROT_ALL, - uc->memory_map_ptr(uc, address, size, perms, ptr)); + return mem_map(uc, uc->memory_map_ptr(uc, address, size, perms, ptr)); } UNICORN_EXPORT @@ -1108,9 +1105,8 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, // The callbacks do not need to be checked for NULL here, as their presence // (or lack thereof) will determine the permissions used. - return mem_map(uc, address, size, UC_PROT_NONE, - uc->memory_map_io(uc, address, size, read_cb, write_cb, - user_data_read, user_data_write)); + return mem_map(uc, uc->memory_map_io(uc, address, size, read_cb, write_cb, + user_data_read, user_data_write)); } // Create a backup copy of the indicated MemoryRegion. @@ -1416,14 +1412,14 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, addr = address; count = 0; while (count < size) { - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); len = (size_t)MIN(size - count, mr->end - addr); if (mr->ram) { if (!split_region(uc, mr, addr, len, false)) { return UC_ERR_NOMEM; } - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); // will this remove EXEC permission? if (((mr->perms & UC_PROT_EXEC) != 0) && ((perms & UC_PROT_EXEC) == 0)) { @@ -1437,7 +1433,7 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, return UC_ERR_NOMEM; } - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); mr->perms = perms; } @@ -1496,7 +1492,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) addr = address; count = 0; while (count < size) { - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); len = (size_t)MIN(size - count, mr->end - addr); if (!mr->ram) { if (!split_mmio_region(uc, mr, addr, len, true)) { @@ -1510,7 +1506,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) // if we can retrieve the mapping, then no splitting took place // so unmap here - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr != NULL) { uc->memory_unmap(uc, mr); } @@ -1522,7 +1518,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) } // find the memory region of this address -MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address) +MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) { unsigned int i; @@ -1537,14 +1533,16 @@ MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address) // try with the cache index first i = uc->mapped_block_cache_index; - if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && + address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) { return uc->mapped_blocks[i]; } i = bsearch_mapped_blocks(uc, address); - if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && + address >= uc->mapped_blocks[i]->addr && address <= uc->mapped_blocks[i]->end - 1) return uc->mapped_blocks[i]; From 3199dd88dee094c3fc456971e5f469c22cb1160d Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 7 Feb 2023 01:07:38 +0100 Subject: [PATCH 25/35] Detect AVX2 correctly for MSVC --- qemu/tcg/i386/tcg-target.inc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/qemu/tcg/i386/tcg-target.inc.c b/qemu/tcg/i386/tcg-target.inc.c index 260de96c..fc5cdbba 100644 --- a/qemu/tcg/i386/tcg-target.inc.c +++ b/qemu/tcg/i386/tcg-target.inc.c @@ -24,6 +24,10 @@ #include "../tcg-pool.inc.c" +#ifdef _MSC_VER +#include +#endif + #ifdef CONFIG_DEBUG_TCG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { #if TCG_TARGET_REG_BITS == 64 @@ -3768,11 +3772,6 @@ static void tcg_target_init(TCGContext *s) have_movbe = (c & bit_MOVBE) != 0; have_popcnt = (c & bit_POPCNT) != 0; -#ifdef _MSC_VER - // FIXME: detect AVX1 & AVX2: https://gist.github.com/hi2p-perim/7855506 - have_avx1 = true; - have_avx2 = true; -#else /* There are a number of things we must check before we can be sure of not hitting invalid opcode. */ if (c & bit_OSXSAVE) { @@ -3780,13 +3779,18 @@ static void tcg_target_init(TCGContext *s) /* The xgetbv instruction is not available to older versions of * the assembler, so we encode the instruction manually. */ +#ifndef _MSC_VER asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcrl), "=d" (xcrh) : "c" (0)); +#else + unsigned long long bv = _xgetbv(0); + xcrl = bv & 0xFFFFFFFF; + xcrh = (bv >> 32) & 0xFFFFFFFF; +#endif if ((xcrl & 6) == 6) { have_avx1 = (c & bit_AVX) != 0; have_avx2 = (b7 & bit_AVX2) != 0; } } -#endif } #ifdef _MSC_VER From 9c9356da6cf5533a469c9a41e2b95ad0d064b2a7 Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 7 Feb 2023 10:40:30 +0100 Subject: [PATCH 26/35] Bump to 2.0.2-rc1 for csharp --- bindings/dotnet/UnicornEngine/UnicornEngine.fsproj | 2 +- bindings/dotnet/UnicornSamples/UnicornSamples.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index f2142473..8fd0d790 100644 --- a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -6,7 +6,7 @@ Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn .NET bindings for unicorn - 2.0.0 + 2.0.2-rc1 $(VersionSuffix) 0c21f1c1-2725-4a46-9022-1905f85822a5 true diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index 4ba2d49e..9aea0c7d 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -6,7 +6,7 @@ UnicornSamples Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn - 2.0.0 + 2.0.2-rc1 {B80B5987-1E24-4309-8BF9-C4F91270F21C} true From 133504b504b4b9005b26f707d7d68cf18eba2993 Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:21:56 +0100 Subject: [PATCH 27/35] Fix wrong IP in x86_16 because of cs_base not substracted --- qemu/target/i386/translate.c | 4 ++-- tests/unit/test_x86.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index b4dc56f2..2cc88f23 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4816,7 +4816,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) } // Sync PC in advance - gen_jmp_im(s, pc_start); + gen_jmp_im(s, pc_start - s->cs_base); // save the last operand prev_op = tcg_last_op(tcg_ctx); @@ -9314,7 +9314,7 @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = dc->uc->tcg_ctx; - dc->prev_pc = dc->base.pc_next; + dc->prev_pc = dc->base.pc_next - dc->cs_base; tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, dc->cc_op); } diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index ddc84710..110e4b41 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -1229,6 +1229,36 @@ static void test_x86_lazy_mapping(void) OK(uc_close(uc)); } +static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address, uint32_t size, void* data) +{ + uint16_t cs, ip; + + OK(uc_reg_read(uc, UC_X86_REG_CS, &cs)); + OK(uc_reg_read(uc, UC_X86_REG_IP, &ip)); + + TEST_CHECK(cs == 0x20); + TEST_CHECK(address == ((cs << 4) + ip)); +} + +static void test_x86_16_incorrect_ip(void) +{ + uc_engine *uc; + uc_hook hk1, hk2; + uint16_t cs = 0x20; + char code[] = "\x41"; // INC cx; + + uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_16, code, sizeof(code) - 1); + + OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); + OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); + + OK(uc_reg_write(uc, UC_X86_REG_CS, &cs)); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + + OK(uc_close(uc)); +} + TEST_LIST = { {"test_x86_in", test_x86_in}, {"test_x86_out", test_x86_out}, @@ -1271,4 +1301,5 @@ TEST_LIST = { {"test_x86_unaligned_access", test_x86_unaligned_access}, #endif {"test_x86_lazy_mapping", test_x86_lazy_mapping}, + {"test_x86_16_incorrect_ip", test_x86_16_incorrect_ip}, {NULL, NULL}}; From 5e5075b4b93fd268b6900914b944a26ff0fb0757 Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:27:31 +0100 Subject: [PATCH 28/35] Install pkg-config on macos runners --- .github/workflows/build-uc2.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-uc2.yml b/.github/workflows/build-uc2.yml index 7ee95894..ded889ef 100644 --- a/.github/workflows/build-uc2.yml +++ b/.github/workflows/build-uc2.yml @@ -305,7 +305,7 @@ jobs: if: contains(matrix.config.name, 'macos-x64') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config ninja --version cmake --version mkdir build @@ -325,7 +325,7 @@ jobs: if: contains(matrix.config.name, 'android') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config mkdir build mkdir instdir cmake . -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ From 2d5d72e6c7f46f2b230d857c2434c5362be6118c Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:51:37 +0100 Subject: [PATCH 29/35] Install deps for macos --- .github/workflows/PyPI-publishing.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/PyPI-publishing.yml b/.github/workflows/PyPI-publishing.yml index 5f254bc2..b152c144 100644 --- a/.github/workflows/PyPI-publishing.yml +++ b/.github/workflows/PyPI-publishing.yml @@ -96,7 +96,12 @@ jobs: run: | choco install ninja cmake - - name: '🛠️ Install dependencies' + - name: '🛠️ macOS dependencies' + if: contains(matrix.config.name, 'macos') + run: | + brew install p7zip cmake ninja pkg-config + + - name: '🛠️ pip dependencies' run: | pip install setuptools wheel From 8a6f4e54c2eea179e321a44c54a85e031f56c24b Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:53:52 +0100 Subject: [PATCH 30/35] Install pkg-config for other workflows --- .github/workflows/Crate-publishing.yml | 6 ++++++ .github/workflows/Nuget-publishing.yml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Crate-publishing.yml b/.github/workflows/Crate-publishing.yml index eb1e0470..e20ba172 100644 --- a/.github/workflows/Crate-publishing.yml +++ b/.github/workflows/Crate-publishing.yml @@ -67,6 +67,12 @@ jobs: run: | choco install ninja cmake + - name: '🛠️ macOS build dependencies' + if: contains(matrix.config.os, 'macOS') + shell: bash + run: | + brew install p7zip cmake ninja pkg-config + - name: '🚧 Cargo test' if: "!startsWith(github.ref, 'refs/tags')" run: | diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 75abbf67..3a6f0207 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -156,7 +156,7 @@ jobs: if: contains(matrix.config.name, 'macos-x64') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config ninja --version cmake --version mkdir build From a91319908d67644cc4cc9befc8bdb1eb04ed083e Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:57:50 +0100 Subject: [PATCH 31/35] Remove obsolete Brewfile --- Brewfile | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 Brewfile diff --git a/Brewfile b/Brewfile deleted file mode 100644 index 82c65634..00000000 --- a/Brewfile +++ /dev/null @@ -1,6 +0,0 @@ -# Travis CI setup for MacOS Brew - -# used for testing framework -brew "cmocka" -# used for cross assembly of code for testing -brew "crosstool-ng" From b961ebc9cb9063775de0de65667b7fb7035902c1 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Sat, 25 Feb 2023 23:40:03 -0800 Subject: [PATCH 32/35] [dotnet] Set begin > end address for hooks --- bindings/dotnet/UnicornEngine/Unicorn.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs index 7d401300..8aaeaaf0 100644 --- a/bindings/dotnet/UnicornEngine/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -249,7 +249,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> 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 + match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0) |> this.CheckResult with | Some e -> raise e | None -> () ) @@ -274,7 +274,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = 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 1, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with | Some e -> raise e | None -> () _inHooks.Add(callback, userData) @@ -290,7 +290,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = 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 1, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with | Some e -> raise e | None -> () _outHooks.Add(callback, userData) @@ -306,7 +306,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = 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 1, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with | Some e -> raise e | None -> () _syscallHooks.Add(callback, userData) From 14404ef04b55662f605c00b31a479e50caff72ab Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 27 Feb 2023 12:34:38 +0100 Subject: [PATCH 33/35] [x86] don't hardcode cpuid results The cpuid results are set by the selected cpu. CLOSES #1787 --- qemu/target/i386/unicorn.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index f10b70e2..4541044e 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -69,17 +69,6 @@ void x86_reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; - env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | - CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH; - env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | - CPUID_EXT_SSE42 | CPUID_EXT_AES | - CPUID_EXT_CX16; - env->features[FEAT_8000_0001_EDX] = CPUID_EXT2_3DNOW | CPUID_EXT2_RDTSCP; - env->features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | - CPUID_EXT3_SKINIT | CPUID_EXT3_CR8LEG; - env->features[FEAT_7_0_EBX] = CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | - CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP; - memset(env->regs, 0, sizeof(env->regs)); memset(env->segs, 0, sizeof(env->segs)); memset(env->cr, 0, sizeof(env->cr)); From 03a793e9345bea4736f29f21d0d2e26cf89a3491 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Tue, 28 Feb 2023 19:31:58 -0800 Subject: [PATCH 34/35] [dotnet] Fix garbage collected hooks and wrong signature --- .../dotnet/UnicornEngine/InternalHooks.fs | 4 +- bindings/dotnet/UnicornEngine/Unicorn.fs | 41 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/InternalHooks.fs b/bindings/dotnet/UnicornEngine/InternalHooks.fs index d9e87954..062de03c 100644 --- a/bindings/dotnet/UnicornEngine/InternalHooks.fs +++ b/bindings/dotnet/UnicornEngine/InternalHooks.fs @@ -14,10 +14,10 @@ type internal BlockHookInternal = delegate of IntPtr * Int64 * Int32 * IntPtr -> type internal InterruptHookInternal = delegate of IntPtr * Int32 * IntPtr -> unit [] -type internal MemReadHookInternal = delegate of IntPtr * Int64 * Int32 * IntPtr -> unit +type internal MemReadHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * IntPtr -> unit [] -type internal MemWriteHookInternal = delegate of IntPtr * Int64 * Int32 * Int64 * IntPtr -> unit +type internal MemWriteHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * Int64 * IntPtr -> unit [] type internal EventMemHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * Int64 * IntPtr-> Boolean diff --git a/bindings/dotnet/UnicornEngine/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs index 8aaeaaf0..e353bf0c 100644 --- a/bindings/dotnet/UnicornEngine/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -32,6 +32,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let _outHooks = new List<(OutHook * Object)>() let _syscallHooks = new List<(SyscallHook * Object)>() let _disposablePointers = new List() + let _hookInternals = new List(); let _eventMemMap = [ @@ -153,7 +154,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _codeHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new CodeHookInternal(trampoline)) + let codeHookInternal = new CodeHookInternal(trampoline) + _hookInternals.Add(codeHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(codeHookInternal) 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 | Some e -> raise e | None -> () @@ -172,7 +175,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _blockHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new BlockHookInternal(trampoline)) + let blockHookInternal = new BlockHookInternal(trampoline) + _hookInternals.Add(blockHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(blockHookInternal) 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 | Some e -> raise e | None -> () @@ -188,7 +193,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, intNumber, userData)) if _interruptHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new InterruptHookInternal(trampoline)) + let interruptHookInternal = new InterruptHookInternal(trampoline) + _hookInternals.Add(interruptHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(interruptHookInternal) 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 | Some e -> raise e | None -> () @@ -202,12 +209,14 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = hookDel _interruptHooks callback member this.AddMemReadHook(callback: MemReadHook, userData: Object, beginAddr: Int64, endAddr: Int64) = - let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = + let trampoline(u: IntPtr) (_eventType: Int32) (addr: Int64) (size: Int32) (user: IntPtr) = _memReadHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _memReadHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new MemReadHookInternal(trampoline)) + let memReadHookInternal = new MemReadHookInternal(trampoline) + _hookInternals.Add(memReadHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memReadHookInternal) 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 | Some e -> raise e | None -> () @@ -218,12 +227,14 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = hookDel _memReadHooks callback member this.AddMemWriteHook(callback: MemWriteHook, userData: Object, beginAddr: Int64, endAddr: Int64) = - let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = + let trampoline(u: IntPtr) (_eventType: Int32) (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 memWriteHookInternal = new MemWriteHookInternal(trampoline) + _hookInternals.Add(memWriteHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memWriteHookInternal) 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 | Some e -> raise e | None -> () @@ -247,7 +258,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) |> Seq.filter(fun eventFlag -> _memEventHooks.[eventFlag] |> Seq.isEmpty) |> Seq.iter(fun eventFlag -> - let funcPointer = Marshal.GetFunctionPointerForDelegate(new EventMemHookInternal(trampoline)) + let memEventHookInternal = new EventMemHookInternal(trampoline) + _hookInternals.Add(memEventHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memEventHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0) |> this.CheckResult with | Some e -> raise e | None -> () @@ -272,7 +285,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.last if _inHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new InHookInternal(trampoline)) + let inHookInternal = new InHookInternal(trampoline) + _hookInternals.Add(inHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(inHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with | Some e -> raise e | None -> () @@ -288,7 +303,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> 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 outHookInternal = new OutHookInternal(trampoline) + _hookInternals.Add(outHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(outHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with | Some e -> raise e | None -> () @@ -304,7 +321,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, userData)) if _syscallHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new SyscallHookInternal(trampoline)) + let syscallHookInternal = new SyscallHookInternal(trampoline) + _hookInternals.Add(syscallHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(syscallHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with | Some e -> raise e | None -> () From cef7d7d0fbefb0c6e1da7eaf782bef36cf8ad64c Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Mon, 27 Feb 2023 23:31:15 -0700 Subject: [PATCH 35/35] Use libunicorn.so.2 as fallback path --- bindings/python/unicorn/unicorn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 2e6a938f..0aacfb13 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -94,7 +94,7 @@ _path_list = [os.getenv('LIBUNICORN_PATH', None), for _path in _path_list: if _path is None: continue - _uc = _load_lib(_path, _lib.get(sys.platform, "libunicorn.so")) + _uc = _load_lib(_path, _lib.get(sys.platform, "libunicorn.so.2")) if _uc is not None: break