Fuzzware is a project for automated, self-configuring fuzzing of firmware images

Overview

Fuzzware

Fuzzware thumbnail

Fuzzware is a project for automated, self-configuring fuzzing of firmware images.

The idea of this project is to configure the memory ranges of an ARM Cortex-M3 / M4 firmware image, and start emulating / fuzzing the target. Fuzzware will figure out how MMIO values are used, configure models, and involve the fuzzer to provide hardware behavior which is not fully covered by MMIO models.

Our paper from USENIX Security '22 explains the system in more detail.

Quick Start

First install:

./build_docker.sh

Then run:

./run_docker.sh examples fuzzware pipeline --skip-afl-cpufreq pw-recovery/ARCH_PRO

Repo Organization and Documents

Directories within this repository. For the experiments in our paper, as well as

Directory Description
docs Documentation files (config optimizations, cov analysis, crash analysis).
examples Target firmware samples to test Fuzzware on.
emulator The emulator which performs runs of a firmware for a given input file.
modeling MMIO modeling (based on angr).
pipeline Orchestration between MMIO modeling and emulator.
scripts Some helper scripts (e.g., gather basic blocks in IDB).
fuzzware-experiments Pre-built images/config, crashing POCs/analyses, build scripts to re-run our experiments.

To not let this document explode, we provide specific documentation in different places:

  1. Firmware targets, build scripts, example crash analyses: the fuzzware-experiments repo
  2. Fuzzware utilities documentation: $ fuzzware -h, and $ fuzzware -h
  3. Firmware configuration file format details: emulator/README_config.yml
  4. Fuzzware project result directory structure: pipeline/README.md

The Idea

At its core, Fuzzware works by plugging an instruction emulator (currently: Unicorn Engine) to a fuzzer (currently: afl) and having the fuzzer supply inputs for all hardware accesses. Whenever hardware in Memory-Mapped (MMIO) registers is accessed, the value is served from fuzzing input.

"The fuzzer has no idea about how the hardware it is emulating is supposed to behave, so how can anything useful come out of this?" You might ask. There are different components to this:

  1. Coverage feedback: While the fuzzer does not know anything about the hardware, it can try different inputs and see how the firmware code reacts to it - whatever inputs make the firmware tick are likely to represent expected hardware behavior. The fuzzer can learn this by trial-and-error.
  2. MMIO Access Modeling: Firmware typically performs a variety of hardware (MMIO) accesses, a lot of those accesses are for status checking and housekeeping purposes. It turns out that a lot of those accesses are not meaningful to the overall firmware logic. This means a majority of MMIO accesses can either be eliminated or condensed automatically. Any MMIO access modeled this way takes away the need for the fuzzer to guess about hardware behavior.
  3. Custom Configurations: The user can supply different pieces of optional configuration to modify firmware behavior (skip or replace logic with custom handlers, define when and which interrupts to trigger) and to guide the emulation to sane firmware states (by describing mandatory checkpoints and error functions to avoid during the boot process). This can focus fuzzing on interesting functionality in case we have a human in the loop.

Fuzzware Components

Fuzzware is comprised of different components:

  1. Pipeline Component (/pipeline): Integrated fuzzing and modeling. The pipeline component represents the glue between emulation and modeling. As the fuzzer/emulator finds new MMIO accesses during runs, the corresponding firmware states need to be forwarded to modeling. Similarly, the updated MMIO configurations produced during modeling need to be made available to the emulator. The Pipeline automates this cycle: It lets the emulator run, and pushes jobs for modeling newly observed MMIO accesses. It subsequently updates emulation with new models. The pipeline also implements additional features such as identifying successfully booted firmware states which are then automatically used for further fuzzing.
  2. Emulation Component (/emulator): Standalone single-input emulation runs. This component allows emulating a firmware image with a provided configuration for a particular input file. It handles the re-routing of fuzzing inputs to answer MMIO accesses as well as triggering interrupts and creating traces as well as state files for further processing. It also provides integration with a fuzzer (an AFL forkserver) for repeated emulation runs with different inputs.
  3. Modeling Component (/modeling): Standalone modeling. This component generates MMIO access models for states exported by the emulation component. It does so by performing symbolic execution and analyzing what is happening to the accessed MMIO values. It outputs configuration snippets which can be fed back to the emulation component for improved emulation.

