- Improved the GitHub python binding workflow: (#2072)

- Added fullMode input in workflow_dispatch
    - Take decision whether to build either in debug or release mode and if to build for all python versions according to the commit message patterns
    - Set proper artifact names
    - Removed not needed steps
    - Compacted some steps in order to leverage more the matrix feature
    - Bumped cibuildwheel action to 2.22.0
    - Run actual regress tests in place of sample scripts
- Specify optional test install in pyproject.toml with proper requirements
- Derive package version from git tags
- Add GENERATORS env var support in setup.py to specify cmake generator and minor refactoring
- Minor cleanup/refactoring for the regress test suite
- Marked some regress tests with skipIf to skip them in case of old python versions
- Marked some failing regress tests to be checked with skipIf
This commit is contained in:
@Antelox
2024-12-29 15:24:48 +01:00
committed by GitHub
parent 07e8162cca
commit 9cfd5cfac3
85 changed files with 543 additions and 838 deletions

View File

@@ -1,4 +1,4 @@
name: Build wheels with cibuildwheel
name: Build and publish wheels with cibuildwheel
on:
workflow_dispatch:
@@ -11,6 +11,14 @@ on:
options:
- '0'
- '1'
fullMode:
description: 'Full Mode'
required: false
default: ''
type: choice
options:
- '0'
- '1'
push:
paths-ignore:
- ".gitignore"
@@ -26,12 +34,12 @@ on:
env:
# Enable DEBUG flag either according to the tag release or manual override
UNICORN_DEBUG: ${{ inputs.debugMode != '' && inputs.debugMode || startsWith(github.ref, 'refs/tags') && '0' || '1' }}
UNICORN_DEBUG: ${{ inputs.debugMode != '' && inputs.debugMode || startsWith(github.ref, 'refs/tags') && '0' || contains(github.event.head_commit.message, 'CI(release)') && '0' || '1' }}
jobs:
# job to be executed for every push - testing purpose
build_wheels_python38_only:
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} - ${{ matrix.cibw_build }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -39,24 +47,35 @@ jobs:
include:
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
# i686 - manylinux
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-manylinux*', cibw_skip: '' }
# i686 - musllinux
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-musllinux*', cibw_skip: '' }
# x86_64 - manylinux
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-manylinux*', cibw_skip: '' }
# x86_64 - musllinux
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-musllinux*', cibw_skip: '' }
# aarch64 - manylinux
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-manylinux*', cibw_skip: '' }
# aarch64 - musllinux
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-musllinux' }
- { os: macos-13, arch: x86_64, cibw_build: '' }
- { os: macos-latest, arch: arm64, cibw_build: '' }
- { os: windows-2019, arch: AMD64, cibw_build: '' }
- { os: windows-2019, arch: x86, cibw_build: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-musllinux*', cibw_skip: '' }
- { os: macos-13, arch: x86_64, cibw_build: 'cp38*', cibw_skip: '' }
- { os: macos-latest, arch: arm64, cibw_build: 'cp38*', cibw_skip: '' }
- { os: windows-2019, arch: AMD64, cibw_build: 'cp38*', cibw_skip: '' }
- { os: windows-2019, arch: x86, cibw_build: 'cp38*', cibw_skip: '' }
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# https://github.com/actions/upload-artifact/issues/22
- name: Prepare a unique name for Artifacts
shell: bash
run: |
# replace not-allowed chars with dash
name="cibw-wheels-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.cibw_build }}"
name=$(echo -n "$name" | sed -e 's/[ \t:\/\\"<>|*?]/-/g' -e 's/--*/-/g' | sed -e 's/\-$//')
echo "ARTIFACT_NAME=$name" >> $GITHUB_ENV
- name: '🛠️ Add msbuild to PATH'
if: runner.os == 'Windows'
@@ -64,17 +83,6 @@ jobs:
with:
vs-version: '16.5'
- name: '🛠️ Win build dependencies'
if: runner.os == 'Windows'
shell: bash
run: |
choco install ninja
- name: '🛠️ macOS dependencies'
if: runner.os == 'macOS'
run: |
brew install ninja
# https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64
- uses: actions/setup-python@v5
if: runner.os == 'macOS' && runner.arch == 'ARM64'
@@ -94,60 +102,20 @@ jobs:
arch: x64
- name: '🛠️ Set up QEMU'
if: runner.os == 'Linux'
if: runner.os == 'Linux' && matrix.arch != 'x86_64'
uses: docker/setup-qemu-action@v3
- name: '🚧 cibuildwheel run - Linux'
if: matrix.os == 'ubuntu-latest'
uses: pypa/cibuildwheel@v2.21.3
- name: '🚧 cibuildwheel run'
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_BUILD_FRONTEND: build
CIBW_BUILD: ${{ matrix.cibw_build }}*
CIBW_BUILD: ${{ matrix.cibw_build }}
CIBW_SKIP: ${{ matrix.cibw_skip }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - Windows'
if: matrix.os == 'windows-2019'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_BUILD: 'cp38*'
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - MacOS x86_84'
if: matrix.os == 'macos-13'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_BUILD: 'cp38*'
CIBW_ENVIRONMENT: SYSTEM_VERSION_COMPAT=0 DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - MacOS arm64'
if: matrix.os == 'macos-latest'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_BUILD: 'cp38*'
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
CIBW_TEST_EXTRAS: test
CIBW_TEST_COMMAND: 'python -m unittest discover -v {project}/tests/regress "*.py"'
# https://github.com/pypa/cibuildwheel/pull/1169
CIBW_TEST_SKIP: "cp38-macosx_*:arm64"
with:
@@ -155,49 +123,42 @@ jobs:
output-dir: wheelhouse
# we re-tag cp38 wheel (just an old one) with py2 tag. Hacky but it works...
- name: '🚧 Python 2.7 wheels re-tagging - Windows'
if: matrix.os == 'windows-2019'
run: |
python -m pip install -U pip wheel && Get-ChildItem -Path wheelhouse/ -Filter *cp38*.whl | Foreach-Object {
python -m wheel tags --python-tag='py2' --abi-tag=none $_.FullName
break
}
- name: '🚧 Python 2.7 wheels re-tagging - Non-Windows'
if: matrix.os != 'windows-2019'
- name: '🚧 Python 2.7 wheels re-tagging'
env:
PIP_BREAK_SYSTEM_PACKAGES: 1
shell: bash
run: |
python3 -m pip install -U pip wheel && python3 -m wheel tags --python-tag='py2' --abi-tag=none wheelhouse/*cp38*.whl
python3 -m pip install -U pip wheel
python3 -m wheel tags --python-tag='py2' --abi-tag=none wheelhouse/*cp38*.whl
- uses: LizardByte/setup-python-action@master
if: (matrix.os == 'ubuntu-latest' && matrix.arch == 'x86_64' && matrix.cibw_build == 'cp38-manylinux') || matrix.os == 'macos-latest' || (matrix.os == 'windows-2019' && matrix.arch == 'AMD64')
- uses: LizardByte/setup-python-action@v2024.919.163656
if: (matrix.os == 'ubuntu-latest' && matrix.arch == 'x86_64' && matrix.cibw_build == 'cp38-manylinux*') || matrix.os == 'macos-latest' || (matrix.os == 'windows-2019' && matrix.arch == 'AMD64')
with:
python-version: 2.7
# we install and test python2.7 wheels only on native arch
- name: 'Python 2.7 tests - Windows'
if: matrix.os == 'windows-2019' && matrix.arch == 'AMD64'
shell: bash
run: |
C:\Python27\python.exe -m pip install -U pip pytest && Get-ChildItem -Path wheelhouse/ -Filter *py2*.whl | Foreach-Object {
C:\Python27\python.exe -m pip install $_.FullName
C:\Python27\python.exe -m pytest bindings/python/tests
break
}
C:/Python27/python.exe -m pip install capstone==4.0.2 wheelhouse/*py2*.whl
C:/Python27/python.exe -m unittest discover tests/regress "*.py"
# we install and test python2.7 wheels only on native arch
# NOTE: no python2.7 support for macos-13: https://github.com/LizardByte/setup-python-action/issues/2
- name: 'Python 2.7 tests - Non-Windows'
if: (matrix.os == 'ubuntu-latest' && matrix.arch == 'x86_64' && matrix.cibw_build == 'cp38-manylinux') || matrix.os == 'macos-latest'
run: python2 -m pip install wheelhouse/*py2*.whl && python2 -m pip install -U pip pytest && python2 -m pytest bindings/python/tests
if: (matrix.os == 'ubuntu-latest' && matrix.arch == 'x86_64' && matrix.cibw_build == 'cp38-manylinux*') || matrix.os == 'macos-latest'
run: |
python2 -m pip install capstone==4.0.2 wheelhouse/*py2*.whl
python2 -m unittest discover tests/regress "*.py"
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}-py38
name: ${{ env.ARTIFACT_NAME }}
path: ./wheelhouse/*.whl
# Job to be executed to build all wheels for all platforms/architectures/python versions only for tag release
build_wheels_all_versions:
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} - ${{ matrix.cibw_build }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -205,54 +166,65 @@ jobs:
include:
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
# i686 - manylinux
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-manylinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-manylinux*', cibw_skip: '' }
# i686 - musllinux
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-musllinux' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-musllinux*', cibw_skip: '' }
# x86_64 - manylinux
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-manylinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-manylinux*', cibw_skip: '' }
# x86_64 - musllinux
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-musllinux' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-musllinux*', cibw_skip: '' }
# aarch64 - manylinux
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-manylinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-manylinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-manylinux*', cibw_skip: '' }
# aarch64 - musllinux
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-musllinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-musllinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-musllinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-musllinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-musllinux' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-musllinux' }
- { os: macos-13, arch: x86_64, cibw_build: '' }
- { os: macos-latest, arch: arm64, cibw_build: '' }
- { os: windows-2019, arch: AMD64, cibw_build: '' }
- { os: windows-2019, arch: x86, cibw_build: '' }
if: startsWith(github.ref, 'refs/tags')
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-musllinux*', cibw_skip: '' }
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-musllinux*', cibw_skip: '' }
- { os: macos-13, arch: x86_64, cibw_build: 'cp*', cibw_skip: '*36* *38*' }
- { os: macos-latest, arch: arm64, cibw_build: 'cp*', cibw_skip: '*36* *37* *38*' }
- { os: windows-2019, arch: AMD64, cibw_build: 'cp*', cibw_skip: '*36* *38*' }
- { os: windows-2019, arch: x86, cibw_build: 'cp*', cibw_skip: '*36* *38*' }
if: ${{ inputs.fullMode == 1 || startsWith(github.ref, 'refs/tags') || contains(github.event.head_commit.message, 'CI(full)') }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# https://github.com/actions/upload-artifact/issues/22
- name: Prepare a unique name for Artifacts
shell: bash
run: |
# replace not-allowed chars with dash
name="cibw-wheels-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.cibw_build }}"
name=$(echo -n "$name" | sed -e 's/[ \t:\/\\"<>|*?]/-/g' -e 's/--*/-/g' | sed -e 's/\-$//')
echo "ARTIFACT_NAME=$name" >> $GITHUB_ENV
- name: '🛠️ Add msbuild to PATH'
if: runner.os == 'Windows'
@@ -260,17 +232,6 @@ jobs:
with:
vs-version: '16.5'
- name: '🛠️ Win build dependencies'
if: runner.os == 'Windows'
shell: bash
run: |
choco install ninja
- name: '🛠️ macOS dependencies'
if: runner.os == 'macOS'
run: |
brew install ninja
- name: '🛠️ Win MSVC 32 dev cmd setup'
if: runner.os == 'Windows' && matrix.arch == 'x86'
uses: ilammy/msvc-dev-cmd@v1
@@ -284,70 +245,27 @@ jobs:
arch: x64
- name: '🛠️ Set up QEMU'
if: runner.os == 'Linux'
if: runner.os == 'Linux' && matrix.arch != 'x86_64'
uses: docker/setup-qemu-action@v3
- name: '🚧 cibuildwheel run - Linux'
if: matrix.os == 'ubuntu-latest'
uses: pypa/cibuildwheel@v2.21.3
- name: '🚧 cibuildwheel run'
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_BUILD_FRONTEND: build
CIBW_BUILD: ${{ matrix.cibw_build }}*
CIBW_BUILD: ${{ matrix.cibw_build }}
CIBW_SKIP: ${{ matrix.cibw_skip }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - Windows'
if: matrix.os == 'windows-2019'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_SKIP: '*36* *38*'
CIBW_BUILD: 'cp*'
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - MacOS x86_84'
if: matrix.os == 'macos-13'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_SKIP: '*36* *38*'
CIBW_BUILD: 'cp*'
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
with:
package-dir: bindings/python
output-dir: wheelhouse
- name: '🚧 cibuildwheel run - MacOS arm64'
if: matrix.os == 'macos-latest'
uses: pypa/cibuildwheel@v2.21.3
env:
CIBW_BUILD_FRONTEND: build
CIBW_SKIP: '*36* *37* *38*'
CIBW_BUILD: 'cp*'
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
CIBW_TEST_EXTRAS: test
CIBW_TEST_COMMAND: 'python -m unittest discover -v {project}/tests/regress "*.py"'
with:
package-dir: bindings/python
output-dir: wheelhouse
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}-all
name: ${{ env.ARTIFACT_NAME }}
path: ./wheelhouse/*.whl
make_sdist:
@@ -356,8 +274,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Optional, use if you use setuptools_scm
submodules: true # Optional, use if you have submodules
fetch-depth: 0
- name: Build SDist
run: |

View File

@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools", "build", "wheel"]
requires = ["setuptools", "build", "wheel", "versioningit"]
build-backend = "setuptools.build_meta"
[project]
name = "unicorn"
version = "2.1.1"
dynamic = ["version"]
requires-python = ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*, != 3.4.*, != 3.5.*, != 3.6.*"
authors = [
{ name = "Nguyen Anh Quynh", email = "quynh@gmail.com" },
@@ -33,9 +33,11 @@ Changelog = "https://github.com/unicorn-engine/unicorn/blob/master/ChangeLog"
[project.optional-dependencies]
test = [
"pytest",
"pytest-cov",
"capstone==6.0.0a2;python_version>'3.7'",
"capstone==5.0.1;python_version<='3.7'"
]
[tool.setuptools.packages.find]
include = ["unicorn*"]
[tool.versioningit]

View File

@@ -102,12 +102,17 @@ def build_libraries():
has_msbuild = shutil.which('msbuild') is not None
conf = 'Debug' if int(os.getenv('DEBUG', 0)) else 'Release'
cmake_args = ['cmake', '-B', BUILD_DIR, "-DCMAKE_BUILD_TYPE=" + conf]
if os.getenv("UNICORN_TRACER"):
cmake_args += ["-DUNICORN_TRACER=on"]
if conf == 'Debug':
cmake_args += ["-DUNICORN_LOGGING=on"]
if has_msbuild and sys.platform == 'win32':
generators = os.getenv('GENERATORS') or 'Visual Studio 16 2019'
plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64'
subprocess.check_call(['cmake', '-B', BUILD_DIR, '-G', "Visual Studio 16 2019", "-A", plat,
"-DCMAKE_BUILD_TYPE=" + conf], cwd=UC_DIR)
cmake_args += ['-G', generators, "-A", plat]
subprocess.check_call(cmake_args, cwd=UC_DIR)
subprocess.check_call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf],
cwd=BUILD_DIR)
@@ -115,11 +120,7 @@ def build_libraries():
shutil.copy(os.path.join(obj_dir, LIBRARY_FILE), LIBS_DIR)
shutil.copy(os.path.join(obj_dir, STATIC_LIBRARY_FILE), LIBS_DIR)
else:
cmake_args = ["cmake", '-B', BUILD_DIR, '-S', UC_DIR, "-DCMAKE_BUILD_TYPE=" + conf]
if os.getenv("TRACE"):
cmake_args += ["-DUNICORN_TRACER=on"]
if conf == "Debug":
cmake_args += ["-DUNICORN_LOGGING=on"]
cmake_args += ['-S', UC_DIR]
subprocess.check_call(cmake_args, cwd=UC_DIR)
threads = os.getenv("THREADS", "4")
subprocess.check_call(["cmake", "--build", ".", "-j" + threads], cwd=BUILD_DIR)

View File

@@ -2,7 +2,6 @@
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.arm_const import *

View File

@@ -2,7 +2,6 @@
# Sample code for ARM64 of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.arm64_const import *

View File

@@ -3,7 +3,6 @@
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
# AARCH64 Python sample ported by zhangwm <rustydaar@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.arm64_const import *

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python
# Sample code for ARM big endian of Unicorn. zhangwm <rustydaar@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.arm_const import *

View File

@@ -2,8 +2,6 @@
# Sample code for Unicorn.
# By Lazymio(@wtdcode), 2021
import pytest
import sys
from unicorn import *
from unicorn.x86_const import *
from datetime import datetime
@@ -36,7 +34,6 @@ def time_emulation(uc, start, end):
# TODO: Check if worth adapting the ctl_request_cache method for py2 bindings
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_uc_ctl_tb_cache():
# Initialize emulator in X86-32bit mode
uc = Uc(UC_ARCH_X86, UC_MODE_32)
@@ -84,7 +81,6 @@ def trace_tcg_sub(uc, address, arg1, arg2, size, data):
# TODO: Check if worth adapting the hook_add method for py2 bindings
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_uc_ctl_exits():
uc = Uc(UC_ARCH_X86, UC_MODE_32)
addr = 0x1000

View File

@@ -2,7 +2,6 @@
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.m68k_const import *

View File

@@ -2,7 +2,6 @@
# Sample code for MIPS of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.mips_const import *

View File

@@ -2,8 +2,6 @@
# Unicorn sample for auditing network connection and file handling in shellcode.
# Nguyen Tan Cong <shenlongbk@gmail.com>
from __future__ import print_function
import pytest
import struct
import uuid
from unicorn import *
@@ -361,7 +359,6 @@ def hook_intr(uc, intno, user_data):
print_sockcall(msg)
@pytest.mark.parametrize("code", [X86_SEND_ETCPASSWD, X86_BIND_TCP, X86_REVERSE_TCP, X86_REVERSE_TCP_2])
# Test X86 32 bit
def test_i386(code):
global fd_chains

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python
# Sample code for PPC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.ppc_const import *

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python
# Sample code for RISCV of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.riscv_const import *

View File

@@ -3,8 +3,6 @@
# Nguyen Anh Quynh <aquynh@gmail.com>
# KaiJern Lau <kj@theshepherdlab.io>
from __future__ import print_function
import pytest
from unicorn import *
from unicorn.x86_const import *
@@ -134,8 +132,6 @@ def hook_syscall64(mu, user_data):
mu.emu_stop()
@pytest.mark.parametrize("mode,code",
[(UC_MODE_32, X86_CODE32_SELF), (UC_MODE_32, X86_CODE32), (UC_MODE_64, X86_CODE64)])
# Test X86 32 bit
def test_i386(mode, code):
if mode == UC_MODE_32:

View File

@@ -2,7 +2,6 @@
# Sample code for SPARC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
from __future__ import print_function
from unicorn import *
from unicorn.sparc_const import *

View File

@@ -5,7 +5,6 @@
Copyright 2022 Aptiv
"""
from __future__ import print_function
from unicorn import *
from unicorn.tricore_const import *

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python
# Sample code for X86 of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
from __future__ import print_function
import pickle
from unicorn import *
from unicorn.x86_const import *

View File

@@ -1,7 +1,4 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.arm64_const import *

View File

@@ -1,10 +1,7 @@
import regress
from unicorn import *
from unicorn.arm_const import *
MAIN_ADDRESS = 0x8d68
ADDRESS = MAIN_ADDRESS & ~(0x1000 - 1)
STACK_ADDR = ADDRESS + 0x1000
@@ -15,51 +12,51 @@ class BxTwiceTest(regress.RegressTest):
# code to be emulated
code = {
0x8cd4: (
b'\x04\xb0\x2d\xe5' # 8cd4 push {r11}
b'\x00\xb0\x8d\xe2' # 8cd8 add r11, sp, #0
b'\x0f\x30\xa0\xe1' # 8cdc mov r3, pc
b'\x03\x00\xa0\xe1' # 8ce0 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8ce4 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8ce8 pop {r11}
b'\x1e\xff\x2f\xe1' # 8cec bx lr
b'\x04\xb0\x2d\xe5' # 8cd4 push {r11}
b'\x00\xb0\x8d\xe2' # 8cd8 add r11, sp, #0
b'\x0f\x30\xa0\xe1' # 8cdc mov r3, pc
b'\x03\x00\xa0\xe1' # 8ce0 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8ce4 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8ce8 pop {r11}
b'\x1e\xff\x2f\xe1' # 8cec bx lr
),
0x8cf0: (
b'\x04\xb0\x2d\xe5' # 8cf0 push {r11}
b'\x00\xb0\x8d\xe2' # 8cf4 add r11, sp, #0
b'\x04\x60\x2d\xe5' # 8cf8 push {r6}
b'\x01\x60\x8f\xe2' # 8cfc add r6, pc, $1
b'\x16\xff\x2f\xe1' # 8d00 bx r6
# .thumb
b'\x7b\x46' # 8d04 mov r3, pc
b'\x03\xf1\x08\x03' # 8d06 add r3, $0x8 # elicn: used to be $0x4 but it kept failing
b'\x08\xb4' # 8d0a push {r3}
b'\x00\xbd' # 8d0c pop {pc}
b'\x00\x00' # 8d0e (alignment)
# .arm
b'\x04\x60\x9d\xe4' # 8d10 pop {r6}
b'\x03\x00\xa0\xe1' # 8d14 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8d18 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8d1c pop {r11}
b'\x1e\xff\x2f\xe1' # 8d20 bx lr
b'\x04\xb0\x2d\xe5' # 8cf0 push {r11}
b'\x00\xb0\x8d\xe2' # 8cf4 add r11, sp, #0
b'\x04\x60\x2d\xe5' # 8cf8 push {r6}
b'\x01\x60\x8f\xe2' # 8cfc add r6, pc, $1
b'\x16\xff\x2f\xe1' # 8d00 bx r6
# .thumb
b'\x7b\x46' # 8d04 mov r3, pc
b'\x03\xf1\x08\x03' # 8d06 add r3, $0x8 # elicn: used to be $0x4 but it kept failing
b'\x08\xb4' # 8d0a push {r3}
b'\x00\xbd' # 8d0c pop {pc}
b'\x00\x00' # 8d0e (alignment)
# .arm
b'\x04\x60\x9d\xe4' # 8d10 pop {r6}
b'\x03\x00\xa0\xe1' # 8d14 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8d18 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8d1c pop {r11}
b'\x1e\xff\x2f\xe1' # 8d20 bx lr
),
0x8d24: ( # elicn: used to be 0x8d20 but it caused this block to overlap with the previous one
b'\x04\xb0\x2d\xe5' # 8d24 push {r11}
b'\x00\xb0\x8d\xe2' # 8d28 add r11, sp, #0
b'\x0e\x30\xa0\xe1' # 8d2c mov r3, lr
b'\x03\x00\xa0\xe1' # 8d20 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8d34 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8d38 pop {r11}
b'\x1e\xff\x2f\xe1' # 8d3c bx lr
0x8d24: ( # elicn: used to be 0x8d20 but it caused this block to overlap with the previous one
b'\x04\xb0\x2d\xe5' # 8d24 push {r11}
b'\x00\xb0\x8d\xe2' # 8d28 add r11, sp, #0
b'\x0e\x30\xa0\xe1' # 8d2c mov r3, lr
b'\x03\x00\xa0\xe1' # 8d20 mov r0, r3
b'\x00\xd0\x4b\xe2' # 8d34 sub sp, r11, #0
b'\x04\xb0\x9d\xe4' # 8d38 pop {r11}
b'\x1e\xff\x2f\xe1' # 8d3c bx lr
),
0x8d68: (
b'\xd9\xff\xff\xeb' # 8d68 bl 0x8cd4 <-- MAIN_ADDRESS
b'\x00\x40\xa0\xe1' # 8d6c mov r4, r0
b'\xde\xff\xff\xeb' # 8d70 bl 0x8cf0
b'\x00\x30\xa0\xe1' # 8d74 mov r3, r0
b'\x03\x40\x84\xe0' # 8d78 add r4, r4, r3
b'\xe8\xff\xff\xeb' # 8d7c bl 0x8d24
b'\x00\x30\xa0\xe1' # 8d80 mov r3, r0
b'\x03\x20\x84\xe0' # 8d84 add r2, r4, r3
b'\xd9\xff\xff\xeb' # 8d68 bl 0x8cd4 <-- MAIN_ADDRESS
b'\x00\x40\xa0\xe1' # 8d6c mov r4, r0
b'\xde\xff\xff\xeb' # 8d70 bl 0x8cf0
b'\x00\x30\xa0\xe1' # 8d74 mov r3, r0
b'\x03\x40\x84\xe0' # 8d78 add r4, r4, r3
b'\xe8\xff\xff\xeb' # 8d7c bl 0x8d24
b'\x00\x30\xa0\xe1' # 8d80 mov r3, r0
b'\x03\x20\x84\xe0' # 8d84 add r2, r4, r3
)
}

View File

@@ -1,7 +1,4 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.arm_const import *

View File

@@ -1,28 +1,25 @@
#!/usr/bin/python
# Added by Peter Mackay, relating to issue 571
# "ARM NEON/VFP support seems to exist but is disabled by default"
# Added by Peter Mackay, relating to issue 571
# ARM NEON/VFP support seems to exist but is disabled by default
# https://github.com/unicorn-engine/unicorn/issues/571
import regress
from unicorn import *
from unicorn.arm_const import *
CODE = (
b'\x11\xEE\x50\x1F' # MRC p15, #0, r1, c1, c0, #2
b'\x41\xF4\x70\x01' # ORR r1, r1, #(0xf << 20)
b'\x01\xEE\x50\x1F' # MCR p15, #0, r1, c1, c0, #2
b'\x4F\xF0\x00\x01' # MOV r1, #0
b'\x07\xEE\x95\x1F' # MCR p15, #0, r1, c7, c5, #4
b'\x4F\xF0\x80\x40' # MOV r0,#0x40000000
b'\xE8\xEE\x10\x0A' # FMXR FPEXC, r0
b'\x2d\xed\x02\x8b' # vpush {d8}
b'\x11\xEE\x50\x1F' # MRC p15, #0, r1, c1, c0, #2
b'\x41\xF4\x70\x01' # ORR r1, r1, #(0xf << 20)
b'\x01\xEE\x50\x1F' # MCR p15, #0, r1, c1, c0, #2
b'\x4F\xF0\x00\x01' # MOV r1, #0
b'\x07\xEE\x95\x1F' # MCR p15, #0, r1, c7, c5, #4
b'\x4F\xF0\x80\x40' # MOV r0,#0x40000000
b'\xE8\xEE\x10\x0A' # FMXR FPEXC, r0
b'\x2d\xed\x02\x8b' # vpush {d8}
)
BASE = 0x1000
class FpVfpDisabled(regress.RegressTest):
def runTest(self):

View File

@@ -1,21 +1,21 @@
#!/usr/bin/env python
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
#
import platform
import regress
import sys
import unittest
from unicorn import *
from unicorn.arm_const import *
# code to be emulated
ARM_CODE = (
b"\x37\x00\xa0\xe3" # mov r0, #0x37
b"\x03\x10\x42\xe0" # sub r1, r2, r3
b"\x37\x00\xa0\xe3" # mov r0, #0x37
b"\x03\x10\x42\xe0" # sub r1, r2, r3
)
THUMB_CODE = b"\x83\xb0" # sub sp, #0xc
THUMB_CODE = b"\x83\xb0" # sub sp, #0xc
# memory address where emulation starts
ADDRESS = 0xF0000000
@@ -32,6 +32,7 @@ def hook_code(uc, address, size, user_data):
class TestInitInputCrash(regress.RegressTest):
@unittest.skipIf(sys.platform == 'win32' or platform.machine().lower() not in ('x86_64', 'arm64'), 'TO BE CHECKED!')
def test_arm(self):
regress.logger.debug("Emulate ARM code")
@@ -42,7 +43,7 @@ class TestInitInputCrash(regress.RegressTest):
mu.mem_map(ADDRESS, mem_size)
stack_address = ADDRESS + mem_size
stack_size = stack_address # >>> here huge memory size
stack_size = stack_address # >>> here huge memory size
mu.mem_map(stack_address, stack_size)
# write machine code to be emulated to memory

View File

@@ -1,44 +1,44 @@
import regress
import sys
import unittest
from unicorn import *
from unicorn.arm_const import *
SHELLCODE = bytes.fromhex(
'03 f0 8f e0' # 0001F894 ADD PC, PC, R3
'0d 07 21 f4' # 0001F898 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F89C VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8A0 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8A4 VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8A8 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8AC VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8B0 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8B4 VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8B8 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8BC VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8C0 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8C4 VST1.8 {D0}, [R12]!
'0d 07 21 f4' # 0001F8C8 VLD1.8 {D0}, [R1]!
'0d 07 0c f4' # 0001F8CC VST1.8 {D0}, [R12]!
'04 00 12 e3' # 0001F8D0 TST R2, #4
'04 30 91 14' # 0001F8D4 LDRNE R3, [R1],#4
'04 30 8c 14' # 0001F8D8 STRNE R3, [R12],#4
'82 2f b0 e1' # 0001F8DC MOVS R2, R2,LSL#31
'b2 30 d1 20' # 0001F8E0 LDRHCS R3, [R1],#2
'00 10 d1 15' # 0001F8E4 LDRBNE R1, [R1]
'b2 30 cc 20' # 0001F8E8 STRHCS R3, [R12],#2
'00 10 cc 15' # 0001F8EC STRBNE R1, [R12]
SHELLCODE = (
b'\x03\xF0\x8F\xE0' # 0001F894 ADD PC, PC, R3
b'\x0D\x07\x21\xF4' # 0001F898 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F89C VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8A0 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8A4 VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8A8 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8AC VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8B0 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8B4 VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8B8 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8BC VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8C0 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8C4 VST1.8 {D0}, [R12]!
b'\x0D\x07\x21\xF4' # 0001F8C8 VLD1.8 {D0}, [R1]!
b'\x0D\x07\x0C\xF4' # 0001F8CC VST1.8 {D0}, [R12]!
b'\x04\x00\x12\xE3' # 0001F8D0 TST R2, #4
b'\x04\x30\x91\x14' # 0001F8D4 LDRNE R3, [R1],#4
b'\x04\x30\x8C\x14' # 0001F8D8 STRNE R3, [R12],#4
b'\x82\x2F\xB0\xE1' # 0001F8DC MOVS R2, R2,LSL#31
b'\xB2\x30\xD1\x20' # 0001F8E0 LDRHCS R3, [R1],#2
b'\x00\x10\xD1\x15' # 0001F8E4 LDRBNE R1, [R1]
b'\xB2\x30\xCC\x20' # 0001F8E8 STRHCS R3, [R12],#2
b'\x00\x10\xCC\x15' # 0001F8EC STRBNE R1, [R12]
)
BASE = 0x1F894
COPY_SRC = 0x1000
COPY_DST = 0x2000
COPY_LEN = 8
DATA = b'c8' * COPY_LEN
class ArmMemcpy(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_arm_memcpy(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
@@ -46,7 +46,7 @@ class ArmMemcpy(regress.RegressTest):
uc.mem_map(COPY_DST, 0x1000)
uc.mem_map(BASE & ~(0x1000 - 1), 0x1000)
uc.mem_write(COPY_SRC, DATA)
uc.mem_write(BASE, bytes(SHELLCODE))
uc.mem_write(BASE, SHELLCODE)
uc.reg_write_batch((
(UC_ARM_REG_R12, COPY_DST),

View File

@@ -1,13 +1,13 @@
#!/usr/bin/python
import platform
import regress
import unittest
from unicorn import *
from unicorn.arm_const import *
class MovHang(regress.RegressTest):
@unittest.skipIf(platform.machine().lower() == 'aarch64', reason='TO BE CHECKED!')
def runTest(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000)
@@ -23,7 +23,7 @@ class MovHang(regress.RegressTest):
uc.hook_add(UC_HOOK_BLOCK, hook_block)
uc.count = 0
#print 'block should only run once'
# print 'block should only run once'
uc.emu_start(0x1000, 0x1004, timeout=500)
self.assertEqual(0x0, uc.reg_read(UC_ARM_REG_R12))

View File

@@ -1,9 +1,5 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.arm_const import *
class VldrPcInsn(regress.RegressTest):
@@ -12,7 +8,7 @@ class VldrPcInsn(regress.RegressTest):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, b'\xed\x9f\x8a\x3d') # vldr s16, [pc, #244]
uc.mem_write(0x1000, b'\xed\x9f\x8a\x3d') # vldr s16, [pc, #244]
with self.assertRaises(UcError) as ex:
uc.emu_start(0x1000, 0x1004)

View File

@@ -1,9 +1,5 @@
import regress
from unicorn import *
from unicorn.arm_const import *
CODE = (
b'\x00\x00\x8a\xe0' # ADD R0, R10, R0

View File

@@ -1,18 +1,15 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
class Hang(regress.RegressTest):
class BadRam(regress.RegressTest):
def runTest(self):
PAGE_SIZE = 0x5000
CODE_ADDR = 0x400000
RSP_ADDR = 0x200000
RSP_ADDR = 0x200000
CODE = b"\xCA\x24\x5D" # retf 0x5d24
CODE = b"\xCA\x24\x5D" # retf 0x5d24
mu = Uc(UC_ARCH_X86, UC_MODE_64)

View File

@@ -1,16 +1,12 @@
#!/usr/bin/env python
# reg_write() can't modify PC from within trace callbacks
# issue #210
import regress
from unicorn import *
from unicorn.arm_const import *
BASE_ADDRESS = 0x10000000
THUMB_CODE = b"\x83\xb0" * 5 # sub sp, #0xc
THUMB_CODE = b"\x83\xb0" * 5 # sub sp, #0xc
TARGET_PC = 0xffffffff

View File

@@ -1,12 +1,11 @@
#!/usr/bin/env python
import platform
import regress
import sys
import unittest
from unicorn import *
from unicorn.arm_const import *
from unicorn.x86_const import *
# count down from maxint to zero
_VALID_CODE = (
b'\x31\xc9' # xor ecx, ecx
@@ -17,7 +16,7 @@ _VALID_CODE = (
)
_INVALID_CODE = (
b'\xff\xff' # (invalid)
b'\xff\xff' # (invalid)
)
CODE = _VALID_CODE + _INVALID_CODE
@@ -44,6 +43,8 @@ class TestCtl(regress.RegressTest):
self.assertEqual(UC_MODE_BIG_ENDIAN, uc.ctl_get_mode())
self.assertEqual(UC_CPU_ARM_CORTEX_M0, uc.ctl_get_cpu_model())
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
@unittest.skipIf(sys.platform == 'win32' or platform.machine().lower() not in ('x86_64', 'arm64'), 'TO BE CHECKED!')
def test_page_size(self):
SIZE_4KB = 4 * 1024 ** 1
SIZE_2MB = 2 * 1024 ** 2
@@ -77,6 +78,7 @@ class TestCtl(regress.RegressTest):
# are we still with the valid value?
self.assertEqual(SIZE_2MB, uc.ctl_get_page_size())
@unittest.skipIf(platform.machine().lower() == 'aarch64', reason='TO BE CHECKED!')
def test_timeout(self):
MILLIS_1S = 1000
@@ -137,6 +139,7 @@ class TestCtl(regress.RegressTest):
# not failing on an invalid instruction is another good indication for that
self.assertEqual(GOOD_EXIT, uc.reg_read(UC_X86_REG_EIP))
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_tlb_mode(self):
MAPPING_LO = 0x0000000001000000
MAPPING_HI = 0x0010000000000000
@@ -155,7 +158,7 @@ class TestCtl(regress.RegressTest):
uc.mem_map(MAPPING_HI, 0x1000)
uc.mem_write(MAPPING_HI, NOPSLED)
# this should prevents us from mapping to high addresses
# this should prevent us from mapping to high addresses
uc.ctl_set_tlb_mode(UC_TLB_CPU)
# this should fail

View File

@@ -1,14 +1,12 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
import regress
CODE_ADDR = 0x0
binary1 = b'\xb8\x02\x00\x00\x00'
binary2 = b'\xb8\x01\x00\x00\x00'
class CrashTB(regress.RegressTest):
def runTest(self):
@@ -32,6 +30,6 @@ class CrashTB(regress.RegressTest):
self.assertEqual(0x1, mu.reg_read(UC_X86_REG_RAX))
if __name__ == '__main__':
regress.main()

View File

@@ -1,11 +1,11 @@
#!/usr/bin/python
# From issue #1 of Ryan Hileman
from unicorn import *
import regress
from unicorn import *
CODE = b"\x90\x91\x92"
class DeadLock(regress.RegressTest):
def runTest(self):
@@ -16,5 +16,6 @@ class DeadLock(regress.RegressTest):
with self.assertRaises(UcError):
mu.emu_start(0x100000, 0x1000 + len(CODE))
if __name__ == '__main__':
regress.main()

View File

@@ -1,27 +1,22 @@
#!/usr/bin/python
import binascii
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = binascii.unhexlify((
"8B 74 01 28" # mov esi, dword ptr [ecx + eax + 0x28] mapped: 0x1000
"03 F0" # add esi, eax 0x1004
"8D 45 FC" # lea eax, dword ptr [ebp - 4] 0x1006
"50" # push eax 0x1009
"6A 40" # push 0x40 0x100A
"6A 10" # push 0x10 0x100C
"56" # push esi 0x100E
).replace(' ', ''))
CODE = (
b'\x8B\x74\x01\x28' # mov esi, dword ptr [ecx + eax + 0x28] mapped: 0x1000
b'\x03\xF0' # add esi, eax 0x1004
b'\x8D\x45\xFC' # lea eax, dword ptr [ebp - 4] 0x1006
b'\x50' # push eax 0x1009
b'\x6A\x40' # push 0x40 0x100A
b'\x6A\x10' # push 0x10 0x100C
b'\x56' # push esi 0x100E
)
BASE = 0x1000
STACK = 0x4000
class HookCodeStopEmuTest(regress.RegressTest):
class EmuClearErrorsTest(regress.RegressTest):
def test_hook_code_stop_emu(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)

View File

@@ -1,9 +1,8 @@
#!/usr/bin/python
""" See https://github.com/unicorn-engine/unicorn/issues/65 """
"""See https://github.com/unicorn-engine/unicorn/issues/65"""
import unicorn
import regress
import unicorn
class EmuStopSegFault(regress.RegressTest):
@@ -16,5 +15,6 @@ class EmuStopSegFault(regress.RegressTest):
# The following should not trigger a null pointer dereference
self.assertEqual(None, mu.emu_stop())
if __name__ == '__main__':
regress.main()

View File

@@ -1,6 +1,5 @@
#!/usr/bin/python
"""See https://github.com/unicorn-engine/unicorn/issues/161
"""
See https://github.com/unicorn-engine/unicorn/issues/161
Ensure that constants which are specified via a typedef, rather than an enum,
are included in the bindings by the script for autogenerating mappings for

View File

@@ -1,18 +1,16 @@
#!/usr/bin/python
import regress
import sys
import unittest
from unicorn import *
from unicorn.x86_const import *
from capstone import Cs, CS_ARCH_X86, CS_ARCH_X86, CS_MODE_64, CS_MODE_32
from capstone import Cs, CS_ARCH_X86, CS_MODE_64, CS_MODE_32
CODE = (
b'\xc7\x04\x24\x7f\x03\x00\x00' # mov DWORD PTR [rsp],0x37f
b'\xd9\x2c\x24' # fldcw WORD PTR [rsp]
b'\xd9\xd0' # fnop
b'\xd9\x74\x24\x08' # fnstenv [rsp+0x8]
b'\x59' # pop rcx
b'\x59' # pop rcx
)
BASE = 0x00000000
@@ -29,6 +27,7 @@ def hook_code(uc, addr, size, user_data):
class FpuIP(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_32(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)
cs = Cs(CS_ARCH_X86, CS_MODE_32)
@@ -40,9 +39,10 @@ class FpuIP(regress.RegressTest):
mu.emu_start(BASE, BASE + len(CODE), count=5)
self.assertSequenceEqual(b'\x7f\x03\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 8, 8))
self.assertSequenceEqual(b'\x7f\x03\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 8, 8))
self.assertSequenceEqual(b'\x55\x55\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 16, 8))
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_64(self):
mu = Uc(UC_ARCH_X86, UC_MODE_64)
cs = Cs(CS_ARCH_X86, CS_MODE_64)
@@ -54,7 +54,7 @@ class FpuIP(regress.RegressTest):
mu.emu_start(BASE, BASE + len(CODE), count=5)
self.assertSequenceEqual(b'\x7f\x03\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 8, 8))
self.assertSequenceEqual(b'\x7f\x03\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 8, 8))
self.assertSequenceEqual(b'\x55\x55\x00\x00\x00\x00\x00\x00', mu.mem_read(STACK + 16, 8))

View File

@@ -1,14 +1,10 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b'\x9b\xd9\x3c\x24' # fstcw WORD PTR [esp]
b'\x59' # pop ecx
b'\x59' # pop ecx
)
BASE = 0x00000000
@@ -17,7 +13,6 @@ STACK = 0x00000f00
def hook_mem_write(uc, access, address, size, value, user_data):
regress.logger.debug("mem WRITE to: %#x, size = %u, value = %#x", address, size, value)
return True

View File

@@ -1,8 +1,5 @@
#!/usr/bin/python
import binascii
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -13,7 +10,7 @@ def hook_code(uc, address, size, user_data):
if size == 0xf1f1f1f1:
return
regress.logger.debug("[%#x] = %s" , address, binascii.hexlify(uc.mem_read(address, size)))
regress.logger.debug("[%#x] = %s", address, binascii.hexlify(uc.mem_read(address, size)))
# callback for tracing Linux interrupt
@@ -31,6 +28,7 @@ def hook_intr(uc, intno, user_data):
class Hang(regress.RegressTest):
def runTest(self):
# self modifying shellcode execve('/bin/sh')
shellcode = (

View File

@@ -1,11 +1,9 @@
#!/usr/bin/env python3
import regress
import sys
import unittest
from unicorn import Uc, UcError, UC_ARCH_X86, UC_MODE_64
from unicorn.unicorn_const import UC_TLB_VIRTUAL, UC_TLB_CPU, UC_ERR_FETCH_UNMAPPED
MAX_INTEL_INSN_SIZE = 15
@@ -23,8 +21,10 @@ class TestMem(regress.RegressTest):
self.uc.mem_map(address, 0x1000)
self.uc.mem_write(address, payload)
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_virt_high_mapping(self):
"""Mapping memory at high addresses should work when TLB mode
"""
Mapping memory at high addresses should work when TLB mode
is set to VIRTUAL.
"""
@@ -42,8 +42,10 @@ class TestMem(regress.RegressTest):
except UcError:
self.fail('high mapping failed at %#018x' % code)
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_cpu_high_mapping(self):
"""Mapping memory at high addresses should work fail TLB mode
"""
Mapping memory at high addresses should work fail TLB mode
is set to CPU (default).
"""

View File

@@ -1,21 +1,15 @@
#!/usr/bin/env python
"""https://github.com/unicorn-engine/unicorn/issues/165"""
""" https://github.com/unicorn-engine/unicorn/issues/165 """
import regress
from unicorn import *
def hook_mem_read_unmapped(mu, access, address, size, value, user_data):
pass
class TestHook(regress.RegressTest):
def test_excessive_hooks(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)
for _ in range(1337):
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped)
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED, lambda *args, **kwargs: None)
if __name__ == '__main__':

View File

@@ -1,10 +1,6 @@
#!/usr/bin/python
""" https://github.com/unicorn-engine/unicorn/issues/334 """
'''https://github.com/unicorn-engine/unicorn/issues/334'''
from __future__ import print_function
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -26,6 +22,7 @@ CODE = (
EP = ADDRESS + 0x54
def hook_code(mu, address, size, user_data):
regress.logger.debug(">>> Tracing instruction at %#x, instruction size = %u", address, size)
@@ -43,7 +40,7 @@ class HookCodeAddDelTest(regress.RegressTest):
i = emu.hook_add(UC_HOOK_CODE, hook_code, None)
emu.hook_del(i)
emu.emu_start(EP, EP + len(CODE), count = 3)
emu.emu_start(EP, EP + len(CODE), count=3)
regress.logger.debug("EIP: %#x", emu.reg_read(UC_X86_REG_EIP))

View File

@@ -1,11 +1,7 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b'\x48\xc7\xc0\x03\x00\x00\x00' # 0x1000: mov rax, 3
b'\x0f\x05' # 0x1007: syscall

View File

@@ -5,7 +5,7 @@ CODE = b"\x90" * 3
CODE_ADDR = 0x1000
class HookCounter(object):
class HookCounter:
"""Counts number of hook calls."""
def __init__(self):

View File

@@ -1,21 +1,18 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
PAGE_SIZE = 0x1000
ACCESS_ADDR = 0x1000
CODE = (
b'\xA1\x00\x10\x00\x00' # mov eax, [0x1000]
b'\xA1\x00\x10\x00\x00' # mov eax, [0x1000]
b'\xA1\x00\x10\x00\x00' # mov eax, [0x1000]
b'\xA1\x00\x10\x00\x00' # mov eax, [0x1000]
)
BASE = 0x00000000
def hook_mem_read(uc, access, address, size, value, data):
regress.logger.debug("Reading at %#x", address)
# BUG: unicorn will segfault when calling "uc.mem_write" to write to a location that was mapped only as UC_PROT_READ
@@ -29,7 +26,7 @@ class REP(regress.RegressTest):
mu.mem_map(BASE, PAGE_SIZE)
mu.mem_write(BASE, CODE)
mu.mem_map(ACCESS_ADDR, PAGE_SIZE, UC_PROT_READ)
mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read, begin = ACCESS_ADDR, end = ACCESS_ADDR + PAGE_SIZE)
mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read, begin=ACCESS_ADDR, end=ACCESS_ADDR + PAGE_SIZE)
mu.emu_start(BASE, BASE + len(CODE))

View File

@@ -1,32 +1,25 @@
#!/usr/bin/python
# By Mariano Graziano
import platform
import regress
import struct
import sys
import unittest
from unicorn import *
from unicorn.x86_const import *
if sys.version_info.major == 2:
range = xrange
mu = 0
class Init(regress.RegressTest):
def init_unicorn(self, ip, sp, counter):
global mu
#print "[+] Emulating IP: %x SP: %x - Counter: %x" % (ip, sp, counter)
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(0x1000000, 2 * 1024 * 1024)
mu.mem_write(0x1000000, b"\x90")
mu.mem_map(0x8000000, 8 * 1024 * 1024)
mu.reg_write(UC_X86_REG_RSP, sp)
regress.logger.debug("[+] Emulating IP: %x SP: %x - Counter: %x" % (ip, sp, counter))
self.emulator = Uc(UC_ARCH_X86, UC_MODE_64)
self.emulator.mem_map(0x1000000, 2 * 1024 * 1024)
self.emulator.mem_write(0x1000000, b"\x90")
self.emulator.mem_map(0x8000000, 8 * 1024 * 1024)
self.emulator.reg_write(UC_X86_REG_RSP, sp)
content = self.generate_value(counter)
mu.mem_write(sp, content)
self.emulator.mem_write(sp, content)
self.set_hooks()
def generate_value(self, counter):
@@ -36,46 +29,41 @@ class Init(regress.RegressTest):
return struct.pack("<Q", address)
def set_hooks(self):
global mu
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, self.hook_mem_invalid)
mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, self.hook_mem_fetch_unmapped)
self.emulator.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, self.hook_mem_invalid)
self.emulator.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, self.hook_mem_fetch_unmapped)
def hook_mem_invalid(self, uc, access, address, size, value, user_data):
global mu
regress.logger.debug("[ HOOK_MEM_INVALID - Address: 0x%x ]", address)
if access == UC_MEM_WRITE_UNMAPPED:
regress.logger.debug(">>> Missing memory is being WRITE at 0x%x, data size = %u, data value = 0x%x", address, size, value)
regress.logger.debug(">>> Missing memory is being WRITE at 0x%x, data size = %u, data value = 0x%x",
address, size, value)
address_page = address & 0xFFFFFFFFFFFFF000
mu.mem_map(address_page, 2 * 1024 * 1024)
mu.mem_write(address, str(value))
uc.mem_map(address_page, 2 * 1024 * 1024)
uc.mem_write(address, str(value))
return True
else:
return False
return False
def hook_mem_fetch_unmapped(self, uc, access, address, size, value, user_data):
global mu
regress.logger.debug("[ HOOK_MEM_FETCH - Address: 0x%x ]", address)
regress.logger.debug("[ mem_fetch_unmapped: faulting address at 0x%x ]", address)
mu.mem_write(0x1000003, b"\x90")
mu.reg_write(UC_X86_REG_RIP, 0x1000001)
uc.mem_write(0x1000003, b"\x90")
uc.reg_write(UC_X86_REG_RIP, 0x1000001)
return True
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
@unittest.skipIf(sys.platform == 'win32' or platform.machine().lower() not in ('x86_64', 'arm64'), 'TO BE CHECKED!')
def runTest(self):
global mu
ips = range(0x1000000, 0x1001000)
sps = range(0x8000000, 0x8001000)
for i, (ip, sp) in enumerate(zip(ips, sps)):
self.init_unicorn(ip, sp, i)
mu.emu_start(0x1000000, 0x1000000 + 0x1)
self.emulator.emu_start(0x1000000, 0x1000000 + 0x1)
if __name__ == '__main__':

View File

@@ -1,16 +1,12 @@
import regress
from unicorn import *
from unicorn.x86_const import *
from capstone import *
CODE = bytes.fromhex(
'48 31 c0' # xor rax,rax
'48 0f c7 f0' # rdrand rax
'f4' # hlt
CODE = (
b'\x48\x31\xc0' # xor rax,rax
b'\x48\x0f\xc7\xf0' # rdrand rax
b'\xf4' # hlt
)
BASE = 0x100000
@@ -41,7 +37,7 @@ def hook_invalid_insn(uc, ud):
# signal uc we are ok
return True
# not handled, uc will crash
return False

View File

@@ -1,13 +1,10 @@
#!/usr/bin/env python
# Test callback that returns False to cancel emulation
from __future__ import print_function
import regress
from unicorn import *
from unicorn.x86_const import *
import regress
X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], ecx; INC ecx; DEC edx
X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], ecx; INC ecx; DEC edx
# callback for tracing invalid memory access (READ or WRITE)

View File

@@ -1,16 +1,13 @@
#!/usr/bin/env python
"""See https://github.com/unicorn-engine/unicorn/issues/82"""
""" See https://github.com/unicorn-engine/unicorn/issues/82 """
import regress
from unicorn import *
from unicorn.x86_const import *
CODE_ADDR = 0x10101000
CODE = b'\xff\xe3' # jmp ebx
class JumEbxHang(regress.RegressTest):
def runTest(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)

View File

@@ -1,13 +1,11 @@
#!/usr/bin/env python
# Mariano Graziano
import binascii
import regress
import sys
import unittest
from unicorn import *
from unicorn.x86_const import *
# set rdx to either 0xbabe or 0xc0ca, based on a comparison.
# rdx would never be set to 0xbabe unless we set zf to 1
CODE = (
@@ -68,20 +66,20 @@ class Jumping(regress.RegressTest):
# callback for tracing instructions
def hook_code(self, uc, address, size, _):
insn = uc.mem_read(address, size)
regress.logger.debug(">>> Tracing instruction at %#x : %s", address, binascii.hexlify(insn))
regress.logger.debug(">>> Tracing instruction at %#x : %s", address, insn.hex())
regs = uc.reg_read_batch((
UC_X86_REG_RAX, UC_X86_REG_RBX, UC_X86_REG_RCX, UC_X86_REG_RDX,
UC_X86_REG_RSI, UC_X86_REG_RDI, UC_X86_REG_RBP, UC_X86_REG_RSP,
UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11,
UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11,
UC_X86_REG_R12, UC_X86_REG_R13, UC_X86_REG_R14, UC_X86_REG_R15,
UC_X86_REG_EFLAGS
))
zf = (regs[16] >> 6) & 0b1
regress.logger.debug(" RAX = %08x, R8 = %08x", regs[0], regs[ 8])
regress.logger.debug(" RBX = %08x, R9 = %08x", regs[1], regs[ 9])
regress.logger.debug(" RAX = %08x, R8 = %08x", regs[0], regs[8])
regress.logger.debug(" RBX = %08x, R9 = %08x", regs[1], regs[9])
regress.logger.debug(" RCX = %08x, R10 = %08x", regs[2], regs[10])
regress.logger.debug(" RDX = %08x, R11 = %08x", regs[3], regs[11])
regress.logger.debug(" RSI = %08x, R12 = %08x", regs[4], regs[12])
@@ -94,7 +92,6 @@ class Jumping(regress.RegressTest):
self.multipath()
regress.logger.debug("-" * 32)
def setUp(self):
# decide how to fixate zf value: 0 to clear, 1 to set
self.fixed_zf = 1
@@ -110,6 +107,7 @@ class Jumping(regress.RegressTest):
self.uc = uc
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
# tracing all basic blocks with customized callback
self.uc.hook_add(UC_HOOK_BLOCK, self.hook_block)
@@ -120,7 +118,8 @@ class Jumping(regress.RegressTest):
# emulate machine code in infinite time
self.uc.emu_start(BASE, BASE + len(CODE))
self.assertEqual(self.uc.reg_read(UC_X86_REG_RDX), 0xbabe, "rdx contains the wrong value. eflags modification failed")
self.assertEqual(self.uc.reg_read(UC_X86_REG_RDX), 0xbabe,
"rdx contains the wrong value. eflags modification failed")
if __name__ == '__main__':

View File

@@ -1,13 +1,9 @@
#!/usr/bin/python
import gc
import regress
import weakref
from unicorn import *
from unicorn.x86_const import *
ADDRESS = 0x8048000
STACK_ADDRESS = 0xffff000
STACK_SIZE = 0x1000
@@ -26,10 +22,10 @@ CODE = (
EP = ADDRESS + 0x54
# Dictionary to keep weak references to instances
instances = weakref.WeakValueDictionary()
def create_instance(key, *args, **kwargs):
obj = Uc(*args, **kwargs)
instances[key] = obj
@@ -52,22 +48,22 @@ def emu_loop(key):
i = emu.hook_add(UC_HOOK_CODE, hook_code, None)
emu.hook_del(i)
emu.emu_start(EP, EP + len(CODE), count = 3)
emu.emu_start(EP, EP + len(CODE), count=3)
regress.logger.debug("EIP: %#x", emu.reg_read(UC_X86_REG_EIP))
def debugMem():
gc.collect() # don't care about stuff that would be garbage collected properly
assert(len(instances) == 0)
class EmuLoopReferenceTest(regress.RegressTest):
def debug_mem(self):
gc.collect() # don't care about stuff that would be garbage collected properly
self.assertEqual(len(instances), 0)
def runTest(self):
for i in range(5):
emu_loop('obj%d' % i)
debugMem()
self.debug_mem()
if __name__ == '__main__':

View File

@@ -1,12 +1,9 @@
#!/usr/bin/python
# By Ryan Hileman, issue #9
# this prints out 2 lines and the contents must be the same
import regress
from unicorn import *
from unicorn.x86_const import *
class MemMap(regress.RegressTest):
@@ -40,7 +37,7 @@ class MemMap(regress.RegressTest):
for i in range(20):
with self.assertRaises(UcError):
u.mem_map(i * 0x1000, 5)
u.mem_read(i * 0x1000+6, 1)
u.mem_read(i * 0x1000 + 6, 1)
if __name__ == '__main__':

View File

@@ -1,9 +1,5 @@
#!/usr/bin/env python
import regress
from unicorn import *
from unicorn.x86_const import *
class MmapSeg1(regress.RegressTest):

View File

@@ -1,15 +1,13 @@
#!/usr/bin/python
import regress
import sys
import unittest
from capstone import *
from unicorn import *
CODE = (
b'\x00\x00\xa4\x12' # beq $a0, $s5, 0x4008a0
b'\x6a\x00\x82\x28' # slti $v0, $a0, 0x6a
b'\x00\x00\x00\x00' # nop
b'\x00\x00\xa4\x12' # beq $a0, $s5, 0x4008a0
b'\x6a\x00\x82\x28' # slti $v0, $a0, 0x6a
b'\x00\x00\x00\x00' # nop
)
BASE = 0x400000
@@ -17,6 +15,7 @@ BASE = 0x400000
class MipsBranchDelay(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN)

View File

@@ -1,11 +1,8 @@
import regress
from unicorn import *
from unicorn.mips_const import *
CODE = b'\x44\x43\xF8\x00' # cfc1 $v1, FCSR
CODE = b'\x44\x43\xF8\x00' # cfc1 $v1, FCSR
BASE = 0x416CB0

View File

@@ -1,14 +1,12 @@
#!/usr/bin/python
import regress
import sys
import unittest
from unicorn import *
from unicorn.mips_const import *
CODE = (
b'\x00\x00\x00\x00' # nop
b'\x00\x00\xa4\x8f' # lw $a0, 0($sp)
b'\x00\x00\x00\x00' # nop
b'\x00\x00\xa4\x8f' # lw $a0, 0($sp)
)
BASE = 0x20000000
@@ -16,6 +14,7 @@ BASE = 0x20000000
class MipsExcept(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)

View File

@@ -1,16 +1,12 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.mips_const import *
CODE = b'\x34\x21\x34\x56' # ori $at, $at, 0x3456
CODE = b'\x34\x21\x34\x56' # ori $at, $at, 0x3456
BASE = 0x10000000
class MipsSyscall(regress.RegressTest):
class MipsKernelMMU(regress.RegressTest):
def test_syscall(self):
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)

View File

@@ -1,27 +1,26 @@
#!/usr/bin/python
import regress
import sys
import unittest
from unicorn import *
from unicorn.mips_const import *
CODE = (
b'\xf8\xff\x01\x24' # addiu $at, $zero, -8
b'\x24\xe8\xa1\x03' # and $sp, $sp, $at
b'\x09\xf8\x20\x03' # jalr $t9
b'\xe8\xff\xbd\x23' # addi $sp, $sp, -0x18
b'\xb8\xff\xbd\x27' # addiu $sp, $sp, -0x48
b'\x00\x00\x00\x00' # nop
b'\xf8\xff\x01\x24' # addiu $at, $zero, -8
b'\x24\xe8\xa1\x03' # and $sp, $sp, $at
b'\x09\xf8\x20\x03' # jalr $t9
b'\xe8\xff\xbd\x23' # addi $sp, $sp, -0x18
b'\xb8\xff\xbd\x27' # addiu $sp, $sp, -0x48
b'\x00\x00\x00\x00' # nop
)
BASE = 0x4010dc
def code_hook(uc, addr, size, user_data):
regress.logger.debug('code hook: pc=%08x sp=%08x', addr, uc.reg_read(UC_MIPS_REG_SP))
def run(step) -> int:
def run(step):
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)
if step:
@@ -45,6 +44,8 @@ def run(step) -> int:
class MipsSingleStep(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
sp1 = run(step=False)
sp2 = run(step=True)

View File

@@ -1,16 +1,14 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.mips_const import *
CODE = b'\x0c\x00\x00\x00' # syscall
BASE = 0x40000
def intr_hook(uc, intno, data):
regress.logger.debug('interrupt=%d, v0=%d, pc=%#010x', intno, uc.reg_read(UC_MIPS_REG_V0), uc.reg_read(UC_MIPS_REG_PC))
regress.logger.debug('interrupt=%d, v0=%d, pc=%#010x', intno, uc.reg_read(UC_MIPS_REG_V0),
uc.reg_read(UC_MIPS_REG_PC))
class MipsSyscall(regress.RegressTest):
@@ -22,7 +20,7 @@ class MipsSyscall(regress.RegressTest):
uc.reg_write(UC_MIPS_REG_V0, 100)
uc.hook_add(UC_HOOK_INTR, intr_hook)
uc.emu_start(BASE, BASE+len(CODE))
uc.emu_start(BASE, BASE + len(CODE))
self.assertEqual(0x40004, uc.reg_read(UC_MIPS_REG_PC))

View File

@@ -1,11 +1,7 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b'\x8e\xe8' # mov gs, eax
b'\xb8\x01\x00\x00\x00' # mov eax, 1
@@ -14,7 +10,7 @@ CODE = (
BASE = 0x1000
class VldrPcInsn(regress.RegressTest):
class MovGsEax(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_X86, UC_MODE_32)

View File

@@ -1,12 +1,10 @@
#!/usr/bin/python
# By Ryan Hileman, issue #3
import regress
import sys
import unittest
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
from unicorn import *
from unicorn.x86_const import *
CODE = b'\xf2\x0f\x10\x05\xaa\x12\x00\x00'
@@ -24,6 +22,8 @@ def hook_code(uc, addr, size, md):
class Movsd(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
addr = 0x400000
mu = Uc(UC_ARCH_X86, UC_MODE_64)

View File

@@ -1,9 +1,7 @@
#!/usr/bin/env python
import regress
from unicorn import *
# OS X: OK with 2047 iterations.
# OS X: Crashes at 2048:th iteration ("qemu: qemu_thread_create: Resource temporarily unavailable").
# Linux: No crashes observed.

View File

@@ -1,15 +1,22 @@
#!/usr/bin/env python
import platform
import resource
import regress
import sys
import unittest
from unicorn import *
try:
# Only available on Unix: https://docs.python.org/3/library/resource.html
import resource
except:
pass
ITERATIONS = 10000
class MemoryLeak(regress.RegressTest):
@unittest.skipIf(sys.platform == 'win32', reason='Test for Unix only')
@unittest.skipIf(platform.machine().lower() == 'aarch64', reason='TO BE CHECKED!')
def test(self):
if platform.system() == "Darwin":
rusage_multiplier = 1

View File

@@ -1,8 +1,6 @@
#!/usr/bin/python
# By Ryan Hileman, issue #91
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -15,7 +13,7 @@ class Pshufb(regress.RegressTest):
uc.mem_map(0x2000, 0x1000)
uc.mem_write(0x2000, b'\x66\x0f\x38\x00\xc1') # pshufb xmm0, xmm1
uc.mem_write(0x2000, b'\x66\x0f\x38\x00\xc1') # pshufb xmm0, xmm1
# Invalid instruction -> test failed
uc.emu_start(0x2000, 0x2005)

View File

@@ -1,27 +1,23 @@
#!/usr/bin/env python
"""See https://github.com/unicorn-engine/unicorn/issues/98"""
""" See https://github.com/unicorn-engine/unicorn/issues/98 """
import regress
from unicorn import *
ADDR = 0xffaabbcc
def hook_mem_invalid(mu, access, address, size, value, user_data):
regress.logger.debug(">>> Access type: %u, expected value: 0x%x, actual value: 0x%x", access, ADDR, address)
assert(address == ADDR)
mu.mem_map(address & 0xfffff000, 4 * 1024)
mu.mem_write(address, b'\xcc')
return True
class RegWriteSignExt(regress.RegressTest):
def hook_mem_invalid(self, mu, access, address, size, value, user_data):
regress.logger.debug(">>> Access type: %u, expected value: 0x%x, actual value: 0x%x", access, ADDR, address)
self.assertEqual(address, ADDR)
mu.mem_map(address & 0xfffff000, 4 * 1024)
mu.mem_write(address, b'\xcc')
return True
def runTest(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.reg_write(x86_const.UC_X86_REG_EBX, ADDR)
@@ -30,7 +26,7 @@ class RegWriteSignExt(regress.RegressTest):
# jmp ebx
mu.mem_write(0x10000000, b'\xff\xe3')
mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid)
mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_FETCH_PROT, self.hook_mem_invalid)
mu.emu_start(0x10000000, 0x10000000 + 2, count=1)

View File

@@ -1,27 +1,25 @@
#!/usr/bin/env python
import glob
import logging
import os
import unittest
class RegressTest(unittest.TestCase):
"""Regress test case dummy class.
"""
""" Regress test case dummy class. """
def main():
unittest.main()
def __setup_logger(name):
"""Set up a unified logger for all tests.
"""
""" Set up a unified logger for all tests. """
instance = logging.getLogger(name)
instance.propagate = False
handler = logging.StreamHandler()
formatter = logging.Formatter('[%(levelname)s] %(message)s')
if not instance.hasHandlers():
if not instance.handlers:
handler = logging.StreamHandler()
formatter = logging.Formatter('[%(levelname)s] %(message)s')
handler.setFormatter(formatter)
instance.addHandler(handler)
@@ -29,36 +27,4 @@ def __setup_logger(name):
logger = __setup_logger('UnicornRegress')
logger.setLevel(os.environ.get("UNICORN_DEBUG", "INFO").upper())
def main():
unittest.main()
if __name__ == '__main__':
suite = unittest.TestSuite()
logger.info('starting discovery')
# Find all unittest type in this directory and run it.
directory = os.path.dirname(__file__) or '.'
pyfiles = glob.glob(directory + '/*.py')
modules = [os.path.splitext(os.path.basename(f))[0] for f in pyfiles if os.path.isfile(f) and f != __file__]
logger.info('%d test modules found', len(modules))
for mname in modules:
try:
module = __import__(mname)
except ImportError as ex:
logger.error('could not load %s: %s is missing', mname, ex.name)
else:
tests = unittest.defaultTestLoader.loadTestsFromModule(module)
suite.addTests(tests)
logger.debug('found %d test cases in %s', tests.countTestCases(), mname)
logger.info('%d test cases were added', suite.countTestCases())
unittest.TextTestRunner().run(suite)
logger.setLevel((os.getenv('REGRESS_LOG_LEVEL') or 'INFO').upper())

View File

@@ -1,11 +1,7 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
PAGE_SIZE = 0x1000
CODE = b'\xf3\xaa' # rep stosb

View File

@@ -1,4 +1,3 @@
#!/usr/bin/python
#
# This test demonstrates emulation behavior within and across
# basic blocks.
@@ -6,11 +5,9 @@
import binascii
import struct
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b"\xb8\x00\x00\x00\x00" # 1000: mov eax,0x0
b"\x40" # 1005: inc eax
@@ -22,7 +19,7 @@ CODE = (
b"\xcc" # 100f: int3
b"\xb8\x00\x00\x00\x00" # 1010: mov eax,0x0
b"\x40" # 1015: inc eax
b"\x40" # 1016: inc eax
b"\x40" # 1016: inc eax
)
@@ -116,13 +113,11 @@ class RunAcrossBBTest(regress.RegressTest):
showpc(mu)
#######################################################################
# emu_run ONE:
# exectue four instructions, until the last instruction in a BB
#######################################################################
mu.emu_start(0x1000, 0x100c)
# should exec the following four instructions:
# 1000: b8 00 00 00 00 mov eax,0x0 <
@@ -134,22 +129,20 @@ class RunAcrossBBTest(regress.RegressTest):
self.assertEqual(0x100c, mu.reg_read(UC_X86_REG_EIP), "unexpected PC (2)")
# single push, so stack diff is 0x4
TOP_OF_STACK = 0x2800-0x4
TOP_OF_STACK = 0x2800 - 0x4
self.assertEqual(TOP_OF_STACK, mu.reg_read(UC_X86_REG_ESP), "unexpected SP (2)")
# top of stack should be 0x1010
self.assertEqual(0x1010,
self.assertEqual(0x1010,
struct.unpack("<I", mu.mem_read(TOP_OF_STACK, 0x4))[0],
"unexpected stack value")
showpc(mu)
#######################################################################
# emu_run TWO
# execute one instruction that jumps to a new BB
#######################################################################
mu.emu_start(0x100c, 0x1010)
# should exec one instruction that jumps to 0x1010:
# 100c: c3 ret -----------+
@@ -165,21 +158,18 @@ class RunAcrossBBTest(regress.RegressTest):
self.assertEqual(0x2800, mu.reg_read(UC_X86_REG_ESP), "unexpected SP (3)")
showpc(mu)
#######################################################################
# emu_run THREE
# execute three instructions to verify things work as expected
#######################################################################
mu.emu_start(0x1010, 0x1016)
# should exec the following three instructions:
# 1010: b8 00 00 00 00 mov eax,0x0 <
# 1015: 40 inc eax <
# 1016: 40 inc eax <
self.assertEqual(0x1016, mu.reg_read(UC_X86_REG_EIP),
"unexpected PC (4): 0x%x vs 0x%x" % (
0x1016, mu.reg_read(UC_X86_REG_EIP)))
"unexpected PC (4): 0x%x vs 0x%x" % (0x1016, mu.reg_read(UC_X86_REG_EIP)))
showpc(mu)
except UcError as e:

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env python
import regress
import unicorn
@@ -9,5 +7,6 @@ class SegfaultOnStop(regress.RegressTest):
unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_64).emu_stop()
self.assertTrue(True, "If not reached, then we have a crashing bug.")
if __name__ == '__main__':
regress.main()

View File

@@ -1,21 +1,18 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.sparc_const import *
CODE = (
b"\xb0\x06\x20\x01" # 0: b0 06 20 01 inc %i0
b"\xb2\x06\x60\x01" # 4: b2 06 60 01 inc %i1
b"\xb0\x06\x20\x01" # 0: b0 06 20 01 inc %i0
b"\xb2\x06\x60\x01" # 4: b2 06 60 01 inc %i1
)
BASE = 0x00000000
class TestSparcRegRead(regress.RegressTest):
class TestSparc64RegRead(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC64|UC_MODE_BIG_ENDIAN)
uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC64 | UC_MODE_BIG_ENDIAN)
uc.mem_map(BASE, 0x1000 ** 2)
uc.mem_write(BASE, CODE)

View File

@@ -1,46 +1,44 @@
#!/usr/bin/python
import regress
import sys
import unittest
from unicorn import *
from unicorn.sparc_const import *
PAGE_SIZE = 1 * 1024 * 1024
CODE =(
b"\x80\x00\x20\x01" # add %g0, 1, %g0
b"\x82\x00\x60\x01" # add %g1, 1, %g1
b"\x84\x00\xA0\x01" # add %g2, 1, %g2
b"\x86\x00\xE0\x01" # add %g3, 1, %g3
b"\x88\x01\x20\x01" # add %g4, 1, %g4
b"\x8A\x01\x60\x01" # add %g5, 1, %g5
b"\x8C\x01\xA0\x01" # add %g6, 1, %g6
b"\x8E\x01\xE0\x01" # add %g7, 1, %g7
b"\x90\x02\x20\x01" # add %o0, 1, %o0
b"\x92\x02\x60\x01" # add %o1, 1, %o1
b"\x94\x02\xA0\x01" # add %o2, 1, %o2
b"\x96\x02\xE0\x01" # add %o3, 1, %o3
b"\x98\x03\x20\x01" # add %o4, 1, %o4
b"\x9A\x03\x60\x01" # add %o5, 1, %o5
b"\x9C\x03\xA0\x01" # add %sp, 1, %sp
b"\x9E\x03\xE0\x01" # add %o7, 1, %o7
b"\xA0\x04\x20\x01" # add %l0, 1, %l0
b"\xA2\x04\x60\x01" # add %l1, 1, %l1
b"\xA4\x04\xA0\x01" # add %l2, 1, %l2
b"\xA6\x04\xE0\x01" # add %l3, 1, %l3
b"\xA8\x05\x20\x01" # add %l4, 1, %l4
b"\xAA\x05\x60\x01" # add %l5, 1, %l5
b"\xAC\x05\xA0\x01" # add %l6, 1, %l6
b"\xAE\x05\xE0\x01" # add %l7, 1, %l7
b"\xB0\x06\x20\x01" # add %i0, 1, %i0
b"\xB2\x06\x60\x01" # add %i1, 1, %i1
b"\xB4\x06\xA0\x01" # add %i2, 1, %i2
b"\xB6\x06\xE0\x01" # add %i3, 1, %i3
b"\xB8\x07\x20\x01" # add %i4, 1, %i4
b"\xBA\x07\x60\x01" # add %i5, 1, %i5
b"\xBC\x07\xA0\x01" # add %fp, 1, %fp
b"\xBE\x07\xE0\x01" # add %i7, 1, %i7
CODE = (
b"\x80\x00\x20\x01" # add %g0, 1, %g0
b"\x82\x00\x60\x01" # add %g1, 1, %g1
b"\x84\x00\xA0\x01" # add %g2, 1, %g2
b"\x86\x00\xE0\x01" # add %g3, 1, %g3
b"\x88\x01\x20\x01" # add %g4, 1, %g4
b"\x8A\x01\x60\x01" # add %g5, 1, %g5
b"\x8C\x01\xA0\x01" # add %g6, 1, %g6
b"\x8E\x01\xE0\x01" # add %g7, 1, %g7
b"\x90\x02\x20\x01" # add %o0, 1, %o0
b"\x92\x02\x60\x01" # add %o1, 1, %o1
b"\x94\x02\xA0\x01" # add %o2, 1, %o2
b"\x96\x02\xE0\x01" # add %o3, 1, %o3
b"\x98\x03\x20\x01" # add %o4, 1, %o4
b"\x9A\x03\x60\x01" # add %o5, 1, %o5
b"\x9C\x03\xA0\x01" # add %sp, 1, %sp
b"\x9E\x03\xE0\x01" # add %o7, 1, %o7
b"\xA0\x04\x20\x01" # add %l0, 1, %l0
b"\xA2\x04\x60\x01" # add %l1, 1, %l1
b"\xA4\x04\xA0\x01" # add %l2, 1, %l2
b"\xA6\x04\xE0\x01" # add %l3, 1, %l3
b"\xA8\x05\x20\x01" # add %l4, 1, %l4
b"\xAA\x05\x60\x01" # add %l5, 1, %l5
b"\xAC\x05\xA0\x01" # add %l6, 1, %l6
b"\xAE\x05\xE0\x01" # add %l7, 1, %l7
b"\xB0\x06\x20\x01" # add %i0, 1, %i0
b"\xB2\x06\x60\x01" # add %i1, 1, %i1
b"\xB4\x06\xA0\x01" # add %i2, 1, %i2
b"\xB6\x06\xE0\x01" # add %i3, 1, %i3
b"\xB8\x07\x20\x01" # add %i4, 1, %i4
b"\xBA\x07\x60\x01" # add %i5, 1, %i5
b"\xBC\x07\xA0\x01" # add %fp, 1, %fp
b"\xBE\x07\xE0\x01" # add %i7, 1, %i7
)
BASE = 0x00000000
@@ -50,7 +48,9 @@ def hook_code(uc, addr, size, ud):
regress.logger.debug("executing at 0x%04x", uc.reg_read(UC_SPARC_REG_PC))
class TestSparcRegRead(regress.RegressTest):
class TestSparc32RegRead(regress.RegressTest):
@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def runTest(self):
uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC32 | UC_MODE_BIG_ENDIAN)
@@ -63,7 +63,7 @@ class TestSparcRegRead(regress.RegressTest):
uc.hook_add(UC_HOOK_CODE, hook_code)
uc.emu_start(BASE, len(CODE))
self.assertEqual(0, uc.reg_read(UC_SPARC_REG_G0)) # G0 is always zero
self.assertEqual(0, uc.reg_read(UC_SPARC_REG_G0)) # G0 is always zero
self.assertEqual(1, uc.reg_read(UC_SPARC_REG_G1))
self.assertEqual(1, uc.reg_read(UC_SPARC_REG_G2))
self.assertEqual(1, uc.reg_read(UC_SPARC_REG_G3))

View File

@@ -1,10 +1,7 @@

import regress
import regress
from unicorn import *
from unicorn.arm_const import *
# issue #287
# Initial Register States: R0=3, R1=24, R2=16, R3=0
#
@@ -90,16 +87,17 @@ from unicorn.arm_const import *
CODE = (
b'\xa1\x01\x50\xe1' # cmp r0, r1, lsr #3
b'\xa1\x01\x40\x20' # subhs r0, r0, r1, lsr #3
b'\x01\x00\x50\xe3' # cmp r0, #1
b'\x21\x12\xa0\xe1' # lsr r1, r1, #4
b'\x04\x20\x52\xa2' # subsge r2, r2, #4
b'\x64\x30\xa0\xa3' # movge r3, #0x64
b'\xa1\x01\x50\xe1' # cmp r0, r1, lsr #3
b'\xa1\x01\x40\x20' # subhs r0, r0, r1, lsr #3
b'\x01\x00\x50\xe3' # cmp r0, #1
b'\x21\x12\xa0\xe1' # lsr r1, r1, #4
b'\x04\x20\x52\xa2' # subsge r2, r2, #4
b'\x64\x30\xa0\xa3' # movge r3, #0x64
)
BASE = 0x00000000
def show_regs(uc):
regress.logger.debug('R0 : %08x', uc.reg_read(UC_ARM_REG_R0))
regress.logger.debug('R1 : %08x', uc.reg_read(UC_ARM_REG_R1))
@@ -126,7 +124,7 @@ def show_regs(uc):
regress.logger.debug('zero : %d', (flags >> 30) & 0b1)
class TestReadMem(regress.RegressTest):
class TestIssue287(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)

View File

@@ -1,9 +1,9 @@
#!/usr/bin/python
# By Mariano Graziano
import struct
import platform
import regress
import struct
import unittest
from unicorn import *
from unicorn.x86_const import *
@@ -21,7 +21,7 @@ class Emulator:
regress.logger.debug("mapping code : %#x", __page_aligned(code))
regress.logger.debug("mapping stack : %#x", __page_aligned(stack))
self.mu.mem_map(__page_aligned(code), 0x1000)
self.mu.mem_map(__page_aligned(code), 0x1000)
self.mu.mem_map(__page_aligned(stack), 0x1000)
self.mu.reg_write(UC_X86_REG_RSP, stack)
@@ -44,7 +44,8 @@ class Emulator:
return True
def hook_mem_invalid(self, uc, access, address, size, value, user_data):
regress.logger.debug("invalid mem access: access type = %d, to = %#x, size = %u, value = %#x", access, address, size, value)
regress.logger.debug("invalid mem access: access type = %d, to = %#x, size = %u, value = %#x", access, address,
size, value)
return True
@@ -65,7 +66,7 @@ class Emulator:
self.mu.reg_write(reg, value)
class Init(regress.RegressTest):
class TranslatorBuffer(regress.RegressTest):
def init_unicorn(self, ip, sp, magic):
emu = Emulator(ip, sp)
@@ -74,10 +75,11 @@ class Init(regress.RegressTest):
emu.emu(1)
@unittest.skipIf(platform.machine().lower() == 'aarch64', reason='TO BE CHECKED!')
def runTest(self):
ip_base = 0x000fffff816a0000 # was: 0xffffffff816a0000
sp_base = 0x000f88001b800000 # was: 0xffff88001b800000
mg_base = 0x000f880026f02000 # was: 0xffff880026f02000
ip_base = 0x000fffff816a0000 # was: 0xffffffff816a0000
sp_base = 0x000f88001b800000 # was: 0xffff88001b800000
mg_base = 0x000f880026f02000 # was: 0xffff880026f02000
ips = range(0x9000, 0xf000, 8)
sps = range(0x0000, 0x6000, 8)

View File

@@ -1,25 +1,21 @@
#!/usr/bin/env python
# Moshe Kravchik
import binascii
import regress
from unicorn import *
from unicorn.arm_const import *
#enable VFP
# enable VFP
ENABLE_VFP_CODE = (
b"\x4f\xf4\x70\x03" # 00000016 mov.w r3, #0xf00000
b"\x01\xee\x50\x3f" # 0000001a mcr p15, #0x0, r3, c1, c0, #0x2
b"\xbf\xf3\x6f\x8f" # 0000bfb6 isb sy
b"\x4f\xf0\x80\x43" # 0000bfba mov.w r3, #0x40000000
b"\xe8\xee\x10\x3a" # 0000bfbe vmsr fpexc, r3
b"\x4f\xf4\x70\x03" # 00000016 mov.w r3, #0xf00000
b"\x01\xee\x50\x3f" # 0000001a mcr p15, #0x0, r3, c1, c0, #0x2
b"\xbf\xf3\x6f\x8f" # 0000bfb6 isb sy
b"\x4f\xf0\x80\x43" # 0000bfba mov.w r3, #0x40000000
b"\xe8\xee\x10\x3a" # 0000bfbe vmsr fpexc, r3
)
VLD_CODE = b"\x21\xf9\x0f\x6a" # 0000002a vld1.8 {d6, d7}, [r1]
VST_CODE = b"\x00\xf9\x0f\x6a" # 0000002e vst1.8 {d6, d7}, [r0]
VLD_CODE = b"\x21\xf9\x0f\x6a" # 0000002a vld1.8 {d6, d7}, [r1]
VST_CODE = b"\x00\xf9\x0f\x6a" # 0000002e vst1.8 {d6, d7}, [r0]
# memory address where emulation starts
ADDRESS = 0x10000
@@ -27,8 +23,9 @@ SCRATCH_ADDRESS = 0x1000
class SIMDNotReadArm(regress.RegressTest):
def runTest(self):
code = ENABLE_VFP_CODE+VLD_CODE+VST_CODE
code = ENABLE_VFP_CODE + VLD_CODE + VST_CODE
regress.logger.debug("Emulate THUMB code")
# Initialize emulator in thumb mode
@@ -84,7 +81,7 @@ class SIMDNotReadArm(regress.RegressTest):
regress.logger.debug(">>> PC = %#x", mu.reg_read(UC_ARM_REG_PC))
for i in range(UC_ARM_REG_R0, UC_ARM_REG_R12):
regress.logger.debug("\tR%d = %#x", (i-UC_ARM_REG_R0), mu.reg_read(i))
regress.logger.debug("\tR%d = %#x", (i - UC_ARM_REG_R0), mu.reg_read(i))
regress.logger.debug("\tD6 = %#x", mu.reg_read(UC_ARM_REG_D6))
regress.logger.debug("\tD7 = %#x", mu.reg_read(UC_ARM_REG_D7))

View File

@@ -1,12 +1,8 @@
#!/usr/bin/env python
import regress
from unicorn import *
from unicorn.x86_const import *
X86_CODE64 = b"\x90" # NOP
X86_CODE64 = b"\x90" # NOP
class WriteBeforeMap(regress.RegressTest):

View File

@@ -1,12 +1,10 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
import regress
binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2
binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1
binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2
binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1
class WrongRIP(regress.RegressTest):
@@ -40,7 +38,7 @@ class WrongRIP(regress.RegressTest):
self.assertEqual(0xa, mu.reg_read(UC_X86_REG_RIP))
def test_step3(self):
bin3 = b'\x40\x01\xc1\x31\xf6' # inc eax; add ecx, eax; xor esi, esi
bin3 = b'\x40\x01\xc1\x31\xf6' # inc eax; add ecx, eax; xor esi, esi
mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0, 2 * 1024 * 1024)
# write machine code to be emulated to memory
@@ -51,7 +49,7 @@ class WrongRIP(regress.RegressTest):
self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EIP))
def test_step_then_fin(self):
bin4 = b'\x40\x01\xc1\x31\xf6\x90\x90\x90' # inc eax; add ecx, eax; xor esi, esi
bin4 = b'\x40\x01\xc1\x31\xf6\x90\x90\x90' # inc eax; add ecx, eax; xor esi, esi
mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0, 2 * 1024 * 1024)
# write machine code to be emulated to memory
@@ -66,6 +64,6 @@ class WrongRIP(regress.RegressTest):
self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EAX))
self.assertEqual(len(bin4), mu.reg_read(UC_X86_REG_EIP))
if __name__ == '__main__':
regress.main()

View File

@@ -1,22 +1,17 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
from unicorn.arm_const import *
CODE = (
b'\x48\x31' # adds r1, #0x48
b'\xff\x57' # ldrsb r7, [r7, r7]
b'\x57\x5e' # ldrsh r7, [r2, r1]
b'\x5a\x48' # ldr r0, [pc, #0x168]
b'\xbf\x2f' # cmp r7, #0xbf
b'\x2f\x62' # str r7, [r5, #0x20]
b'\x69\x6e' # ldr r1, [r5, #0x64]
b'\x2f\x73' # strb r7, [r5, #0xc]
b'\x68\x48' # ldr r0, [pc, #0x1a0]
b'\x48\x31' # adds r1, #0x48
b'\xff\x57' # ldrsb r7, [r7, r7]
b'\x57\x5e' # ldrsh r7, [r2, r1]
b'\x5a\x48' # ldr r0, [pc, #0x168]
b'\xbf\x2f' # cmp r7, #0xbf
b'\x2f\x62' # str r7, [r5, #0x20]
b'\x69\x6e' # ldr r1, [r5, #0x64]
b'\x2f\x73' # strb r7, [r5, #0xc]
b'\x68\x48' # ldr r0, [pc, #0x1a0]
b'\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05' # data?
)

View File

@@ -1,11 +1,10 @@
#!/usr/bin/python
# By Ryan Hileman, issue #16
import regress
from unicorn import *
from unicorn.arm_const import *
from unicorn.arm64_const import *
import regress
class WrongSPArm(regress.RegressTest):
@@ -24,5 +23,6 @@ class WrongSPArm(regress.RegressTest):
uc.reg_write(UC_ARM_REG_SP, 4)
self.assertEqual(0x4, uc.reg_read(UC_ARM_REG_SP))
if __name__ == '__main__':
regress.main()

View File

@@ -1,7 +1,4 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *

View File

@@ -1,7 +1,4 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -19,7 +16,6 @@ class WrongEFLAGS(regress.RegressTest):
uc.mem_write(0x6000b0, CODE)
uc.emu_start(0x6000b0, 0, count=1)
# Here's the original execution trace for this on actual hardware.
#
# (gdb) x/i $pc

View File

@@ -1,11 +1,7 @@
#!/usr/bin/env python
import regress
from unicorn import *
from unicorn.x86_const import *
CODE_ADDR = 0x40000
CODE_SIZE = 0x1000
@@ -15,16 +11,15 @@ SCRATCH_SIZE = 0x1000
SEGMENT_ADDR = 0x5000
SEGMENT_SIZE = 0x1000
FSMSR = 0xC0000100
GSMSR = 0xC0000101
def set_msr(uc, msr, value, scratch=SCRATCH_ADDR):
'''
"""
set the given model-specific register (MSR) to the given value.
this will clobber some memory at the given scratch address, as it emits some code.
'''
"""
# save clobbered registers
orax = uc.reg_read(UC_X86_REG_RAX)
ordx = uc.reg_read(UC_X86_REG_RDX)
@@ -37,7 +32,7 @@ def set_msr(uc, msr, value, scratch=SCRATCH_ADDR):
uc.reg_write(UC_X86_REG_RAX, value & 0xFFFFFFFF)
uc.reg_write(UC_X86_REG_RDX, (value >> 32) & 0xFFFFFFFF)
uc.reg_write(UC_X86_REG_RCX, msr & 0xFFFFFFFF)
uc.emu_start(scratch, scratch+len(buf), count=1)
uc.emu_start(scratch, scratch + len(buf), count=1)
# restore clobbered registers
uc.reg_write(UC_X86_REG_RAX, orax)
@@ -47,10 +42,10 @@ def set_msr(uc, msr, value, scratch=SCRATCH_ADDR):
def get_msr(uc, msr, scratch=SCRATCH_ADDR):
'''
"""
fetch the contents of the given model-specific register (MSR).
this will clobber some memory at the given scratch address, as it emits some code.
'''
"""
# save clobbered registers
orax = uc.reg_read(UC_X86_REG_RAX)
ordx = uc.reg_read(UC_X86_REG_RDX)
@@ -61,7 +56,7 @@ def get_msr(uc, msr, scratch=SCRATCH_ADDR):
buf = b'\x0f\x32'
uc.mem_write(scratch, buf)
uc.reg_write(UC_X86_REG_RCX, msr & 0xFFFFFFFF)
uc.emu_start(scratch, scratch+len(buf), count=1)
uc.emu_start(scratch, scratch + len(buf), count=1)
eax = uc.reg_read(UC_X86_REG_EAX)
edx = uc.reg_read(UC_X86_REG_EDX)
@@ -75,32 +70,32 @@ def get_msr(uc, msr, scratch=SCRATCH_ADDR):
def set_gs(uc, addr):
'''
"""
set the GS.base hidden descriptor-register field to the given address.
this enables referencing the gs segment on x86-64.
'''
"""
return set_msr(uc, GSMSR, addr)
def get_gs(uc):
'''
"""
fetch the GS.base hidden descriptor-register field.
'''
"""
return get_msr(uc, GSMSR)
def set_fs(uc, addr):
'''
"""
set the FS.base hidden descriptor-register field to the given address.
this enables referencing the fs segment on x86-64.
'''
"""
return set_msr(uc, FSMSR, addr)
def get_fs(uc):
'''
"""
fetch the FS.base hidden descriptor-register field.
'''
"""
return get_msr(uc, FSMSR)
@@ -124,12 +119,12 @@ class TestGetSetMSR(regress.RegressTest):
code = b'\x65\x48\x33\x0C\x25\x18\x00\x00\x00' # xor rcx, qword ptr gs:[0x18]
uc.mem_write(CODE_ADDR, code)
uc.mem_write(SEGMENT_ADDR+0x18, b'AAAAAAAA')
uc.mem_write(SEGMENT_ADDR + 0x18, b'AAAAAAAA')
set_gs(uc, SEGMENT_ADDR)
self.assertEqual(SEGMENT_ADDR, get_gs(uc))
uc.emu_start(CODE_ADDR, CODE_ADDR+len(code))
uc.emu_start(CODE_ADDR, CODE_ADDR + len(code))
self.assertEqual(uc.reg_read(UC_X86_REG_RCX), 0x4141414141414141)
@@ -142,12 +137,12 @@ class TestGetSetMSR(regress.RegressTest):
code = b'\x64\x48\x33\x0C\x25\x18\x00\x00\x00' # xor rcx, qword ptr fs:[0x18]
uc.mem_write(CODE_ADDR, code)
uc.mem_write(SEGMENT_ADDR+0x18, b'AAAAAAAA')
uc.mem_write(SEGMENT_ADDR + 0x18, b'AAAAAAAA')
set_fs(uc, SEGMENT_ADDR)
self.assertEqual(SEGMENT_ADDR, get_fs(uc))
uc.emu_start(CODE_ADDR, CODE_ADDR+len(code))
uc.emu_start(CODE_ADDR, CODE_ADDR + len(code))
self.assertEqual(uc.reg_read(UC_X86_REG_RCX), 0x4141414141414141)

View File

@@ -1,7 +1,4 @@
#!/usr/bin/python
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -21,7 +18,6 @@ class WrongEFLAGS2(regress.RegressTest):
uc.mem_write(0x6000b0, CODE)
uc.emu_start(0x6000b0, 0, count=1)
# Here's the original execution trace for this on actual hardware.
#
# (gdb) x/i $eip
@@ -39,5 +35,6 @@ class WrongEFLAGS2(regress.RegressTest):
self.assertEqual(0x202, uc.reg_read(UC_X86_REG_EFLAGS))
if __name__ == '__main__':
regress.main()

View File

@@ -1,9 +1,5 @@
#!/usr/bin/env python
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b'\xb8\x00\x00\x00\x02' # mov eax, 0x2000000

View File

@@ -1,12 +1,8 @@
#!/usr/bin/env python
import regress
from unicorn import *
from unicorn.x86_const import *
from struct import pack
F_GRANULARITY = 0x8
F_PROT_32 = 0x4
F_LONG = 0x2
@@ -36,7 +32,8 @@ S_PRIV_2 = 0x2
S_PRIV_1 = 0x1
S_PRIV_0 = 0x0
CODE = b'\x65\x33\x0d\x18\x00\x00\x00' # xor ecx, dword ptr gs:[0x18]
CODE = b'\x65\x33\x0d\x18\x00\x00\x00' # xor ecx, dword ptr gs:[0x18]
def create_selector(idx, flags):
to_ret = flags
@@ -47,16 +44,16 @@ def create_selector(idx, flags):
def create_gdt_entry(base, limit, access, flags):
return pack('<Q', (
limit & 0xffff
| (base & 0xffffff) << 16
| (access & 0xff) << 40
| ((limit >> 16) & 0xf) << 48
| (flags & 0xff) << 52
| ((base >> 24) & 0xff) << 56
limit & 0xffff
| (base & 0xffffff) << 16
| (access & 0xff) << 40
| ((limit >> 16) & 0xf) << 48
| (flags & 0xff) << 52
| ((base >> 24) & 0xff) << 56
))
def hook_mem_read(uc, type, addr,*args):
def hook_mem_read(uc, type, addr, *args):
regress.logger.debug("%#x", addr)
return False
@@ -72,6 +69,7 @@ GDT_ENTRY_SIZE = 0x8
SEGMENT_ADDR = 0x5000
SEGMENT_SIZE = 0x1000
class GdtRead(regress.RegressTest):
def test_gdt(self):
@@ -85,7 +83,8 @@ class GdtRead(regress.RegressTest):
uc.mem_write(CODE_ADDR, CODE)
uc.mem_write(SEGMENT_ADDR + 0x18, b'AAAA')
gdt_entry = create_gdt_entry(SEGMENT_ADDR, SEGMENT_SIZE, A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)
gdt_entry = create_gdt_entry(SEGMENT_ADDR, SEGMENT_SIZE,
A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)
uc.mem_write(GDT_ADDR + 8, gdt_entry)
uc.reg_write(UC_X86_REG_GDTR, (0, GDT_ADDR, GDT_LIMIT, 0x0))
@@ -93,7 +92,7 @@ class GdtRead(regress.RegressTest):
selector = create_selector(1, S_GDT | S_PRIV_3)
uc.reg_write(UC_X86_REG_GS, selector)
uc.emu_start(CODE_ADDR, CODE_ADDR+len(CODE))
uc.emu_start(CODE_ADDR, CODE_ADDR + len(CODE))
self.assertEqual(uc.reg_read(UC_X86_REG_ECX), 0x41414141)

View File

@@ -1,13 +1,10 @@
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = (
b'\x8b\x83\xd4\x05\x00\x00' # mov eax, DWORD PTR [ebx+0x5d4]
b'\x8b\x93\x80\x05\x00\x00' # mov edx, DWORD PTR [ebx+0x580]
b'\x8b\x83\xd4\x05\x00\x00' # mov eax, DWORD PTR [ebx+0x5d4]
b'\x8b\x93\x80\x05\x00\x00' # mov edx, DWORD PTR [ebx+0x580]
)
BASE = 0x47bb000

View File

@@ -1,8 +1,5 @@
#!/usr/bin/env python
import os
import regress
from unicorn import *
from unicorn.x86_const import *
@@ -12,12 +9,14 @@ filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'x86_self_m
CODE_ADDR = 0x08048000
STACK_ADDR = 0x2000000
CODE = open(filename, 'rb').read()
with open(filename, 'rb') as f:
CODE = f.read()
CODE_SIZE = len(CODE) + (0x1000 - len(CODE) % 0x1000)
STACK_SIZE = 0x8000
ENTRY_POINT = 0x8048074
def hook_intr(uc, intno, data):
uc.emu_stop()

View File

@@ -1,10 +1,7 @@
import regress
from unicorn import *
from unicorn.x86_const import *
NOPSLED = b"\x90" * 5