Merge branch 'dev' into patch

This commit is contained in:
Bet4 2021-10-17 18:18:09 +08:00 committed by GitHub
commit c400924fe1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 1044 additions and 3188 deletions

93
.github/workflows/Crate-publishing.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: Crate 📦 Distribution
on:
push:
paths-ignore:
- ".gitignore"
- "docs/**"
- "README"
- "CREDITS.TXT"
- "COPYING_GLIB"
- "COPYING.LGPL2"
- "AUTHORS.TXT"
- "CHANGELOG"
- "COPYING"
pull_request:
env:
CI: true
jobs:
build:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.name }}
strategy:
fail-fast: false
matrix:
config:
- {
os: windows-latest,
arch: x64,
name: 'Windows x86_64'
}
- {
os: windows-latest,
arch: x32,
name: 'Windows x86'
}
- {
os: ubuntu-latest,
arch: x64,
name: 'Ubuntu x86_64'
}
- {
os: macos-latest,
arch: x64,
name: 'macOS x86_64'
}
steps:
- uses: actions/checkout@v2
- name: '🛠️ Set up Rust'
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
default: true
- name: '🛠️ Add msbuild to PATH'
if: contains(matrix.config.name, 'win')
uses: microsoft/setup-msbuild@v1.0.3
with:
vs-version: '16.5'
- name: '🛠️ Win build dependencies'
if: contains(matrix.config.name, 'win')
shell: bash
run: |
choco install ninja cmake
- name: '🚧 Cargo test'
run: |
cd bindings/rust && cargo test
# - name: '📤 Upload artifact'
# uses: actions/upload-artifact@v2
# with:
# path: ${{ github.workspace }}/bindings/python/dist/*
# publish:
# needs: [build]
# runs-on: ubuntu-latest
# if: startsWith(github.ref, 'refs/tags')
# steps:
# - uses: actions/download-artifact@v2
# with:
# name: artifact
# path: dist
# - name: '📦 Publish distribution to PyPI'
# uses: pypa/gh-action-pypi-publish@master
# with:
# user: __token__
# password: ${{ secrets.pypi_pass }}

View File

@ -3,7 +3,6 @@ name: PyPI 📦 Distribution
on: on:
push: push:
paths-ignore: paths-ignore:
- ".github/**"
- ".gitignore" - ".gitignore"
- "docs/**" - "docs/**"
- "README" - "README"

View File

@ -1,10 +1,8 @@
name: Build UC2 name: Build UC2
on: on:
push: push:
tags-ignore:
- "*"
paths-ignore: paths-ignore:
- ".github/**"
- ".gitignore" - ".gitignore"
- "docs/**" - "docs/**"
- "README" - "README"
@ -16,13 +14,14 @@ on:
- "COPYING" - "COPYING"
pull_request: pull_request:
env: env:
CI: true CI: true
jobs: jobs:
Windows: Windows:
runs-on: ${{ matrix.config.os }} runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.name }} - ${{ matrix.compiler }} name: ${{ matrix.config.name }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -65,15 +64,22 @@ jobs:
archiver: '7z a', archiver: '7z a',
generators: 'Visual Studio 16 2019' generators: 'Visual Studio 16 2019'
} }
- {
os: windows-latest,
arch: x86,
python-arch: x86,
python-ver: '3.8',
name: 'windows-x86 MSVC 32bit',
msvc-arch: x86,
artifact: 'windows_msvc32.7z',
build_type: 'Debug',
archiver: '7z a',
generators: 'Visual Studio 16 2019'
}
compiler: [ gcc ] compiler: [ gcc ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
# - name: '🛠️ Python setup'
# uses: actions/setup-python@v2
# with:
# python-version: ${{ matrix.config.python-ver }}
- name: '🛠️ Win MINGW setup' - name: '🛠️ Win MINGW setup'
if: contains(matrix.config.mingw, 'MINGW') if: contains(matrix.config.mingw, 'MINGW')
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
@ -87,12 +93,12 @@ jobs:
mingw-w64-${{ matrix.config.mingw-arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.config.mingw-arch }}-${{ matrix.compiler }}
mingw-w64-${{ matrix.config.mingw-arch }}-toolchain mingw-w64-${{ matrix.config.mingw-arch }}-toolchain
- name: '🛠️ Win MSVC setup' - name: '🛠️ Win MSVC 64 setup'
if: contains(matrix.config.name, 'MSVC') if: contains(matrix.config.name, 'MSVC 64')
uses: microsoft/setup-msbuild@v1 uses: microsoft/setup-msbuild@v1
- name: '🚧 Win MSVC build' - name: '🚧 Win MSVC 64 build'
if: contains(matrix.config.name, 'MSVC') if: contains(matrix.config.name, 'MSVC 64')
shell: bash shell: bash
run: | run: |
choco install ninja cmake choco install ninja cmake
@ -110,6 +116,32 @@ jobs:
ctest -C ${{ matrix.config.build_type }} ctest -C ${{ matrix.config.build_type }}
mv Debug instdir mv Debug 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
cmake --build . --config ${{ matrix.config.build_type }}
cmake --install . --strip --config ${{ matrix.config.build_type }}
ctest -C ${{ matrix.config.build_type }}
mv Debug instdir
- name: '🚧 Win MINGW build' - name: '🚧 Win MINGW build'
if: contains(matrix.config.mingw, 'MINGW') if: contains(matrix.config.mingw, 'MINGW')
shell: msys2 {0} shell: msys2 {0}
@ -167,6 +199,17 @@ jobs:
archiver: '7za a', archiver: '7za a',
generators: 'Ninja' generators: 'Ninja'
} }
- {
os: macos-11,
arch: x86_64,
python-arch: x86_64,
python-ver: '3.8',
name: 'android cmake',
artifact: 'Android-x86_64.7z',
build_type: 'Debug',
archiver: '7za a',
generators: 'Ninja'
}
compiler: [ gcc ] compiler: [ gcc ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -177,24 +220,81 @@ jobs:
# python-version: ${{ matrix.config.python-ver }} # python-version: ${{ matrix.config.python-ver }}
- name: '🚧 Mac build' - name: '🚧 Mac build'
if: contains(matrix.config.os, 'macos') if: contains(matrix.config.name, 'macos-x64')
shell: bash shell: bash
run: | run: |
brew install p7zip cmake ninja brew install p7zip cmake ninja
ninja --version ninja --version
cmake --version cmake --version
mkdir build mkdir build
mkdir instdir mkdir instdir
cmake \ cmake \
-S . \ -S . \
-B . \ -B . \
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
-G "${{ matrix.config.generators }}" \ -G "${{ matrix.config.generators }}" \
-DCMAKE_INSTALL_PREFIX:PATH=instdir -DCMAKE_INSTALL_PREFIX:PATH=instdir
cmake --build . --config ${{ matrix.config.build_type }} cmake --build . --config ${{ matrix.config.build_type }}
cmake --install . --strip cmake --install . --strip
ctest -C ${{ matrix.config.build_type }} ctest -C ${{ matrix.config.build_type }}
- name: '🚧 Android x86_64 build'
if: contains(matrix.config.name, 'android')
shell: bash
run: |
brew install p7zip cmake ninja
mkdir build
mkdir instdir
cmake . -DCMAKE_TOOLCHAIN_FILE="$ANDROID_HOME/ndk/21.4.7075529/build/cmake/android.toolchain.cmake" \
-DANDROID_PLATFORM=android-28 \
-DANDROID_NDK="$ANDROID_HOME/ndk/21.4.7075529" \
-DANDROID_ABI=${{ matrix.config.arch }} \
-DOLP_SDK_ENABLE_TESTING=NO \
-DOLP_SDK_BUILD_EXAMPLES=ON \
-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
- name: '🚧 AVD Cache'
if: contains(matrix.config.name, 'android')
uses: actions/cache@v2
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-28
- name: '🚧 Create x86_64 tests environment'
if: contains(matrix.config.name, 'android') && steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 28
arch: ${{ matrix.config.arch }}
force-avd-creation: false
disable-animations: false
target: default
profile: Nexus 6
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -verbose -show-kernel
script: echo "Generated AVD snapshot for caching."
- name: '🚧 Android x86_64 tests'
if: contains(matrix.config.name, 'android')
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 28
force-avd-creation: false
disable-animations: true
arch: ${{ matrix.config.arch }}
target: default
profile: Nexus 6
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -verbose -show-kernel
script: bash ./adb.sh
- name: '📦 Pack artifact' - name: '📦 Pack artifact'
shell: bash shell: bash
working-directory: instdir working-directory: instdir
@ -331,4 +431,4 @@ jobs:
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v1
with: with:
path: ./${{ matrix.config.artifact }} path: ./${{ matrix.config.artifact }}
name: ${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }}

1
.gitignore vendored
View File

@ -60,6 +60,7 @@ _*.txt
_*.diff _*.diff
tmp/ tmp/
bindings/java/unicorn_Unicorn.h
bindings/python/build/ bindings/python/build/
bindings/python/dist/ bindings/python/dist/
bindings/python/src/ bindings/python/src/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "docs/Unicorn_Engine_Documentation"]
path = docs/Unicorn_Engine_Documentation
url = git@github.com:kabeor/Unicorn-Engine-Documentation