For more information on the different components, please refer to the corresponding component subdirectories and READMEs.

Installation

There are two out-of-the-box ways to go about using Fuzzware: Native and Docker-based setups. For local development of Fuzzware itself, you may prefer a local setup while for using it, Docker may be the way to go.

After one of the installation options has been successful, Fuzzware should be available (within docker or the fuzzware virtualenv):

fuzzware -h

Fuzzware in Docker

To build as Docker container:

./build_docker.sh

A docker image "fuzzware" is built which contains all the necessary binaries and python modules. To start fuzzing and emulation, a directory can be mapped into the container which contains firmware images and configurations. To run:

./run_docker.sh 
   
     [/bin/bash]

   

Fuzzware on Host

For a local setup, your system will have to have a list of local tooling installed to handle building unicorn, setting up virtual environments and finally run different pipeline components. You can see how to set those dependencies up in the Docker file. Without installing all the dependencies first, different steps of the installation process will complain and you will be able to install them one by one.

To install locally:

./install_local.sh

The script will set up two Python virtualenvs:

  1. fuzzware: The virtualenv containing the local pipeline and emulator modules. This also includes the fuzzware executable which exposes different parts of the system.
  2. fuzzware-modeling: The virtualenv used for performing symbolic execution-based MMIO access modeling. You should not try installing this without a virtualenv as angr is one of its dependencies.

To use Fuzzware from here, simply use the fuzzware virtualenv.

workon fuzzware

Configuring Firmware Images For Fuzzing

Find a detailed overview of configuration options in emulator/README_config.yml.

At minimum, you will need a bare-metal firmware blob and know where it is located in memory. With this, you can setup a memory map. For a firmware blob fw.bin located at address 0x08000000 in ROM, a config located in a newly created examples/my-fw directory would look like this:

include:
    - ../configs/hw/cortexm_memory.yml
    # For optional interrupts
    - ./../configs/fuzzing/round_robin_interrupts.yml

memory_map:
    rom: 
        base_addr: 0x08000000
        size: 0x800000
        permissions: r-x
        file: ./fw.bin

Alternatively, you may also try out the experimental fuzzware genconfig utility which creates a basic configuration based on an elf file (extracts the binary from the ELF file, parses sections, and creates an initial memory config).

This will get your firmware image up and running initially. There are different additional configuration options to set which are specific to a firmware image and can support hardware features such as DMA, increase performance / decrease MMIO overhead, guide the firmware boot process, focus the fuzzer on specific interrupts, add introspection and debug symbols.

An inline-documentation of firmware image configuration features can be found in the config README of the emulator. These configuration options allow you to configure different aspects concerning:

  • Interrupt raising (When? Which? How often?)
  • Firmware Boot guidance (snapshot state after boot is successful)
  • Symbols
  • Custom input regions (e.g. to feed input whenever a static DMA buffer is accessed)
  • Custom code hooks (function replacement, providing input, corruption detection)

Fuzzware Workflow

Workflow for fellow academics:

  1. Configure your target image (don't blindly trust fuzzware genconfig)
  2. Fuzz target: fuzzware pipeline --run-for 24:00:00
  3. Collect coverage statistics: fuzzware genstats coverage
  4. Find your coverage info in fuzzware-project/stats

If you want to get the best out of Fuzzware (as a human in the loop), you should prefer the following steps:

  1. Build or obtain the target firmware image
  2. Configure basic memory ranges: Create config manually or use fuzzware genconfig (works best with elf files, still take the output with a grain of salt and verify manually!)
  3. Fuzz the target: fuzzware pipeline
  4. Check coverage: fuzzware cov, fuzzware cov -o cov.txt and fuzzware cov , fuzzware replay --covering
  5. Adapt the configuration: emulator/README_config.yml and fuzz again. If the image requires a rebuild, go to step 1. If the config needs adaption, goto step 3.
  6. Once you are reasonably sure that meaningful functionality is reached in the current setup, it might make sense to scale up cores: fuzzware pipeline -n 16.
  7. Check for crashes: fuzzware genstats crashcontexts
  8. Replay and analyze crashes: fuzzware replay -M -t mainXXX/fuzzers/fuzzerY/crashes/idZZZ

There is a range of fuzzware utilities which we created that you may find useful along the way. The utils and their command-line arguments are documented in fuzzware itself:

fuzzware -h

For additional descriptions of different steps of the workflow, also check out

Troubleshooting

Issues with Workers

In case issues with worker processes are indicated by the pipeline, refer to the project's fuzzware-project/logs directory for information on what made the worker processes unhappy.

Inotify Limits

If you are running the pipeline with a large number of fuzzing processes, inotify instance limits may be reached. In this case, run (as root, on the host):

scripts/set_inotify_limits.sh

Missing Local Dependencies

In case things are missing in your local setup, refer to the dockerfile to figure out which package you might have missed or use a docker setup.

Too Recent Python Version (>=3.10)

We based our MMIO modeling component on angr version 8.19.10.30. We learned just before the publication of the prototype that this version of angr only supports Python versions lower than 3.10. We added a detection for this into the install scripts and let you install based on a previous version of Python using the environment variable MODELING_VENV_PYTHON3.

Floating-Point Unit

As Fuzzware relies on Unicorn and unicorn does not support floating-point instructions, Cortex-M4f targets need to be compiled using a softfpu.

Citing the Paper

In case you would like to cite Fuzzware, you may use the following BibTex entry:

@inproceedings {277252,
title = {Fuzzware: Using Precise {MMIO} Modeling for Effective Firmware Fuzzing},
booktitle = {31st USENIX Security Symposium (USENIX Security 22)},
year = {2022},
address = {Boston, MA},
url = {https://www.usenix.org/conference/usenixsecurity22/presentation/scharnowski},
publisher = {USENIX Association},
month = aug,
}

Found Bugs? Let us know!

In case you found bugs using Fuzzware, feel free to let us know! :-)

How to Contribute

As a researcher, time for coding is finite. This is why there are still TODOs which could make the Fuzzware implementation better (even if we had infinite time, there would always be more things to improve, of course). If you are interested, here are some sample projects to work on for hacking on Fuzzware:

  1. Upgrade angr version: To make use of the newest features of angr and support Python in version >=3.10, we could upgrade the modeling code to use an up-to-date angr (while of course making sure that the angr APIs and its behavior have not changed in an unforseen way).
  2. Architecture Independence: Currently, the Fuzzware code is rather tighly coupled with ARM / Cortex-M. We started uncoupling the modeling logic from the architecture (see arch_specific), but there is more work to be done to make Fuzzware applicable to other CPU architectures (e.g., ARM Cortex-R) or instruction set architectures (e.g., MIPS).
  3. CompCov: Currently, Fuzzware does not make use of some AFL++ features such as compcov. This would be an opportunity to integrate some more such features into unicorn.
  4. Crash Analysis Tooling: Currently, analyzing crashes is a largely manual task. However, Fuzzware contains code to generate and parse detailed traces, and to inject custom hooks during firmware emulation. Some more tooling based on traces and custom hooks could be created to easen the crash analysis process.
  5. Input Patching Tooling: Currently, manually modifying existing inputs is a manual task and involves manually interpreting MMIO trace files to match file contents to MMIO accesses. With proper tooling, modifying inputs could be made much more convenient, making it practical to manually create seed inputs which trigger important coverage, or more easily craft a proof-of-concept exploit from a given crashing input. These could then be used as a starting point for the fuzzer.
  6. Refactoring: When looking through the code you will certainly find grown pieces of code which could make use of cleanup and larger refactoring. To make your search easy, one such place is naming_conventions.py. Prior to publication, we did some cleanup, but also dedicated extra time to adding more tooling functionality in the hopes that it makes Fuzzware more easy for people to use and get into, without having to use some of the bash ugliness that you get away with as the author of a tool. As coding time is limited for us, we appreciate any community efforts in making the code better.
Comments
  • Running in AFL++ mode still uses AFL

    Running in AFL++ mode still uses AFL

    Hello,

    During my testing I noticed that the fuzzer output files didn't all correspond to the AFL++ format even when the --aflpp flag is used. Looking at the pipeline code, the AFLplusplus folder can never be selected. The execution of the fuzzer process in this function https://github.com/fuzzware-fuzzer/fuzzware-pipeline/blob/d868ab800d0e1186ad088699cc081c68219c5401/fuzzware_pipeline/run_fuzzer.py#L45 depends on the value of AFL_FUZZ. When this value is defined, it does not consider the usage of AFLplusplus https://github.com/fuzzware-fuzzer/fuzzware-pipeline/blob/d868ab800d0e1186ad088699cc081c68219c5401/fuzzware_pipeline/run_fuzzer.py#L11-L12

    The string ../../emulator/afl/afl-fuzz is always appended onto the end of the directory for the fuzzer. This results in the execution of path/to/fuzzware/emulator/AFLplusplus/../../emulator/afl/afl-fuzz rather than path/to/fuzzware/emulator/AFLplusplus/afl-fuzz

    I'm unsure if any changes need to be made to AFLplusplus to function correctly with fuzzware, or whether simply changing the directory is enough to fix it.

    opened by CounterCycle 3
  • fuzzware genconfig --fuzz-for

    fuzzware genconfig --fuzz-for

    using the fuzz-for option on genconfig does very strange things it somehow results in lots of nonexistant sed accesses when fuzzing afterwards without any manual configurations (tried it on "examples/pw-recovery/ARCH_PRO/basic_exercises.bin") is this already implemented?

    opened by MrMatch246 3
  • Question about how set model consume the afl_input

    Question about how set model consume the afl_input

    I have a little question about set model. How emulator choose input if the size of set consequences is not power of 2. For example, when encountering this situation.

    Set = [0,1,2,3,4,5]
    afl_input = b110.....
    

    According to the paper, 3 bits will be extracted from the input of AFL. Which value will be chosen if this extracted value is 6 ? Considering Set[6] is out of bound. Thanks.

    opened by dingiso 2
  • Rebuild Fuzzware after modifications with minimal effort

    Rebuild Fuzzware after modifications with minimal effort

    Hello,

    I would like to locally modify some code in modeling/fuzzware_modeling/ and see how the modification affects Fuzzware. I have set up Fuzzware locally. Could you share some suggestions on how to compile modifications to Fuzzware with minimal effort?

    My current plan is to run the setup.sh in modeling/. The fallback plan is to rerun install_local.sh, which I would like to avoid. I raise this issue due to the concern that trying out these plans carelessly may break my local Fuzzware. Thank you very much.

    Best regards.

    opened by B03901108 1
  • Add

    Add "arm-none-eabi-objcopy" in docker

    Hello,

    I try to use fuzzware genconfig to generate the config of other firmware which not in your dataset. And then I found that there are no arm-none-eabi-objcopy in the docker system. If the .elf file need to extract to .bin there will be an error.

    I think the solution is to add binutils-arm-none-eabi in the dockerfile on 3 line. I made this change and it worked.

    Best regards.

    opened by Zero871015 1
  • Fix broken links in documentation

    Fix broken links in documentation

    Note: Now some links are not relative anymore because this currently does not work with submodules and how github handles relative links in *.md files.

    But this still seems better than links that do not work at all.

    opened by TheFunctionalGuy 0
  • First input byte in 04-crash-analysis/08

    First input byte in 04-crash-analysis/08

    I have encountered a curious problem which have bothered me for hours. Ask for help :sob:

    I'm working on how unicorn accept the input from fuzz. I compared the crashing_input with the log generated by replay command and everything goes right except the first byte

    this log entry is like this

    >>> Read: addr= 0x0000000040023808 size=4 data=0x00000000 (pc 0x08001b04)
    

    and the model generated by fuzzware is

    set:
        pc_08001b04_mmio_40023808:
          access_size: 0x4
          addr: 0x40023808
          pc: 0x8001b04
          vals:
          - 0x0
          - 0x4
          - 0x8
    

    the first byte generated by fuzzer is 0x20 so the data should be

    data = vals[0x20 % len(vals)]
         = vals[32 % 3]
         = vals[2]
         = 0x8
    

    But the data in log is 0x0. Other read operations are all right , so I think it's not my model's wrong. Is there any hints or something I misunderstood ?

    Thanks.

    opened by dingiso 0
  • Fuzzware sometimes stops generating traces

    Fuzzware sometimes stops generating traces

    I've noticed occasionally after running the pipeline, that genstats will cause a large number of traces to be generated. They all seem to correspond to the final main folder. The output block coverage from genstats is also considerably higher than what was written in the console at the time the pipeline exited.

    In my tests, this seems to occur about 50% of the time in the Reflow Oven binary (24 hours, AFL++ mode)

    Given that the pipeline appears unaware of these reached blocks, could models be missing for MMIO access in these blocks?

    Thanks, CounterCycle

    opened by CounterCycle 1
  • More handlers

    More handlers

    Two suggestions for handlers:

    Fuzz Return: Sometimes it would be nice to fuzz the return value of a function instead of replacing it with a static value. I've prototyped this with the inline asm native.inline_asm_024900bfd1f800007047efbe0040 which returns the value of 0x4000beef (a made up peripheral address), but I suspect there may be better ways to do this.

    Readable ASM: Rather than specify inline_asm through hex values, it would be nice to have an option to write it out in readable form, and have it assembled, so as to make the config files more readable. This should be pretty easy with the keystone library. Something like

    from keystone import Ks,KS_ARCH_ARM,KS_MODE_THUMB
    patch = bytes(Ks(KS_ARCH_ARM, KS_MODE_THUMB).asm(readable_patch)[0])
    

    as compared to

    patch = binascii.unhexlify(inline_patch_hex)
    

    in emulator/harness/fuzzware_harness/user_hooks/__init__.py should work

    opened by YSaxon 1
  • Unexpected pipeline exit in AFL++ mode after modelling

    Unexpected pipeline exit in AFL++ mode after modelling

    Hello,

    I've been doing some testing with AFL++ after the fixes done in issue #7, thanks for resolving that. I've encountered a couple of additional issues.

    Most significantly, some pipeline sessions exit during the middle of fuzzing. The failure seems to occur when a round of modelling is completed. An error line appear stating "Exit code 2 != 0 received from afl-showmap, terminating...". Then an exception in python for no such file or directory at /main/base_inputs. I've pasted the error output below.

    I encountered this issue fuzzing the Zephyr SocketCAN binary from the fuzzware-experiments repo. I believe the issue is triggered when an input discovered using the old models triggers a firmware crash when run with the new models.

    [!] Exit code 2 != 0 received from afl-showmap, terminating...
    [10-25 14:22:25 ERROR] __init__.py - Got exception, shutting down pipeline: [Errno 2] No such file or directory: '/home/vagrant/fuzzware-experiments/02-comparison-with-state-of-the-art/uEmu/Zepyhr_SocketCan/run1/main002/base_inputs'
    Traceback (most recent call last):
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/session.py", line 230, in minimize_inputs
        run_corpus_minimizer(harness_args, self.temp_minimization_dir, self.base_input_dir, silent=silent, use_aflpp=self.parent.use_aflpp)
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/run_fuzzer.py", line 39, in run_corpus_minimizer
        subprocess.check_call(full_args, env={**os.environ, **{'AFL_SKIP_CRASHES': '1'}})
      File "/usr/lib/python3.8/subprocess.py", line 364, in check_call
        raise CalledProcessError(retcode, cmd)
    subprocess.CalledProcessError: Command '['/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/../../emulator/AFLplusplus/afl-cmin', '-m', 'none', '-U', '-t', '10000', '-i', '/home/vagrant/fuzzware-experiments/02-comparison-with-state-of-the-art/uEmu/Zepyhr_SocketCan/run1/main002/base_inputs_non_minimized', '-o', '/home/vagrant/fuzzware-experiments/02-comparison-with-state-of-the-art/uEmu/Zepyhr_SocketCan/run1/main002/base_inputs', '-e', '--', '/home/vagrant/.virtualenvs/fuzzware/bin/python', '-m', 'fuzzware_harness.harness', '-c', '/home/vagrant/fuzzware-experiments/02-comparison-with-state-of-the-art/uEmu/Zepyhr_SocketCan/run1/main002/config.yml', '@@']' returned non-zero exit status 2.
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/__init__.py", line 281, in do_pipeline
        pipeline.start()
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/pipeline.py", line 751, in start
        self.handle_queue_forever()
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/pipeline.py", line 704, in handle_queue_forever
        self.add_main_session(pending_prefix_candidate)
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/pipeline.py", line 541, in add_main_session
        self.curr_main_session.minimize_inputs(prefix_candidate_path=prefix_input_candidate, is_previously_used_prefix=is_previously_used_prefix)
      File "/home/vagrant/fuzzware/pipeline/fuzzware_pipeline/session.py", line 239, in minimize_inputs
        shutil.rmtree(self.base_input_dir)
      File "/usr/lib/python3.8/shutil.py", line 709, in rmtree
        onerror(os.lstat, path, sys.exc_info())
      File "/usr/lib/python3.8/shutil.py", line 707, in rmtree
        orig_st = os.lstat(path)
    FileNotFoundError: [Errno 2] No such file or directory: '/home/vagrant/fuzzware-experiments/02-comparison-with-state-of-the-art/uEmu/Zepyhr_SocketCan/run1/main002/base_inputs'
    [10-25 14:22:25 INFO] __init__.py - Shutting down pipeline now
    
    

    Additionally, I've noticed some minor issues with other components when AFL++ is used. Using fuzzware fuzz in AFL++ mode failed to start, even when pipeline works. And the output from fuzzware genstats coverage contains incorrect timestamps for block discoveries, I'm guessing because AFL++ already uses relative times in the plot_data file, while AFL used Unix time.

    Thank-you, CounterCycle

    opened by CounterCycle 2
  • Invalid instruction - ARM TrustZone Cortex-m33

    Invalid instruction - ARM TrustZone Cortex-m33

    Target

    The firmware I am trying to fuzz is compiled for the following targe : Manufacturer : STMicro Board : U-585i Architecture : cortex-m33 (+TrustZone)

    Setup

    Fuzzware has been installed locally using the install_local.sh script. On another virtualenv, I am using unicorn 2.0.0rc7 alongside afl++ 4.01c for testing purposes.

    My config.yml file is at the end of the ticket.

    Tests done

    I compiled and tested the firmware on the board -> works as intended. I tried to emulate it with unicorn 2.0.7 with the architecture set as : uc=Uc(UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS). It runs smoothly until it reaches peripheral accesses.

    After reading the paper, I decided to use fuzzware's heuristic. When running the pipeline, I get a UC_ERR_INSN_INVALID error while executing Instr: 0xc00e1f4: vldr s0, [pc, #0x144]. This instruction is understood correctly by unicorn 2.0.0rc7, so I decided to test it with unicorn 1.0.3 (the version unicorn-fuzzware is based on, if I understood right) -> I also get the UC_ERR_INSN_INVALID error.

    My question is : is this issue related to the version of unicorn used for fuzzware-unicorn ? If it is, would a fix require adding support for a more recent version of unicorn ?

    config.yaml

    include:
      - ./syms.yml
    
    entry_point: 0x0c00907c
    initial_sp: 0x30040000
    
    memory_map:
    
      mmio:
        base_addr:  0x40000000
        size: 0x20000000
        permissions: rw-
      mmio_core:
        base_addr:  0xe0000000
        size: 0x100000
        permissions: rw-
    
      ram_ns:
        base_addr: 0x20000000
        permissions: rw-
        size: 0xc0000
      ram_s:
        base_addr: 0x30000000
        permissions: rw-
        size: 0xc0000  
    
      sbfu_flash:
        base_addr: 0x0c004000
        file: 'bin/Project.bin'
        permissions: r-x
        size: 0x00022000
        is_entry: True
    
      loader_flash:
        base_addr: 0x0C1FA000
        file: bin/loader.bin
        permissions: r-x
        size: 0x00006000
    
      data_s:
        base_addr: 0x0c026000
        file: bin/tfm_s_data_init.bin
        permissions: r-x
        size: 0x00002000
    
      app_s:
        base_addr: 0x0c028000
        file: bin/tfm_s_app_init.bin
        permissions: r-x
        size: 0x0002e000
    
      data_ns:
        base_addr: 0x0C0F6000
        file: bin/tfm_ns_data_init.bin
        permissions: r-x
        size: 0x00002000
    
      app_ns:
        base_addr: 0x0C056000
        file: bin/tfm_ns_app_init.bin
        permissions: r-x
        size: 0x000a0000
    
    
    use_nvic: False
    use_systick: False  
    
    exit_at:
      addr: 0x0c00916a
    
    opened by Servax314 4
Releases(sec22-ae-accepted)
粉專/IG圖文加工器

粉專/IG圖文加工器 介紹 給PS智障(ex:我)使用,用於產生圖文 腳本省去每次重複步驟 可載入圖片(方形,請先處理過,歡迎PR) 圖片簡易套用濾鏡 可將圖片切片 要求 Python 版本 3.9 安裝 安裝最新 python pip3 install -r requirement.txt 效果

Louis Tang 7 Aug 10, 2022
Nudity detection with Python

nude.py About Nudity detection with Python. Port of nude.js to Python. Installation from pip: $ pip install --upgrade nudepy from easy_install: $ eas

Hideo Hattori 881 Jan 06, 2023
A utility for quickly cropping large collections of images.

Crop Tool A utility for quickly cropping large collections of images. Inspired by Derrick Schultz's dataset-tools. Setup It's suggested that you use A

dusk (they/them) 6 Nov 14, 2021
Pixel art as well as various sets for hand crafting

Pixel art as well as various sets for hand crafting

1 Nov 09, 2021
Music Thumbnail Maker

Music Thumbnail Installing pip install TMFrame

krypton 4 Jan 28, 2022
QR fixer part is standalone but for image to FQR conversion

f-qr-fixer QR fixer part is standalone but for image to FQR conversion it requires Pillow (can be installed with easy_install), qrtools (on ubuntu the

2 Nov 22, 2022
Image Processing - Make noise images clean

影像處理-影像降躁化(去躁化) (Image Processing - Make Noise Images Clean) 得力於電腦效能的大幅提升以及GPU的平行運算架構,讓我們能夠更快速且有效地訓練AI,並將AI技術應用於不同領域。本篇將帶給大家的是 「將深度學習應用於影像處理中的影像降躁化 」,

2 Aug 04, 2022
🎨 Generate and change color-schemes on the fly.

Generate and change color-schemes on the fly. Pywal is a tool that generates a color palette from the dominant colors in an image. It then applies the

dylan 6.9k Jan 03, 2023
An executor that wraps 3D mesh models and encodes 3D content documents to d-dimension vector.

3D Mesh Encoder An Executor that receives Documents containing point sets data in its blob attribute, with shape (N, 3) and encodes it to embeddings o

Jina AI 11 Dec 14, 2022
Archive of the image generator stuff from my API

alex_api_archive Archive of the image generator stuff from my API FAQ Q: Why? A: Because I am removing these components from the API Q: How do I run i

AlexFlipnote 26 Nov 17, 2022
A Icon Maker GUI Made - Convert your image into icon ( .ico format ).

Icon-Maker-GUI A Icon Maker GUI Made Using Python 3.9.0 . It will take any image and convert it to ICO file, for web site favicon or Windows applicati

Insanecodes 12 Dec 15, 2021
This Github Action automatically creates a GIF from a given web page to display on your project README

This Github Action automatically creates a GIF from a given web page to display on your project README

Pablo Lecolinet 28 Dec 15, 2022
ProsePainter combines direct digital painting with real-time guided machine-learning based image optimization.

ProsePainter Create images by painting with words. ProsePainter combines direct digital painting with real-time guided machine-learning based image op

Morphogen 276 Dec 17, 2022
An API that renders HTML/CSS content to PNG using Chromium

html_png An API that renders HTML/CSS content to PNG using Chromium Disclaimer I am not responsible if you happen to make your own instance of this AP

10 Aug 08, 2022
📷 Python package and CLI utility to create photo mosaics.

📷 Python package and CLI utility to create photo mosaics.

Loic Coyle 7 Oct 29, 2022
A Robust Avatar Generator with a huge number of templates

CoolAvatars Welcome to this repository of CoolAvatars. Using this project, you can generate cool avatars not only from the samples present in my image

RAVI PRAKASH 5 Oct 12, 2021
sK1 2.0 cross-platform vector graphics editor

sK1 2.0 sK1 2.0 is a cross-platform open source vector graphics editor similar to CorelDRAW, Adobe Illustrator, or Freehand. sK1 is oriented for prepr

sK1 Project 238 Dec 04, 2022
A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos.

font2png A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos. To use from command line it expects python3 to be at /

Rich Elmes 3 Dec 22, 2021
Extract the temperature data of each wire from the thermal imager raw data.

Wire-Tempurature-Detection Extract the temperature data of each wire from the thermal imager raw data. The motivation of this computer vision project

JohanAckerman 1 Nov 03, 2021
PSD (Photoshop, Krita, Gimp...) -> Godot.

limage v0.2.2 Features Getting Started Tags Settings Todo Customizer Changes Solutions WARNING: Requires Python to be installed PSD (Photoshop, Krita,

21 Nov 10, 2022