View File

@ -90,6 +90,7 @@ else()
endif() endif()
elseif(ANDROID_ABI) elseif(ANDROID_ABI)
string(FIND "${ANDROID_ABI}" "arm64" UC_RET) string(FIND "${ANDROID_ABI}" "arm64" UC_RET)
file(WRITE ${CMAKE_BINARY_DIR}/adb.sh "#!/bin/bash\n\n# Auto-generated by CMakeLists.txt\n\nadb shell mkdir -p /data/local/tmp/build\n")
if (${UC_RET} GREATER_EQUAL "0") if (${UC_RET} GREATER_EQUAL "0")
set(UNICORN_TARGET_ARCH "aarch64") set(UNICORN_TARGET_ARCH "aarch64")
@ -1031,6 +1032,9 @@ if (UNICORN_BUILD_SHARED)
add_library(unicorn SHARED add_library(unicorn SHARED
${UNICORN_SRCS} ${UNICORN_SRCS}
) )
if (ANDROID_ABI)
file(APPEND ${CMAKE_BINARY_DIR}/adb.sh "adb push ./libunicorn.so /data/local/tmp/build/\n")
endif()
else() else()
add_library(unicorn STATIC add_library(unicorn STATIC
${UNICORN_SRCS} ${UNICORN_SRCS}
@ -1167,22 +1171,27 @@ if(UNICORN_FUZZ)
endforeach() endforeach()
else() else()
foreach(SAMPLE_FILE ${UNICORN_SAMPLE_FILE}) foreach(SAMPLE_FILE ${UNICORN_SAMPLE_FILE})
add_executable(${SAMPLE_FILE} add_executable(${SAMPLE_FILE}
${CMAKE_CURRENT_SOURCE_DIR}/samples/${SAMPLE_FILE}.c ${CMAKE_CURRENT_SOURCE_DIR}/samples/${SAMPLE_FILE}.c
) )
target_link_libraries(${SAMPLE_FILE} target_link_libraries(${SAMPLE_FILE}
${SAMPLES_LIB} ${SAMPLES_LIB}
) )
endforeach(SAMPLE_FILE) endforeach(SAMPLE_FILE)
foreach(TEST_FILE ${UNICORN_TEST_FILE}) foreach(TEST_FILE ${UNICORN_TEST_FILE})
add_executable(${TEST_FILE} add_executable(${TEST_FILE}
${CMAKE_CURRENT_SOURCE_DIR}/tests/unit/${TEST_FILE}.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/unit/${TEST_FILE}.c
) )
target_link_libraries(${TEST_FILE} target_link_libraries(${TEST_FILE}
${SAMPLES_LIB} ${SAMPLES_LIB}
) )
add_test(${TEST_FILE} ${TEST_FILE}) add_test(${TEST_FILE} ${TEST_FILE})
if (ANDROID_ABI)
file(APPEND ${CMAKE_BINARY_DIR}/adb.sh "adb push ${TEST_FILE} /data/local/tmp/build/\n")
file(APPEND ${CMAKE_BINARY_DIR}/adb.sh "adb shell \"chmod +x /data/local/tmp/build/${TEST_FILE}\"\n")
file(APPEND ${CMAKE_BINARY_DIR}/adb.sh "adb shell \'LD_LIBRARY_PATH=/data/local/tmp/build:$LD_LIBRARY_PATH /data/local/tmp/build/${TEST_FILE}\' || exit -1\n")
endif()
endforeach(TEST_FILE) endforeach(TEST_FILE)
endif() endif()

View File

@ -79,3 +79,4 @@ Simon Gorchakov: PowerPC target
Stuart Dootson (studoot): MSVC compatibility with PowerPC target support Stuart Dootson (studoot): MSVC compatibility with PowerPC target support
Ziqiao Kong (lazymio): uc_context_free() API and various bug fix & improvement. Ziqiao Kong (lazymio): uc_context_free() API and various bug fix & improvement.
Sven Almgren (blindmatrix): bug fix Sven Almgren (blindmatrix): bug fix
Chenxu Wu (kabeor): Documentation

View File

@ -1,9 +1,11 @@
.PHONY: gen_const clean .PHONY: gen_const clean
JAVA_HOME := $(shell jrunscript -e 'java.lang.System.out.println(java.lang.System.getProperty("java.home"));') JC=javac
JAVA_INC := $(shell realpath $(JAVA_HOME)/../include) JAVA_HOME := $(shell readlink -f `which $(JC)` | sed "s:/bin/$(JC)::")
JAVA_INC := $(shell realpath $(JAVA_HOME)/include)
JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`) JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`)
@ -28,7 +30,6 @@ LIBS=-lunicorn
LIBDIR=-L../../ LIBDIR=-L../../
INCS=-I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC) INCS=-I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC)
JC=javac
CLASSPATH=./ CLASSPATH=./
.SUFFIXES: .java .class .SUFFIXES: .java .class
@ -46,7 +47,7 @@ all: lib jar samples
$(CC) -c $(CFLAGS) $(INCS) $< -o $@ $(CC) -c $(CFLAGS) $(INCS) $< -o $@
unicorn_Unicorn.h: unicorn/Unicorn.java unicorn_Unicorn.h: unicorn/Unicorn.java
javah unicorn.Unicorn javac -h . $<
unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h
$(CC) -c $(CFLAGS) $(INCS) $< -o $@ $(CC) -c $(CFLAGS) $(INCS) $< -o $@
@ -63,12 +64,12 @@ jar: jarfiles
jar cf $(JARFILE) unicorn/*.class jar cf $(JARFILE) unicorn/*.class
install: lib jar install: lib jar
cp libunicorn_java$(LIB_EXT) $(JAVA_HOME)/lib/ext cp libunicorn_java$(LIB_EXT) /usr/lib
cp $(JARFILE) $(JAVA_HOME)/lib/ext cp $(JARFILE) /usr/share/java
uninstall: uninstall:
rm $(JAVA_HOME)/lib/ext/libunicorn_java$(LIB_EXT) rm /usr/lib/libunicorn_java$(LIB_EXT)
rm $(JAVA_HOME)/lib/ext/$(JARFILE) rm /usr/share/java/$(JARFILE)
gen_const: gen_const:
cd .. && python const_generator.py java cd .. && python const_generator.py java

View File

@ -30,12 +30,12 @@ import java.util.*;
public class SampleNetworkAuditing { public class SampleNetworkAuditing {
public static int next_id = 3; public static long next_id = 3;
public static final int SIZE_REG = 4; public static final int SIZE_REG = 4;
private static LogChain fd_chains = new LogChain(); private static LogChain fd_chains = new LogChain();
public static int get_id() { public static long get_id() {
return next_id++; return next_id++;
} }
@ -112,7 +112,7 @@ public class SampleNetworkAuditing {
long mode = edx; long mode = edx;
String filename = read_string(uc, filename_addr); String filename = read_string(uc, filename_addr);
Long dummy_fd = new Long(get_id()); Long dummy_fd = get_id();
uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd);
String msg = String.format("open file (filename=%s flags=%d mode=%d) with fd(%d)", filename, flags, mode, dummy_fd); String msg = String.format("open file (filename=%s flags=%d mode=%d) with fd(%d)", filename, flags, mode, dummy_fd);
@ -144,8 +144,8 @@ public class SampleNetworkAuditing {
long sock_type = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); long sock_type = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG));
long protocol = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); long protocol = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG));
Long dummy_fd = new Long(get_id()); Long dummy_fd = get_id();
uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd.intValue()); uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd);
if (family == 2) { // AF_INET if (family == 2) { // AF_INET
String msg = String.format("create socket (%s, %s) with fd(%d)", ADDR_FAMILY.get(family), SOCKET_TYPES.get(sock_type), dummy_fd); String msg = String.format("create socket (%s, %s) with fd(%d)", ADDR_FAMILY.get(family), SOCKET_TYPES.get(sock_type), dummy_fd);
@ -401,7 +401,7 @@ public class SampleNetworkAuditing {
mu.mem_write(ADDRESS, code); mu.mem_write(ADDRESS, code);
// initialize stack // initialize stack
mu.reg_write(Unicorn.UC_X86_REG_ESP, new Long(ADDRESS + 0x200000)); mu.reg_write(Unicorn.UC_X86_REG_ESP, ADDRESS + 0x200000L);
// handle interrupt ourself // handle interrupt ourself
mu.hook_add(new MyInterruptHook(), null); mu.hook_add(new MyInterruptHook(), null);

View File

@ -40,9 +40,9 @@ public class Sample_arm {
static void test_arm() static void test_arm()
{ {
Long r0 = new Long(0x1234); // R0 register Long r0 = 0x1234L; // R0 register
Long r2 = new Long(0x6789); // R1 register Long r2 = 0x6789L; // R1 register
Long r3 = new Long(0x3333); // R2 register Long r3 = 0x3333L; // R2 register
Long r1; // R1 register Long r1; // R1 register
System.out.print("Emulate ARM code\n"); System.out.print("Emulate ARM code\n");
@ -85,7 +85,7 @@ public class Sample_arm {
static void test_thumb() static void test_thumb()
{ {
Long sp = new Long(0x1234); // R0 register Long sp = 0x1234L; // R0 register
System.out.print("Emulate THUMB code\n"); System.out.print("Emulate THUMB code\n");

View File

@ -69,9 +69,9 @@ public class Sample_arm64 {
static void test_arm64() static void test_arm64()
{ {
Long x11 = new Long(0x1234); // X11 register Long x11 = 0x1234L; // X11 register
Long x13 = new Long(0x6789); // X13 register Long x13 = 0x6789L; // X13 register
Long x15 = new Long(0x3333); // X15 register Long x15 = 0x3333L; // X15 register
System.out.print("Emulate ARM64 code\n"); System.out.print("Emulate ARM64 code\n");

View File

@ -68,26 +68,26 @@ public class Sample_m68k {
static void test_m68k() static void test_m68k()
{ {
Long d0 = new Long(0x0000); // d0 data register Long d0 = 0x0000L; // d0 data register
Long d1 = new Long(0x0000); // d1 data register Long d1 = 0x0000L; // d1 data register
Long d2 = new Long(0x0000); // d2 data register Long d2 = 0x0000L; // d2 data register
Long d3 = new Long(0x0000); // d3 data register Long d3 = 0x0000L; // d3 data register
Long d4 = new Long(0x0000); // d4 data register Long d4 = 0x0000L; // d4 data register
Long d5 = new Long(0x0000); // d5 data register Long d5 = 0x0000L; // d5 data register
Long d6 = new Long(0x0000); // d6 data register Long d6 = 0x0000L; // d6 data register
Long d7 = new Long(0x0000); // d7 data register Long d7 = 0x0000L; // d7 data register
Long a0 = new Long(0x0000); // a0 address register Long a0 = 0x0000L; // a0 address register
Long a1 = new Long(0x0000); // a1 address register Long a1 = 0x0000L; // a1 address register
Long a2 = new Long(0x0000); // a2 address register Long a2 = 0x0000L; // a2 address register
Long a3 = new Long(0x0000); // a3 address register Long a3 = 0x0000L; // a3 address register
Long a4 = new Long(0x0000); // a4 address register Long a4 = 0x0000L; // a4 address register
Long a5 = new Long(0x0000); // a5 address register Long a5 = 0x0000L; // a5 address register
Long a6 = new Long(0x0000); // a6 address register Long a6 = 0x0000L; // a6 address register
Long a7 = new Long(0x0000); // a6 address register Long a7 = 0x0000L; // a6 address register
Long pc = new Long(0x0000); // program counter Long pc = 0x0000L; // program counter
Long sr = new Long(0x0000); // status register Long sr = 0x0000L; // status register
System.out.print("Emulate M68K code\n"); System.out.print("Emulate M68K code\n");

View File

@ -70,7 +70,7 @@ public class Sample_mips {
static void test_mips_eb() static void test_mips_eb()
{ {
Long r1 = new Long(0x6789); // R1 register Long r1 = 0x6789L; // R1 register
System.out.print("Emulate MIPS code (big-endian)\n"); System.out.print("Emulate MIPS code (big-endian)\n");
@ -107,7 +107,7 @@ public class Sample_mips {
static void test_mips_el() static void test_mips_el()
{ {
Long r1 = new Long(0x6789); // R1 register Long r1 = 0x6789L; // R1 register
System.out.print("===========================\n"); System.out.print("===========================\n");
System.out.print("Emulate MIPS code (little-endian)\n"); System.out.print("Emulate MIPS code (little-endian)\n");

View File

@ -69,9 +69,9 @@ public class Sample_sparc {
static void test_sparc() static void test_sparc()
{ {
Long g1 = new Long(0x1230); // G1 register Long g1 = 0x1230L; // G1 register
Long g2 = new Long(0x6789); // G2 register Long g2 = 0x6789L; // G2 register
Long g3 = new Long(0x5555); // G3 register Long g3 = 0x5555L; // G3 register
System.out.print("Emulate SPARC code\n"); System.out.print("Emulate SPARC code\n");

View File

@ -171,8 +171,8 @@ public class Sample_x86 {
} }
static void test_i386() { static void test_i386() {
Long r_ecx = new Long(0x1234); // ECX register Long r_ecx = 0x1234L; // ECX register
Long r_edx = new Long(0x7890); // EDX register Long r_edx = 0x7890L; // EDX register
System.out.print("Emulate i386 code\n"); System.out.print("Emulate i386 code\n");
@ -234,8 +234,8 @@ public class Sample_x86 {
static void test_i386_inout() static void test_i386_inout()
{ {
Long r_eax = new Long(0x1234); // ECX register Long r_eax = 0x1234L; // ECX register
Long r_ecx = new Long(0x6789); // EDX register Long r_ecx = 0x6789L; // EDX register
System.out.print("===================================\n"); System.out.print("===================================\n");
System.out.print("Emulate i386 code with IN/OUT instructions\n"); System.out.print("Emulate i386 code with IN/OUT instructions\n");
@ -309,8 +309,8 @@ public class Sample_x86 {
// emulate code that loop forever // emulate code that loop forever
static void test_i386_loop() static void test_i386_loop()
{ {
Long r_ecx = new Long(0x1234); // ECX register Long r_ecx = 0x1234L; // ECX register
Long r_edx = new Long(0x7890); // EDX register Long r_edx = 0x7890L; // EDX register
System.out.print("===================================\n"); System.out.print("===================================\n");
System.out.print("Emulate i386 code that loop forever\n"); System.out.print("Emulate i386 code that loop forever\n");
@ -346,8 +346,8 @@ public class Sample_x86 {
// emulate code that read invalid memory // emulate code that read invalid memory
static void test_i386_invalid_mem_read() static void test_i386_invalid_mem_read()
{ {
Long r_ecx = new Long(0x1234); // ECX register Long r_ecx = 0x1234L; // ECX register
Long r_edx = new Long(0x7890); // EDX register Long r_edx = 0x7890L; // EDX register
System.out.print("===================================\n"); System.out.print("===================================\n");
System.out.print("Emulate i386 code that read from invalid memory\n"); System.out.print("Emulate i386 code that read from invalid memory\n");
@ -393,8 +393,8 @@ public class Sample_x86 {
// emulate code that read invalid memory // emulate code that read invalid memory
static void test_i386_invalid_mem_write() static void test_i386_invalid_mem_write()
{ {
Long r_ecx = new Long(0x1234); // ECX register Long r_ecx = 0x1234L; // ECX register
Long r_edx = new Long(0x7890); // EDX register Long r_edx = 0x7890L; // EDX register
System.out.print("===================================\n"); System.out.print("===================================\n");
System.out.print("Emulate i386 code that write to invalid memory\n"); System.out.print("Emulate i386 code that write to invalid memory\n");
@ -453,8 +453,8 @@ public class Sample_x86 {
// emulate code that jump to invalid memory // emulate code that jump to invalid memory
static void test_i386_jump_invalid() static void test_i386_jump_invalid()
{ {
Long r_ecx = new Long(0x1234); // ECX register Long r_ecx = 0x1234L; // ECX register
Long r_edx = new Long(0x7890); // EDX register Long r_edx = 0x7890L; // EDX register
System.out.print("===================================\n"); System.out.print("===================================\n");
System.out.print("Emulate i386 code that jumps to invalid memory\n"); System.out.print("Emulate i386 code that jumps to invalid memory\n");
@ -527,22 +527,22 @@ public class Sample_x86 {
u.mem_write(ADDRESS, X86_CODE64); u.mem_write(ADDRESS, X86_CODE64);
// initialize machine registers // initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_RSP, new Long(rsp)); u.reg_write(Unicorn.UC_X86_REG_RSP, rsp);
u.reg_write(Unicorn.UC_X86_REG_RAX, new Long(rax)); u.reg_write(Unicorn.UC_X86_REG_RAX, rax);
u.reg_write(Unicorn.UC_X86_REG_RBX, new Long(rbx)); u.reg_write(Unicorn.UC_X86_REG_RBX, rbx);
u.reg_write(Unicorn.UC_X86_REG_RCX, new Long(rcx)); u.reg_write(Unicorn.UC_X86_REG_RCX, rcx);
u.reg_write(Unicorn.UC_X86_REG_RDX, new Long(rdx)); u.reg_write(Unicorn.UC_X86_REG_RDX, rdx);
u.reg_write(Unicorn.UC_X86_REG_RSI, new Long(rsi)); u.reg_write(Unicorn.UC_X86_REG_RSI, rsi);
u.reg_write(Unicorn.UC_X86_REG_RDI, new Long(rdi)); u.reg_write(Unicorn.UC_X86_REG_RDI, rdi);
u.reg_write(Unicorn.UC_X86_REG_R8, new Long(r8)); u.reg_write(Unicorn.UC_X86_REG_R8, r8);
u.reg_write(Unicorn.UC_X86_REG_R9, new Long(r9)); u.reg_write(Unicorn.UC_X86_REG_R9, r9);
u.reg_write(Unicorn.UC_X86_REG_R10, new Long(r10)); u.reg_write(Unicorn.UC_X86_REG_R10, r10);
u.reg_write(Unicorn.UC_X86_REG_R11, new Long(r11)); u.reg_write(Unicorn.UC_X86_REG_R11, r11);
u.reg_write(Unicorn.UC_X86_REG_R12, new Long(r12)); u.reg_write(Unicorn.UC_X86_REG_R12, r12);
u.reg_write(Unicorn.UC_X86_REG_R13, new Long(r13)); u.reg_write(Unicorn.UC_X86_REG_R13, r13);
u.reg_write(Unicorn.UC_X86_REG_R14, new Long(r14)); u.reg_write(Unicorn.UC_X86_REG_R14, r14);
u.reg_write(Unicorn.UC_X86_REG_R15, new Long(r15)); u.reg_write(Unicorn.UC_X86_REG_R15, r15);
// tracing all basic blocks with customized callback // tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null); u.hook_add(new MyBlockHook(), 1, 0, null);
@ -598,9 +598,9 @@ public class Sample_x86 {
static void test_x86_16() static void test_x86_16()
{ {
Long eax = new Long(7); Long eax = 7L;
Long ebx = new Long(5); Long ebx = 5L;
Long esi = new Long(6); Long esi = 6L;
System.out.print("Emulate x86 16-bit code\n"); System.out.print("Emulate x86 16-bit code\n");

View File

@ -49,7 +49,7 @@ public class Sample_x86_mmr {
uc.reg_write(Unicorn.UC_X86_REG_LDTR, ldtr1); uc.reg_write(Unicorn.UC_X86_REG_LDTR, ldtr1);
uc.reg_write(Unicorn.UC_X86_REG_GDTR, gdtr1); uc.reg_write(Unicorn.UC_X86_REG_GDTR, gdtr1);
uc.reg_write(Unicorn.UC_X86_REG_EAX, new Long(0xdddddddd)); uc.reg_write(Unicorn.UC_X86_REG_EAX, 0xddddddddL);
// read the registers back out // read the registers back out
eax = (int)((Long)uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue(); eax = (int)((Long)uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue();

View File

@ -113,7 +113,7 @@ public class Shellcode {
static void test_i386() static void test_i386()
{ {
Long r_esp = new Long(ADDRESS + 0x200000); // ESP register Long r_esp = ADDRESS + 0x200000L; // ESP register
System.out.print("Emulate i386 code\n"); System.out.print("Emulate i386 code\n");
@ -158,4 +158,4 @@ public class Shellcode {
} }
} }

View File

@ -25,7 +25,7 @@ import java.util.*;
public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const { public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const {
private long eng; public long eng;
private int arch; private int arch;
private int mode; private int mode;

View File

@ -1,8 +1,8 @@
[package] [package]
name = "unicorn" name = "unicorn-engine"
version = "1.0.0" version = "2.0.0-rc3"
authors = ["Lukas Seidel"] authors = ["Ziqiao Kong", "Lukas Seidel"]
documentation = "" documentation = "https://github.com/unicorn-engine/unicorn/wiki"
edition = "2018" edition = "2018"
include = [ include = [
"/.gitmodules", "/.gitmodules",
@ -10,6 +10,7 @@ include = [
"/Cargo.toml", "/Cargo.toml",
"/README.md", "/README.md",
"/src/*", "/src/*",
"build.rs"
] ]
license = "GPL-2.0" license = "GPL-2.0"
readme = "README.md" readme = "README.md"

View File

@ -1,17 +1,17 @@
# unicorn-rs # Unicorn-engine
Rust bindings for the [Unicorn](http://www.unicorn-engine.org/) emulator with utility functions. Rust bindings for the [Unicorn](http://www.unicorn-engine.org/) emulator with utility functions.
An extended version for fuzzing with AFL++ support can be found in https://github.com/aflplusplus/unicornafl. Checkout Unicorn2 source code at [dev branch](https://github.com/unicorn-engine/unicorn/tree/dev).
```rust ```rust
use unicorn::RegisterARM; use unicorn_engine::RegisterARM;
use unicorn::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE}; use unicorn_engine::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE};
fn main() { fn main() {
let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23 let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23
let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance"); let mut unicorn = unicorn-engine::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page"); emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page");
emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions"); emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions");
@ -26,20 +26,18 @@ fn main() {
``` ```
Further sample code can be found in ```tests/unicorn.rs```. Further sample code can be found in ```tests/unicorn.rs```.
## Installation ## Usage
This project has been tested on Linux, OS X and Windows. Add this to your `Cargo.toml`:
To use unicorn-rs, simply add it as a dependency to the Cargo.toml of your program.
``` ```
[dependencies] [dependencies]
unicorn = { path = "/path/to/bindings/rust", version="1.0.0" } unicorn-engine = "2.0.0-rc3"
``` ```
## Acknowledgements ## Acknowledgements
These bindings are based on Sébastien Duquette's (@ekse) [unicorn-rs](https://github.com/unicorn-rs/unicorn-rs). These bindings are based on Sébastien Duquette's (@ekse) [unicorn-rs](https://github.com/unicorn-rs/unicorn-rs).
We picked up the project, as it is no longer maintained. We picked up the project, as it is no longer maintained.
Thanks to all contributers. Thanks to all contributors.

View File

@ -1,20 +1,128 @@
use std::result::Result;
use std::{env, process::Command}; use std::{env, process::Command};
use build_helper::rustc::{link_lib, link_search};
fn main() { fn main() {
println!("cargo:rerun-if-changed=unicorn");
let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap();
let unicorn = "libunicorn.a"; let profile = env::var("PROFILE").unwrap();
let _ = Command::new("cp") let mut version = String::from("dev");
.current_dir("../..") if let Result::Ok(version_env) = env::var("UNICORN_BRANCH") {
.arg(&unicorn) version = version_env;
.arg(&out_dir) }
.status()
.unwrap(); let unicorn_dir;
link_search( if let Result::Ok(_) = env::var("CI") {
Some(build_helper::SearchKind::Native), unicorn_dir = format!("../..");
build_helper::out_dir(), } else {
); unicorn_dir = format!("{}/unicorn_git", out_dir);
link_lib(Some(build_helper::LibKind::Static), "unicorn");
Command::new("rm").arg("-rf").arg(&unicorn_dir);
Command::new("git")
.arg("clone")
.arg("git@github.com:unicorn-engine/unicorn.git")
.arg("-b")
.arg(version)
.arg(&unicorn_dir)
.output()
.expect("Fail to clone Unicorn repository.");
}
println!("cargo:rerun-if-changed={}", &unicorn_dir);
// We don't use TARGET since we can't cross-build.
if env::consts::OS == "windows" {
// Windows
let mut cmd = Command::new("cmake");
cmd.current_dir(&unicorn_dir)
.arg("-B")
.arg("rust_build")
.arg("-DUNICORN_BUILD_SHARED=off")
.arg("-G")
.arg("Visual Studio 16 2019");
if profile == "debug" {
cmd.arg("-DCMAKE_BUILD_TYPE=Debug");
} else {
cmd.arg("-DCMAKE_BUILD_TYPE=Release");
}
cmd.output()
.expect("Fail to create build directory on Windows.");
let mut platform = "x64";
let mut conf = "Release";
if std::mem::size_of::<usize>() == 4 {
platform = "Win32";
}
if profile == "debug" {
conf = "Debug";
}
Command::new("msbuild")
.current_dir(format!("{}/rust_build", &unicorn_dir))
.arg("unicorn.sln")
.arg("-m")
.arg("-p:Platform=".to_owned() + platform)
.arg("-p:Configuration=".to_owned() + conf)
.output()
.expect("Fail to build unicorn on Win32.");
println!(
"cargo:rustc-link-search={}/rust_build/{}",
unicorn_dir, conf
);
} else {
// Most Unix-like systems
let mut cmd = Command::new("cmake");
cmd.current_dir(&unicorn_dir)
.arg("-B")
.arg("rust_build")
.arg("-DUNICORN_BUILD_SHARED=off");
if profile == "debug" {
cmd.arg("-DCMAKE_BUILD_TYPE=Debug");
} else {
cmd.arg("-DCMAKE_BUILD_TYPE=Release");
}
cmd.output()
.expect("Fail to create build directory on *nix.");
Command::new("make")
.current_dir(format!("{}/rust_build", &unicorn_dir))
.arg("-j6")
.output()
.expect("Fail to build unicorn on *nix.");
println!("cargo:rustc-link-search={}/rust_build", unicorn_dir);
}
// This is a workaround for Unicorn static link since libunicorn.a is also linked again lib*-softmmu.a.
// Static libs is just a bundle of objects files. The link relation defined in CMakeLists is only
// valid within the cmake project scope and cmake would help link again sub static libs automatically.
//
// Lazymio(@wtdcode): Why do I stick to static link? See: https://github.com/rust-lang/cargo/issues/5077
println!("cargo:rustc-link-lib=unicorn");
for arch in [
"x86_64",
"arm",
"armeb",
"aarch64",
"aarch64eb",
"riscv32",
"riscv64",
"mips",
"mipsel",
"mips64",
"mips64el",
"sparc",
"sparc64",
"m68k",
"ppc",
"ppc64",
]
.iter()
{
println!("cargo:rustc-link-lib={}-softmmu", arch);
}
println!("cargo:rustc-link-lib=unicorn-common");
} }

View File

@ -123,8 +123,31 @@ pub enum RegisterARM {
MSP = 115, MSP = 115,
PSP = 116, PSP = 116,
CONTROL = 117, CONTROL = 117,
XPSR = 118, IAPSR = 118,
ENDING = 119, EAPSR = 119,
XPSR = 120,
EPSR = 121,
IEPSR = 122,
PRIMASK = 123,
BASEPRI = 124,
BASEPRI_MAX = 125,
FAULTMASK = 126,
APSR_NZCVQ = 127,
APSR_G = 128,
APSR_NZCVQG = 129,
IAPSR_NZCVQ = 130,
IAPSR_G = 131,
IAPSR_NZCVQG = 132,
EAPSR_NZCVQ = 133,
EAPSR_G = 134,
EAPSR_NZCVQG = 135,
XPSR_NZCVQ = 136,
XPSR_G = 137,
XPSR_NZCVQG = 138,
ENDING = 139,
}
impl RegisterARM {
// alias registers // alias registers
// (assoc) R13 = 12, // (assoc) R13 = 12,
// (assoc) R14 = 10, // (assoc) R14 = 10,
@ -133,9 +156,6 @@ pub enum RegisterARM {
// (assoc) SL = 76, // (assoc) SL = 76,
// (assoc) FP = 77, // (assoc) FP = 77,
// (assoc) IP = 78, // (assoc) IP = 78,
}
impl RegisterARM {
pub const R13: RegisterARM = RegisterARM::SP; pub const R13: RegisterARM = RegisterARM::SP;
pub const R14: RegisterARM = RegisterARM::LR; pub const R14: RegisterARM = RegisterARM::LR;
pub const R15: RegisterARM = RegisterARM::PC; pub const R15: RegisterARM = RegisterARM::PC;

View File

@ -1,4 +1,5 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
// ARM64 registers // ARM64 registers
#[repr(C)] #[repr(C)]

View File

@ -6,13 +6,13 @@
//! //!
//! ```rust //! ```rust
//! //!
//! use unicorn::RegisterARM; //! use unicorn_engine::RegisterARM;
//! use unicorn::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE}; //! use unicorn_engine::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE};
//! //!
//! fn main() { //! fn main() {
//! let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23 //! let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23
//! //!
//! let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance"); //! let mut unicorn = unicorn_engine::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance");
//! let mut emu = unicorn.borrow(); //! let mut emu = unicorn.borrow();
//! emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page"); //! emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page");
//! emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions"); //! emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions");
@ -35,9 +35,10 @@ mod arm64;
mod m68k; mod m68k;
mod mips; mod mips;
mod ppc; mod ppc;
mod riscv;
mod sparc; mod sparc;
mod x86; mod x86;
pub use crate::{arm::*, arm64::*, m68k::*, mips::*, ppc::*, sparc::*, x86::*}; pub use crate::{arm::*, arm64::*, m68k::*, mips::*, ppc::*, riscv::*, sparc::*, x86::*};
use ffi::uc_handle; use ffi::uc_handle;
use std::collections::HashMap; use std::collections::HashMap;

View File

@ -21,4 +21,5 @@ pub enum RegisterM68K {
D7, D7,
SR, SR,
PC, PC,
ENDING,
} }

View File

@ -1,4 +1,5 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
// MIPS registers // MIPS registers
#[repr(C)] #[repr(C)]
@ -155,7 +156,11 @@ pub enum RegisterMIPS {
MPL2 = 136, MPL2 = 136,
CP0_CONFIG3 = 137, CP0_CONFIG3 = 137,
CP0_USERLOCAL = 138, CP0_USERLOCAL = 138,
ENDING = 139, CP0_STATUS = 139,
ENDING = 140,
}
impl RegisterMIPS {
// alias registers // alias registers
// (assoc) ZERO = 2, // (assoc) ZERO = 2,
// (assoc) AT = 3, // (assoc) AT = 3,
@ -198,9 +203,6 @@ pub enum RegisterMIPS {
// (assoc) LO1 = 46, // (assoc) LO1 = 46,
// (assoc) LO2 = 47, // (assoc) LO2 = 47,
// (assoc) LO3 = 48, // (assoc) LO3 = 48,
}
impl RegisterMIPS {
pub const ZERO: RegisterMIPS = RegisterMIPS::GPR0; pub const ZERO: RegisterMIPS = RegisterMIPS::GPR0;
pub const AT: RegisterMIPS = RegisterMIPS::GPR1; pub const AT: RegisterMIPS = RegisterMIPS::GPR1;
pub const V0: RegisterMIPS = RegisterMIPS::GPR2; pub const V0: RegisterMIPS = RegisterMIPS::GPR2;

213
bindings/rust/src/riscv.rs Normal file
View File

@ -0,0 +1,213 @@
#![allow(non_camel_case_types)]
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
// RISCV registers
#[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum RegisterRISCV {
INVALID = 0,
// General purpose registers
X0 = 1,
X1 = 2,
X2 = 3,
X3 = 4,
X4 = 5,
X5 = 6,
X6 = 7,
X7 = 8,
X8 = 9,
X9 = 10,
X10 = 11,
X11 = 12,
X12 = 13,
X13 = 14,
X14 = 15,
X15 = 16,
X16 = 17,
X17 = 18,
X18 = 19,
X19 = 20,
X20 = 21,
X21 = 22,
X22 = 23,
X23 = 24,
X24 = 25,
X25 = 26,
X26 = 27,
X27 = 28,
X28 = 29,
X29 = 30,
X30 = 31,
X31 = 32,
// Floating-point registers
F0 = 33,
F1 = 34,
F2 = 35,
F3 = 36,
F4 = 37,
F5 = 38,
F6 = 39,
F7 = 40,
F8 = 41,
F9 = 42,
F10 = 43,
F11 = 44,
F12 = 45,
F13 = 46,
F14 = 47,
F15 = 48,
F16 = 49,
F17 = 50,
F18 = 51,
F19 = 52,
F20 = 53,
F21 = 54,
F22 = 55,
F23 = 56,
F24 = 57,
F25 = 58,
F26 = 59,
F27 = 60,
F28 = 61,
F29 = 62,
F30 = 63,
F31 = 64,
PC = 65,
ENDING = 66,
}
impl RegisterRISCV {
// Alias registers
// (assoc) ZERO = 1,
// (assoc) RA = 2,
// (assoc) SP = 3,
// (assoc) GP = 4,
// (assoc) TP = 5,
// (assoc) T0 = 6,
// (assoc) T1 = 7,
// (assoc) T2 = 8,
// (assoc) S0 = 9,
// (assoc) FP = 9,
// (assoc) S1 = 10,
// (assoc) A0 = 11,
// (assoc) A1 = 12,
// (assoc) A2 = 13,
// (assoc) A3 = 14,
// (assoc) A4 = 15,
// (assoc) A5 = 16,
// (assoc) A6 = 17,
// (assoc) A7 = 18,
// (assoc) S2 = 19,
// (assoc) S3 = 20,
// (assoc) S4 = 21,
// (assoc) S5 = 22,
// (assoc) S6 = 23,
// (assoc) S7 = 24,
// (assoc) S8 = 25,
// (assoc) S9 = 26,
// (assoc) S10 = 27,
// (assoc) S11 = 28,
// (assoc) T3 = 29,
// (assoc) T4 = 30,
// (assoc) T5 = 31,
// (assoc) T6 = 32,
// (assoc) FT0 = 33,
// (assoc) FT1 = 34,
// (assoc) FT2 = 35,
// (assoc) FT3 = 36,
// (assoc) FT4 = 37,
// (assoc) FT5 = 38,
// (assoc) FT6 = 39,
// (assoc) FT7 = 40,
// (assoc) FS0 = 41,
// (assoc) FS1 = 42,
// (assoc) FA0 = 43,
// (assoc) FA1 = 44,
// (assoc) FA2 = 45,
// (assoc) FA3 = 46,
// (assoc) FA4 = 47,
// (assoc) FA5 = 48,
// (assoc) FA6 = 49,
// (assoc) FA7 = 50,
// (assoc) FS2 = 51,
// (assoc) FS3 = 52,
// (assoc) FS4 = 53,
// (assoc) FS5 = 54,
// (assoc) FS6 = 55,
// (assoc) FS7 = 56,
// (assoc) FS8 = 57,
// (assoc) FS9 = 58,
// (assoc) FS10 = 59,
// (assoc) FS11 = 60,
// (assoc) FT8 = 61,
// (assoc) FT9 = 62,
// (assoc) FT10 = 63,
// (assoc) FT11 = 64,
pub const ZERO: RegisterRISCV = RegisterRISCV::X0;
pub const RA: RegisterRISCV = RegisterRISCV::X1;
pub const SP: RegisterRISCV = RegisterRISCV::X2;
pub const GP: RegisterRISCV = RegisterRISCV::X3;
pub const TP: RegisterRISCV = RegisterRISCV::X4;
pub const T0: RegisterRISCV = RegisterRISCV::X5;
pub const T1: RegisterRISCV = RegisterRISCV::X6;
pub const T2: RegisterRISCV = RegisterRISCV::X7;
pub const S0: RegisterRISCV = RegisterRISCV::X8;
pub const FP: RegisterRISCV = RegisterRISCV::X8;
pub const S1: RegisterRISCV = RegisterRISCV::X9;
pub const A0: RegisterRISCV = RegisterRISCV::X10;
pub const A1: RegisterRISCV = RegisterRISCV::X11;
pub const A2: RegisterRISCV = RegisterRISCV::X12;
pub const A3: RegisterRISCV = RegisterRISCV::X13;
pub const A4: RegisterRISCV = RegisterRISCV::X14;
pub const A5: RegisterRISCV = RegisterRISCV::X15;
pub const A6: RegisterRISCV = RegisterRISCV::X16;
pub const A7: RegisterRISCV = RegisterRISCV::X17;
pub const S2: RegisterRISCV = RegisterRISCV::X18;
pub const S3: RegisterRISCV = RegisterRISCV::X19;
pub const S4: RegisterRISCV = RegisterRISCV::X20;
pub const S5: RegisterRISCV = RegisterRISCV::X21;
pub const S6: RegisterRISCV = RegisterRISCV::X22;
pub const S7: RegisterRISCV = RegisterRISCV::X23;
pub const S8: RegisterRISCV = RegisterRISCV::X24;
pub const S9: RegisterRISCV = RegisterRISCV::X25;
pub const S10: RegisterRISCV = RegisterRISCV::X26;
pub const S11: RegisterRISCV = RegisterRISCV::X27;
pub const T3: RegisterRISCV = RegisterRISCV::X28;
pub const T4: RegisterRISCV = RegisterRISCV::X29;
pub const T5: RegisterRISCV = RegisterRISCV::X30;
pub const T6: RegisterRISCV = RegisterRISCV::X31;
pub const FT0: RegisterRISCV = RegisterRISCV::F0;
pub const FT1: RegisterRISCV = RegisterRISCV::F1;
pub const FT2: RegisterRISCV = RegisterRISCV::F2;
pub const FT3: RegisterRISCV = RegisterRISCV::F3;
pub const FT4: RegisterRISCV = RegisterRISCV::F4;
pub const FT5: RegisterRISCV = RegisterRISCV::F5;
pub const FT6: RegisterRISCV = RegisterRISCV::F6;
pub const FT7: RegisterRISCV = RegisterRISCV::F7;
pub const FS0: RegisterRISCV = RegisterRISCV::F8;
pub const FS1: RegisterRISCV = RegisterRISCV::F9;
pub const FA0: RegisterRISCV = RegisterRISCV::F10;
pub const FA1: RegisterRISCV = RegisterRISCV::F11;
pub const FA2: RegisterRISCV = RegisterRISCV::F12;
pub const FA3: RegisterRISCV = RegisterRISCV::F13;
pub const FA4: RegisterRISCV = RegisterRISCV::F14;
pub const FA5: RegisterRISCV = RegisterRISCV::F15;
pub const FA6: RegisterRISCV = RegisterRISCV::F16;
pub const FA7: RegisterRISCV = RegisterRISCV::F17;
pub const FS2: RegisterRISCV = RegisterRISCV::F18;
pub const FS3: RegisterRISCV = RegisterRISCV::F19;
pub const FS4: RegisterRISCV = RegisterRISCV::F20;
pub const FS5: RegisterRISCV = RegisterRISCV::F21;
pub const FS6: RegisterRISCV = RegisterRISCV::F22;
pub const FS7: RegisterRISCV = RegisterRISCV::F23;
pub const FS8: RegisterRISCV = RegisterRISCV::F24;
pub const FS9: RegisterRISCV = RegisterRISCV::F25;
pub const FS10: RegisterRISCV = RegisterRISCV::F26;
pub const FS11: RegisterRISCV = RegisterRISCV::F27;
pub const FT8: RegisterRISCV = RegisterRISCV::F28;
pub const FT9: RegisterRISCV = RegisterRISCV::F29;
pub const FT10: RegisterRISCV = RegisterRISCV::F30;
pub const FT11: RegisterRISCV = RegisterRISCV::F31;
}

View File

@ -1,3 +1,5 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
// SPARC registers // SPARC registers
#[repr(C)] #[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)] #[derive(PartialEq, Debug, Clone, Copy)]
@ -91,4 +93,13 @@ pub enum RegisterSPARC {
Y = 86, Y = 86,
XCC = 87, XCC = 87,
PC = 88, PC = 88,
ENDING = 89,
}
impl RegisterSPARC {
// alias registers
// (assoc) O6 = 84,
// (assoc) I6 = 67,
pub const O6: RegisterSPARC = RegisterSPARC::SP;
pub const I6: RegisterSPARC = RegisterSPARC::FP;
} }

View File

@ -1,11 +1,11 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use bitflags::bitflags; use bitflags::bitflags;
pub const API_MAJOR: u64 = 1; pub const API_MAJOR: u64 = 2;
pub const API_MINOR: u64 = 0; pub const API_MINOR: u64 = 0;
pub const VERSION_MAJOR: u64 = 1; pub const VERSION_MAJOR: u64 = 2;
pub const VERSION_MINOR: u64 = 0; pub const VERSION_MINOR: u64 = 0;
pub const VERSION_EXTRA: u64 = 2; pub const VERSION_EXTRA: u64 = 0;
pub const SECOND_SCALE: u64 = 1_000_000; pub const SECOND_SCALE: u64 = 1_000_000;
pub const MILISECOND_SCALE: u64 = 1_000; pub const MILISECOND_SCALE: u64 = 1_000;
@ -93,6 +93,7 @@ pub enum Query {
MODE = 1, MODE = 1,
PAGE_SIZE = 2, PAGE_SIZE = 2,
ARCH = 3, ARCH = 3,
TIMEOUT = 4,
} }
bitflags! { bitflags! {
@ -124,7 +125,8 @@ pub enum Arch {
PPC = 5, PPC = 5,
SPARC = 6, SPARC = 6,
M68K = 7, M68K = 7,
MAX = 8, RISCV = 8,
MAX = 9,
} }
bitflags! { bitflags! {
@ -154,5 +156,7 @@ bitflags! {
const SPARC32 = Self::MIPS32.bits; const SPARC32 = Self::MIPS32.bits;
const SPARC64 = Self::MIPS64.bits; const SPARC64 = Self::MIPS64.bits;
const V9 = Self::THUMB.bits; const V9 = Self::THUMB.bits;
const RISCV32 = Self::MIPS32.bits;
const RISCV64 = Self::MIPS64.bits;
} }
} }

View File

@ -1,257 +1,245 @@
#![allow(non_camel_case_types)]
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
// X86 registers // X86 registers
#[repr(C)] #[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)] #[derive(PartialEq, Debug, Clone, Copy)]
pub enum RegisterX86 { pub enum RegisterX86 {
INVALID = 0, INVALID = 0,
AH, AH = 1,
AL, AL = 2,
AX, AX = 3,
BH, BH = 4,
BL, BL = 5,
BP, BP = 6,
BPL, BPL = 7,
BX, BX = 8,
CH, CH = 9,
CL, CL = 10,
CS, CS = 11,
CX, CX = 12,
DH, DH = 13,
DI, DI = 14,
DIL, DIL = 15,
DL, DL = 16,
DS, DS = 17,
DX, DX = 18,
EAX, EAX = 19,
EBP, EBP = 20,
EBX, EBX = 21,
ECX, ECX = 22,
EDI, EDI = 23,
EDX, EDX = 24,
EFLAGS, EFLAGS = 25,
EIP, EIP = 26,
EIZ, ES = 27,
ES, ESI = 28,
ESI, ESP = 29,
ESP, FPSW = 30,
FPSW, FS = 31,
FS, GS = 32,
GS, IP = 33,
IP, RAX = 34,
RAX, RBP = 35,
RBP, RBX = 36,
RBX, RCX = 37,
RCX, RDI = 38,
RDI, RDX = 39,
RDX, RIP = 40,
RIP, RSI = 41,
RIZ, RSP = 42,
RSI, SI = 43,
RSP, SIL = 44,
SI, SP = 45,
SIL, SPL = 46,
SP, SS = 47,
SPL, CR0 = 48,
SS, CR1 = 49,
CR0, CR2 = 50,
CR1, CR3 = 51,
CR2, CR4 = 52,
CR3, CR8 = 53,
CR4, DR0 = 54,
CR5, DR1 = 55,
CR6, DR2 = 56,
CR7, DR3 = 57,
CR8, DR4 = 58,
CR9, DR5 = 59,
CR10, DR6 = 60,
CR11, DR7 = 61,
CR12, FP0 = 62,
CR13, FP1 = 63,
CR14, FP2 = 64,
CR15, FP3 = 65,
DR0, FP4 = 66,
DR1, FP5 = 67,
DR2, FP6 = 68,
DR3, FP7 = 69,
DR4, K0 = 70,
DR5, K1 = 71,
DR6, K2 = 72,
DR7, K3 = 73,
DR8, K4 = 74,
DR9, K5 = 75,
DR10, K6 = 76,
DR11, K7 = 77,
DR12, MM0 = 78,
DR13, MM1 = 79,
DR14, MM2 = 80,
DR15, MM3 = 81,
FP0, MM4 = 82,
FP1, MM5 = 83,
FP2, MM6 = 84,
FP3, MM7 = 85,
FP4, R8 = 86,
FP5, R9 = 87,
FP6, R10 = 88,
FP7, R11 = 89,
K0, R12 = 90,
K1, R13 = 91,
K2, R14 = 92,
K3, R15 = 93,
K4, ST0 = 94,
K5, ST1 = 95,
K6, ST2 = 96,
K7, ST3 = 97,
MM0, ST4 = 98,
MM1, ST5 = 99,
MM2, ST6 = 100,
MM3, ST7 = 101,
MM4, XMM0 = 102,
MM5, XMM1 = 103,
MM6, XMM2 = 104,
MM7, XMM3 = 105,
R8, XMM4 = 106,
R9, XMM5 = 107,
R10, XMM6 = 108,
R11, XMM7 = 109,
R12, XMM8 = 110,
R13, XMM9 = 111,
R14, XMM10 = 112,
R15, XMM11 = 113,
ST0, XMM12 = 114,
ST1, XMM13 = 115,
ST2, XMM14 = 116,
ST3, XMM15 = 117,
ST4, XMM16 = 118,
ST5, XMM17 = 119,
ST6, XMM18 = 120,
ST7, XMM19 = 121,
XMM0, XMM20 = 122,
XMM1, XMM21 = 123,
XMM2, XMM22 = 124,
XMM3, XMM23 = 125,
XMM4, XMM24 = 126,
XMM5, XMM25 = 127,
XMM6, XMM26 = 128,
XMM7, XMM27 = 129,
XMM8, XMM28 = 130,
XMM9, XMM29 = 131,
XMM10, XMM30 = 132,
XMM11, XMM31 = 133,
XMM12, YMM0 = 134,
XMM13, YMM1 = 135,
XMM14, YMM2 = 136,
XMM15, YMM3 = 137,
XMM16, YMM4 = 138,
XMM17, YMM5 = 139,
XMM18, YMM6 = 140,
XMM19, YMM7 = 141,
XMM20, YMM8 = 142,
XMM21, YMM9 = 143,
XMM22, YMM10 = 144,
XMM23, YMM11 = 145,
XMM24, YMM12 = 146,
XMM25, YMM13 = 147,
XMM26, YMM14 = 148,
XMM27, YMM15 = 149,
XMM28, YMM16 = 150,
XMM29, YMM17 = 151,
XMM30, YMM18 = 152,
XMM31, YMM19 = 153,
YMM0, YMM20 = 154,
YMM1, YMM21 = 155,
YMM2, YMM22 = 156,
YMM3, YMM23 = 157,
YMM4, YMM24 = 158,
YMM5, YMM25 = 159,
YMM6, YMM26 = 160,
YMM7, YMM27 = 161,
YMM8, YMM28 = 162,
YMM9, YMM29 = 163,
YMM10, YMM30 = 164,
YMM11, YMM31 = 165,
YMM12, ZMM0 = 166,
YMM13, ZMM1 = 167,
YMM14, ZMM2 = 168,
YMM15, ZMM3 = 169,
YMM16, ZMM4 = 170,
YMM17, ZMM5 = 171,
YMM18, ZMM6 = 172,
YMM19, ZMM7 = 173,
YMM20, ZMM8 = 174,
YMM21, ZMM9 = 175,
YMM22, ZMM10 = 176,
YMM23, ZMM11 = 177,
YMM24, ZMM12 = 178,
YMM25, ZMM13 = 179,
YMM26, ZMM14 = 180,
YMM27, ZMM15 = 181,
YMM28, ZMM16 = 182,
YMM29, ZMM17 = 183,
YMM30, ZMM18 = 184,
YMM31, ZMM19 = 185,
ZMM0, ZMM20 = 186,
ZMM1, ZMM21 = 187,
ZMM2, ZMM22 = 188,
ZMM3, ZMM23 = 189,
ZMM4, ZMM24 = 190,
ZMM5, ZMM25 = 191,
ZMM6, ZMM26 = 192,
ZMM7, ZMM27 = 193,
ZMM8, ZMM28 = 194,
ZMM9, ZMM29 = 195,
ZMM10, ZMM30 = 196,
ZMM11, ZMM31 = 197,
ZMM12, R8B = 198,
ZMM13, R9B = 199,
ZMM14, R10B = 200,
ZMM15, R11B = 201,
ZMM16, R12B = 202,
ZMM17, R13B = 203,
ZMM18, R14B = 204,
ZMM19, R15B = 205,
ZMM20, R8D = 206,
ZMM21, R9D = 207,
ZMM22, R10D = 208,
ZMM23, R11D = 209,
ZMM24, R12D = 210,
ZMM25, R13D = 211,
ZMM26, R14D = 212,
ZMM27, R15D = 213,
ZMM28, R8W = 214,
ZMM29, R9W = 215,
ZMM30, R10W = 216,
ZMM31, R11W = 217,
R8B, R12W = 218,
R9B, R13W = 219,
R10B, R14W = 220,
R11B, R15W = 221,
R12B, IDTR = 222,
R13B, GDTR = 223,
R14B, LDTR = 224,
R15B, TR = 225,
R8D, FPCW = 226,
R9D, FPTAG = 227,
R10D, MSR = 228,
R11D, MXCSR = 229,
R12D, FS_BASE = 230,
R13D, GS_BASE = 231,
R14D, FLAGS = 232,
R15D, RFLAGS = 233,
R8W, ENDING = 234,
R9W,
R10W,
R11W,
R12W,
R13W,
R14W,
R15W,
IDTR,
GDTR,
LDTR,
TR,
FPCW,
FPTAG,
MSR,
MXCSR,
} }
#[repr(C)] #[repr(C)]

View File

@ -1,11 +1,9 @@
#![deny(rust_2018_idioms)]
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use unicorn::unicorn_const::{uc_error, Arch, HookType, MemType, Mode, Permission, SECOND_SCALE}; use unicorn_engine::unicorn_const::{uc_error, Arch, HookType, MemType, Mode, Permission, SECOND_SCALE};
use unicorn::{InsnSysX86, RegisterARM, RegisterMIPS, RegisterPPC, RegisterX86}; use unicorn_engine::{InsnSysX86, RegisterARM, RegisterMIPS, RegisterPPC, RegisterX86};
pub static X86_REGISTERS: [RegisterX86; 145] = [ pub static X86_REGISTERS: [RegisterX86; 125] = [
RegisterX86::AH, RegisterX86::AH,
RegisterX86::AL, RegisterX86::AL,
RegisterX86::AX, RegisterX86::AX,
@ -32,7 +30,6 @@ pub static X86_REGISTERS: [RegisterX86; 145] = [
RegisterX86::EDX, RegisterX86::EDX,
RegisterX86::EFLAGS, RegisterX86::EFLAGS,
RegisterX86::EIP, RegisterX86::EIP,
RegisterX86::EIZ,
RegisterX86::ES, RegisterX86::ES,
RegisterX86::ESI, RegisterX86::ESI,
RegisterX86::ESP, RegisterX86::ESP,
@ -47,7 +44,6 @@ pub static X86_REGISTERS: [RegisterX86; 145] = [
RegisterX86::RDI, RegisterX86::RDI,
RegisterX86::RDX, RegisterX86::RDX,
RegisterX86::RIP, RegisterX86::RIP,
RegisterX86::RIZ,
RegisterX86::RSI, RegisterX86::RSI,
RegisterX86::RSP, RegisterX86::RSP,
RegisterX86::SI, RegisterX86::SI,
@ -60,17 +56,7 @@ pub static X86_REGISTERS: [RegisterX86; 145] = [
RegisterX86::CR2, RegisterX86::CR2,
RegisterX86::CR3, RegisterX86::CR3,
RegisterX86::CR4, RegisterX86::CR4,
RegisterX86::CR5,
RegisterX86::CR6,
RegisterX86::CR7,
RegisterX86::CR8, RegisterX86::CR8,
RegisterX86::CR9,
RegisterX86::CR10,
RegisterX86::CR11,
RegisterX86::CR12,
RegisterX86::CR13,
RegisterX86::CR14,
RegisterX86::CR15,
RegisterX86::DR0, RegisterX86::DR0,
RegisterX86::DR1, RegisterX86::DR1,
RegisterX86::DR2, RegisterX86::DR2,
@ -79,14 +65,6 @@ pub static X86_REGISTERS: [RegisterX86; 145] = [
RegisterX86::DR5, RegisterX86::DR5,
RegisterX86::DR6, RegisterX86::DR6,
RegisterX86::DR7, RegisterX86::DR7,
RegisterX86::DR8,
RegisterX86::DR9,
RegisterX86::DR10,
RegisterX86::DR11,
RegisterX86::DR12,
RegisterX86::DR13,
RegisterX86::DR14,
RegisterX86::DR15,
RegisterX86::FP0, RegisterX86::FP0,
RegisterX86::FP1, RegisterX86::FP1,
RegisterX86::FP2, RegisterX86::FP2,
@ -153,13 +131,13 @@ pub static X86_REGISTERS: [RegisterX86; 145] = [
RegisterX86::R15W, RegisterX86::R15W,
]; ];
type Unicorn<'a> = unicorn::UnicornHandle<'a>; type Unicorn<'a> = unicorn_engine::UnicornHandle<'a>;
#[test] #[test]
fn emulate_x86() { fn emulate_x86() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.reg_write(RegisterX86::EAX as i32, 123), Ok(())); assert_eq!(emu.reg_write(RegisterX86::EAX as i32, 123), Ok(()));
@ -210,7 +188,7 @@ fn x86_code_callback() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -241,7 +219,7 @@ fn x86_intr_callback() {
let x86_code32: Vec<u8> = vec![0xcd, 0x80]; // INT 0x80; let x86_code32: Vec<u8> = vec![0xcd, 0x80]; // INT 0x80;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -278,9 +256,15 @@ fn x86_mem_callback() {
let callback_mems = mems_cell.clone(); let callback_mems = mems_cell.clone();
let callback = let callback =
move |_: Unicorn<'_>, mem_type: MemType, address: u64, size: usize, value: i64| { move |uc: Unicorn<'_>, mem_type: MemType, address: u64, size: usize, value: i64| {
let mut mems = callback_mems.borrow_mut(); let mut mems = callback_mems.borrow_mut();
let mut uc = uc;
mems.push(MemExpectation(mem_type, address, size, value)); mems.push(MemExpectation(mem_type, address, size, value));
if mem_type == MemType::READ_UNMAPPED {
uc.mem_map(address, 0x1000, Permission::ALL).unwrap();
}
}; };
// mov eax, 0xdeadbeef; // mov eax, 0xdeadbeef;
@ -290,7 +274,7 @@ fn x86_mem_callback() {
0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xA3, 0x00, 0x20, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x01, 0x00, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xA3, 0x00, 0x20, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x01, 0x00,
]; ];
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -307,7 +291,7 @@ fn x86_mem_callback() {
10 * SECOND_SCALE, 10 * SECOND_SCALE,
0x1000 0x1000
), ),
Err(uc_error::READ_UNMAPPED) Ok(())
); );
assert_eq!(expects, *mems_cell.borrow()); assert_eq!(expects, *mems_cell.borrow());
@ -328,7 +312,7 @@ fn x86_insn_in_callback() {
let x86_code32: Vec<u8> = vec![0xe5, 0x10]; // IN eax, 0x10; let x86_code32: Vec<u8> = vec![0xe5, 0x10]; // IN eax, 0x10;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -365,7 +349,7 @@ fn x86_insn_out_callback() {
let x86_code32: Vec<u8> = vec![0xb0, 0x32, 0xe6, 0x46]; // MOV al, 0x32; OUT 0x46, al; let x86_code32: Vec<u8> = vec![0xb0, 0x32, 0xe6, 0x46]; // MOV al, 0x32; OUT 0x46, al;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -407,7 +391,7 @@ fn x86_insn_sys_callback() {
0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05,
]; ];
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_64) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_64)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -434,7 +418,7 @@ fn x86_insn_sys_callback() {
fn emulate_arm() { fn emulate_arm() {
let arm_code32: Vec<u8> = vec![0x83, 0xb0]; // sub sp, #0xc let arm_code32: Vec<u8> = vec![0x83, 0xb0]; // sub sp, #0xc
let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::THUMB) let mut unicorn = unicorn_engine::Unicorn::new(Arch::ARM, Mode::THUMB)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.reg_write(RegisterARM::R1 as i32, 123), Ok(())); assert_eq!(emu.reg_write(RegisterARM::R1 as i32, 123), Ok(()));
@ -475,7 +459,7 @@ fn emulate_arm() {
fn emulate_mips() { fn emulate_mips() {
let mips_code32 = vec![0x56, 0x34, 0x21, 0x34]; // ori $at, $at, 0x3456; let mips_code32 = vec![0x56, 0x34, 0x21, 0x34]; // ori $at, $at, 0x3456;
let mut unicorn = unicorn::Unicorn::new(Arch::MIPS, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::MIPS, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -501,7 +485,7 @@ fn emulate_mips() {
fn emulate_ppc() { fn emulate_ppc() {
let ppc_code32 = vec![0x7F, 0x46, 0x1A, 0x14]; // add 26, 6, 3 let ppc_code32 = vec![0x7F, 0x46, 0x1A, 0x14]; // add 26, 6, 3
let mut unicorn = unicorn::Unicorn::new(Arch::PPC, Mode::PPC32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::PPC, Mode::PPC32 | Mode::BIG_ENDIAN)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -526,7 +510,7 @@ fn emulate_ppc() {
#[test] #[test]
fn mem_unmapping() { fn mem_unmapping() {
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -539,7 +523,7 @@ fn mem_map_ptr() {
let mut mem: [u8; 4000] = [0; 4000]; let mut mem: [u8; 4000] = [0; 4000];
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
@ -619,7 +603,7 @@ fn x86_context_save_and_restore() {
0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05,
]; ];
let mut unicorn = let mut unicorn =
unicorn::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance"); unicorn_engine::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
assert_eq!(emu.mem_write(0x1000, &x86_code), Ok(())); assert_eq!(emu.mem_write(0x1000, &x86_code), Ok(()));
@ -636,7 +620,7 @@ fn x86_context_save_and_restore() {
/* and create a new emulator, into which we will "restore" that context */ /* and create a new emulator, into which we will "restore" that context */
let mut unicorn2 = let mut unicorn2 =
unicorn::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance"); unicorn_engine::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance");
let emu2 = unicorn2.borrow(); let emu2 = unicorn2.borrow();
assert_eq!(emu2.context_restore(&context), Ok(())); assert_eq!(emu2.context_restore(&context), Ok(()));
for register in X86_REGISTERS.iter() { for register in X86_REGISTERS.iter() {
@ -653,7 +637,7 @@ fn x86_context_save_and_restore() {
fn x86_block_callback() { fn x86_block_callback() {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct BlockExpectation(u64, u32); struct BlockExpectation(u64, u32);
let expects = vec![BlockExpectation(0x1000, 2), BlockExpectation(0x1000, 2)]; let expects = vec![BlockExpectation(0x1000, 2)];
let blocks: Vec<BlockExpectation> = Vec::new(); let blocks: Vec<BlockExpectation> = Vec::new();
let blocks_cell = Rc::new(RefCell::new(blocks)); let blocks_cell = Rc::new(RefCell::new(blocks));
@ -665,7 +649,7 @@ fn x86_block_callback() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -12,6 +12,6 @@ Documention of Unicorn engine.
http://unicorn-engine.org/docs/beyond_qemu.html http://unicorn-engine.org/docs/beyond_qemu.html
* Micro Uncorn-Engine API Documentation in Chinese * Uncorn-Engine Documentation
https://github.com/kabeor/Micro-Unicorn-Engine-API-Documentation https://github.com/kabeor/Unicorn-Engine-Documentation

@ -0,0 +1 @@
Subproject commit e1111e1b8b253bf7292ad911f43c125808a95f1e

View File

@ -2018,9 +2018,13 @@ enum {
PPC_MEM_TLBIA = 0x0000000010000000ULL, PPC_MEM_TLBIA = 0x0000000010000000ULL,
PPC_MEM_TLBIE = 0x0000000020000000ULL, PPC_MEM_TLBIE = 0x0000000020000000ULL,
PPC_MEM_TLBSYNC = 0x0000000040000000ULL, PPC_MEM_TLBSYNC = 0x0000000040000000ULL,
// The enum in msvc is 32bit **signed**.
// https://godbolt.org/z/nYbvWPWET
#ifndef _MSC_VER
/* sync instruction */ /* sync instruction */
PPC_MEM_SYNC = 0x0000000080000000ULL, PPC_MEM_SYNC = 0x0000000080000000ULL,
#ifndef _MSC_VER
/* eieio instruction */ /* eieio instruction */
PPC_MEM_EIEIO = 0x0000000100000000ULL, PPC_MEM_EIEIO = 0x0000000100000000ULL,
@ -2084,6 +2088,7 @@ enum {
/* popcntw and popcntd instructions */ /* popcntw and popcntd instructions */
PPC_POPCNTWD = 0x8000000000000000ULL, PPC_POPCNTWD = 0x8000000000000000ULL,
#else #else
#define PPC_MEM_SYNC 0x0000000080000000ULL
#define PPC_MEM_EIEIO 0x0000000100000000ULL #define PPC_MEM_EIEIO 0x0000000100000000ULL
#define PPC_CACHE 0x0000000200000000ULL #define PPC_CACHE 0x0000000200000000ULL
#define PPC_CACHE_ICBI 0x0000000400000000ULL #define PPC_CACHE_ICBI 0x0000000400000000ULL

View File

@ -3,6 +3,34 @@
const uint64_t code_start = 0x1000; const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000; const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine** uc, uc_arch arch, uc_mode mode, const char* code, uint64_t size) {
OK(uc_open(arch, mode, uc));
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_ppc32_add() {
uc_engine* uc;
char code[] = "\x7f\x46\x1a\x14"; // ADD 26, 6, 3
int reg;
uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code, sizeof(code) - 1);
reg = 42;
OK(uc_reg_write(uc, UC_PPC_REG_3, &reg));
reg = 1337;
OK(uc_reg_write(uc, UC_PPC_REG_6, &reg));
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
OK(uc_reg_read(uc, UC_PPC_REG_26, &reg));
TEST_CHECK(reg == 1379);
OK(uc_close(uc));
}
TEST_LIST = { TEST_LIST = {
{ NULL, NULL } { "test_ppc32_add", test_ppc32_add },
{ NULL, NULL}
}; };