├── .tool-versions ├── pkg ├── debian │ ├── debian │ │ ├── compat │ │ ├── source │ │ │ └── format │ │ ├── panopticon.install │ │ ├── copyright │ │ ├── control │ │ ├── rules │ │ └── changelog │ ├── entrypoint.sh │ ├── README.md │ ├── Dockerfile.debian │ └── Dockerfile.ubuntu ├── fedora │ ├── package.sh │ ├── Dockerfile │ └── panopticon.spec ├── xdg │ └── usr │ │ └── share │ │ ├── applications │ │ └── panopticon.desktop │ │ └── pixmaps │ │ └── panopticon.svg ├── osx │ ├── package_dmg.sh │ └── Info.plist ├── windows │ └── package_zip.bat ├── arch │ └── PKGBUILD └── README.md ├── Cargo.toml ├── logo.png ├── test-data ├── sosse ├── static ├── ia32.com ├── test.exe ├── amd64.com ├── hello-world ├── libbeef.dll ├── libfoo.so ├── save.panop ├── deadbeef.mach ├── libbeef.dylib ├── avr-overflow.bin ├── avr-all-opcodes.bin └── avr-jmp-overflow.bin ├── qml ├── icons │ ├── logo.png │ ├── external-link.png │ ├── chevron-down.svg │ ├── chevron-up.svg │ ├── eraser.svg │ ├── arrow-left.svg │ ├── file-o.svg │ ├── arrow-right.svg │ ├── pencil.svg │ ├── home.svg │ ├── search.svg │ ├── arrow-circle-up.svg │ ├── arrow-circle-left.svg │ ├── arrow-circle-right.svg │ ├── exclamation-triangle.svg │ ├── repeat.svg │ ├── undo.svg │ ├── external-link.svg │ ├── folder-open-o.svg │ ├── history-icon.svg │ ├── link.svg │ ├── cross.svg │ ├── warning-icon.svg │ ├── open-icon.svg │ ├── sandbox-icon.svg │ ├── example-icon.svg │ └── logo.svg ├── fonts │ ├── SourceSansPro-It.ttf │ ├── SourceSansPro-Black.ttf │ ├── SourceSansPro-Bold.ttf │ ├── SourceSansPro-Light.ttf │ ├── SourceCodePro-Regular.ttf │ ├── SourceSansPro-BlackIt.ttf │ ├── SourceSansPro-BoldIt.ttf │ ├── SourceSansPro-LightIt.ttf │ ├── SourceSansPro-Regular.ttf │ ├── SourceSansPro-Semibold.ttf │ ├── SourceSansPro-ExtraLight.ttf │ ├── SourceSansPro-SemiboldIt.ttf │ └── SourceSansPro-ExtraLightIt.ttf ├── qmldir ├── Panopticon │ ├── qmldir │ ├── Label.qml │ ├── Monospace.qml │ ├── ColumnHeader.qml │ ├── MessageBlock.qml │ ├── EditPopover.qml │ ├── CommentOverlay.qml │ ├── PreviewOverlay.qml │ ├── Window.qml │ └── Welcome.qml └── Window.qml ├── .gitignore ├── data-flow ├── Cargo.toml └── src │ └── lib.rs ├── mos6502 ├── Cargo.toml └── src │ └── lib.rs ├── graph-algos ├── Cargo.toml └── src │ ├── lib.rs │ └── traits.rs ├── avr ├── Cargo.toml ├── src │ └── lib.rs └── tests │ └── avr.rs ├── abstract-interp ├── Cargo.toml └── src │ ├── lib.rs │ └── widening.rs ├── analysis ├── Cargo.toml └── src │ └── lib.rs ├── glue ├── Cargo.toml ├── ext │ ├── CMakeLists.txt │ └── lib │ │ ├── CMakeLists.txt │ │ ├── src │ │ ├── qrecentsession.cpp │ │ ├── qbasicblockline.cpp │ │ ├── qsidebar.cpp │ │ ├── qpanopticon.cpp │ │ └── glue.cpp │ │ └── include │ │ ├── qsidebar.h │ │ ├── qrecentsession.h │ │ ├── glue.h │ │ ├── qbasicblockline.h │ │ ├── qcontrolflowgraph.h │ │ └── qpanopticon.h └── src │ ├── lib.rs │ ├── ffi.rs │ └── types.rs ├── rustfmt.toml ├── amd64 ├── Cargo.toml ├── src │ ├── lib.rs │ └── architecture.rs └── tests │ └── opcodes.rs ├── cli └── Cargo.toml ├── core ├── Cargo.toml ├── tests │ ├── project.rs │ ├── region.rs │ └── loader.rs └── src │ ├── result.rs │ ├── lib.rs │ └── project.rs ├── AUTHORS ├── qt ├── Cargo.toml ├── src │ ├── paths.rs │ └── main.rs └── tests │ └── sugiyama.rs ├── CONTRIBUTING.md ├── CHANGELOG ├── appveyor.yml ├── README.md └── .travis.yml /.tool-versions: -------------------------------------------------------------------------------- 1 | rust stable 2 | -------------------------------------------------------------------------------- /pkg/debian/debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /pkg/debian/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["qt", "cli"] 3 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/logo.png -------------------------------------------------------------------------------- /test-data/sosse: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/sosse -------------------------------------------------------------------------------- /test-data/static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/static -------------------------------------------------------------------------------- /qml/icons/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/icons/logo.png -------------------------------------------------------------------------------- /test-data/ia32.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/ia32.com -------------------------------------------------------------------------------- /test-data/test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/test.exe -------------------------------------------------------------------------------- /test-data/amd64.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/amd64.com -------------------------------------------------------------------------------- /test-data/hello-world: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/hello-world -------------------------------------------------------------------------------- /test-data/libbeef.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/libbeef.dll -------------------------------------------------------------------------------- /test-data/libfoo.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/libfoo.so -------------------------------------------------------------------------------- /test-data/save.panop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/save.panop -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /doc/_build 2 | *.swp 3 | doc/html 4 | /target 5 | **/*.qmlc 6 | **/*.jsc 7 | **/*.rs.bk 8 | -------------------------------------------------------------------------------- /test-data/deadbeef.mach: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/deadbeef.mach -------------------------------------------------------------------------------- /test-data/libbeef.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/libbeef.dylib -------------------------------------------------------------------------------- /test-data/avr-overflow.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/avr-overflow.bin -------------------------------------------------------------------------------- /qml/icons/external-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/icons/external-link.png -------------------------------------------------------------------------------- /pkg/debian/debian/panopticon.install: -------------------------------------------------------------------------------- 1 | ../../target/release/panopticon usr/bin 2 | ../../qml usr/share/panopticon 3 | -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-It.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-It.ttf -------------------------------------------------------------------------------- /test-data/avr-all-opcodes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/avr-all-opcodes.bin -------------------------------------------------------------------------------- /test-data/avr-jmp-overflow.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/test-data/avr-jmp-overflow.bin -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-Black.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-Bold.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceCodePro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceCodePro-Regular.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-BlackIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-BlackIt.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-BoldIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-BoldIt.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-LightIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-LightIt.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-Semibold.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-ExtraLight.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-SemiboldIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-SemiboldIt.ttf -------------------------------------------------------------------------------- /qml/fonts/SourceSansPro-ExtraLightIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/das-labor/panopticon/HEAD/qml/fonts/SourceSansPro-ExtraLightIt.ttf -------------------------------------------------------------------------------- /qml/qmldir: -------------------------------------------------------------------------------- 1 | module Panopticon 2 | 3 | ColumnHeader 1.0 ColumnHeader.qml 4 | Sidebar 1.0 Sidebar.qml 5 | Welcome 1.0 Welcome.qml 6 | Window 1.0 Window.qml 7 | -------------------------------------------------------------------------------- /qml/Panopticon/qmldir: -------------------------------------------------------------------------------- 1 | module Panopticon 2 | 3 | ColumnHeader 1.0 ColumnHeader.qml 4 | Sidebar 1.0 Sidebar.qml 5 | Welcome 1.0 Welcome.qml 6 | Window 1.0 Window.qml 7 | -------------------------------------------------------------------------------- /qml/Panopticon/Label.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtQuick.Controls 1.3 3 | 4 | Label { 5 | font { 6 | family: "Source Sans Pro" 7 | } 8 | color: "black" 9 | } 10 | -------------------------------------------------------------------------------- /qml/Panopticon/Monospace.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtQuick.Controls 1.3 3 | 4 | Label { 5 | font { 6 | family: "Source Code Pro" 7 | } 8 | color: "black" 9 | } 10 | -------------------------------------------------------------------------------- /pkg/fedora/package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | spectool -g panopticon.spec 3 | fedpkg --release f25 local 4 | fedpkg --release f25 lint 5 | 6 | cp /x86_64/panopticon*.rpm /out/panopticon_0.16_amd64.rpm 7 | -------------------------------------------------------------------------------- /pkg/xdg/usr/share/applications/panopticon.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Exec=/usr/bin/panopticon 3 | Type=Application 4 | Terminal=false 5 | Icon=panopticon 6 | Categories=Development; 7 | Name=Panopticon 8 | GenericName=Disassembler 9 | -------------------------------------------------------------------------------- /data-flow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-data-flow" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | panopticon-core = { path = "../core" } 8 | panopticon-graph-algos = { path = "../graph-algos" } 9 | -------------------------------------------------------------------------------- /mos6502/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-mos6502" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | panopticon-core = { path = "../core" } 8 | log = "0.3.6" 9 | byteorder = "1" 10 | lazy_static = "0" 11 | -------------------------------------------------------------------------------- /pkg/debian/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sh /tmp/rustup.sh --disable-sudo --yes 3 | git clone $PANOPTICON_URL 4 | cd panopticon 5 | git checkout $PANOPTICON_BRANCH 6 | cd pkg/debian 7 | dpkg-buildpackage 8 | lintian ../*.deb 9 | cp ../*.{dsc,deb} /out/ 10 | -------------------------------------------------------------------------------- /graph-algos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-graph-algos" 3 | version = "0.11.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | serde = "1.0" 8 | serde_derive = "1.0" 9 | bit-set = "0.4" 10 | 11 | [dev-dependencies] 12 | rmp-serde = "0.13" 13 | -------------------------------------------------------------------------------- /qml/icons/chevron-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/chevron-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /avr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-avr" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | panopticon-core = { path = "../core" } 8 | panopticon-graph-algos = { path = "../graph-algos" } 9 | log = "0.3.6" 10 | byteorder = "1" 11 | env_logger = "0.3" 12 | -------------------------------------------------------------------------------- /pkg/debian/README.md: -------------------------------------------------------------------------------- 1 | Docker build: 2 | 1. Build the docker image: `docker build -t panopticon-build .` 3 | 2. Run a docker container to build the package: ``docker run -v `pwd`:/out panopticon-build`` 4 | 5 | Normal build: 6 | 1. Build the package: `dpkg-buildpackage` 7 | 2. Basic sanitiy checks: `lintian *.{deb,dsc}` 8 | -------------------------------------------------------------------------------- /qml/icons/eraser.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/file-o.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/pencil.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/osx/package_dmg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cargo build --all --release 3 | mkdir -p Panopticon.app/Contents/{MacOS,Resources} 4 | cp Info.plist Panopticon.app/Contents 5 | cp ../../target/release/panopticon Panopticon.app/Contents/MacOS/Panopticon 6 | cp -R ../../qml Panopticon.app/Contents/Resources 7 | $QTDIR64/bin/macdeployqt Panopticon.app -qmldir=Panopticon.app/Contents/Resources/qml/ -dmg 8 | -------------------------------------------------------------------------------- /pkg/debian/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | 3 | Files: * 4 | Copyright: 2013-2017 Panopticon authors 5 | License: GPL-3 6 | See /usr/share/common-licenses/GPL-3 7 | 8 | Files: qml/fonts 9 | See http://scripts.sil.org/OFL for full license 10 | 11 | Files: glue/build.rs 12 | https://github.com/flanfly/qmlrs/blob/master/LICENSE-MIT 13 | for full license. 14 | -------------------------------------------------------------------------------- /abstract-interp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-abstract-interp" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | panopticon-core = { path = "../core" } 8 | panopticon-data-flow = { path = "../data-flow" } 9 | panopticon-graph-algos = { path = "../graph-algos" } 10 | log = "0.3.6" 11 | quickcheck = "0.3" 12 | env_logger = "0.3" 13 | serde = "1.0" 14 | serde_derive = "1.0" 15 | -------------------------------------------------------------------------------- /analysis/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-analysis" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | log = "0.3.6" 8 | futures = "0.1.13" 9 | rayon = "0.8" 10 | chashmap = "2.2.0" 11 | uuid = "0.5" 12 | parking_lot = "0.4" 13 | panopticon-core = { path = "../core" } 14 | panopticon-data-flow = { path = "../data-flow" } 15 | panopticon-graph-algos = { path = "../graph-algos" } 16 | -------------------------------------------------------------------------------- /qml/icons/home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /glue/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-glue" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | build = "build.rs" 6 | 7 | [build-dependencies] 8 | cmake = "0.1" 9 | pkg-config = "0.3.9" 10 | 11 | [dependencies] 12 | panopticon-core = { path = "../core" } 13 | panopticon-graph-algos = { path = "../graph-algos" } 14 | log = "0.3.6" 15 | error-chain = "0.8.1" 16 | uuid = { version = "0.5", features = ["v4"]} 17 | futures = "0.1.13" 18 | -------------------------------------------------------------------------------- /qml/icons/arrow-circle-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/arrow-circle-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width=160 2 | fn_call_width=60 3 | chain_one_line_max=160 4 | reorder_imports=true 5 | reorder_imported_names=true 6 | fn_args_layout = "Block" 7 | array_layout = "Block" 8 | where_style = "Rfc" 9 | generics_indent = "Block" 10 | fn_call_style = "Block" 11 | struct_lit_style = "Block" 12 | struct_lit_multiline_style = "PreferSingle" 13 | struct_lit_width = 60 14 | struct_variant_width = 60 15 | array_width = 80 16 | tab_spaces = 4 17 | use_try_shorthand = true 18 | -------------------------------------------------------------------------------- /qml/icons/arrow-circle-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /amd64/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-amd64" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | 6 | [dependencies] 7 | panopticon-core = { path = "../core" } 8 | log = "0.3.6" 9 | byteorder = "1" 10 | env_logger = "0.3" 11 | quickcheck = "0.3" 12 | 13 | [dev-dependencies] 14 | regex = "0.1" 15 | 16 | [features] 17 | # Cross checks the x86/AMD64 simulator against the CPU. Needs the rappel tool 18 | # installed (https://github.com/yrp604/rappel). 19 | cross-check-amd64 = [] 20 | -------------------------------------------------------------------------------- /qml/icons/exclamation-triangle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/repeat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/undo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /qml/icons/external-link.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /qml/icons/folder-open-o.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/fedora/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:25 2 | 3 | MAINTAINER sphinxc0re 4 | 5 | RUN dnf install -y gcc-c++ cmake make \ 6 | qt5-qtdeclarative-devel \ 7 | qt5-qtquickcontrols \ 8 | qt5-qtgraphicaleffects \ 9 | qt5-qtsvg-devel \ 10 | adobe-source-sans-pro-fonts \ 11 | adobe-source-code-pro-fonts \ 12 | fedora-packager \ 13 | rustc \ 14 | cargo 15 | 16 | COPY panopticon.spec /panopticon.spec 17 | COPY package.sh /package.sh 18 | 19 | CMD /package.sh 20 | -------------------------------------------------------------------------------- /cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-cli" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | edition = "2018" 6 | 7 | [[bin]] 8 | name = "panop" 9 | path = "src/main.rs" 10 | 11 | [dependencies] 12 | structopt = "0.0.5" 13 | structopt-derive = "0.0.5" 14 | error-chain = "0.8" 15 | futures = "0.1" 16 | panopticon-core = { path = "../core" } 17 | panopticon-analysis = { path = "../analysis" } 18 | panopticon-amd64 = { path = "../amd64" } 19 | panopticon-avr = { path = "../avr" } 20 | panopticon-graph-algos = { path = "../graph-algos" } 21 | log = "0.3" 22 | env_logger = "0.3" 23 | termcolor = "0.3.2" 24 | atty = "0.2.2" 25 | -------------------------------------------------------------------------------- /core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon-core" 3 | version = "0.16.0" 4 | authors = ["seu "] 5 | build = "build.rs" 6 | 7 | [dependencies] 8 | num = "0.1" 9 | log = "0.3.6" 10 | env_logger = "0.3" 11 | tempdir = "0.3.4" 12 | libc = "0.2.9" 13 | uuid = { version = "0.5", features = ["v4", "serde"]} 14 | flate2 = "0.2.13" 15 | byteorder = "1" 16 | goblin = "0.0.11" 17 | quickcheck = "0.3" 18 | panopticon-graph-algos = { path = "../graph-algos" } 19 | serde = { version = "1.0", features = ["rc"] } 20 | serde_derive = "1.0" 21 | serde_cbor = "0.6" 22 | 23 | [dev-dependencies] 24 | regex = "0.1" 25 | panopticon-avr = { path = "../avr" } 26 | -------------------------------------------------------------------------------- /qml/icons/history-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/osx/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrincipalClass 6 | NSApplication 7 | NSHighResolutionCapable 8 | True 9 | CFBundleName 10 | Panopticon 11 | CFBundleIdentifier 12 | re.panopticon 13 | CFBundleVersion 14 | 0.16.0 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | panopticon 19 | CFBundleExecutable 20 | Panopticon 21 | 22 | 23 | -------------------------------------------------------------------------------- /pkg/debian/debian/control: -------------------------------------------------------------------------------- 1 | Source: panopticon 2 | Maintainer: seu 3 | Build-Depends: debhelper (>= 9.0), cdbs, cmake (>= 2.8.9), qtdeclarative5-dev, libqt5svg5-dev, qtbase5-private-dev, pkg-config 4 | Homepage: http://panopticon.re/ 5 | Priority: optional 6 | Standards-Version: 3.9.5.0 7 | Section: editors 8 | 9 | Package: panopticon 10 | Architecture: amd64 i386 11 | Description: Qt 5 frontend of Panopticon 12 | Graphical interface for browsing and manipulating binary programs. 13 | Depends: ${misc:Depends}, ${shlibs:Depends}, qml-module-qtquick-controls, qml-module-qttest, qml-module-qtquick2, qml-module-qtquick-layouts, qml-module-qtgraphicaleffects, qml-module-qtqml-models2, qml-module-qtquick-dialogs 14 | Priority: optional 15 | Section: editors 16 | -------------------------------------------------------------------------------- /pkg/debian/Dockerfile.debian: -------------------------------------------------------------------------------- 1 | FROM debian:stretch 2 | 3 | MAINTAINER seu 4 | 5 | RUN apt-get -y update && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get -y upgrade && \ 7 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 8 | qt5-default qtdeclarative5-dev \ 9 | qml-module-qtquick-controls qml-module-qttest \ 10 | qml-module-qtquick2 qml-module-qtquick-layouts \ 11 | qml-module-qtgraphicaleffects \ 12 | libqt5svg5-dev qtbase5-private-dev pkg-config \ 13 | libglpk-dev git build-essential cmake \ 14 | git dpkg-dev lintian debhelper cdbs file curl 15 | 16 | COPY entrypoint.sh /entrypoint.sh 17 | COPY rustup.sh /tmp/rustup.sh 18 | 19 | ENV PANOPTICON_URL="https://github.com/das-labor/panopticon" 20 | ENV PANOPTICON_BRANCH="master" 21 | 22 | CMD /entrypoint.sh 23 | -------------------------------------------------------------------------------- /pkg/debian/Dockerfile.ubuntu: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | 3 | MAINTAINER seu 4 | 5 | RUN apt-get -y update && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get -y upgrade && \ 7 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 8 | qt5-default qtdeclarative5-dev \ 9 | qml-module-qtquick-controls qml-module-qttest \ 10 | qml-module-qtquick2 qml-module-qtquick-layouts \ 11 | qml-module-qtgraphicaleffects \ 12 | libqt5svg5-dev qtbase5-private-dev pkg-config \ 13 | libglpk-dev git build-essential cmake \ 14 | git dpkg-dev lintian debhelper cdbs file curl 15 | 16 | COPY entrypoint.sh /entrypoint.sh 17 | COPY rustup.sh /tmp/rustup.sh 18 | 19 | ENV PANOPTICON_URL="https://github.com/das-labor/panopticon" 20 | ENV PANOPTICON_BRANCH="master" 21 | 22 | CMD /entrypoint.sh 23 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | List of authors 2 | =============== 3 | 4 | Mikko Perttunen 5 | Build script glue/build.rs. See 6 | https://github.com/flanfly/qmlrs/blob/master/LICENSE-MIT 7 | for full license. 8 | Philipp Deppenwiese 9 | Gentoo ebuild and supporting files inside pkg/gentoo. 10 | Dave Gandy 11 | The file qml/fonts/. See http://scripts.sil.org/OFL 12 | for full license 13 | Marcus Brinkmann 14 | MOS-6502 disassembler in mos6502/src/. 15 | m4b 16 | The binary file loader in core/src/loader.rs 17 | Kai Michaelis 18 | Everything not listed above. 19 | 20 | All other contributors 21 | ====================== 22 | 23 | Andre Bogus 24 | Endres Puschner 25 | Harris Brakmic 26 | Ismail Khoffi 27 | Jean Pierre Dudey 28 | Michael Büsch 29 | Philipp Deppenwiese 30 | Stefan Schindler 31 | Tobias Bucher 32 | m4b 33 | -------------------------------------------------------------------------------- /qml/icons/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /glue/ext/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | # Add Coverage option 4 | option(ENABLE_COVERAGE "Enable coverage" OFF) 5 | 6 | # Add additional source path for cmake 7 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/) 8 | 9 | # Add strict warning checking for C++ 10 | if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") 12 | endif() 13 | 14 | if (ENABLE_COVERAGE) 15 | message(STATUS "Enabling coverage") 16 | set(CMAKE_BUILD_TYPE Debug) 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 19 | endif() 20 | 21 | # Add additional source path for cmake 22 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/) 23 | 24 | #add_subdirectory(doc) 25 | add_subdirectory(lib) 26 | #add_subdirectory(test) 27 | -------------------------------------------------------------------------------- /qml/icons/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /pkg/debian/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/dpkg/pkg-info.mk 4 | include /usr/share/dpkg/architecture.mk 5 | include /usr/share/dpkg/buildflags.mk 6 | export CFLAGS CXXFLAGS CPPFLAGS LDFLAGS 7 | 8 | rust_cpu = $(subst i586,i686,$(1)) 9 | DEB_HOST_RUST_TYPE := $(call rust_cpu,$(DEB_HOST_GNU_CPU))-unknown-$(DEB_HOST_GNU_SYSTEM) 10 | DEB_TARGET_RUST_TYPE := $(call rust_cpu,$(DEB_TARGET_GNU_CPU))-unknown-$(DEB_TARGET_GNU_SYSTEM) 11 | 12 | # Cargo looks for config in and writes cache to $CARGO_HOME/ 13 | export CARGO_HOME = $(CURDIR)/.cargohome 14 | # Ask cargo to be verbose when building 15 | export VERBOSE = 1 16 | 17 | DEB_DESTDIR := $(CURDIR)/debian/tmp 18 | VENDORDIR := $(CURDIR)/vendor 19 | INDEXDIR := $(CURDIR)/vendor/index 20 | DEPSDIR := $(CURDIR)/deps 21 | 22 | %: 23 | dh $@ 24 | 25 | override_dh_auto_build: 26 | cargo build --all --release 27 | 28 | override_dh_auto_clean: 29 | cargo clean 30 | rm -rf "$(CARGO_HOME)" 31 | 32 | override_dh_auto_install: 33 | # We pick stuff directly from target/ 34 | -------------------------------------------------------------------------------- /core/tests/project.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | 21 | use panopticon_core::Project; 22 | use std::path::Path; 23 | 24 | #[test] 25 | fn project_open() { 26 | let maybe_project = Project::open(Path::new("../test-data/save.panop")); 27 | 28 | assert!(maybe_project.ok().is_some()); 29 | } 30 | -------------------------------------------------------------------------------- /pkg/windows/package_zip.bat: -------------------------------------------------------------------------------- 1 | rem Variables 2 | rem set QTDIR=C:\Qt\5.5\msvc2013_64 3 | rem set RUSTDIR=C:\Program Files\Rust stable MSVC 1.10 4 | rem set CMAKEDIR=C:\Program Files (x86)\CMake 5 | rem set VSDIR=C:\Program Files (x86)\Microsoft Visual Studio 12.0 6 | rem set P7ZDIR="C:\Program Files\7-Zip\7z.exe" 7 | set VERSION="0.16" 8 | 9 | rem Aux var setup 10 | rem set PATH=%GLPKDIR%\w64;%RUSTDIR%\bin;%CMAKEDIR%\bin;%QTDIR%\bin;%PATH% 11 | rem set CMAKE_PREFIX_PATH=%QTDIR%;%CMAKE_PREFIX_PATH% 12 | rem set LIB=%GLPKDIR%\w64;%LIB% 13 | rem call "%VSDIR%\VC\vcvarsall.bat" x64 14 | 15 | rem Build 16 | cargo build --all --release 17 | 18 | rem Package 19 | md out 20 | copy ..\..\target\release\panopticon.exe out\panopticon.exe 21 | xcopy /e /i /s /y ..\..\qml out\qml 22 | TYPE ..\..\README.md | MORE /P > out\README.txt 23 | TYPE ..\..\LICENSE | MORE /P > out\LICENSE.txt 24 | TYPE ..\..\AUTHORS | MORE /P > out\AUTHORS.txt 25 | TYPE ..\..\CHANGELOG | MORE /P > out\CHANGELOG.txt 26 | %QTDIR%\bin\windeployqt.exe --release --qmldir out\qml out\panopticon.exe 27 | 7z a panopticon-%VERSION%.zip .\out\* 28 | 29 | rmdir /s /q out 30 | -------------------------------------------------------------------------------- /pkg/arch/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Kai Michaelis 2 | pkgname=panopticon-git 3 | pkgver=0.16.0.1246 4 | pkgrel=1 5 | pkgdesc="A libre cross platform disassembler" 6 | arch=('x86_64' 'i686') 7 | url="https://panopticon.re/" 8 | license=('GPL3') 9 | groups=('devel') 10 | depends=( 11 | 'qt5-quickcontrols>=5.4' 12 | 'qt5-svg>=5.4' 13 | 'qt5-graphicaleffects>=5.4') 14 | makedepends=( 15 | 'rust' 16 | 'cargo' 17 | 'git>=1' 18 | 'cmake>=2.8.9') 19 | provides=('panopticon') 20 | conflicts=('panopticon') 21 | source=($pkgname::git+https://github.com/das-labor/panopticon.git) 22 | md5sums=('SKIP') 23 | 24 | pkgver() { 25 | cd $pkgname 26 | echo "0.16.0.$(git rev-list --count HEAD)" 27 | } 28 | 29 | build() { 30 | cd $pkgname 31 | cargo build --release 32 | } 33 | 34 | package() { 35 | cd $pkgname 36 | install -d -m755 "$pkgdir/usr/bin" 37 | install -D -s -m555 "$srcdir/$pkgname/target/release/qtpanopticon" "$pkgdir/usr/bin/qtpanopticon" 38 | install -m755 -d "$pkgdir/usr/share/panopticon/qml" 39 | cp -R "qml/"* "$pkgdir/usr/share/panopticon/qml" 40 | chown -R root:root "$pkgdir/usr/share/panopticon/qml" 41 | } 42 | -------------------------------------------------------------------------------- /glue/ext/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(panopticon-glue) 2 | 3 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 4 | set(CMAKE_AUTOMOC ON) 5 | 6 | if (WIN32) 7 | add_definitions(-DWIN32) 8 | endif() 9 | 10 | find_package(Qt5Core) 11 | find_package(Qt5Qml) 12 | find_package(Qt5Quick) 13 | find_package(Qt5Svg) 14 | 15 | set(HEADERS_LIST 16 | include/glue.h 17 | include/qpanopticon.h 18 | include/qcontrolflowgraph.h 19 | include/qsidebar.h 20 | include/qbasicblockline.h 21 | include/qrecentsession.h 22 | ) 23 | 24 | set(SRC_LIST 25 | src/glue.cpp 26 | src/qpanopticon.cpp 27 | src/qcontrolflowgraph.cpp 28 | src/qsidebar.cpp 29 | src/qbasicblockline.cpp 30 | src/qrecentsession.cpp 31 | ) 32 | 33 | include_directories(include include/Qt) 34 | 35 | set(major 0) 36 | set(minor 0) 37 | set(patch 0) 38 | 39 | add_library("${PROJECT_NAME}" ${SRC_LIST} ${HEADERS_LIST}) 40 | set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) 41 | target_link_libraries("${PROJECT_NAME}" PRIVATE Qt5::Core Qt5::Gui 42 | Qt5::Svg Qt5::Qml Qt5::Quick) 43 | 44 | # Install directive for binaries 45 | install(TARGETS ${PROJECT_NAME} 46 | RUNTIME DESTINATION bin 47 | LIBRARY DESTINATION lib 48 | ARCHIVE DESTINATION lib 49 | ) 50 | -------------------------------------------------------------------------------- /analysis/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! Disassembly-Analysis loop. 20 | 21 | #[macro_use] 22 | extern crate log; 23 | 24 | extern crate panopticon_core; 25 | extern crate panopticon_data_flow; 26 | extern crate panopticon_graph_algos; 27 | extern crate futures; 28 | extern crate chashmap; 29 | extern crate rayon; 30 | extern crate uuid; 31 | extern crate parking_lot; 32 | 33 | mod pipeline; 34 | pub use crate::pipeline::pipeline; 35 | pub use crate::pipeline::analyze; 36 | -------------------------------------------------------------------------------- /avr/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2014,2015,2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! 8-bit AVR disassembler. 20 | //! 21 | //! This disassembler handles the 8-bit AVR microcontroller instruction set including XMEGA. 22 | 23 | #![allow(missing_docs)] 24 | 25 | #[macro_use] 26 | extern crate log; 27 | 28 | #[macro_use] 29 | extern crate panopticon_core; 30 | extern crate panopticon_graph_algos; 31 | extern crate byteorder; 32 | 33 | mod syntax; 34 | mod semantic; 35 | 36 | mod disassembler; 37 | pub use crate::disassembler::{Avr, Mcu}; 38 | -------------------------------------------------------------------------------- /mos6502/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2014, 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! MOS 6502 disassembler. 20 | //! 21 | //! This disassembler handles all documented opcode of the MOS Technology 6502 microprocessor. 22 | 23 | #![allow(missing_docs)] 24 | 25 | #[macro_use] 26 | extern crate log; 27 | #[macro_use] 28 | extern crate panopticon_core; 29 | #[macro_use] 30 | extern crate lazy_static; 31 | 32 | extern crate byteorder; 33 | 34 | mod syntax; 35 | mod semantic; 36 | 37 | mod disassembler; 38 | pub use crate::disassembler::{Mos, Variant}; 39 | -------------------------------------------------------------------------------- /data-flow/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! Collection of data flow algorithms. 20 | //! 21 | //! This module contains algorithms to convert RREIL code into SSA form. Aside from SSA form this 22 | //! module implements functions to compute liveness sets and basic reverse data flow information. 23 | 24 | extern crate panopticon_core; 25 | extern crate panopticon_graph_algos; 26 | 27 | mod liveness; 28 | pub use crate::liveness::{liveness, liveness_sets}; 29 | 30 | mod ssa; 31 | pub use crate::ssa::{flag_operations, ssa_convertion, type_check}; 32 | -------------------------------------------------------------------------------- /glue/ext/lib/src/qrecentsession.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "qrecentsession.h" 20 | 21 | QRecentSession::QRecentSession(const RecentSession& line, QObject* parent) 22 | : QObject(parent), m_title(line.title), m_kind(line.kind), m_timestamp(line.timestamp), m_path(line.path) 23 | {} 24 | 25 | QRecentSession::~QRecentSession() {} 26 | 27 | QString QRecentSession::getTitle(void) const { return m_title; } 28 | QString QRecentSession::getKind(void) const { return m_kind; } 29 | quint64 QRecentSession::getTimestamp(void) const { return m_timestamp; } 30 | QString QRecentSession::getPath(void) const { return m_path; } 31 | -------------------------------------------------------------------------------- /qt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "panopticon" 3 | version = "0.16.0" 4 | authors = ["seu ", "m4b "] 5 | edition = "2018" 6 | 7 | [[bin]] 8 | name = "panopticon" 9 | path = "src/main.rs" 10 | 11 | [dependencies] 12 | panopticon-core = { path = "../core" } 13 | panopticon-data-flow = { path = "../data-flow" } 14 | panopticon-abstract-interp = { path = "../abstract-interp" } 15 | panopticon-amd64 = { path = "../amd64" } 16 | panopticon-avr = { path = "../avr" } 17 | panopticon-mos6502 = { path = "../mos6502" } 18 | panopticon-analysis = { path = "../analysis" } 19 | panopticon-glue = { path = "../glue" } 20 | panopticon-graph-algos = { path = "../graph-algos" } 21 | log = "0.3.6" 22 | env_logger = "0.3" 23 | uuid = { version = "0.5", features = ["v4", "serde"]} 24 | cassowary = "0.1" 25 | tempdir = "0.3" 26 | chrono = "0.2" 27 | chrono-humanize = "0.0" 28 | clap = "2.24" 29 | futures = "0.1.13" 30 | futures-cpupool = "0.1" 31 | parking_lot = "0.4" 32 | multimap = "0.3" 33 | error-chain = "0.8" 34 | lazy_static = "0.1" 35 | libc = "0.2" 36 | hamt = "0.2" 37 | num = "0.1" 38 | 39 | [dev-dependencies] 40 | regex = "0.1" 41 | quickcheck = "0.3" 42 | 43 | [target.i686-unknown-linux-gnu.dependencies] 44 | xdg = "^2.0" 45 | 46 | [target.x86_64-unknown-linux-gnu.dependencies] 47 | xdg = "^2.0" 48 | 49 | [target.x86_64-apple-darwin.dependencies] 50 | xdg = "^2.0" 51 | 52 | [target.i686-apple-darwin.dependencies] 53 | xdg = "^2.0" 54 | -------------------------------------------------------------------------------- /qml/Panopticon/ColumnHeader.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.4 2 | import QtQuick.Controls 1.3 as Ctrl 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Controls.Styles 1.2 5 | 6 | Item { 7 | property int columnWidth: 0 8 | property string columnTitle: "" 9 | property int columnOrdinal: 0 10 | 11 | Layout.alignment: Qt.AlignHCenter 12 | Layout.preferredWidth: columnWidth 13 | Layout.preferredHeight: childrenRect.height 14 | 15 | Item { 16 | anchors.centerIn: parent 17 | width: childrenRect.width 18 | height: childrenRect.height 19 | 20 | Label { 21 | id: title 22 | text: columnTitle 23 | color: "#8e8e8e" 24 | font.pointSize: 9 25 | } 26 | 27 | Image { 28 | height: 10 29 | anchors.left: title.right 30 | anchors.leftMargin: 10 31 | anchors.verticalCenter: title.verticalCenter 32 | antialiasing: true 33 | fillMode: Image.PreserveAspectFit 34 | source: "../icons/chevron-down.svg" 35 | mipmap: true 36 | visible: Panopticon.fileBrowserSortColumn === columnOrdinal || mouseArea.containsMouse 37 | rotation: (Panopticon.fileBrowserSortAscending ? 180 : 0) 38 | } 39 | } 40 | 41 | MouseArea { 42 | id: mouseArea 43 | anchors.fill: parent 44 | hoverEnabled: true 45 | onClicked: { 46 | if(columnOrdinal !== Panopticon.fileBrowserSortColumn) { 47 | Panopticon.sortBy(columnOrdinal,Panopticon.fileBrowserSortAscending) 48 | } else { 49 | Panopticon.sortBy(columnOrdinal,!Panopticon.fileBrowserSortAscending) 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # For contributors 2 | 1. Please have fun, nobody is paid for developing Panopticon. 3 | 1. Everything is up to debate, none of the following guidelines are set in stone. 4 | 1. If you want to help, check out the [easy issues](https://github.com/das-labor/panopticon/issues?q=is%3Aissue+is%3Aopen+label%3AE-easy). 5 | 1. If you want a feature, open an issue _before_ you're dumping your 5k line patch. 6 | 1. Format w/ [rustfmt](https://github.com/rust-lang-nursery/rustfmt) before submitting. 7 | 1. Please add tests, at least one positive and one negative test. Make sure the coverage doesn't decrease. 8 | 1. Consider splitting your change into multiple smaller PRs. 9 | 1. All CI jobs must pass. You have an infinite amount of tries. 10 | 11 | # For maintainers & reviewers 12 | 1. Assume good faith. 13 | 1. Please have fun, nobody is paid for developing Panopticon. 14 | 1. Everything is up to debate, none of the following guidelines are set in stone. 15 | 1. Check whether contributed code: 16 | 1. scales reasonably well, 17 | 1. has no (obvious) security problems, 18 | 1. isn't reimplementing features that already exist in Panopticon, 19 | 1. is in the right place, 20 | 1. comes w/ unit tests that demonstrate the code works and make sure it can be changed later, 21 | 1. includes legible documentation. 22 | 1. No bikeshedding about naming, brace placement, argument order, "taste" or "style". 23 | 1. If in doubt, merge. 24 | 1. Please thank the contributor. It costs nothing. Also, see 2. 25 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 2016-10-: 0.16 (Pentonville) 2 | - Remove dependency on GLPK 3 | - Provide packages for Debian, Ubuntu, Windows and OS X 4 | - Display errors in the control flow graph 5 | - Add title screen 6 | - Add API documentation 7 | - Speed up AMD64 disassembler 8 | - Fix major bug in graph layout drawing 9 | 10 | 2016-05-29: 0.15 (Modelo) 11 | - Unit test for AVR and MOS 6502 decoders 12 | - Move analysis engine from PIL to RREIL 13 | - Factor out widening into cofibered domain 14 | - Use Kset for indirect jump resolution 15 | 16 | 2016-04-01: 0.14 (Crematoria) 17 | - Implement Kset abstract domain 18 | - Speed-up disassembly 19 | - Major rework of save, load and open dialogs 20 | - Fix various bugs in AI and graph layouting 21 | 22 | 2016-01-24: 0.13 (Insein) 23 | - Decode most AMD64 instructions 24 | - Basic Abstract Interpretaion framework 25 | - SSA conversion of PIL code 26 | - MOS-6502 support (thanks to Marcus Brinkmann) 27 | 28 | 2015-11-30: 0.12 (Pentridge) 29 | - ELF loader 30 | - Primitive x86 disassembling 31 | - Various graph view improvments 32 | - Disassembles whole AVR interrupt vector table 33 | 34 | 2015-10-11: 0.11 (Bastille) 35 | - Partial port from C++ to Rust 36 | - Layout control flow graphs in QML 37 | - Add function call graph 38 | - Add comment function in graph view (double click on row to comment) 39 | - Functions can be renamed by double clicking them in the function table 40 | 41 | 2015-06-03: 0.10 (Salt Pit) 42 | - Prototype AMD64 disassembler 43 | 44 | 2015-03-03: 0.9 (Stammheim) 45 | - Initial release 46 | -------------------------------------------------------------------------------- /glue/ext/lib/include/qsidebar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #pragma once 27 | 28 | class QSidebar : public QAbstractListModel { 29 | Q_OBJECT 30 | 31 | public: 32 | QSidebar(QObject* parent = 0); 33 | virtual ~QSidebar(); 34 | 35 | virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; 36 | virtual QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const override; 37 | virtual QHash roleNames(void) const override; 38 | 39 | public slots: 40 | void insert(QString title,QString subtitle,QString uuid); 41 | 42 | protected: 43 | std::vector> m_items; 44 | }; 45 | -------------------------------------------------------------------------------- /glue/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | extern crate panopticon_graph_algos; 21 | extern crate futures; 22 | extern crate uuid; 23 | 24 | #[macro_use] 25 | extern crate log; 26 | #[macro_use] 27 | extern crate error_chain; 28 | 29 | mod errors { 30 | error_chain! { 31 | foreign_links { 32 | Panopticon(::panopticon_core::Error); 33 | Time(::std::time::SystemTimeError); 34 | Io(::std::io::Error); 35 | NulError(::std::ffi::NulError); 36 | UuidParseError(::uuid::ParseError); 37 | } 38 | } 39 | } 40 | pub use crate::errors::{Error, ErrorKind, Result}; 41 | 42 | mod ffi; 43 | 44 | mod glue; 45 | pub use crate::glue::Glue; 46 | 47 | mod types; 48 | pub use crate::types::{CBasicBlockLine, CBasicBlockOperand}; 49 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.16.0-{build} 2 | platform: 3 | - x64 4 | environment: 5 | RUST_INSTALL_DIR: C:\Rust 6 | RUSTFLAGS: "-D warnings" 7 | matrix: 8 | - RUST_INSTALL_TRIPLE: x86_64-pc-windows-msvc 9 | RUST_VERSION: stable 10 | - RUST_INSTALL_TRIPLE: x86_64-pc-windows-msvc 11 | RUST_VERSION: stable 12 | PACKAGE: win 13 | FTP_PASSWD: 14 | secure: DBE4nt5J/zQUXTGe8QTOJg== 15 | install: 16 | # Rust & Qt 17 | - set PATH=%USERPROFILE%\.cargo\bin;%PATH% 18 | - set QTDIR=C:\Qt\5.9.7\msvc2013_64 19 | - set PATH=%QTDIR%\bin;%PATH% 20 | - set CMAKE_PREFIX_PATH=%QTDIR%;%CMAKE_PREFIX_PATH% 21 | - appveyor DownloadFile https://static.rust-lang.org/rustup/dist/%RUST_INSTALL_TRIPLE%/rustup-init.exe 22 | - if defined APPVEYOR_PULL_REQUEST_TITLE ( 23 | if NOT defined PACKAGE ( 24 | rustup-init.exe -y 25 | ) 26 | ) else ( 27 | rustup-init.exe -y 28 | ) 29 | build_script: 30 | - call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64 31 | - if NOT DEFINED PACKAGE ( 32 | cargo build --verbose --all 33 | ) else ( 34 | if NOT DEFINED APPVEYOR_PULL_REQUEST_TITLE ( 35 | if "%PACKAGE%"=="win" ( 36 | cd pkg\windows & 37 | call package_zip.bat & 38 | curl -T panopticon-0.16.zip -u upload:%FTP_PASSWD% -Q "-SITE CHMOD 664 panopticon-master.zip" ftp://files.panopticon.re/panopticon-master.zip 39 | ) 40 | ) 41 | ) 42 | test_script: 43 | - if NOT DEFINED PACKAGE ( 44 | call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64 & 45 | cargo test --verbose --all 46 | ) 47 | -------------------------------------------------------------------------------- /qml/icons/warning-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /qml/Panopticon/MessageBlock.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler (https://panopticon.re/) 3 | * Copyright (C) 2014-2016 Kai Michaelis 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.3 20 | import QtQuick.Controls 1.2 as Ctrl 21 | import QtGraphicalEffects 1.0 22 | import QtQuick.Layouts 1.1 23 | import Panopticon 1.0 24 | 25 | Monospace { 26 | property real nodeX: 0 27 | property real nodeY: 0 28 | property var nodeValue: null 29 | property string alt: nodeValue ? nodeValue.operandAlt[0] : "" 30 | property string kind: nodeValue ? nodeValue.operandKind[0] : "" 31 | property string ddata: nodeValue ? nodeValue.operandData[0] : "" 32 | property string display: nodeValue ? nodeValue.operandDisplay[0] : "" 33 | 34 | x: nodeX - width / 2 35 | y: nodeY + height / 3 36 | width: contentWidth 37 | height: Panopticon.basicBlockLineHeight 38 | verticalAlignment: Text.AlignVCenter 39 | font { 40 | capitalization: Font.AllLowercase 41 | pointSize: 11 42 | } 43 | color: alt == "" ? "black" : "#297f7a" 44 | text: display 45 | } 46 | -------------------------------------------------------------------------------- /graph-algos/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | mod traits; 20 | pub mod search; 21 | pub mod dominator; 22 | pub mod order; 23 | pub mod adjacency_list; 24 | pub mod adjacency_matrix; 25 | 26 | extern crate serde; 27 | #[macro_use] extern crate serde_derive; 28 | extern crate bit_set; 29 | 30 | #[cfg(test)] 31 | extern crate rmp_serde; 32 | 33 | pub use crate::adjacency_list::AdjacencyList; 34 | pub use crate::adjacency_matrix::AdjacencyMatrix; 35 | pub use crate::traits::AdjacencyGraph as AdjacencyGraphTrait; 36 | pub use crate::traits::AdjacencyMatrixGraph as AdjacencyMatrixGraphTrait; 37 | pub use crate::traits::BidirectionalGraph as BidirectionalGraphTrait; 38 | pub use crate::traits::EdgeListGraph as EdgeListGraphTrait; 39 | 40 | pub use crate::traits::Graph as GraphTrait; 41 | pub use crate::traits::IncidenceGraph as IncidenceGraphTrait; 42 | pub use crate::traits::MutableGraph as MutableGraphTrait; 43 | pub use crate::traits::VertexListGraph as VertexListGraphTrait; 44 | -------------------------------------------------------------------------------- /glue/ext/lib/include/qrecentsession.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | 21 | #include "glue.h" 22 | 23 | #pragma once 24 | 25 | class QRecentSession : public QObject { 26 | Q_OBJECT 27 | 28 | public: 29 | QRecentSession(const RecentSession& obj, QObject* parent = nullptr); 30 | virtual ~QRecentSession(); 31 | 32 | Q_PROPERTY(QString title READ getTitle NOTIFY titleChanged) 33 | Q_PROPERTY(QString kind READ getKind NOTIFY kindChanged) 34 | Q_PROPERTY(QString path READ getPath NOTIFY pathChanged) 35 | Q_PROPERTY(quint64 timestamp READ getTimestamp NOTIFY timestampChanged) 36 | 37 | QString getTitle(void) const; 38 | QString getKind(void) const; 39 | QString getPath(void) const; 40 | quint64 getTimestamp(void) const; 41 | 42 | signals: 43 | void titleChanged(void); 44 | void kindChanged(void); 45 | void pathChanged(void); 46 | void timestampChanged(void); 47 | 48 | protected: 49 | QString m_title; 50 | QString m_kind; 51 | QString m_path; 52 | quint64 m_timestamp; 53 | }; 54 | -------------------------------------------------------------------------------- /pkg/fedora/panopticon.spec: -------------------------------------------------------------------------------- 1 | Name: panopticon 2 | Version: master 3 | Release: 1%{?dist} 4 | Summary: A libre cross-platform disassembler 5 | URL: http://panopticon.re 6 | License: GPLv3 7 | 8 | Source0: https://github.com/das-labor/panopticon/archive/%{version}.tar.gz 9 | 10 | BuildRequires: gcc-c++ 11 | BuildRequires: cmake 12 | BuildRequires: make 13 | BuildRequires: qt5-qtdeclarative-devel 14 | BuildRequires: qt5-qtquickcontrols 15 | BuildRequires: qt5-qtgraphicaleffects 16 | BuildRequires: qt5-qtsvg-devel 17 | BuildRequires: rustc 18 | BuildRequires: cargo 19 | 20 | Requires: adobe-source-sans-pro-fonts 21 | Requires: adobe-source-code-pro-fonts 22 | Requires: qt5-qtquickcontrols 23 | Requires: qt5-qtgraphicaleffects 24 | Requires: qt5-qtsvg 25 | 26 | %description 27 | Panopticon is a cross platform disassembler for reverse engineering written in 28 | Rust. It can disassemble AMD64, x86, AVR and MOS 6502 instruction sets and open 29 | ELF files. Panopticon comes with Qt GUI for browsing and annotating control 30 | flow graphs. 31 | 32 | %global debug_package %{nil} 33 | 34 | %prep 35 | %autosetup 36 | 37 | %build 38 | cargo build --all --release 39 | 40 | %install 41 | %{__install} -d -m755 %{buildroot}/usr/bin 42 | %{__install} -D -s -m755 target/release/panopticon %{buildroot}/usr/bin/panopticon 43 | %{__install} -d -m755 %{buildroot}/usr/share/panopticon/qml 44 | cp -R qml/* %{buildroot}/usr/share/panopticon/qml 45 | chown -R root:root %{buildroot}/usr/share/panopticon/qml 46 | %{__install} -d -m755 %{buildroot}/usr/share/doc/panopticon 47 | cp README.md %{buildroot}/usr/share/doc/panopticon/README.md 48 | 49 | %files 50 | %doc README.md 51 | %{_bindir}/panopticon 52 | %{_datarootdir}/panopticon/qml 53 | 54 | %changelog 55 | * Thu Oct 20 2016 seu 0.16-1 56 | - Remove dependency on GLPK 57 | -------------------------------------------------------------------------------- /qml/icons/open-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /pkg/README.md: -------------------------------------------------------------------------------- 1 | # Creating a new release 2 | When creating a new release of _Panopticon_, there are a few things that have to be considered beforehand. This small guide will help you through the process. 3 | 4 | These are the steps of creating a release: 5 | 6 | 1. Bumping version numbers 7 | 1. Adding new sections to the changelogs 8 | 1. Building the project 9 | 1. Creating a tag 10 | 1. Writing a blog article containing a changelog 11 | 12 | ## Bumping version numbers 13 | This means ***everywhere***: 14 | - in `.travis.yml` 15 | - in `appveyor.yml` 16 | - in `Cargo.toml` 17 | - in `pkg/arch/PKGBUILD` 18 | - in `pkg/osx/Info.plist` 19 | - in `pkg/fedora/package.sh` 20 | - in `pkg/fedora/panopticon.spec` 21 | - in `pkg/windows/package_zip.bat` 22 | - in `qml/Title.qml` 23 | 24 | ## Adding new sections to the changelogs 25 | Several packages as well as the project itself contain a changelog. New entries have to be added to the following files: 26 | - `pkg/debian/debian/changelog` 27 | - `CHANGELOG` 28 | 29 | ## Building the project 30 | To make sure that the version bump didn't corrupt the codebase, build the project as stated in the top level `README.md`. 31 | 32 | ## Creating a tag 33 | If everything changed before is correctly committed, you now have to create a tag with the following format: 34 | `..` e.g. `0.12.6`, `2.13.54` 35 | Also remember to crop all trailing zeros. 36 | 37 | After creating the tag it has to be pushed as well to make sure it can be referenced to in a changelog. 38 | 39 | ## Writing a blog article 40 | After successfully creating a release you should consider writing a markdown formatted blog article containing a changelog and short summary of the changes. 41 | The blog is a `jekyll` blog located here: [https://github.com/flanfly/panopticon.re](https://github.com/flanfly/panopticon.re). 42 | To submit your article just add it to the other articles and open a pull request to get it merged. 43 | -------------------------------------------------------------------------------- /qml/icons/sandbox-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /glue/ext/lib/src/qbasicblockline.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "qbasicblockline.h" 20 | 21 | QBasicBlockLine::QBasicBlockLine(const BasicBlockLine& line, QObject* parent) 22 | : QObject(parent), m_opcode(line.opcode), m_region(line.region), m_offset(line.offset), m_comment(line.comment) 23 | { 24 | for(size_t idx = 0; line.args[idx]; ++idx) { 25 | const BasicBlockOperand* op = line.args[idx]; 26 | 27 | m_operandKind.append(QVariant(QString(op->kind))); 28 | m_operandDisplay.append(QVariant(QString(op->display))); 29 | m_operandAlt.append(QVariant(QString(op->alt))); 30 | m_operandData.append(QVariant(QString(op->data))); 31 | } 32 | } 33 | 34 | QBasicBlockLine::~QBasicBlockLine() {} 35 | 36 | QString QBasicBlockLine::getOpcode(void) const { return m_opcode; } 37 | QString QBasicBlockLine::getRegion(void) const { return m_region; } 38 | quint64 QBasicBlockLine::getOffset(void) const { return m_offset; } 39 | QString QBasicBlockLine::getComment(void) const { return m_comment; } 40 | QVariantList QBasicBlockLine::getOperandKind(void) const { return m_operandKind; } 41 | QVariantList QBasicBlockLine::getOperandDisplay(void) const { return m_operandDisplay; } 42 | QVariantList QBasicBlockLine::getOperandAlt(void) const { return m_operandAlt; } 43 | QVariantList QBasicBlockLine::getOperandData(void) const { return m_operandData; } 44 | -------------------------------------------------------------------------------- /qml/icons/example-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /amd64/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2014,2015,2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! Intel x86 and AMD64 disassembler. 20 | //! 21 | //! This disassembler handles the Intel x86 instruction set from the 16-bit 8086 over 32-bit x86 to 22 | //! 64-bit AMD64 instructions, including MMX, SSE1-4, AVX, x87 and miscellaneous instruction set 23 | //! extensions. 24 | //! 25 | //! Decoding instructions is done my a hierarchy of tables defined in `tables.rs`. For each 26 | //! mnemonic a function is defined in `semantic.rs` that emits RREIL code implementing it. 27 | //! 28 | //! Instruction decoding is done in `read`. It expects a 15 bytes of code and will decode 29 | //! instruction prefixes, opcode (including escapes) and opcode arguments encoded in the MODR/M 30 | //! byte and/or immediates. 31 | //! 32 | //! All functions in `semantic.rs` follow the same structure. They get the decoded opcode arguments 33 | //! as input and return a vector of RREIL statements and a `JumpSpec` instance that tells the 34 | //! disassembler where to continue. 35 | 36 | #![allow(missing_docs)] 37 | 38 | #[macro_use] 39 | extern crate log; 40 | 41 | #[macro_use] 42 | extern crate panopticon_core; 43 | extern crate byteorder; 44 | 45 | #[macro_use] 46 | pub mod tables; 47 | pub mod semantic; 48 | 49 | mod disassembler; 50 | pub use crate::disassembler::{AddressingMethod, JumpSpec, MnemonicSpec, Opcode, Operand, OperandSpec, OperandType, read_spec_register}; 51 | 52 | mod architecture; 53 | pub use crate::architecture::{Amd64, Mode}; 54 | -------------------------------------------------------------------------------- /abstract-interp/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2014,2015,2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! Abstract Interpretation Framework. 20 | //! 21 | //! Abstract Interpretation executes an program over sets of concrete values. Each operation is 22 | //! extended to work on some kind of abstract value called abstract domain that approximates a 23 | //! set of concrete values (called the concrete domain). A simple example is the domain of signs. 24 | //! Each value can either be positive, negative, both or none. An abstract interpretation will first 25 | //! replace all constant values with their signs and then execute all basic blocks using the 26 | //! abstract sign domain. For example multiplying two positive values yields a positive value. 27 | //! Adding a positive and a negative sign yields an abstract value representing both signs (called 28 | //! join). 29 | 30 | #[macro_use] 31 | extern crate log; 32 | 33 | #[cfg(test)] 34 | #[macro_use] 35 | extern crate quickcheck; 36 | 37 | #[cfg(test)] 38 | extern crate env_logger; 39 | 40 | extern crate panopticon_core; 41 | extern crate panopticon_data_flow; 42 | extern crate panopticon_graph_algos; 43 | extern crate serde; 44 | #[macro_use] extern crate serde_derive; 45 | 46 | mod interpreter; 47 | pub use crate::interpreter::{Avalue, Constraint, ProgramPoint, approximate, results, lift}; 48 | 49 | mod bounded_addr_track; 50 | pub use crate::bounded_addr_track::BoundedAddrTrack; 51 | 52 | pub mod kset; 53 | pub use crate::kset::Kset; 54 | 55 | mod widening; 56 | pub use crate::widening::Widening; 57 | -------------------------------------------------------------------------------- /pkg/debian/debian/changelog: -------------------------------------------------------------------------------- 1 | panopticon (0.16) trusty; urgency=low 2 | 3 | * Remove dependency on GLPK 4 | * Provide packages for Debian, Ubuntu, Windows and OS X 5 | * Display errors in the control flow graph 6 | * Add title screen 7 | * Add API documentation 8 | * Speed up AMD64 disassembler 9 | * Fix major bug in graph layout drawing * Unit test for AVR and MOS 6502 decoders 10 | 11 | -- seu Fri, 27 Oct 2016 00:00:00 +0200 12 | 13 | panopticon (0.15) trusty; urgency=low 14 | 15 | * Unit test for AVR and MOS 6502 decoders 16 | * Move analysis engine from PIL to RREIL 17 | * Factor out widening into cofibered domain 18 | * Use Kset for indirect jump resolution 19 | 20 | -- seu Fri, 13 May 2016 00:00:00 +0200 21 | 22 | panopticon (0.14) trusty; urgency=low 23 | 24 | * Implement Kset abstract domain 25 | * Speed-up disassembly 26 | * Major rework of save, load and open dialogs 27 | * Fix various bugs in AI and graph layouting 28 | 29 | -- seu Sun, 13 Mar 2016 00:00:00 +0200 30 | 31 | panopticon (0.13) trusty; urgency=low 32 | 33 | * Decode most AMD64 instructions 34 | * Basic Abstract Interpretaion framework 35 | * SSA conversion of PIL code 36 | * MOS-6502 support (thanks to Marcus Brinkmann) 37 | 38 | -- seu Sun, 24 Jan 2016 00:00:00 +0200 39 | 40 | panopticon (0.12) trusty; urgency=low 41 | 42 | * ELF loader 43 | * Primitive x86 disassembling 44 | * Various graph view improvments 45 | * Disassembles whole AVR interrupt vector table 46 | 47 | -- seu Mon, 30 Nov 2015 00:00:00 +0200 48 | 49 | panopticon (0.11) trusty; urgency=low 50 | 51 | * Partial port from C++ to Rust 52 | * Layout control flow graphs in QML 53 | * Add function call graph 54 | * Add comment function in graph view (double click on row to comment) 55 | * Functions can be renamed by double clicking them in the function table 56 | 57 | -- seu Sun, 11 Oct 2016 00:00:00 +0200 58 | 59 | panopticon (0.10) trusty; urgency=low 60 | 61 | * Prototype AMD64 disassembler 62 | 63 | -- seu Wed, 3 Jun 2015 00:00:00 +0200 64 | 65 | panopticon (0.9) trusty; urgency=low 66 | 67 | * Initial release 68 | 69 | -- seu Tue, 13 Jan 2015 10:07:00 +0200 70 | 71 | -------------------------------------------------------------------------------- /glue/ext/lib/src/qsidebar.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include "qsidebar.h" 21 | 22 | QSidebar::QSidebar(QObject* parent) : QAbstractListModel(parent) {} 23 | 24 | QSidebar::~QSidebar() {} 25 | 26 | int QSidebar::rowCount(const QModelIndex& parent) const { 27 | return m_items.size(); 28 | } 29 | 30 | QVariant QSidebar::data(const QModelIndex& idx, int role) const { 31 | if(idx.column() != 0 || idx.row() >= m_items.size()) 32 | return QVariant(); 33 | 34 | switch(role) { 35 | case Qt::DisplayRole: 36 | case Qt::UserRole: 37 | return QVariant(std::get<0>(m_items[idx.row()])); 38 | case Qt::UserRole + 1: 39 | return QVariant(std::get<1>(m_items[idx.row()])); 40 | case Qt::UserRole + 2: 41 | return QVariant(std::get<2>(m_items[idx.row()])); 42 | default: 43 | return QVariant(); 44 | } 45 | } 46 | 47 | QHash QSidebar::roleNames(void) const { 48 | QHash ret; 49 | 50 | ret.insert(Qt::UserRole, QByteArray("title")); 51 | ret.insert(Qt::UserRole + 1, QByteArray("subtitle")); 52 | ret.insert(Qt::UserRole + 2, QByteArray("uuid")); 53 | 54 | return ret; 55 | } 56 | 57 | void QSidebar::insert(QString title,QString subtitle,QString uuid) { 58 | auto tpl = std::make_tuple(title,subtitle,uuid); 59 | size_t idx = 0; 60 | 61 | for(; idx < m_items.size(); ++idx) { 62 | auto& x = m_items[idx]; 63 | 64 | if(std::get<2>(x) == uuid) { 65 | x = tpl; 66 | dataChanged(index(idx,0),index(idx,0)); 67 | return; 68 | } 69 | } 70 | 71 | beginInsertRows(QModelIndex(), idx, idx); 72 | m_items.push_back(tpl); 73 | endInsertRows(); 74 | } 75 | -------------------------------------------------------------------------------- /glue/src/ffi.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use crate::types::{CBasicBlockLine, CRecentSession, CSidebarItem}; 20 | 21 | extern "C" { 22 | pub fn start_gui_loop( 23 | qml_dir: *const i8, 24 | inital_file: *const i8, 25 | recent_sessions: *const *const CRecentSession, 26 | get_function: extern "C" fn(*const i8, i8, i8, i8) -> i32, 27 | subscribe_to: extern "C" fn(*const i8, i8) -> i32, 28 | open_program: extern "C" fn(*const i8) -> i32, 29 | save_session: extern "C" fn(*const i8) -> i32, 30 | comment_on: extern "C" fn(u64, *const i8) -> i32, 31 | rename_function: extern "C" fn(*const i8, *const i8) -> i32, 32 | set_value_for: extern "C" fn(*const i8, *const i8, *const i8) -> i32, 33 | undo: extern "C" fn() -> i32, 34 | redo: extern "C" fn() -> i32, 35 | ); 36 | 37 | // thread-safe 38 | pub fn update_function_node(uuid: *const i8, id: u32, x: f32, y: f32, is_entry: i8, lines: *const *const CBasicBlockLine); 39 | 40 | // thread-safe 41 | pub fn update_function_edges( 42 | uuid: *const i8, 43 | ids: *const u32, 44 | labels: *const *const i8, 45 | kinds: *const *const i8, 46 | head_xs: *const f32, 47 | head_ys: *const f32, 48 | tail_xs: *const f32, 49 | tail_ys: *const f32, 50 | svg: *const i8, 51 | ); 52 | 53 | // thread-safe 54 | pub fn update_sidebar_items(items: *const *const CSidebarItem); 55 | 56 | // thread-safe 57 | pub fn update_undo_redo(undo: i8, redo: i8); 58 | 59 | // thread-safe 60 | pub fn update_current_session(path: *const i8); 61 | 62 | // thread-safe 63 | pub fn update_layout_task(task: *const i8); 64 | } 65 | -------------------------------------------------------------------------------- /glue/ext/lib/include/glue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #pragma once 29 | 30 | struct BasicBlockOperand { 31 | const char* kind; 32 | const char* display; 33 | const char* alt; 34 | const char* data; 35 | }; 36 | 37 | struct BasicBlockLine { 38 | const char* opcode; 39 | const char* region; 40 | uint64_t offset; 41 | const char* comment; 42 | const BasicBlockOperand** args; 43 | }; 44 | 45 | struct BasicBlock { 46 | const BasicBlockLine** lines; 47 | }; 48 | 49 | struct SidebarItem { 50 | const char* title; 51 | const char* subtitle; 52 | const char* uuid; 53 | }; 54 | 55 | struct RecentSession { 56 | const char* title; 57 | const char* kind; 58 | const char* path; 59 | uint32_t timestamp; 60 | }; 61 | 62 | typedef int32_t (*GetFunctionFunc)(const char* uuid, int8_t only_entry, int8_t do_nodes, int8_t do_edges); 63 | typedef int32_t (*SubscribeToFunc)(const char* uuid, int8_t subscribe); 64 | 65 | // session management 66 | typedef int32_t (*OpenProgramFunc)(const char* path); 67 | typedef int32_t (*SaveSessionFunc)(const char* path); 68 | 69 | // actions 70 | typedef int32_t (*CommentOnFunc)(uint64_t address, const char* comment); 71 | typedef int32_t (*RenameFunctionFunc)(const char* uuid, const char* name); 72 | typedef int32_t (*SetValueForFunc)(const char* uuid, const char* variable, const char* value); 73 | 74 | // undo/redo 75 | typedef int32_t (*UndoFunc)(); 76 | typedef int32_t (*RedoFunc)(); 77 | 78 | class QSideBarItem : public QObject { 79 | Q_OBJECT 80 | public: 81 | QSideBarItem(QObject* parent = 0) : QObject(parent) {} 82 | virtual ~QSideBarItem() {} 83 | }; 84 | -------------------------------------------------------------------------------- /glue/ext/lib/include/qbasicblockline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | 21 | #include "glue.h" 22 | 23 | #pragma once 24 | 25 | class QBasicBlockLine : public QObject { 26 | Q_OBJECT 27 | 28 | public: 29 | QBasicBlockLine(const BasicBlockLine& op, QObject* parent = 0); 30 | virtual ~QBasicBlockLine(); 31 | 32 | Q_PROPERTY(QString opcode READ getOpcode NOTIFY opcodeChanged) 33 | Q_PROPERTY(QString region READ getRegion NOTIFY regionChanged) 34 | Q_PROPERTY(quint64 offset READ getOffset NOTIFY offsetChanged) 35 | Q_PROPERTY(QString comment READ getComment NOTIFY commentChanged) 36 | Q_PROPERTY(QVariantList operandKind READ getOperandKind NOTIFY operandKindChanged) 37 | Q_PROPERTY(QVariantList operandDisplay READ getOperandDisplay NOTIFY operandDisplayChanged) 38 | Q_PROPERTY(QVariantList operandAlt READ getOperandAlt NOTIFY operandAltChanged) 39 | Q_PROPERTY(QVariantList operandData READ getOperandData NOTIFY operandDataChanged) 40 | 41 | QString getOpcode(void) const; 42 | QString getRegion(void) const; 43 | quint64 getOffset(void) const; 44 | QString getComment(void) const; 45 | QVariantList getOperandKind(void) const; 46 | QVariantList getOperandDisplay(void) const; 47 | QVariantList getOperandAlt(void) const; 48 | QVariantList getOperandData(void) const; 49 | 50 | void replace(const BasicBlockLine& line); 51 | 52 | signals: 53 | void opcodeChanged(void); 54 | void regionChanged(void); 55 | void offsetChanged(void); 56 | void commentChanged(void); 57 | void operandKindChanged(void); 58 | void operandDisplayChanged(void); 59 | void operandAltChanged(void); 60 | void operandDataChanged(void); 61 | 62 | protected: 63 | QString m_opcode; 64 | QString m_region; 65 | quint64 m_offset; 66 | QString m_comment; 67 | QVariantList m_operandKind; 68 | QVariantList m_operandDisplay; 69 | QVariantList m_operandAlt; 70 | QVariantList m_operandData; 71 | }; 72 | -------------------------------------------------------------------------------- /amd64/tests/opcodes.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015, 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | extern crate panopticon_amd64; 21 | 22 | extern crate env_logger; 23 | 24 | use panopticon_amd64 as amd64; 25 | use panopticon_core::{Architecture, Region}; 26 | use std::path::Path; 27 | 28 | #[test] 29 | fn amd64_opcodes() { 30 | let reg = Region::open("com".to_string(), Path::new("../test-data/amd64.com")).unwrap(); 31 | let mut addr = 0; 32 | 33 | loop { 34 | let maybe_match = ::decode(®, addr, &amd64::Mode::Long); 35 | 36 | if let Ok(match_st) = maybe_match { 37 | for mne in match_st.mnemonics { 38 | println!("{:x}: {}", mne.area.start, mne.opcode); 39 | addr = mne.area.end; 40 | 41 | if addr >= reg.size() { 42 | return; 43 | } 44 | } 45 | } else if addr < reg.size() { 46 | unreachable!("failed to match anything at {:x}", addr); 47 | } else { 48 | break; 49 | } 50 | } 51 | } 52 | 53 | #[test] 54 | fn ia32_opcodes() { 55 | env_logger::init().unwrap(); 56 | 57 | let reg = Region::open("com".to_string(), Path::new("../test-data/ia32.com")).unwrap(); 58 | let mut addr = 0; 59 | 60 | loop { 61 | let maybe_match = amd64::Amd64::decode(®, addr, &amd64::Mode::Protected); 62 | 63 | if let Ok(match_st) = maybe_match { 64 | for mne in match_st.mnemonics { 65 | println!("{:x}: {}", mne.area.start, mne.opcode); 66 | addr = mne.area.end; 67 | 68 | if addr >= reg.size() { 69 | return; 70 | } 71 | } 72 | } else if addr < reg.size() { 73 | unreachable!("failed to match anything at {:x}", addr); 74 | } else { 75 | break; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /core/tests/region.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | extern crate tempdir; 21 | 22 | use panopticon_core::{Bound, Layer, Region}; 23 | use std::fs::File; 24 | use std::io::Write; 25 | use std::path::Path; 26 | use tempdir::TempDir; 27 | 28 | #[test] 29 | fn read_one_layer() { 30 | if let Ok(ref tmpdir) = TempDir::new("test-panop") { 31 | let p1 = tmpdir.path().join(Path::new("test")); 32 | 33 | let mut r1 = Region::undefined("test".to_string(), 128); 34 | 35 | { 36 | let fd = File::create(p1.clone()); 37 | assert!(fd.unwrap().write_all(b"Hello, World").is_ok()); 38 | } 39 | 40 | assert!(r1.cover(Bound::new(1, 8), Layer::wrap(vec![1, 2, 3, 4, 5, 6, 7]))); 41 | assert!( 42 | r1.cover( 43 | Bound::new(50, 62), 44 | Layer::wrap(vec![1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1]), 45 | ) 46 | ); 47 | assert!(r1.cover(Bound::new(62, 63), Layer::wrap(vec![1]))); 48 | assert!(r1.cover(Bound::new(70, 82), Layer::open(&p1).unwrap())); 49 | 50 | let s = r1.iter(); 51 | let mut idx = 0; 52 | 53 | assert_eq!(s.len(), 128); 54 | 55 | for i in s { 56 | if idx >= 1 && idx < 8 { 57 | assert_eq!(i, Some(idx)); 58 | } else if idx >= 50 && idx < 56 { 59 | assert_eq!(i, Some(idx - 49)); 60 | } else if idx >= 56 && idx < 62 { 61 | assert_eq!(i, Some(6 - (idx - 56))); 62 | } else if idx >= 70 && idx < 82 { 63 | assert_eq!( 64 | i, 65 | Some("Hello, World".to_string().into_bytes()[(idx - 70) as usize]) 66 | ); 67 | } else if idx == 62 { 68 | assert_eq!(i, Some(1)); 69 | } else { 70 | assert_eq!(i, None); 71 | } 72 | idx += 1; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /core/src/result.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! Result type used throughout the library. 20 | //! 21 | //! The error type is simply a string. 22 | 23 | 24 | use goblin; 25 | 26 | use std::borrow::Cow; 27 | use std::convert::From; 28 | use std::error; 29 | use std::fmt; 30 | use std::io; 31 | use std::result; 32 | use std::sync::PoisonError; 33 | use serde_cbor; 34 | 35 | /// Panopticon error type 36 | #[derive(Debug)] 37 | pub struct Error(pub Cow<'static, str>); 38 | /// Panopticon result type 39 | pub type Result = result::Result; 40 | 41 | impl fmt::Display for Error { 42 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 43 | write!(f, "{}", self.0) 44 | } 45 | } 46 | 47 | impl error::Error for Error { 48 | fn description<'a>(&'a self) -> &'a str { 49 | match &self.0 { 50 | &Cow::Borrowed(s) => s, 51 | &Cow::Owned(ref s) => s, 52 | } 53 | } 54 | } 55 | 56 | impl From for Error { 57 | fn from(s: String) -> Error { 58 | Error(Cow::Owned(s)) 59 | } 60 | } 61 | 62 | impl From<&'static str> for Error { 63 | fn from(s: &'static str) -> Error { 64 | Error(Cow::Borrowed(s)) 65 | } 66 | } 67 | 68 | impl From> for Error { 69 | fn from(s: Cow<'static, str>) -> Error { 70 | Error(s) 71 | } 72 | } 73 | 74 | impl From> for Error { 75 | fn from(_: PoisonError) -> Error { 76 | Error(Cow::Borrowed("Lock poisoned")) 77 | } 78 | } 79 | 80 | impl From for Error { 81 | fn from(e: io::Error) -> Error { 82 | Error(Cow::Owned(format!("I/O error: {:?}", e))) 83 | } 84 | } 85 | 86 | impl From for Error { 87 | fn from(e: goblin::error::Error) -> Error { 88 | Error(Cow::Owned(format!("Goblin error: {}", e))) 89 | } 90 | } 91 | 92 | impl From for Error { 93 | fn from(e: serde_cbor::Error) -> Error { 94 | Error(Cow::Owned(format!("Serde error: {}", e))) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /amd64/src/architecture.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015, 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use panopticon_core::{Architecture, Match, Region, Result}; 20 | 21 | #[derive(Clone,Debug)] 22 | pub enum Amd64 {} 23 | 24 | #[derive(Clone,PartialEq,Copy,Debug)] 25 | pub enum Mode { 26 | Real, // Real mode / Virtual 8086 mode 27 | Protected, // Protected mode / Long compatibility mode 28 | Long, // Long 64-bit mode 29 | } 30 | 31 | impl Mode { 32 | pub fn alt_bits(&self) -> usize { 33 | match self { 34 | &Mode::Real => 32, 35 | &Mode::Protected => 16, 36 | &Mode::Long => 16, 37 | } 38 | } 39 | 40 | pub fn bits(&self) -> usize { 41 | match self { 42 | &Mode::Real => 16, 43 | &Mode::Protected => 32, 44 | &Mode::Long => 64, 45 | } 46 | } 47 | } 48 | 49 | impl Architecture for Amd64 { 50 | type Token = u8; 51 | type Configuration = Mode; 52 | 53 | fn prepare(_: &Region, _: &Self::Configuration) -> Result> { 54 | Ok(vec![]) 55 | } 56 | 57 | fn decode(reg: &Region, start: u64, cfg: &Self::Configuration) -> Result> { 58 | let data = reg.iter(); 59 | let mut buf: Vec = vec![]; 60 | let mut i = data.seek(start); 61 | let p = start; 62 | 63 | while let Some(Some(b)) = i.next() { 64 | buf.push(b); 65 | if buf.len() == 15 { 66 | break; 67 | } 68 | } 69 | 70 | debug!("disass @ {:#x}: {:?}", p, buf); 71 | 72 | let ret = crate::disassembler::read(*cfg, &buf, p).and_then( 73 | |(len, mne, mut jmp)| { 74 | Ok( 75 | Match:: { 76 | tokens: buf[0..len as usize].to_vec(), 77 | mnemonics: vec![mne], 78 | jumps: jmp.drain(..).map(|x| (p, x.0, x.1)).collect::>(), 79 | configuration: cfg.clone(), 80 | } 81 | ) 82 | } 83 | ); 84 | 85 | debug!(" res: {:?}", ret); 86 | 87 | ret 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /pkg/xdg/usr/share/pixmaps/panopticon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 64 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /qml/icons/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /avr/tests/avr.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | extern crate panopticon_avr; 21 | extern crate panopticon_graph_algos; 22 | extern crate env_logger; 23 | 24 | use panopticon_avr::{Avr, Mcu}; 25 | use panopticon_core::{ControlFlowTarget, Function, Region, loader}; 26 | use panopticon_graph_algos::{EdgeListGraphTrait, GraphTrait, VertexListGraphTrait}; 27 | 28 | use std::path::Path; 29 | 30 | #[test] 31 | fn avr_jmp_overflow() { 32 | let reg = Region::open( 33 | "flash".to_string(), 34 | Path::new("../test-data/avr-jmp-overflow.bin"), 35 | ) 36 | .unwrap(); 37 | 38 | let func = Function::new::(0, ®, None, Mcu::atmega88()).unwrap(); 39 | 40 | assert_eq!(func.cfg().num_vertices(), 2); 41 | assert_eq!(func.cfg().num_edges(), 2); 42 | 43 | let mut vxs = func.cfg().vertices(); 44 | if let Some(&ControlFlowTarget::Resolved(ref bb1)) = func.cfg().vertex_label(vxs.next().unwrap()) { 45 | if let Some(&ControlFlowTarget::Resolved(ref bb2)) = func.cfg().vertex_label(vxs.next().unwrap()) { 46 | assert!(bb1.area.start == 0 || bb1.area.start == 6000); 47 | assert!(bb2.area.start == 0 || bb2.area.start == 6000); 48 | assert!(bb1.area.end == 2 || bb1.area.end == 6004); 49 | assert!(bb2.area.end == 2 || bb2.area.end == 6004); 50 | } 51 | } 52 | } 53 | 54 | #[test] 55 | fn avr_wrap_around() { 56 | let reg = Region::open( 57 | "flash".to_string(), 58 | Path::new("../test-data/avr-overflow.bin"), 59 | ) 60 | .unwrap(); 61 | let func = Function::new::(0, ®, None, Mcu::atmega88()).unwrap(); 62 | 63 | assert_eq!(func.cfg().num_vertices(), 2); 64 | assert_eq!(func.cfg().num_edges(), 2); 65 | 66 | let mut vxs = func.cfg().vertices(); 67 | if let Some(&ControlFlowTarget::Resolved(ref bb1)) = func.cfg().vertex_label(vxs.next().unwrap()) { 68 | if let Some(&ControlFlowTarget::Resolved(ref bb2)) = func.cfg().vertex_label(vxs.next().unwrap()) { 69 | println!("bb1: {:?}, bb2: {:?}", bb1.area, bb2.area); 70 | assert!(bb1.area.start == 0 || bb1.area.start == 8190); 71 | assert!(bb2.area.start == 0 || bb2.area.start == 8190); 72 | assert!(bb1.area.end == 2 || bb1.area.end == 8192); 73 | assert!(bb2.area.end == 2 || bb2.area.end == 8192); 74 | } 75 | } 76 | } 77 | 78 | #[test] 79 | fn avr_elf() { 80 | let proj = loader::load(Path::new("../test-data/hello-world")).ok(); 81 | assert!(proj.is_some()); 82 | } 83 | -------------------------------------------------------------------------------- /qml/Panopticon/EditPopover.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler (https://panopticon.re/) 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.3 20 | import QtQuick.Controls 1.2 as Ctrl 21 | import QtQuick.Controls.Styles 1.2 as Style 22 | import QtQuick.Layouts 1.1 23 | import QtGraphicalEffects 1.0 24 | import Panopticon 1.0 25 | 26 | Item { 27 | id: editOverlay 28 | 29 | property string variable: "" 30 | property string uuid: "" 31 | 32 | function open(x,y,v,u) { 33 | editOverlay.x = x; 34 | editOverlay.y = y; 35 | editOverlay.visible = true 36 | editOverlayField.focus = true 37 | editOverlay.variable = v; 38 | editOverlay.uuid = u; 39 | editOverlayField.forceActiveFocus() 40 | } 41 | 42 | function close() { 43 | editOverlayField.focus = false 44 | editOverlay.visible = false; 45 | editOverlayField.text = ""; 46 | } 47 | 48 | z: 2 49 | visible: false 50 | /* 51 | Glow { 52 | anchors.fill: editOverlayBox 53 | radius: 6 54 | samples: 17 55 | color: "#555555" 56 | source: editOverlayBox 57 | }*/ 58 | 59 | Rectangle { 60 | id: editOverlayBox 61 | anchors.topMargin: -1 62 | anchors.top: editOverlayTip.bottom 63 | anchors.horizontalCenter: parent.left 64 | width: editOverlayField.width + 10 65 | height: editOverlayField.height + 10 66 | //color: "white" 67 | color: "#fafafa" 68 | border { 69 | //color: "#9a9a9a" 70 | color: "#d8dae4" 71 | width: .7 72 | } 73 | radius: 2 74 | 75 | Ctrl.TextField { 76 | id: editOverlayField 77 | 78 | x: 5 79 | y: 5 80 | 81 | style: Style.TextFieldStyle { 82 | background: Rectangle { color: "#fafafa"; border { width: 0 } } 83 | } 84 | 85 | onAccepted: { 86 | Panopticon.setValueFor(editOverlay.uuid,editOverlay.variable,editOverlayField.text); 87 | } 88 | 89 | onEditingFinished: { editOverlay.close() } 90 | } 91 | } 92 | 93 | Canvas { 94 | id: editOverlayTip 95 | x: parent.width - width / 2 96 | y: 0 97 | width: 20 98 | height: 6 99 | 100 | onPaint: { 101 | var ctx = editOverlayTip.getContext('2d'); 102 | 103 | ctx.fillStyle = "#fafafa"; 104 | ctx.strokeStyle = "#d8dae4"; 105 | ctx.lineWidth = 1; 106 | 107 | ctx.beginPath(); 108 | ctx.moveTo(0,editOverlayTip.height); 109 | ctx.lineTo(editOverlayTip.width / 2,0); 110 | ctx.lineTo(editOverlayTip.width,editOverlayTip.height); 111 | ctx.closePath(); 112 | ctx.fill(); 113 | 114 | ctx.beginPath(); 115 | ctx.moveTo(0,editOverlayTip.height + 1); 116 | ctx.lineTo(editOverlayTip.width / 2,0); 117 | ctx.lineTo(editOverlayTip.width,editOverlayTip.height + 1); 118 | ctx.stroke(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /graph-algos/src/traits.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use std::hash::Hash; 20 | 21 | pub trait Graph<'a, V, E> { 22 | type Vertex: Clone + Hash + PartialEq + Eq + Ord + Copy; 23 | type Edge: Clone + Hash + PartialEq + Eq + Copy; 24 | 25 | fn edge_label(&self, _: Self::Edge) -> Option<&E>; 26 | #[inline] 27 | fn vertex_label(&self, _: Self::Vertex) -> Option<&V>; 28 | fn source(&self, _: Self::Edge) -> Self::Vertex; 29 | fn target(&self, _: Self::Edge) -> Self::Vertex; 30 | } 31 | 32 | pub trait IncidenceGraph<'a, V, E>: Graph<'a, V, E> { 33 | type Incidence: Iterator; 34 | fn out_degree(&'a self, _: Self::Vertex) -> usize; 35 | fn out_edges(&'a self, _: Self::Vertex) -> Self::Incidence; 36 | } 37 | 38 | pub trait BidirectionalGraph<'a, V, E>: IncidenceGraph<'a, V, E> { 39 | fn in_degree(&'a self, _: Self::Vertex) -> usize; 40 | fn degree(&'a self, _: Self::Vertex) -> usize; 41 | fn in_edges(&'a self, _: Self::Vertex) -> Self::Incidence; 42 | } 43 | 44 | pub trait AdjacencyGraph<'a, V, E>: Graph<'a, V, E> { 45 | type Adjacency: Iterator; 46 | fn adjacent_vertices(&'a self, _: Self::Vertex) -> Self::Adjacency; 47 | } 48 | 49 | pub trait VertexListGraph<'a, V: 'a, E> 50 | : IncidenceGraph<'a, V, E> + AdjacencyGraph<'a, V, E> { 51 | type Vertices: Iterator; 52 | type VertexLabels: Iterator; 53 | fn vertices(&'a self) -> Self::Vertices; 54 | fn num_vertices(&self) -> usize; 55 | fn vertex_labels(&'a self) -> Self::VertexLabels; 56 | } 57 | 58 | pub trait EdgeListGraph<'a, V, E: 'a>: Graph<'a, V, E> { 59 | type Edges: Iterator; 60 | type EdgeLabels: Iterator; 61 | fn num_edges(&self) -> usize; 62 | fn edges(&'a self) -> Self::Edges; 63 | fn edge_labels(&'a self) -> Self::EdgeLabels; 64 | } 65 | 66 | pub trait AdjacencyMatrixGraph<'a, V, E>: Graph<'a, V, E> { 67 | fn edge(&'a self, _: Self::Vertex, _: Self::Vertex) -> Option; 68 | } 69 | 70 | pub trait MutableGraph<'a, V: 'a, E: 'a>: Graph<'a, V, E> { 71 | type VertexLabelsMut: Iterator; 72 | type EdgeLabelsMut: Iterator; 73 | fn add_vertex(&mut self, _: V) -> Self::Vertex; 74 | fn add_edge(&mut self, _: E, _: Self::Vertex, _: Self::Vertex) -> Option; 75 | fn remove_vertex<'t>(&'t mut self, _: Self::Vertex) -> Option; 76 | fn remove_edge(&mut self, _: Self::Edge) -> Option; 77 | fn edge_label_mut(&mut self, _: Self::Edge) -> Option<&mut E>; 78 | fn edge_labels_mut(&'a mut self) -> Self::EdgeLabelsMut; 79 | fn vertex_label_mut(&mut self, _: Self::Vertex) -> Option<&mut V>; 80 | fn vertex_labels_mut(&'a mut self) -> Self::VertexLabelsMut; 81 | } 82 | -------------------------------------------------------------------------------- /glue/ext/lib/include/qcontrolflowgraph.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "glue.h" 33 | #include "qbasicblockline.h" 34 | 35 | #pragma once 36 | 37 | class QControlFlowGraph : public QQuickPaintedItem { 38 | Q_OBJECT 39 | 40 | public: 41 | QControlFlowGraph(QQuickItem* parent = 0); 42 | virtual ~QControlFlowGraph(); 43 | 44 | Q_PROPERTY(QString uuid READ getUuid WRITE setUuid NOTIFY uuidChanged) 45 | Q_PROPERTY(QVariant delegate READ getDelegate WRITE setDelegate NOTIFY delegateChanged) 46 | Q_PROPERTY(QVariant edgeDelegate READ getEdgeDelegate WRITE setEdgeDelegate NOTIFY edgeDelegateChanged) 47 | Q_PROPERTY(QVariantList preview READ getPreview NOTIFY previewChanged) 48 | Q_PROPERTY(bool isEmpty READ getIsEmpty NOTIFY isEmptyChanged) 49 | 50 | QString getUuid(void) const; 51 | QVariant getDelegate(void) const; 52 | QVariant getEdgeDelegate(void) const; 53 | QVariantList getPreview(void) const; 54 | bool getIsEmpty(void) const; 55 | 56 | void setUuid(QString& s); 57 | void setDelegate(QVariant& v); 58 | void setEdgeDelegate(QVariant& v); 59 | 60 | virtual void paint(QPainter* painter = nullptr) override; 61 | 62 | static std::mutex allInstancesLock; 63 | static std::vector allInstances; 64 | 65 | using node_tuple = std::tuple>>; 66 | 67 | public slots: 68 | void insertNode(QString uuid, unsigned int id, float x, float y, bool is_entry, QVector block); 69 | void insertEdges(QString uuid, QVector ids, QVector label, QVector kind, 70 | QVector head, QVector tail, QImage svg); 71 | void requestPreview(QString uuid); 72 | 73 | signals: 74 | void uuidChanged(void); 75 | void delegateChanged(void); 76 | void edgeDelegateChanged(void); 77 | void previewChanged(void); 78 | void isEmptyChanged(void); 79 | 80 | protected: 81 | void updateNodes(void); 82 | void updateEdges(void); 83 | void updateNode(unsigned int id, float x, float y, bool is_entry, const std::vector>& block, QQmlContext*); 84 | 85 | QString m_uuid; 86 | std::unique_ptr m_delegate; 87 | std::unique_ptr m_edgeDelegate; 88 | std::vector,QQmlContext*>> m_nodeItems; 89 | std::vector,QQmlContext*>> m_edgeItems; 90 | std::vector m_nodes; 91 | std::tuple>> m_preview; 92 | std::pair>,QImage> m_edges; 93 | }; 94 | -------------------------------------------------------------------------------- /abstract-interp/src/widening.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015, 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use crate::{Avalue, Constraint, ProgramPoint, lift}; 20 | use serde::{Serialize,Deserialize}; 21 | use panopticon_core::{Rvalue, Operation}; 22 | 23 | /// Mihaila et.al. Widening Point inferring cofibered domain. This domain is parameterized with a 24 | /// child domain. 25 | #[derive(Debug,PartialEq,Eq,Clone,Hash,Serialize,Deserialize)] 26 | #[serde(bound(deserialize = "A: Avalue + Serialize + for<'a> Deserialize<'a>"))] 27 | pub struct Widening Deserialize<'a>> { 28 | value: A, 29 | point: Option, 30 | } 31 | 32 | impl Avalue for Widening { 33 | fn abstract_value(v: &Rvalue) -> Self { 34 | Widening { value: A::abstract_value(v), point: None } 35 | } 36 | 37 | fn abstract_constraint(c: &Constraint) -> Self { 38 | Widening { value: A::abstract_constraint(c), point: None } 39 | } 40 | 41 | fn execute(pp: &ProgramPoint, op: &Operation) -> Self { 42 | match op { 43 | &Operation::Phi(ref ops) => { 44 | let widen = ops.iter().map(|x| x.point.clone().unwrap_or(pp.clone())).max() > Some(pp.clone()); 45 | 46 | Widening { 47 | value: match ops.len() { 48 | 0 => unreachable!("Phi function w/o arguments"), 49 | 1 => ops[0].value.clone(), 50 | _ => { 51 | ops.iter() 52 | .map(|x| x.value.clone()) 53 | .fold( 54 | A::initial(), |acc, x| if widen { 55 | acc.widen(&x) 56 | } else { 57 | acc.combine(&x) 58 | } 59 | ) 60 | } 61 | }, 62 | point: Some(pp.clone()), 63 | } 64 | } 65 | _ => { 66 | Widening { 67 | value: A::execute(pp, &lift(op, &|x| x.value.clone())), 68 | point: Some(pp.clone()), 69 | } 70 | } 71 | } 72 | } 73 | 74 | fn widen(&self, s: &Self) -> Self { 75 | Widening { value: self.value.widen(&s.value), point: self.point.clone() } 76 | } 77 | 78 | fn combine(&self, s: &Self) -> Self { 79 | Widening { 80 | value: self.value.combine(&s.value), 81 | point: self.point.clone(), 82 | } 83 | } 84 | 85 | fn narrow(&self, _: &Self) -> Self { 86 | self.clone() 87 | } 88 | 89 | fn initial() -> Self { 90 | Widening { value: A::initial(), point: None } 91 | } 92 | 93 | fn more_exact(&self, a: &Self) -> bool { 94 | self.value.more_exact(&a.value) 95 | } 96 | 97 | fn extract(&self, size: usize, offset: usize) -> Self { 98 | Widening { 99 | value: self.value.extract(size, offset), 100 | point: self.point.clone(), 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /core/tests/loader.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | extern crate panopticon_core; 20 | 21 | use panopticon_core::loader; 22 | use std::path::Path; 23 | 24 | #[test] 25 | fn elf_load_static() { 26 | match loader::load(Path::new("../test-data/static")) { 27 | Ok((proj, _)) => { 28 | println!("{:?}", proj); 29 | assert_eq!(proj.imports.len(), 0); 30 | } 31 | Err(error) => { 32 | println!("{:?}", error); 33 | assert!(false); 34 | } 35 | } 36 | } 37 | 38 | #[test] 39 | fn elf_load_dynamic() { 40 | match loader::load(Path::new("../test-data/libfoo.so")) { 41 | Ok((proj, _)) => { 42 | println!("{:?}", &proj); 43 | assert_eq!(proj.name, "libfoo.so"); 44 | assert_eq!(proj.code.len(), 1); 45 | assert_eq!(proj.imports.len(), 6); 46 | } 47 | Err(error) => { 48 | println!("{:?}", error); 49 | assert!(false); 50 | } 51 | } 52 | } 53 | 54 | #[test] 55 | fn mach_load_lib() { 56 | match loader::load(Path::new("../test-data/libbeef.dylib")) { 57 | Ok((proj, _)) => { 58 | println!("{:?}", &proj); 59 | assert_eq!(proj.imports.len(), 0); 60 | } 61 | Err(error) => { 62 | println!("{:?}", error); 63 | assert!(false); 64 | } 65 | } 66 | } 67 | 68 | #[test] 69 | fn mach_load_exe() { 70 | match loader::load(Path::new("../test-data/deadbeef.mach")) { 71 | Ok((proj, _)) => { 72 | println!("{:?}", &proj); 73 | assert_eq!(proj.imports.len(), 2); 74 | } 75 | Err(error) => { 76 | println!("{:?}", error); 77 | assert!(false); 78 | } 79 | } 80 | } 81 | 82 | #[test] 83 | fn mach_load_bytes() { 84 | use std::fs::File; 85 | use std::io::Read; 86 | let bytes = { 87 | let mut v = Vec::new(); 88 | let mut fd = File::open(Path::new("../test-data/deadbeef.mach")).unwrap(); 89 | fd.read_to_end(&mut v).unwrap(); 90 | v 91 | }; 92 | match loader::load_mach(&bytes, 0, "../test-data/deadbeef.mach".to_owned()) { 93 | Ok((proj, _)) => { 94 | println!("{}", proj.name); 95 | assert_eq!(proj.imports.len(), 2); 96 | } 97 | Err(error) => { 98 | println!("{:?}", error); 99 | assert!(false); 100 | } 101 | } 102 | } 103 | 104 | // TODO: add imports into the PE loader 105 | 106 | #[test] 107 | fn load_pe32() { 108 | let project = loader::load(Path::new("../test-data/test.exe")); 109 | match project { 110 | Ok((proj, _)) => { 111 | println!("{:?}", proj); 112 | assert_eq!(proj.imports.len(), 0); 113 | } 114 | Err(error) => { 115 | println!("{:?}", error); 116 | assert!(false); 117 | } 118 | } 119 | } 120 | 121 | #[test] 122 | fn load_pe32_dll() { 123 | let project = loader::load(Path::new("../test-data/libbeef.dll")); 124 | match project { 125 | Ok((proj, _)) => { 126 | println!("{:?}", proj); 127 | assert_eq!(proj.imports.len(), 0); 128 | } 129 | Err(error) => { 130 | println!("{:?}", error); 131 | assert!(false); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /qt/src/paths.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use panopticon_core::result; 20 | use panopticon_core::result::Result; 21 | use std::borrow::Cow; 22 | 23 | use std::env; 24 | use std::error::Error; 25 | use std::fs::DirBuilder; 26 | use std::path::{Path, PathBuf}; 27 | 28 | #[cfg(all(unix,not(target_os = "macos")))] 29 | pub fn session_directory() -> Result { 30 | use xdg::BaseDirectories; 31 | match BaseDirectories::with_prefix("panopticon") { 32 | Ok(dirs) => { 33 | let ret = dirs.get_data_home().join("sessions"); 34 | DirBuilder::new().recursive(true).create(ret.clone())?; 35 | Ok(ret) 36 | } 37 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 38 | } 39 | } 40 | 41 | #[cfg(all(unix,target_os = "macos"))] 42 | pub fn session_directory() -> Result { 43 | match env::var("HOME") { 44 | Ok(home) => { 45 | let ret = Path::new(&home).join("Library").join("Application Support").join("Panopticon").join("sessions"); 46 | DirBuilder::new().recursive(true).create(ret.clone())?; 47 | Ok(ret) 48 | } 49 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 50 | } 51 | } 52 | 53 | #[cfg(windows)] 54 | pub fn session_directory() -> Result { 55 | match env::var("APPDATA") { 56 | Ok(appdata) => { 57 | let ret = Path::new(&appdata).join("Panopticon").join("sessions"); 58 | DirBuilder::new().recursive(true).create(ret.clone())?; 59 | Ok(ret) 60 | } 61 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 62 | } 63 | } 64 | 65 | pub fn find_data_file(p: &Path) -> Result> { 66 | match find_data_file_impl(p) { 67 | r @ Ok(Some(_)) => r, 68 | Ok(None) => { 69 | let q = env::current_exe()?.parent().unwrap().parent().unwrap().parent().unwrap().join(p); 70 | if q.exists() { Ok(Some(q)) } else { Ok(None) } 71 | } 72 | e @ Err(_) => e, 73 | } 74 | } 75 | 76 | #[cfg(all(unix,not(target_os = "macos")))] 77 | fn find_data_file_impl(p: &Path) -> Result> { 78 | use xdg::BaseDirectories; 79 | match BaseDirectories::with_prefix("panopticon") { 80 | Ok(dirs) => Ok(dirs.find_data_file(p)), 81 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 82 | } 83 | } 84 | 85 | #[cfg(all(unix,target_os = "macos"))] 86 | fn find_data_file_impl(p: &Path) -> Result> { 87 | match env::current_exe() { 88 | Ok(path) => Ok(path.parent().and_then(|x| x.parent()).map(|x| x.join("Resources").join(p)).and_then(|x| if x.exists() { Some(x) } else { None })), 89 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 90 | } 91 | } 92 | 93 | #[cfg(windows)] 94 | fn find_data_file_impl(p: &Path) -> Result> { 95 | match env::current_exe() { 96 | Ok(path) => Ok(path.parent().map(|x| x.join(p)).and_then(|x| if x.exists() { Some(x) } else { None })), 97 | Err(e) => Err(result::Error(Cow::Owned(e.description().to_string()))), 98 | } 99 | } 100 | 101 | #[cfg(test)] 102 | mod tests { 103 | use super::*; 104 | use std::path::Path; 105 | 106 | #[test] 107 | fn paths() { 108 | assert!(find_data_file(Path::new("test")).is_ok()); 109 | assert!(session_directory().is_ok()); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /qml/Panopticon/CommentOverlay.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.4 2 | import QtQuick.Controls 1.3 as Ctrl 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Controls.Styles 1.2 5 | import Panopticon 1.0 6 | 7 | MouseArea { 8 | id: overlay 9 | 10 | property int tipX: 0 11 | property int tipY: 0 12 | property string address: "" 13 | 14 | signal accepted; 15 | signal canceled; 16 | 17 | function open(tipX,tipY,address,comment) { 18 | overlay.tipX = tipX; 19 | overlay.tipY = tipY; 20 | overlay.address = address; 21 | overlayComment.text = comment; 22 | overlay.visible = true 23 | } 24 | 25 | onAccepted: { 26 | Panopticon.commentOn(overlay.address,overlayComment.text) 27 | overlay.visible = false 28 | overlayComment.text = "" 29 | } 30 | 31 | onCanceled: { 32 | overlay.visible = false 33 | overlayComment.text = "" 34 | } 35 | 36 | visible: false 37 | hoverEnabled: true 38 | 39 | Rectangle { 40 | anchors.fill: parent 41 | color: "black" 42 | opacity: .8 43 | } 44 | 45 | Canvas { 46 | id: overlayTip 47 | x: overlay.tipX 48 | y: overlay.tipY - height / 2 49 | width: 20 50 | height: 20 51 | visible: false 52 | 53 | onPaint: { 54 | var ctx = overlayTip.getContext('2d'); 55 | 56 | ctx.fillStyle = "white"; 57 | ctx.moveTo(overlayTip.width,0); 58 | ctx.lineTo(0,(overlayTip.height - 1)/ 2); 59 | ctx.lineTo(overlayTip.width,overlayTip.height - 1); 60 | ctx.closePath(); 61 | ctx.fill(); 62 | } 63 | } 64 | 65 | Rectangle { 66 | id: overlayBox 67 | 68 | anchors.centerIn: parent 69 | //anchors.left: overlayTip.right 70 | //y: overlay.tipY - overlayTip.height - 5 71 | 72 | width: 350 73 | height: 300 74 | radius: 2 75 | color: "#fafafa" 76 | 77 | MouseArea { 78 | anchors.fill: parent 79 | onClicked: {} 80 | } 81 | 82 | Image { 83 | id: overlayClose 84 | 85 | anchors.right: parent.right 86 | anchors.top: parent.top 87 | anchors.topMargin: 12 88 | anchors.rightMargin: 12 89 | width: 22 90 | height: 22 91 | //Layout.preferredHeight: 22 92 | //Layout.alignment: Qt.AlignRight 93 | 94 | source: "../icons/cross.svg" 95 | fillMode: Image.PreserveAspectFit 96 | mipmap: true 97 | 98 | MouseArea { 99 | anchors.fill: parent 100 | onClicked: { 101 | overlay.canceled() 102 | } 103 | } 104 | } 105 | 106 | ColumnLayout { 107 | anchors.fill: parent 108 | anchors.margins: 20 109 | spacing: 30 110 | 111 | RowLayout { 112 | Layout.row: 0 113 | 114 | Label { 115 | Layout.fillWidth: true 116 | 117 | font { 118 | pointSize: 15 119 | weight: Font.DemiBold 120 | family: "Source Sans Pro" 121 | } 122 | text: "Add Comment" 123 | } 124 | } 125 | 126 | Ctrl.TextArea { 127 | id: overlayComment 128 | 129 | Layout.row: 1 130 | Layout.fillHeight: true 131 | Layout.fillWidth: true 132 | 133 | Keys.onReturnPressed: { 134 | if(event.modifiers & Qt.ControlModifier) { 135 | overlay.accepted() 136 | } else { 137 | event.accepted = false 138 | } 139 | } 140 | Keys.onEscapePressed: { 141 | overlay.canceled() 142 | } 143 | 144 | font { 145 | pointSize: 12 146 | family: "Source Sans Pro" 147 | } 148 | focus: overlay.visible 149 | } 150 | 151 | Ctrl.Label { 152 | Layout.row: 2 153 | Layout.alignment: Qt.AlignRight 154 | 155 | function getPlatformCommentShortcut() { 156 | if (Qt.platform.os == "osx") { 157 | return "Comment (⌘+Return)"; 158 | } else { 159 | return "Comment (Ctrl+Return)"; 160 | } 161 | } 162 | 163 | text: getPlatformCommentShortcut() 164 | horizontalAlignment: Text.AlignRight 165 | font { 166 | family: "Source Sans Pro" 167 | pointSize: 12 168 | underline: mousearea.containsMouse 169 | } 170 | color: "#4a95e2" 171 | 172 | MouseArea { 173 | id: mousearea 174 | anchors.fill: parent 175 | hoverEnabled: true 176 | cursorShape: (containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor) 177 | onClicked: { 178 | overlay.accepted() 179 | } 180 | } 181 | } 182 | } 183 | } 184 | 185 | onClicked: { 186 | overlay.canceled() 187 | } 188 | 189 | onWheel: {} 190 | } 191 | -------------------------------------------------------------------------------- /qml/Panopticon/PreviewOverlay.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.4 2 | import QtQuick.Controls 1.3 as Ctrl 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Controls.Styles 1.2 5 | import Panopticon 1.0 6 | 7 | MouseArea { 8 | id: overlay 9 | 10 | property rect boundingBox: "0,0,0x0" 11 | property var code: [] 12 | property string uuid: "" 13 | 14 | signal showControlFlowGraph(string uuid) 15 | 16 | function open(bb,uuid) { 17 | overlay.boundingBox = bb; 18 | overlay.visible = true 19 | overlay.uuid = uuid; 20 | } 21 | 22 | x: overlay.boundingBox.x 23 | y: overlay.boundingBox.y 24 | width: overlay.boundingBox.width 25 | height: overlay.boundingBox.height 26 | hoverEnabled: true 27 | 28 | onExited: { 29 | overlay.visible = false 30 | } 31 | 32 | onWheel: { 33 | overlay.visible = false 34 | } 35 | 36 | onClicked: { 37 | overlay.visible = false 38 | if(overlay.uuid != "") { 39 | showControlFlowGraph(overlay.uuid); 40 | } 41 | } 42 | 43 | Rectangle { 44 | id: overlayBox 45 | 46 | anchors.left: overlayTip.right 47 | anchors.top: overlayTip.top 48 | anchors.topMargin: -5 49 | anchors.leftMargin: -2 50 | 51 | width: basicBlockGrid.width + basicBlockGrid.x 52 | height: basicBlockGrid.height + basicBlockGrid.y + Panopticon.basicBlockPadding 53 | color: "#fafafa" 54 | radius: 2 55 | border { 56 | width: .7 57 | color: "#d8dae4" 58 | } 59 | 60 | Label { 61 | anchors.left: parent.left 62 | anchors.leftMargin: Panopticon.basicBlockPadding 63 | anchors.bottom: parent.top 64 | anchors.bottomMargin: Panopticon.basicBlockPadding 65 | 66 | text: overlay.code.length > 0 ? "0x" + overlay.code[0].offset.toString(16) : "" 67 | font { 68 | pointSize: 12 69 | } 70 | color: "#d8dae4" 71 | } 72 | 73 | Row { 74 | id: basicBlockGrid 75 | 76 | x: Panopticon.basicBlockMargin 77 | y: Panopticon.basicBlockPadding 78 | 79 | Column { 80 | id: opcodeColumn 81 | Repeater { 82 | model: overlay.code 83 | delegate: Monospace { 84 | text: modelData.opcode 85 | width: contentWidth + 26 86 | height: Panopticon.basicBlockLineHeight 87 | verticalAlignment: Text.AlignVCenter 88 | font { 89 | pointSize: 10 90 | } 91 | } 92 | } 93 | } 94 | 95 | Column { 96 | id: argumentColumn 97 | Repeater { 98 | model: overlay.code 99 | delegate: Row { 100 | id: argumentRow 101 | property var argumentModel: modelData 102 | 103 | Item { 104 | id: padder 105 | height: Panopticon.basicBlockLineHeight 106 | width: 1 107 | visible: modelData.operandDisplay.length == 0 108 | } 109 | 110 | Repeater { 111 | model: modelData.operandDisplay 112 | delegate: Monospace { 113 | property string alt: argumentRow.argumentModel ? argumentRow.argumentModel.operandAlt[index] : "" 114 | property string kind: argumentRow.argumentModel ? argumentRow.argumentModel.operandKind[index] : "" 115 | property string ddata: argumentRow.argumentModel ? argumentRow.argumentModel.operandData[index] : "" 116 | 117 | id: operandLabel 118 | width: contentWidth 119 | height: Panopticon.basicBlockLineHeight 120 | verticalAlignment: Text.AlignVCenter 121 | font { 122 | capitalization: Font.AllLowercase 123 | pointSize: 10 124 | } 125 | color: alt == "" ? "black" : "#297f7a" 126 | text: modelData 127 | } 128 | } 129 | } 130 | } 131 | } 132 | } 133 | } 134 | 135 | Canvas { 136 | id: overlayTip 137 | 138 | x: parent.width + 3 139 | y: parent.height / 2 - height / 2 140 | width: 6 141 | height: 20 142 | 143 | onPaint: { 144 | var ctx = overlayTip.getContext('2d'); 145 | 146 | ctx.fillStyle = "#fafafa"; 147 | ctx.strokeStyle = "#d8dae4"; 148 | ctx.lineWidth = 1; 149 | 150 | ctx.beginPath(); 151 | ctx.moveTo(overlayTip.width,0); 152 | ctx.lineTo(0,(overlayTip.height - 1)/ 2); 153 | ctx.lineTo(overlayTip.width,overlayTip.height - 1); 154 | ctx.closePath(); 155 | ctx.fill(); 156 | 157 | ctx.beginPath(); 158 | ctx.moveTo(overlayTip.width - 1,0); 159 | ctx.lineTo(0,(overlayTip.height - 1)/ 2); 160 | ctx.lineTo(overlayTip.width -1,overlayTip.height - 1); 161 | ctx.stroke(); 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Gitter](https://badges.gitter.im/das-labor/panopticon.svg)](https://gitter.im/das-labor/panopticon) [![Build Status](https://travis-ci.org/das-labor/panopticon.svg?branch=master)](https://travis-ci.org/das-labor/panopticon) [![Build status](https://ci.appveyor.com/api/projects/status/ht1wnf4qc0iocoar?svg=true)](https://ci.appveyor.com/project/flanfly/panopticon) [![Coverage Status](https://coveralls.io/repos/das-labor/panopticon/badge.svg?branch=master&service=github)](https://coveralls.io/github/das-labor/panopticon?branch=master) 2 | 3 | # DEPRECATED 4 | 5 | **The Panopticon project moved to [Gitlab](https://gitlab.com/p8n/panopticon) and was restructed into multiple crates. The Qt GUI was replaced with [Verso](https://gitlab.com/p8n/verso).** I will merge PRs but won't do any substantial work on this version. Most links below are dead. 6 | 7 | ![Panopticon](https://raw.githubusercontent.com/das-labor/panopticon/master/logo.png) 8 | 9 | # Panopticon - A Libre Cross Platform Disassembler 10 | Panopticon is a cross platform disassembler for reverse engineering written in 11 | Rust. It can disassemble AMD64, x86, AVR and MOS 6502 instruction sets and open 12 | ELF files. Panopticon comes with Qt GUI for browsing and annotating control 13 | flow graphs, 14 | 15 | ## Install 16 | If you simply want to use Panopticon follow the 17 | [install instructions](https://panopticon.re/get) on the website. 18 | 19 | ## Building 20 | Panopticon builds with Rust stable. The only dependencies aside from 21 | a working Rust stable toolchain and Cargo you need is Qt 5.5 or higher. 22 | 23 | **Ubuntu 15.10 and 16.04** 24 | ```bash 25 | sudo apt install qt5-default qtdeclarative5-dev libqt5svg5-dev \ 26 | qml-module-qtquick-controls qml-module-qttest \ 27 | qml-module-qtquick2 qml-module-qtquick-layouts \ 28 | qml-module-qtgraphicaleffects qml-module-qtqml-models2 \ 29 | qml-module-qtquick-dialogs \ 30 | qtbase5-private-dev pkg-config \ 31 | git build-essential cmake \ 32 | qml-module-qt-labs-folderlistmodel \ 33 | qml-module-qt-labs-settings 34 | ``` 35 | 36 | **Fedora 22, 23 and 24** 37 | ```bash 38 | sudo dnf install gcc-c++ cmake make qt5-qtdeclarative-devel qt5-qtquickcontrols \ 39 | qt5-qtgraphicaleffects qt5-qtsvg-devel \ 40 | adobe-source-sans-pro-fonts \ 41 | adobe-source-code-pro-fonts 42 | ``` 43 | 44 | **Gentoo** 45 | ```bash 46 | layman -a rust 47 | 48 | USE=widgets sudo -E emerge -av qtgraphicaleffects:5 qtsvg:5 qtquickcontrols:5 \ 49 | rust cargo cmake 50 | ``` 51 | 52 | After that clone the repository onto disk and use cargo to build 53 | everything. 54 | 55 | ```bash 56 | git clone https://github.com/das-labor/panopticon.git 57 | cd panopticon 58 | cargo build --all --release 59 | ``` 60 | 61 | **Windows** 62 | 63 | Install the [Qt 5.4 SDK](http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe), 64 | the [Rust toolchain](https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe) 65 | and [CMake](https://cmake.org/files/v3.6/cmake-3.6.1-win64-x64.msi). 66 | Panopticon can be built using ``cargo build --all --release``. 67 | 68 | **OS X** 69 | 70 | Install [Homebrew](http://brew.sh/) and get Qt 5.5, CMake and the Rust toolchain. 71 | Then, compile Panopticon using cargo. 72 | 73 | ```bash 74 | brew install qt cmake rust 75 | brew link qt --force 76 | brew linkapps qt 77 | export HOMEBREW_QT5_VERSION=$(brew list --versions qt | rev | cut -d ' ' -f1 | rev) 78 | ln -s /usr/local/Cellar/qt/$HOMEBREW_QT5_VERSION/mkspecs /usr/local/mkspecs 79 | ln -s /usr/local/Cellar/qt/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins 80 | QTDIR64=/usr/local cargo build --all --release 81 | ``` 82 | 83 | ## Running 84 | After installation start the ``panopticon`` binary. If you build it from 85 | source you can type: 86 | 87 | ```bash 88 | cargo run --bin panopticon --release 89 | ``` 90 | 91 | For detailed usage information see the 92 | [user documentaion](https://panopticon.re/usage). 93 | 94 | ## Contributing 95 | Panopticon is licensed under GPLv3 and is Free Software. Hackers are always 96 | welcome. Please check out [`CONTRIBUTING.md`](https://github.com/das-labor/panopticon/blob/master/CONTRIBUTING.md). 97 | 98 | - [Issue Tracker](https://github.com/das-labor/panopticon/issues) 99 | - [API Documentation](https://doc.panopticon.re/panopticon/index.html) 100 | 101 | ## Contact 102 | - IRC: #panopticon on Freenode. 103 | - Twitter: [```@panopticon_re```](https://twitter.com/@panopticon_re) 104 | -------------------------------------------------------------------------------- /qt/src/main.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015,2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #![recursion_limit = "1024"] 20 | 21 | extern crate env_logger; 22 | extern crate panopticon_core; 23 | extern crate panopticon_glue; 24 | extern crate panopticon_analysis; 25 | extern crate panopticon_abstract_interp; 26 | extern crate panopticon_data_flow; 27 | extern crate panopticon_graph_algos; 28 | extern crate panopticon_amd64; 29 | extern crate panopticon_avr; 30 | extern crate libc; 31 | extern crate uuid; 32 | extern crate cassowary; 33 | extern crate tempdir; 34 | extern crate chrono; 35 | extern crate chrono_humanize; 36 | extern crate clap; 37 | extern crate futures; 38 | extern crate futures_cpupool; 39 | extern crate parking_lot; 40 | extern crate multimap; 41 | 42 | #[cfg(unix)] 43 | extern crate xdg; 44 | 45 | #[macro_use] 46 | extern crate log; 47 | #[macro_use] 48 | extern crate error_chain; 49 | #[macro_use] 50 | extern crate lazy_static; 51 | 52 | mod sugiyama; 53 | mod singleton; 54 | mod control_flow_layout; 55 | mod paths; 56 | mod action; 57 | mod qt; 58 | mod errors { 59 | error_chain! { 60 | links { 61 | GlueError(::panopticon_glue::Error, ::panopticon_glue::ErrorKind); 62 | } 63 | 64 | foreign_links { 65 | Panopticon(::panopticon_core::Error); 66 | Time(::std::time::SystemTimeError); 67 | Io(::std::io::Error); 68 | NulError(::std::ffi::NulError); 69 | UuidParseError(::uuid::ParseError); 70 | } 71 | } 72 | } 73 | use clap::{App, Arg}; 74 | use crate::errors::*; 75 | use crate::qt::Qt; 76 | 77 | use std::path::{Path, PathBuf}; 78 | use std::result; 79 | 80 | fn main() { 81 | use std::env; 82 | use crate::paths::find_data_file; 83 | use panopticon_glue::Glue; 84 | 85 | env_logger::init().unwrap(); 86 | 87 | if cfg!(unix) { 88 | // workaround bug #165 89 | env::set_var("UBUNTU_MENUPROXY", ""); 90 | 91 | // workaround bug #183 92 | env::set_var("QT_QPA_PLATFORMTHEME", ""); 93 | 94 | // needed for UI tests 95 | env::set_var("QT_LINUX_ACCESSIBILITY_ALWAYS_ON", "1"); 96 | } 97 | 98 | 99 | let matches = App::new("Panopticon") 100 | .about("A libre cross-platform disassembler.") 101 | .arg(Arg::with_name("INPUT").help("File to disassemble").validator(exists_path_val).index(1)) 102 | .get_matches(); 103 | let main_window = find_data_file(&Path::new("qml")); 104 | 105 | match main_window { 106 | Ok(Some(ref path)) => { 107 | let recent_sessions = match read_recent_sessions() { 108 | Ok(s) => s, 109 | Err(s) => { 110 | error!("Failed to read recent sessions: {}", s); 111 | vec![] 112 | } 113 | }; 114 | match Qt::exec( 115 | path, 116 | matches.value_of("INPUT").map(str::to_string), 117 | recent_sessions, 118 | ) { 119 | Ok(()) => {} 120 | Err(s) => error!("{}", s), 121 | } 122 | } 123 | Ok(None) => { 124 | error!("QML files not found :("); 125 | } 126 | Err(s) => { 127 | error!("{}", s); 128 | } 129 | } 130 | } 131 | 132 | fn exists_path_val(filepath: String) -> result::Result<(), String> { 133 | match Path::new(&filepath).is_file() { 134 | true => Ok(()), 135 | false => Err(format!("'{}': no such file", filepath)), 136 | } 137 | } 138 | 139 | fn read_recent_sessions() -> Result> { 140 | use std::fs; 141 | use std::time; 142 | use panopticon_core::Project; 143 | 144 | let path = paths::session_directory()?; 145 | let mut ret = vec![]; 146 | 147 | if let Ok(dir) = fs::read_dir(path) { 148 | for ent in dir.filter_map(|x| x.ok()) { 149 | if let Ok(ref project) = Project::open(&ent.path()) { 150 | if let Ok(ref md) = ent.metadata() { 151 | let mtime = md.modified()?.duration_since(time::UNIX_EPOCH)?.as_secs() as u32; 152 | let fname = ent.path(); 153 | ret.push((project.name.clone(), "".to_string(), fname, mtime)); 154 | } 155 | } 156 | } 157 | } 158 | Ok(ret) 159 | } 160 | -------------------------------------------------------------------------------- /qml/Panopticon/Window.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.4 2 | import QtQuick.Controls 1.3 as Ctrl 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Dialogs 1.0 5 | import QtGraphicalEffects 1.0 6 | import Panopticon 1.0 7 | 8 | Ctrl.ApplicationWindow { 9 | id: mainWindow 10 | 11 | title: "Panopticon" 12 | width: 1024 13 | height: 768 14 | visible: true 15 | menuBar: Ctrl.MenuBar { 16 | Ctrl.Menu { 17 | title: "File" 18 | Ctrl.MenuItem { 19 | text: "Open" 20 | action: Ctrl.Action { 21 | text: "Open" 22 | shortcut: StandardKey.Open 23 | enabled: Panopticon.currentSession == "" 24 | onTriggered: { 25 | workspace.state = "welcomeState" 26 | welcome.open() 27 | } 28 | } 29 | } 30 | Ctrl.MenuItem { 31 | text: "Save" 32 | action: Ctrl.Action { 33 | text: "Save" 34 | shortcut: StandardKey.Save 35 | enabled: Panopticon.currentSession != "" 36 | onTriggered: { Panopticon.saveSession(Panopticon.currentSession) } 37 | } 38 | } 39 | Ctrl.MenuItem { 40 | text: "Save as..." 41 | action: Ctrl.Action { 42 | text: "Save as..." 43 | shortcut: StandardKey.SaveAs 44 | enabled: Panopticon.currentSession != "" 45 | onTriggered: { 46 | var diag = fileDialog.createObject(mainWindow) 47 | diag.open(); 48 | } 49 | } 50 | } 51 | Ctrl.MenuItem { 52 | text: "Quit" 53 | action: Ctrl.Action { 54 | text: "Quit" 55 | shortcut: StandardKey.Quit 56 | onTriggered: { Qt.quit() } 57 | } 58 | } 59 | } 60 | 61 | Ctrl.Menu { 62 | title: "Edit" 63 | Ctrl.MenuItem { 64 | text: "Undo" 65 | action: Ctrl.Action { 66 | text: "Undo" 67 | shortcut: StandardKey.Undo 68 | enabled: Panopticon.canUndo 69 | onTriggered: { Panopticon.undo() } 70 | } 71 | } 72 | Ctrl.MenuItem { 73 | text: "Redo" 74 | action: Ctrl.Action { 75 | text: "Redo" 76 | shortcut: StandardKey.Redo 77 | enabled: Panopticon.canRedo 78 | onTriggered: { Panopticon.redo() } 79 | } 80 | } 81 | //Ctrl.MenuItem { text: "Erase Values" } 82 | } 83 | 84 | Ctrl.Menu { 85 | title: "View" 86 | //Ctrl.MenuItem { text: "Back" } 87 | //Ctrl.MenuItem { text: "Forward" } 88 | //Ctrl.MenuItem { text: "Jump To..." } 89 | Ctrl.MenuItem { 90 | action: Ctrl.Action { 91 | text: "Center Entry Point" 92 | enabled: workspace.state == "functionState" 93 | onTriggered: { controlflow.centerEntryPoint() } 94 | } 95 | } 96 | } 97 | 98 | Ctrl.Menu { 99 | title: "Help" 100 | //Ctrl.MenuItem { text: "Documentation" } 101 | Ctrl.MenuItem { 102 | text: "About" 103 | action: Ctrl.Action { 104 | text: "About" 105 | onTriggered: { workspace.state = "welcomeState" } 106 | } 107 | } 108 | } 109 | } 110 | 111 | Component.onCompleted: { 112 | if(Panopticon.initialFile !== "") { 113 | Panopticon.openProgram(Panopticon.initialFile); 114 | } 115 | } 116 | 117 | Component { 118 | id: fileDialog 119 | 120 | FileDialog { 121 | id: fileDialog 122 | title: "Please choose a file" 123 | folder: shortcuts.home 124 | selectExisting: false 125 | selectMultiple: false 126 | onAccepted: { 127 | var p = fileDialog.fileUrls.toString().substring(7); 128 | Panopticon.saveSession(p) 129 | } 130 | Component.onCompleted: visible = true 131 | } 132 | } 133 | 134 | Item { 135 | id: workspace 136 | 137 | anchors.fill: parent 138 | state: "welcomeState" 139 | states: [ 140 | State { 141 | name: "functionState" 142 | PropertyChanges { target: controlflow; visible: true } 143 | PropertyChanges { target: welcome; visible: false } 144 | }, 145 | State { 146 | name: "welcomeState" 147 | PropertyChanges { target: controlflow; visible: false } 148 | PropertyChanges { target: welcome; visible: true } 149 | } 150 | ] 151 | 152 | Sidebar { 153 | id: bar 154 | anchors.top: parent.top 155 | anchors.bottom: parent.bottom 156 | width: Math.min(parent.width * 0.3, 400) 157 | z: 2 158 | 159 | onShowControlFlowGraph: { 160 | controlflow.showControlFlowGraph(uuid) 161 | parent.state = "functionState" 162 | } 163 | } 164 | 165 | Welcome { 166 | id: welcome 167 | anchors.left: bar.right 168 | anchors.right: parent.right 169 | anchors.top: parent.top 170 | anchors.bottom: parent.bottom 171 | } 172 | 173 | ControlFlowWidget { 174 | id: controlflow 175 | anchors.left: bar.right 176 | anchors.right: parent.right 177 | anchors.top: parent.top 178 | anchors.bottom: parent.bottom 179 | 180 | onFunctionUuidChanged: { 181 | bar.functionUuid = functionUuid; 182 | } 183 | } 184 | 185 | LinearGradient { 186 | id: gradient 187 | anchors.left: parent.left 188 | anchors.right: parent.right 189 | anchors.top: parent.top 190 | height: 3 191 | start: Qt.point(0, 0) 192 | end: Qt.point(0, 3) 193 | gradient: Gradient { 194 | GradientStop { position: 0.0; color: "#f0f0f0" } 195 | GradientStop { position: 1.0; color: "transparent" } 196 | } 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /qml/Panopticon/Welcome.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.4 2 | import QtQuick.Controls 1.3 as Ctrl 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Dialogs 1.0 5 | import Panopticon 1.0 6 | 7 | Rectangle { 8 | color: "#fdfdfd" 9 | 10 | FontLoader { source: "../fonts/SourceSansPro-Semibold.ttf" } 11 | FontLoader { source: "../fonts/SourceSansPro-Regular.ttf" } 12 | FontLoader { source: "../fonts/SourceCodePro-Regular.ttf" } 13 | 14 | function open() { 15 | scrolled.open() 16 | } 17 | 18 | Ctrl.ScrollView { 19 | id: scroll 20 | anchors.fill: parent 21 | 22 | Item { 23 | id: scrolled 24 | height: childrenRect.height + childrenRect.y + 100 25 | width: Math.max(childrenRect.width + childrenRect.x,scroll.viewport.width) 26 | 27 | function open() { 28 | var diag = fileDialog.createObject(view) 29 | diag.open(); 30 | } 31 | 32 | // Panopticon logo font 33 | Image { 34 | id: logo 35 | x: 68; y: 70 36 | source: "../icons/logo.svg" 37 | sourceSize.width: 500 38 | sourceSize.height: 44 39 | } 40 | 41 | Component { 42 | id: fileDialog 43 | 44 | FileDialog { 45 | id: fileDialog 46 | title: "Please choose a file" 47 | folder: shortcuts.home 48 | selectExisting: true 49 | selectMultiple: false 50 | onAccepted: { 51 | var p = fileDialog.fileUrls.toString().substring(7); 52 | Panopticon.openProgram(p) 53 | } 54 | Component.onCompleted: visible = true 55 | } 56 | } 57 | 58 | // Welcome text 59 | Ctrl.Label { 60 | id: view 61 | anchors.left: logo.left 62 | anchors.top: logo.bottom 63 | anchors.topMargin: 50 64 | 65 | width: logo.width + 10 66 | height: 250 67 | textFormat: Text.RichText 68 | wrapMode: Text.Wrap 69 | lineHeight: 1.2 70 | 71 | font { 72 | family: "Source Sans Pro"; pointSize: 13 73 | } 74 | 75 | text: 'This is version 0.16.0 of Panopticon. To start working you need to open a new file or pick one from your previous sessions below.

For more usage information check out panopticon.re. If you think you found a bug please open an issue in our bug tracker at https://github.com/das-labor/panopticon/issues.

' 76 | 77 | onLinkActivated: { 78 | if(link == "panop:open") { 79 | scrolled.open() 80 | } 81 | } 82 | 83 | MouseArea { 84 | cursorShape: (view.hoveredLink != "" ? Qt.PointingHandCursor : Qt.ArrowCursor) 85 | anchors.fill: parent 86 | acceptedButtons: Qt.NoButton 87 | } 88 | } 89 | 90 | // Recent sessions 91 | GridLayout { 92 | id: layout 93 | anchors.left: view.left 94 | anchors.top: view.bottom 95 | anchors.topMargin: 20 96 | 97 | Accessible.role: Accessible.List 98 | Accessible.name: "Recent Sessions" 99 | 100 | visible: Panopticon.recentSessions.length > 0 && Panopticon.currentSession == "" 101 | width: logo.width 102 | columns: 4 103 | rowSpacing: 15 104 | columnSpacing: 40 105 | 106 | // Modified 107 | Repeater { 108 | model: Panopticon.recentSessions 109 | Ctrl.Label { 110 | Layout.column: 0; 111 | Layout.row: (index + 1) * 2 112 | Layout.alignment: Qt.AlignHCenter 113 | 114 | color: "#aaa9b0" 115 | text: "Yesterday" 116 | font { 117 | family: "Source Sans Pro"; pointSize: 11 118 | } 119 | } 120 | } 121 | 122 | // Title 123 | Repeater { 124 | model: Panopticon.recentSessions 125 | Column { 126 | Layout.column: 1; 127 | Layout.row: (index + 1) * 2 128 | Layout.fillWidth: true 129 | Layout.maximumWidth: Number.POSITIVE_INFINITY 130 | Layout.minimumWidth: 100 131 | Ctrl.Label { 132 | text: modelData.title 133 | font { 134 | family: "Source Sans Pro"; pointSize: 13; weight: Font.DemiBold; 135 | } 136 | horizontalAlignment: Text.AlignLeft 137 | } 138 | Ctrl.Label { 139 | text: modelData.kind 140 | font { 141 | family: "Source Sans Pro"; pointSize: 11 142 | } 143 | horizontalAlignment: Text.AlignLeft 144 | } 145 | } 146 | } 147 | 148 | // Actions 149 | Repeater { 150 | model: Panopticon.recentSessions 151 | Ctrl.Label { 152 | Layout.column: 3; 153 | Layout.row: (index + 1) * 2 154 | Layout.alignment: Qt.AlignHCenter 155 | 156 | text: "Continue" 157 | horizontalAlignment: Text.AlignHCenter 158 | font { 159 | family: "Source Sans Pro"; pointSize: 11; underline: mousearea.containsMouse 160 | } 161 | color: "#4a95e2" 162 | 163 | MouseArea { 164 | id: mousearea 165 | anchors.fill: parent 166 | hoverEnabled: true 167 | cursorShape: (containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor) 168 | onClicked: { 169 | Panopticon.openProgram(modelData.path) 170 | } 171 | } 172 | } 173 | } 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /core/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2014,2015,2016 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! A library for disassembling and analysing binary code. 20 | //! 21 | //! The panopticon crate implements structures to model the in-memory representation of a 22 | //! program including is control flow, call graph and memory maps. 23 | //! The most important types and their interaction are as follows: 24 | //! 25 | //! ```text 26 | //! Project 27 | //! ├── Region 28 | //! │   └── Layer 29 | //! └── Program 30 | //! └── Function 31 | //! └── BasicBlock 32 | //! └── Mnemonic 33 | //! └── Statement 34 | //! ``` 35 | //! 36 | //! The [`Program`](program/index.html), [`Function`](function/index.html), 37 | //! [`BasicBlock`](basic_block/index.html) and [`Statement`](il/struct.Statement.html) 38 | //! types model the behaviour of code. 39 | //! The [`Region`](region/index.html) and [`Layer`](layer/index.html) types 40 | //! represent how the program is laid out in memory. 41 | //! 42 | //! # Code 43 | //! 44 | //! Panopticon models code as a collection of programs. Each 45 | //! [`Program`](program/index.html) consists of functions. A [`Function`](function/index.html) a graph with nodes representing a 46 | //! sequence of instructions and edges representing jumps. These instruction sequences are [`BasicBlock`s](basic_block/index.html) 47 | //! and contain a list of [`Mnemonic`](mnemonic/index.html)s. The meaning of each 48 | //! `Mnemonic` is described in the [RREIL][1] language. Each mnemonic includes a sequence of 49 | //! [`Statement`s](il/struct.Statement.html) implementing it. 50 | //! 51 | //! Panopticon allows multiple programs per project. For example, imagine a C# application that calls into a 52 | //! native DLL written in C. Such an application would have two program instances. One for the CIL 53 | //! code of the C# part of the application and one for the AMD64 object code inside the DLL. 54 | //! 55 | //! The [`Disassembler`](disassembler/index.html) and [`CodeGen`](codegen/index.html) are used to fill `Function` 56 | //! structures with `Mnemonic`s. 57 | //! 58 | //! # Data 59 | //! 60 | //! The in-memory layout of an executable is modeled using the [`Region`](region/index.html), [`Layer`](layer/index.html) and 61 | //! [`Cell`](layer/type.Cell.html) types. All data is organized into `Region`s. Each `Region` is an array of 62 | //! `Cell`s numbered from 0 to n. Each `Cell` is an is either 63 | //! undefined or has a value between 0 and 255 (both including). `Region`s are read 64 | //! only. Changing their contents is done by applying `Layer` instance to them. A `Layer` 65 | //! reads part of a `Region` or another `Layer` and returns a new `Cell` array. For example, `Layer` 66 | //! can decrypt parts of a `Region` or replace individual `Cell`s with new 67 | //! ones. 68 | //! 69 | 70 | //! In normal operation there is one `Region` for each memory address space, one on 71 | //! Von-Neumann machines two on Harvard architectures. Other uses for `Region`s are 72 | //! applying functions to `Cell` array where the result is not equal in size to the 73 | //! input (for example uncompressing parts of the executable image). 74 | 75 | #![recursion_limit="100"] 76 | #![warn(missing_docs)] 77 | 78 | #[macro_use] 79 | extern crate log; 80 | 81 | extern crate num; 82 | extern crate flate2; 83 | extern crate panopticon_graph_algos; 84 | extern crate uuid; 85 | extern crate byteorder; 86 | extern crate goblin; 87 | extern crate quickcheck; 88 | extern crate serde; 89 | #[macro_use] extern crate serde_derive; 90 | extern crate serde_cbor; 91 | 92 | #[cfg(test)] 93 | extern crate env_logger; 94 | 95 | // core 96 | pub mod disassembler; 97 | pub use crate::disassembler::{Architecture, Disassembler, Match, State}; 98 | 99 | #[macro_use] 100 | pub mod il; 101 | pub use crate::il::{Guard, Lvalue, Operation, Rvalue, Statement, execute, Endianess}; 102 | 103 | pub mod mnemonic; 104 | pub use crate::mnemonic::{Bound, Mnemonic, MnemonicFormatToken}; 105 | pub mod basic_block; 106 | pub use crate::basic_block::BasicBlock; 107 | 108 | pub mod function; 109 | pub use crate::function::{ControlFlowEdge, ControlFlowGraph, ControlFlowRef, ControlFlowTarget, Function, FunctionKind}; 110 | 111 | pub mod program; 112 | pub use crate::program::{CallGraph, CallGraphRef, CallTarget, Program}; 113 | 114 | pub mod project; 115 | pub use crate::project::Project; 116 | 117 | pub mod region; 118 | pub use crate::region::{Region, World}; 119 | 120 | pub mod layer; 121 | pub use crate::layer::{Layer, LayerIter, OpaqueLayer}; 122 | 123 | pub mod result; 124 | pub use crate::result::{Error, Result}; 125 | 126 | // file formats 127 | pub mod loader; 128 | pub use crate::loader::{Machine, load}; 129 | -------------------------------------------------------------------------------- /qt/tests/sugiyama.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /*extern crate panopticon_amd64; 20 | extern crate panopticon_core; 21 | extern crate panopticon_analysis; 22 | extern crate panopticon_graph_algos; 23 | extern crate futures; 24 | extern crate env_logger; 25 | 26 | use std::path::Path; 27 | use panopticon_core::{Machine, loader}; 28 | use panopticon_analysis::pipeline; 29 | use panopticon_graph_algos::{ 30 | GraphTrait, 31 | VertexListGraphTrait, 32 | EdgeListGraphTrait, 33 | }; 34 | use panopticon_amd64 as amd64; 35 | use panopticon::linear_layout; 36 | use futures::Stream; 37 | use std::collections::HashMap; 38 | 39 | #[test] 40 | #[ignore] 41 | fn layout_all() { 42 | let _ = ::env_logger::init(); 43 | 44 | for path in &[ 45 | "tests/data/static", 46 | "tests/data/libbeef.dll", 47 | "tests/data/libbeef.dylib", 48 | ] { 49 | if let Ok((mut proj, machine)) = loader::load(&Path::new(path)) { 50 | let maybe_prog = proj.code.pop(); 51 | let reg = proj.data 52 | .dependencies 53 | .vertex_label(proj.data.root) 54 | .unwrap() 55 | .clone(); 56 | 57 | if let Some(prog) = maybe_prog { 58 | let pipe: Box<_> = match machine { 59 | Machine::Amd64 => { 60 | pipeline::( 61 | prog, 62 | reg.clone(), 63 | amd64::Mode::Long, 64 | ) 65 | } 66 | Machine::Ia32 => { 67 | pipeline::( 68 | prog, 69 | reg.clone(), 70 | amd64::Mode::Protected, 71 | ) 72 | } 73 | _ => unreachable!(), 74 | }; 75 | 76 | for i in pipe.wait() { 77 | if let Ok(func) = i { 78 | let cfg = &func.cflow_graph; 79 | let vertices = 80 | HashMap::::from_iter( 82 | cfg.vertices().enumerate().map( 83 | |(idx, 84 | vx)| { 85 | (vx, idx) 86 | } 87 | ) 88 | ); 89 | let entry = func.entry_point.map(|x| vertices[&x]); 90 | let edges: Vec<(usize, 91 | usize)> = cfg.edges() 92 | .map( 93 | |e| { 94 | (vertices[&cfg.source(e)], 95 | vertices[&cfg.target(e)]) 96 | } 97 | ) 98 | .collect(); 99 | let dims = HashMap::from_iter( 100 | vertices.iter().map( 101 | |(_, &x)| { 102 | (x, (42., 23.)) 103 | } 104 | ) 105 | ); 106 | 107 | linear_layout( 108 | &vertices.into_iter().map(|(_, x)| x).collect(), 109 | &edges, 110 | &dims, 111 | entry, 112 | 5., 113 | 10., 114 | 2., 115 | 5., 116 | 5., 117 | 120., 118 | ) 119 | .unwrap(); 120 | } else { 121 | unreachable!(); 122 | } 123 | } 124 | } else { 125 | unreachable!(); 126 | } 127 | } else { 128 | unreachable!(); 129 | } 130 | } 131 | }*/ 132 | -------------------------------------------------------------------------------- /glue/ext/lib/src/qpanopticon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "qpanopticon.h" 26 | 27 | QObject *qpanopticon_provider(QQmlEngine *engine, QJSEngine *scriptEngine) { 28 | Q_UNUSED(engine) 29 | Q_UNUSED(scriptEngine) 30 | 31 | QPanopticon::staticInstance = new QPanopticon(); 32 | return QPanopticon::staticInstance; 33 | } 34 | 35 | SubscribeToFunc QPanopticon::staticSubscribeTo = nullptr; 36 | GetFunctionFunc QPanopticon::staticGetFunction = nullptr; 37 | OpenProgramFunc QPanopticon::staticOpenProgram = nullptr; 38 | SaveSessionFunc QPanopticon::staticSaveSession = nullptr; 39 | CommentOnFunc QPanopticon::staticCommentOn = nullptr; 40 | RenameFunctionFunc QPanopticon::staticRenameFunction = nullptr; 41 | SetValueForFunc QPanopticon::staticSetValueFor = nullptr; 42 | UndoFunc QPanopticon::staticUndo = nullptr; 43 | RedoFunc QPanopticon::staticRedo = nullptr; 44 | QPanopticon* QPanopticon::staticInstance = nullptr; 45 | QString QPanopticon::staticInitialFile = QString(); 46 | std::vector QPanopticon::staticRecentSessions = {}; 47 | 48 | QPanopticon::QPanopticon() 49 | : m_recentSessions(), m_currentSession(""), 50 | m_sidebar(new QSidebar(this)), m_sortedSidebar(new QSortFilterProxyModel(this)), m_canUndo(false), m_canRedo(false) 51 | { 52 | m_sortedSidebar->setSourceModel(m_sidebar); 53 | 54 | for(auto qobj: staticRecentSessions) { 55 | updateRecentSession(qobj); 56 | } 57 | staticRecentSessions.clear(); 58 | } 59 | 60 | QPanopticon::~QPanopticon() {} 61 | 62 | bool QPanopticon::hasRecentSessions(void) const { return m_recentSessions.size() != 0; } 63 | QString QPanopticon::getCurrentSession(void) const { return m_currentSession; } 64 | QString QPanopticon::getInitialFile(void) const { return staticInitialFile; } 65 | 66 | QSidebar* QPanopticon::getSidebar(void) const { return m_sidebar; } 67 | QSortFilterProxyModel* QPanopticon::getSortedSidebar(void) const { return m_sortedSidebar; } 68 | unsigned int QPanopticon::getSidebarSortRole(void) const { return m_sortedSidebar->sortRole(); } 69 | bool QPanopticon::getSidebarSortAscending(void) const { return m_sortedSidebar->sortOrder() == Qt::AscendingOrder; } 70 | 71 | int QPanopticon::getBasicBlockPadding(void) const { return 3; } 72 | int QPanopticon::getBasicBlockMargin(void) const { return 8; } 73 | int QPanopticon::getBasicBlockLineHeight(void) const { return 17; } 74 | int QPanopticon::getBasicBlockCharacterWidth(void) const { return 8; } 75 | int QPanopticon::getBasicBlockColumnPadding(void) const { return 26; } 76 | int QPanopticon::getBasicBlockCommentWidth(void) const { return 150; } 77 | 78 | bool QPanopticon::getCanUndo(void) const { return m_canUndo; } 79 | bool QPanopticon::getCanRedo(void) const { return m_canRedo; } 80 | 81 | QString QPanopticon::getLayoutTask(void) const { return m_layoutTask; } 82 | 83 | void QPanopticon::setSidebarSortRole(unsigned int role) { 84 | m_sortedSidebar->setSortRole(role); 85 | emit sidebarSortRoleChanged(); 86 | } 87 | 88 | void QPanopticon::setSidebarSortAscending(bool asc) { 89 | m_sortedSidebar->sort(0, asc ? Qt::AscendingOrder : Qt::DescendingOrder); 90 | emit sidebarSortAscendingChanged(); 91 | } 92 | 93 | int QPanopticon::openProgram(QString path) { 94 | return QPanopticon::staticOpenProgram(path.toStdString().c_str()); 95 | } 96 | 97 | int QPanopticon::saveSession(QString path) { 98 | return QPanopticon::staticSaveSession(path.toStdString().c_str()); 99 | } 100 | 101 | int QPanopticon::commentOn(QString address, QString comment) { 102 | qlonglong l = address.toLongLong(); 103 | return QPanopticon::staticCommentOn(l,comment.toStdString().c_str()); 104 | } 105 | 106 | int QPanopticon::renameFunction(QString uuid, QString name) { 107 | return QPanopticon::staticRenameFunction(uuid.toStdString().c_str(),name.toStdString().c_str()); 108 | } 109 | 110 | int QPanopticon::setValueFor(QString uuid, QString variable, QString value) { 111 | return QPanopticon::staticSetValueFor(uuid.toStdString().c_str(), 112 | variable.toStdString().c_str(), 113 | value.toStdString().c_str()); 114 | } 115 | 116 | int QPanopticon::undo() { 117 | return QPanopticon::staticUndo(); 118 | } 119 | 120 | int QPanopticon::redo() { 121 | return QPanopticon::staticRedo(); 122 | } 123 | 124 | void QPanopticon::updateUndoRedo(bool undo, bool redo) { 125 | m_canUndo = undo; 126 | m_canRedo = redo; 127 | 128 | emit canUndoChanged(); 129 | emit canRedoChanged(); 130 | } 131 | 132 | void QPanopticon::updateCurrentSession(QString path) { 133 | m_currentSession = path; 134 | emit currentSessionChanged(); 135 | } 136 | 137 | void QPanopticon::updateRecentSession(QRecentSession* sess) { 138 | sess->setParent(this); 139 | m_recentSessions.append(QVariant::fromValue(sess)); 140 | emit recentSessionsChanged(); 141 | } 142 | 143 | void QPanopticon::updateLayoutTask(QString task) { 144 | m_layoutTask = task; 145 | emit layoutTaskChanged(); 146 | } 147 | -------------------------------------------------------------------------------- /glue/src/types.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | use crate::errors::*; 20 | use panopticon_core::Function; 21 | use std::ffi::CString; 22 | use std::path::Path; 23 | use std::ptr; 24 | 25 | #[repr(C)] 26 | pub struct CSidebarItem { 27 | title: *const i8, 28 | subtitle: *const i8, 29 | uuid: *const i8, 30 | } 31 | 32 | impl CSidebarItem { 33 | pub fn new(func: &Function) -> Result { 34 | let str_entry = CString::new(format!("0x{:x}", func.start()))?; 35 | let name = CString::new(func.name.to_string().into_bytes())?; 36 | let uuid = CString::new(func.uuid().to_string().into_bytes())?; 37 | 38 | Ok( 39 | CSidebarItem { 40 | title: name.into_raw(), 41 | subtitle: str_entry.into_raw(), 42 | uuid: uuid.into_raw(), 43 | } 44 | ) 45 | } 46 | } 47 | 48 | impl Drop for CSidebarItem { 49 | fn drop(&mut self) { 50 | unsafe { 51 | CString::from_raw(self.title as *mut i8); 52 | CString::from_raw(self.subtitle as *mut i8); 53 | CString::from_raw(self.uuid as *mut i8); 54 | } 55 | } 56 | } 57 | 58 | #[repr(C)] 59 | pub struct CBasicBlockOperand { 60 | kind: *const i8, 61 | display: *const i8, 62 | alt: *const i8, 63 | data: *const i8, 64 | } 65 | 66 | impl CBasicBlockOperand { 67 | pub fn new(kind: String, display: String, alt: String, data: String) -> Result { 68 | let kind = CString::new(kind.into_bytes())?; 69 | let display = CString::new(display.into_bytes())?; 70 | let alt = CString::new(alt.into_bytes())?; 71 | let data = CString::new(data.into_bytes())?; 72 | 73 | Ok( 74 | CBasicBlockOperand { 75 | kind: kind.into_raw(), 76 | display: display.into_raw(), 77 | alt: alt.into_raw(), 78 | data: data.into_raw(), 79 | } 80 | ) 81 | } 82 | } 83 | 84 | impl Drop for CBasicBlockOperand { 85 | fn drop(&mut self) { 86 | unsafe { 87 | CString::from_raw(self.kind as *mut i8); 88 | CString::from_raw(self.display as *mut i8); 89 | CString::from_raw(self.alt as *mut i8); 90 | CString::from_raw(self.data as *mut i8); 91 | } 92 | } 93 | } 94 | 95 | #[repr(C)] 96 | pub struct CBasicBlockLine { 97 | opcode: *const i8, 98 | region: *const i8, 99 | offset: u64, 100 | comment: *const i8, 101 | args: *const *const CBasicBlockOperand, 102 | } 103 | 104 | impl CBasicBlockLine { 105 | pub fn new(opcode: String, region: String, offset: u64, comment: String, args: Vec) -> Result { 106 | let opcode = CString::new(opcode.into_bytes())?; 107 | let region = CString::new(region.into_bytes())?; 108 | let comment = CString::new(comment.into_bytes())?; 109 | let mut args: Vec<*const CBasicBlockOperand> = args.into_iter().map(|i| -> *const CBasicBlockOperand { Box::into_raw(Box::new(i)) }).collect(); 110 | 111 | args.push(ptr::null()); 112 | 113 | Ok( 114 | CBasicBlockLine { 115 | opcode: opcode.into_raw(), 116 | region: region.into_raw(), 117 | offset: offset, 118 | comment: comment.into_raw(), 119 | args: unsafe { (*Box::into_raw(Box::new(args))).as_ptr() }, 120 | } 121 | ) 122 | } 123 | } 124 | 125 | impl Drop for CBasicBlockLine { 126 | fn drop(&mut self) { 127 | unsafe { 128 | CString::from_raw(self.opcode as *mut i8); 129 | CString::from_raw(self.region as *mut i8); 130 | CString::from_raw(self.comment as *mut i8); 131 | /* let mut idx = 0; 132 | 133 | while !self.args.offset(idx).is_null() { 134 | Box::<*const CBasicBlockOperand>::from_raw(self.args.offset(idx) as *mut CBasicBlockOperand); 135 | idx += 1; 136 | } 137 | Box::from_raw(self.args as *mut *const CBasicBlockOperand);*/ 138 | } 139 | } 140 | } 141 | 142 | #[repr(C)] 143 | pub struct CRecentSession { 144 | title: *const i8, 145 | kind: *const i8, 146 | path: *const i8, 147 | timestamp: u32, 148 | } 149 | 150 | impl CRecentSession { 151 | pub fn new(title: String, kind: String, path: &Path, timestamp: u32) -> Result { 152 | let title = CString::new(title.into_bytes())?; 153 | let kind = CString::new(kind.into_bytes())?; 154 | let path = CString::new(format!("{}", path.display()).into_bytes())?; 155 | 156 | Ok( 157 | CRecentSession { 158 | title: title.into_raw(), 159 | kind: kind.into_raw(), 160 | path: path.into_raw(), 161 | timestamp: timestamp, 162 | } 163 | ) 164 | } 165 | } 166 | 167 | impl Drop for CRecentSession { 168 | fn drop(&mut self) { 169 | unsafe { 170 | CString::from_raw(self.kind as *mut i8); 171 | CString::from_raw(self.title as *mut i8); 172 | CString::from_raw(self.path as *mut i8); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /glue/ext/lib/include/qpanopticon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "qsidebar.h" 30 | #include "qrecentsession.h" 31 | #include "glue.h" 32 | 33 | #pragma once 34 | 35 | QObject *qpanopticon_provider(QQmlEngine *engine, QJSEngine *scriptEngine); 36 | 37 | class QPanopticon : public QObject { 38 | Q_OBJECT 39 | public: 40 | QPanopticon(); 41 | virtual ~QPanopticon(); 42 | 43 | Q_PROPERTY(QString initialFile READ getInitialFile) 44 | 45 | // sessions 46 | Q_PROPERTY(QVariantList recentSessions MEMBER m_recentSessions NOTIFY recentSessionsChanged) 47 | Q_PROPERTY(bool hasRecentSessions READ hasRecentSessions NOTIFY hasRecentSessionsChanged) 48 | Q_PROPERTY(QString currentSession READ getCurrentSession NOTIFY currentSessionChanged) 49 | 50 | // sidebar 51 | Q_PROPERTY(QSidebar* sidebar READ getSidebar NOTIFY sidebarChanged) 52 | Q_PROPERTY(QSortFilterProxyModel* sortedSidebar READ getSortedSidebar NOTIFY sortedSidebarChanged) 53 | Q_PROPERTY(unsigned int sidebarSortRole READ getSidebarSortRole WRITE setSidebarSortRole NOTIFY sidebarSortRoleChanged) 54 | Q_PROPERTY(bool sidebarSortAscending READ getSidebarSortAscending WRITE setSidebarSortAscending NOTIFY sidebarSortAscendingChanged) 55 | 56 | // basic block metrics 57 | Q_PROPERTY(unsigned int basicBlockPadding READ getBasicBlockPadding NOTIFY basicBlockPaddingChanged) 58 | Q_PROPERTY(unsigned int basicBlockMargin READ getBasicBlockMargin NOTIFY basicBlockMarginChanged) 59 | Q_PROPERTY(unsigned int basicBlockLineHeight READ getBasicBlockLineHeight NOTIFY basicBlockLineHeightChanged) 60 | Q_PROPERTY(unsigned int basicBlockCharacterWidth READ getBasicBlockCharacterWidth NOTIFY basicBlockCharacterWidthChanged) 61 | Q_PROPERTY(unsigned int basicBlockColumnPadding READ getBasicBlockColumnPadding NOTIFY basicBlockColumnPaddingChanged) 62 | Q_PROPERTY(unsigned int basicBlockCommentWidth READ getBasicBlockCommentWidth NOTIFY basicBlockCommentWidthChanged) 63 | 64 | // undo/redo 65 | Q_PROPERTY(bool canUndo READ getCanUndo NOTIFY canUndoChanged) 66 | Q_PROPERTY(bool canRedo READ getCanRedo NOTIFY canRedoChanged) 67 | 68 | // tasks 69 | Q_PROPERTY(QString layoutTask READ getLayoutTask NOTIFY layoutTaskChanged) 70 | 71 | bool hasRecentSessions(void) const; 72 | QString getCurrentSession(void) const; 73 | QString getInitialFile(void) const; 74 | 75 | QSidebar* getSidebar(void) const; 76 | QSortFilterProxyModel* getSortedSidebar(void) const; 77 | unsigned int getSidebarSortRole(void) const; 78 | bool getSidebarSortAscending(void) const; 79 | 80 | int getBasicBlockPadding(void) const; 81 | int getBasicBlockMargin(void) const; 82 | int getBasicBlockLineHeight(void) const; 83 | int getBasicBlockCharacterWidth(void) const; 84 | int getBasicBlockColumnPadding(void) const; 85 | int getBasicBlockCommentWidth(void) const; 86 | 87 | bool getCanUndo(void) const; 88 | bool getCanRedo(void) const; 89 | 90 | QString getLayoutTask(void) const; 91 | 92 | // C to Rust functions 93 | static SubscribeToFunc staticSubscribeTo; 94 | static GetFunctionFunc staticGetFunction; 95 | static OpenProgramFunc staticOpenProgram; 96 | static SaveSessionFunc staticSaveSession; 97 | static CommentOnFunc staticCommentOn; 98 | static RenameFunctionFunc staticRenameFunction; 99 | static SetValueForFunc staticSetValueFor; 100 | static UndoFunc staticUndo; 101 | static RedoFunc staticRedo; 102 | 103 | // Singleton instance 104 | static QPanopticon* staticInstance; 105 | 106 | static QString staticInitialFile; 107 | static std::vector staticRecentSessions; 108 | 109 | public slots: 110 | // session management 111 | int openProgram(QString path); 112 | int saveSession(QString path); 113 | 114 | // actions 115 | int commentOn(QString address, QString comment); 116 | int renameFunction(QString uuid, QString name); 117 | int setValueFor(QString uuid, QString variable, QString value); 118 | 119 | // undo/redo 120 | int undo(); 121 | int redo(); 122 | 123 | void setSidebarSortRole(unsigned int); 124 | void setSidebarSortAscending(bool); 125 | 126 | void updateUndoRedo(bool undo, bool redo); 127 | void updateCurrentSession(QString path); 128 | void updateRecentSession(QRecentSession* sess); 129 | void updateLayoutTask(QString task); 130 | 131 | signals: 132 | void recentSessionsChanged(void); 133 | void hasRecentSessionsChanged(void); 134 | void currentSessionChanged(void); 135 | 136 | void sidebarChanged(void); 137 | void sortedSidebarChanged(void); 138 | void sidebarSortRoleChanged(void); 139 | void sidebarSortAscendingChanged(void); 140 | 141 | void basicBlockPaddingChanged(void); 142 | void basicBlockMarginChanged(void); 143 | void basicBlockLineHeightChanged(void); 144 | void basicBlockCharacterWidthChanged(void); 145 | void basicBlockColumnPaddingChanged(void); 146 | void basicBlockCommentWidthChanged(void); 147 | 148 | void canUndoChanged(void); 149 | void canRedoChanged(void); 150 | 151 | void layoutTaskChanged(void); 152 | 153 | protected: 154 | QVariantList m_recentSessions; 155 | QString m_currentSession; 156 | QSidebar* m_sidebar; 157 | QSortFilterProxyModel* m_sortedSidebar; 158 | bool m_canUndo; 159 | bool m_canRedo; 160 | QString m_layoutTask; 161 | }; 162 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | env: 2 | global: 3 | - RUSTFLAGS="-D warnings" 4 | matrix: 5 | fast_finish: true 6 | include: 7 | # CI targets 8 | - os: osx 9 | rust: stable 10 | env: TARGET=x86_64-apple-darwin 11 | - os: linux 12 | dist: trusty 13 | rust: stable 14 | env: 15 | - TARGET=x86_64-unknown-linux-gnu 16 | - COMPILER_NAME=gcc 17 | - CXX=g++-5 18 | - CC=gcc-5 19 | # rustdoc 20 | - os: linux 21 | dist: trusty 22 | rust: stable 23 | env: 24 | - TARGET=x86_64-unknown-linux-gnu 25 | - COMPILER_NAME=gcc 26 | - CXX=g++-5 27 | - CC=gcc-5 28 | - PACKAGE=doc 29 | - secure: "J9YvYryNyAZZSfJfXw64xHGmuwbwjPWxfvQ1vaLoC3ZXla2Nf1tEQN7P0UgnJkC3MZYop/yIZFa0bbdTG0Kef7+RHeD15Yp70bI6fyP9i048KRQYLPubTOHWIm5Ow6qIMo5hKZsVO3z+Lg7s3/y6L+DR5bT3PXWdZHovhe1QlA8=" 30 | # nightly builds 31 | - os: linux 32 | dist: trusty 33 | rust: stable 34 | env: 35 | - TARGET=x86_64-unknown-linux-gnu 36 | - COMPILER_NAME=gcc 37 | - CXX=g++-5 38 | - CC=gcc-5 39 | - PACKAGE=ubuntu 40 | - secure: "HwY2nRi7xuAQTkuVWgUupdVcJmutiiq+A4iDCbC4NI/vRB7WKCifxlzivCeTJMBu22LSLPJBMoaQ0S7w1PLaPkuG2d0qqFhublmhzk5sLaQt6AiwpEnJaHLqGy6aDVPDbqd4EWlPZ1MMCV+uXhtHzsg9XmrlZH9l5hMGx3mUDJw=" 41 | branches: 42 | only: 43 | - master 44 | - os: linux 45 | dist: trusty 46 | rust: stable 47 | env: 48 | - TARGET=x86_64-unknown-linux-gnu 49 | - PACKAGE=debian 50 | - secure: "HwY2nRi7xuAQTkuVWgUupdVcJmutiiq+A4iDCbC4NI/vRB7WKCifxlzivCeTJMBu22LSLPJBMoaQ0S7w1PLaPkuG2d0qqFhublmhzk5sLaQt6AiwpEnJaHLqGy6aDVPDbqd4EWlPZ1MMCV+uXhtHzsg9XmrlZH9l5hMGx3mUDJw=" 51 | branches: 52 | only: 53 | - master 54 | - os: linux 55 | dist: trusty 56 | rust: stable 57 | env: 58 | - TARGET=x86_64-unknown-linux-gnu 59 | - PACKAGE=fedora 60 | - secure: "HwY2nRi7xuAQTkuVWgUupdVcJmutiiq+A4iDCbC4NI/vRB7WKCifxlzivCeTJMBu22LSLPJBMoaQ0S7w1PLaPkuG2d0qqFhublmhzk5sLaQt6AiwpEnJaHLqGy6aDVPDbqd4EWlPZ1MMCV+uXhtHzsg9XmrlZH9l5hMGx3mUDJw=" 61 | branches: 62 | only: 63 | - master 64 | - os: osx 65 | rust: stable 66 | env: 67 | - TARGET=x86_64-apple-darwin 68 | - PACKAGE=osx 69 | - secure: "HwY2nRi7xuAQTkuVWgUupdVcJmutiiq+A4iDCbC4NI/vRB7WKCifxlzivCeTJMBu22LSLPJBMoaQ0S7w1PLaPkuG2d0qqFhublmhzk5sLaQt6AiwpEnJaHLqGy6aDVPDbqd4EWlPZ1MMCV+uXhtHzsg9XmrlZH9l5hMGx3mUDJw=" 70 | branches: 71 | only: 72 | - master 73 | 74 | sudo: false 75 | services: 76 | - docker 77 | notifications: 78 | webhooks: 79 | urls: 80 | - "https://webhooks.gitter.im/e/b55d667112f600c858d4" 81 | irc: 82 | channels: 83 | - "chat.freenode.net#panopticon" 84 | on_success: change 85 | on_failure: always 86 | language: rust 87 | cache: cargo 88 | addons: 89 | apt: 90 | sources: &sources 91 | - ubuntu-toolchain-r-test 92 | packages: 93 | # qml-rust 94 | - g++-5 95 | # panopticon 96 | - cmake 97 | - qt5-default 98 | - qtdeclarative5-dev 99 | - libqt5qml-quickcontrols 100 | - qtbase5-private-dev 101 | - libqt5svg5-dev 102 | - pkg-config 103 | - git 104 | - build-essential 105 | # kcov 106 | - libelf-dev 107 | - libcurl4-openssl-dev 108 | - libdw-dev 109 | before_install: | 110 | if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 111 | brew update 112 | brew install qt 113 | brew link qt --force 114 | brew linkapps qt 115 | export HOMEBREW_QT5_VERSION=$(brew list --versions qt | rev | cut -d ' ' -f1 | rev) 116 | ln -s /usr/local/Cellar/qt/$HOMEBREW_QT5_VERSION/mkspecs /usr/local/mkspecs 117 | ln -s /usr/local/Cellar/qt/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins 118 | fi 119 | before_script: | 120 | if [[ "$TRAVIS_OS_NAME" == "linux" && "$PACKAGE" == "" ]]; then 121 | (cargo install cargo-travis || true) 122 | export PATH=$HOME/.cargo/bin:$PATH 123 | fi 124 | script: | 125 | if [[ "$PACKAGE" != "" && ( "$TRAVIS_BRANCH" != "master" || "$TRAVIS_PULL_REQUEST" != "false" ) ]] 126 | then 127 | echo "" 128 | else 129 | if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export QTDIR64=/usr/local; fi && 130 | case "$PACKAGE" in 131 | "osx") 132 | cd pkg/osx/ && 133 | ./package_dmg.sh && 134 | curl -vT Panopticon.dmg -u upload:$FTP_PASSWD -Q "-SITE CHMOD 664 panopticon-master.dmg" ftp://files.panopticon.re/panopticon-master.dmg 135 | ;; 136 | "ubuntu") 137 | cd pkg/debian && 138 | docker build -t panopticon-build -f Dockerfile.ubuntu . && 139 | docker run -v `pwd`:/out panopticon-build && 140 | curl -vT panopticon_0.16_amd64.deb -u upload:$FTP_PASSWD -Q "-SITE CHMOD 664 panopticon-master-xenial.deb" ftp://files.panopticon.re/panopticon-master-xenial.deb 141 | ;; 142 | "doc") 143 | cargo doc --all && 144 | cd target/doc && 145 | tar cvf ../../doc.tar * && 146 | curl -H "X-Token: $DOC_TOKEN" --data-binary @../../doc.tar https://doc.panopticon.re/update 147 | ;; 148 | "debian") 149 | cd pkg/debian && 150 | docker build -t panopticon-build -f Dockerfile.debian . && 151 | docker run -v `pwd`:/out panopticon-build && 152 | curl -vT panopticon_0.16_amd64.deb -u upload:$FTP_PASSWD -Q "-SITE CHMOD 664 panopticon-master-stretch.deb" ftp://files.panopticon.re/panopticon-master-stretch.deb 153 | ;; 154 | "fedora") 155 | cd pkg/fedora && 156 | docker build -t panopticon-build . && 157 | docker run -v `pwd`:/out panopticon-build && 158 | curl -vT panopticon_0.16_amd64.rpm -u upload:$FTP_PASSWD -Q "-SITE CHMOD 664 panopticon-master-fedora-25.rpm" ftp://files.panopticon.re/panopticon-master-fedora-25.rpm 159 | ;; 160 | "") 161 | cargo build --verbose --all && 162 | cargo test --verbose --all 163 | ;; 164 | *) 165 | exit 166 | ;; 167 | esac 168 | fi 169 | after_success: | 170 | # send coverage report to coveralls.io 171 | if [[ "$TRAVIS_OS_NAME" == "linux" && "$PACKAGE" == "" ]]; then 172 | cargo coveralls --verbose --all 173 | fi 174 | -------------------------------------------------------------------------------- /qml/Window.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler (https://panopticon.re/) 3 | * Copyright (C) 2014,2015,2016 Kai Michaelis 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.4 20 | import QtQuick.Controls 1.3 as Ctrl 21 | import QtQuick.Layouts 1.1 22 | 23 | import Panopticon 1.0 24 | 25 | import "." 26 | 27 | Ctrl.ApplicationWindow { 28 | id: mainWindow 29 | 30 | function serveRequest(req) { 31 | targetSelect.request = req 32 | 33 | switch(req.kind) { 34 | case "panop": { 35 | var res = JSON.parse(Panopticon.openProject(req.path)) 36 | if(res.status == "err") { 37 | console.exception(res.error); 38 | } 39 | break; 40 | } 41 | case "mach-o": { 42 | var res = JSON.parse(Panopticon.createProject(req.path)) 43 | if(res.status == "err") { 44 | console.exception(res.error); 45 | } 46 | break; 47 | } 48 | case "elf": { 49 | var res = JSON.parse(Panopticon.createProject(req.path)) 50 | if(res.status == "err") { 51 | console.exception(res.error); 52 | } 53 | break; 54 | } 55 | case "pe": { 56 | var res = JSON.parse(Panopticon.createProject(req.path)) 57 | if(res.status == "err") { 58 | console.exception(res.error); 59 | } 60 | break; 61 | } 62 | case "raw": { 63 | targetSelect.visible = true; 64 | break; 65 | } 66 | case "sandbox":{ 67 | // do nothing 68 | break; 69 | } 70 | case "avr": { 71 | var res = JSON.parse(Panopticon.createRawProject(req.path,"atmega88",0,-1)) 72 | if(res.status == "err") { 73 | console.exception(res.error); 74 | } 75 | break; 76 | } 77 | default: 78 | console.exception("Unknown request kind " + req.kind); 79 | } 80 | } 81 | 82 | Component { 83 | id: fileBrowser 84 | FileBrowser {} 85 | } 86 | 87 | Component { 88 | id: errorPopup 89 | ErrorPopup {} 90 | } 91 | 92 | property bool enabled: true 93 | property bool workspaceLoaded: false 94 | 95 | title: "Panopticon" 96 | height: 1000 97 | width: 1000 98 | visible: true 99 | 100 | menuBar: Ctrl.MenuBar { 101 | Ctrl.Menu { 102 | title: "Project" 103 | id: projectMenu 104 | 105 | Ctrl.MenuItem { 106 | text: action.text 107 | action: Open { 108 | window: mainWindow 109 | fileBrowser: fileBrowser; 110 | errorPopup: errorPopup; 111 | } 112 | } 113 | 114 | Ctrl.MenuItem { 115 | text: action.text 116 | action: SaveAs { 117 | window: mainWindow 118 | fileBrowser: fileBrowser; 119 | errorPopup: errorPopup; 120 | } 121 | } 122 | 123 | Ctrl.MenuSeparator {} 124 | 125 | Ctrl.MenuItem { 126 | text: action.text 127 | action: Quit { 128 | window: mainWindow 129 | errorPopup: errorPopup; 130 | } 131 | } 132 | } 133 | } 134 | 135 | Workspace { 136 | id: workspace 137 | visible: !targetSelect.visible 138 | anchors.fill: parent 139 | } 140 | 141 | Rectangle { 142 | id: targetSelect 143 | 144 | property var request: null 145 | 146 | anchors.fill: parent 147 | color: "#eeeeee" 148 | visible: false 149 | 150 | Item { 151 | anchors.horizontalCenter: parent.horizontalCenter 152 | y: 0.25 * parent.height 153 | width: childrenRect.width 154 | height: childrenRect.height 155 | 156 | Column { 157 | spacing: 30 158 | 159 | Row { 160 | anchors.horizontalCenter: parent.horizontalCenter 161 | spacing: 27 162 | Image { 163 | width: sourceSize.width 164 | height: sourceSize.height 165 | source: "icons/warning-icon.svg" 166 | fillMode: Image.Pad 167 | } 168 | 169 | Label { 170 | text: "Cannot recognize file type" 171 | font { 172 | pointSize: 28 173 | } 174 | color: "#555555" 175 | } 176 | } 177 | 178 | Rectangle { 179 | color: "#888888" 180 | width: 560 181 | height: 1 182 | } 183 | 184 | Column { 185 | anchors.horizontalCenter: parent.horizontalCenter 186 | spacing: 18 187 | 188 | Label { 189 | width: 500 190 | text: "Microcontroller to assume for analysis. This option defines what instructions are supported and the size of the Program Counter register." 191 | wrapMode: Text.WordWrap 192 | font { 193 | pointSize: 12 194 | } 195 | } 196 | 197 | Ctrl.ComboBox { 198 | id: targetCombobox 199 | model: targetModel 200 | width: 140 201 | 202 | ListModel { 203 | id: targetModel 204 | ListElement { 205 | text: "MOS 6502" 206 | ident: "mos6502" 207 | } 208 | ListElement { 209 | text: "ATmega103" 210 | ident: "atmega103" 211 | } 212 | ListElement { 213 | text: "ATmega16" 214 | ident: "atmega16" 215 | } 216 | ListElement { 217 | text: "ATmega8" 218 | ident: "atmega8" 219 | } 220 | ListElement { 221 | text: "ATmega88" 222 | ident: "atmega88" 223 | } 224 | } 225 | } 226 | } 227 | 228 | Ctrl.Button { 229 | anchors.right: parent.right 230 | text: "Apply" 231 | 232 | onClicked: { 233 | var tgt = targetModel.get(targetCombobox.currentIndex).ident; 234 | var res = JSON.parse(Panopticon.createRawProject(targetSelect.request.path,tgt,0,-1)) 235 | if(res.status == "ok") { 236 | targetSelect.visible = false; 237 | } else { 238 | console.exception(res.error); 239 | } 240 | } 241 | } 242 | } 243 | } 244 | } 245 | 246 | Component.onCompleted: { 247 | console.log(Panopticon.state); 248 | if(Panopticon.state == "NEW") { 249 | var res = JSON.parse(Panopticon.request()); 250 | 251 | if(res.status == "ok" && res.payload != null) { 252 | serveRequest(res.payload) 253 | } 254 | } 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /core/src/project.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2015 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | //! The root of a Panopticon session. 20 | //! 21 | //! Projects are a set of `Program`s, associated memory `Region`s and comments. 22 | 23 | 24 | use crate::{CallGraphRef, Function, Program, Region, Result, World}; 25 | use panopticon_graph_algos::GraphTrait; 26 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 27 | use flate2::Compression; 28 | use flate2::read::ZlibDecoder; 29 | use flate2::write::ZlibEncoder; 30 | use serde_cbor::de::Deserializer; 31 | use serde_cbor::ser::Serializer; 32 | use serde::{Deserialize, Serialize}; 33 | use std::collections::HashMap; 34 | use std::fs::File; 35 | use std::io::{Read, Write}; 36 | use std::path::Path; 37 | 38 | use uuid::Uuid; 39 | 40 | /// Complete Panopticon session 41 | #[derive(Serialize,Deserialize,Debug)] 42 | pub struct Project { 43 | /// Human-readable name 44 | pub name: String, 45 | /// Recognized code 46 | pub code: Vec, 47 | /// Memory regions 48 | pub data: World, 49 | /// Comments 50 | pub comments: HashMap<(String, u64), String>, 51 | /// Symbolic References (Imports) 52 | pub imports: HashMap, 53 | } 54 | 55 | impl Project { 56 | /// Returns a new `Project` named `s` from memory `Region` `r`. 57 | pub fn new(s: String, r: Region) -> Project { 58 | Project { 59 | name: s, 60 | code: Vec::new(), 61 | data: World::new(r), 62 | comments: HashMap::new(), 63 | imports: HashMap::new(), 64 | } 65 | } 66 | 67 | /// Returns this project's root Region 68 | pub fn region(&self) -> &Region { 69 | // this cannot fail because World::new guarantees that data.root = r 70 | self.data.dependencies.vertex_label(self.data.root).unwrap() 71 | } 72 | 73 | /// Reads a serialized project from disk. 74 | pub fn open(p: &Path) -> Result { 75 | let mut fd = match File::open(p) { 76 | Ok(fd) => fd, 77 | Err(e) => return Err(format!("failed to open file: {:?}", e).into()), 78 | }; 79 | let mut magic = [0u8; 10]; 80 | 81 | if fd.read(&mut magic)? == 10 && magic == *b"PANOPTICON" { 82 | let version = fd.read_u32::()?; 83 | 84 | if version == 0 { 85 | let mut z = ZlibDecoder::new(fd); 86 | let mut cbor = Deserializer::new(&mut z); 87 | let proj = Deserialize::deserialize(&mut cbor)?; 88 | Ok(proj) 89 | } else { 90 | Err("wrong version".into()) 91 | } 92 | } else { 93 | Err("wrong magic number".into()) 94 | } 95 | } 96 | 97 | /// Returns the program with UUID `uu` 98 | pub fn find_program_by_uuid(&self, uu: &Uuid) -> Option<&Program> { 99 | self.code.iter().find(|x| x.uuid == *uu) 100 | } 101 | 102 | /// Returns the program with UUID `uu` 103 | pub fn find_program_by_uuid_mut(&mut self, uu: &Uuid) -> Option<&mut Program> { 104 | self.code.iter_mut().find(|x| x.uuid == *uu) 105 | } 106 | 107 | /// Returns function and enclosing program with UUID `uu` 108 | pub fn find_function_by_uuid<'a>(&'a self, uu: &Uuid) -> Option<&'a Function> { 109 | for p in self.code.iter() { 110 | if let Some(f) = p.find_function_by_uuid(uu) { 111 | return Some(f); 112 | } 113 | } 114 | 115 | None 116 | } 117 | 118 | /// Returns function and enclosing program with UUID `uu` 119 | pub fn find_function_by_uuid_mut<'a>(&'a mut self, uu: &Uuid) -> Option<&'a mut Function> { 120 | for p in self.code.iter_mut() { 121 | if let Some(f) = p.find_function_by_uuid_mut(uu) { 122 | return Some(f); 123 | } 124 | } 125 | 126 | None 127 | } 128 | 129 | /// Returns function/reference and enclosing program with UUID `uu` 130 | pub fn find_call_target_by_uuid<'a>(&'a self, uu: &Uuid) -> Option<(CallGraphRef, &'a Program)> { 131 | for p in self.code.iter() { 132 | if let Some(ct) = p.find_call_target_by_uuid(uu) { 133 | return Some((ct, p)); 134 | } 135 | } 136 | 137 | None 138 | } 139 | 140 | /// Returns function/reference and enclosing program with UUID `uu` 141 | pub fn find_call_target_by_uuid_mut<'a>(&'a mut self, uu: &Uuid) -> Option<(CallGraphRef, &'a mut Program)> { 142 | for p in self.code.iter_mut() { 143 | if let Some(ct) = p.find_call_target_by_uuid(uu) { 144 | return Some((ct, p)); 145 | } 146 | } 147 | 148 | None 149 | } 150 | 151 | /// Serializes the project into the file at `p`. The format looks like this: 152 | /// [u8;10] magic = "PANOPTICON" 153 | /// u32 version = 0 154 | /// zlib compressed MsgPack 155 | pub fn snapshot(&self, p: &Path) -> Result<()> { 156 | let mut fd = File::create(p)?; 157 | 158 | fd.write(b"PANOPTICON")?; 159 | fd.write_u32::(0)?; 160 | 161 | let mut z = ZlibEncoder::new(fd, Compression::Default); 162 | let mut enc = Serializer::new(&mut z); 163 | 164 | match self.serialize(&mut enc) { 165 | Ok(()) => Ok(()), 166 | Err(e) => Err(format!("failed to write to save file: {}",e).into()), 167 | } 168 | } 169 | } 170 | 171 | #[cfg(test)] 172 | mod tests { 173 | use super::*; 174 | use crate::region::Region; 175 | 176 | #[test] 177 | fn new() { 178 | let p = Project::new( 179 | "test".to_string(), 180 | Region::undefined("base".to_string(), 128), 181 | ); 182 | 183 | assert_eq!(p.name, "test".to_string()); 184 | assert_eq!(p.code.len(), 0); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /glue/ext/lib/src/glue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Panopticon - A libre disassembler 3 | * Copyright (C) 2017 Panopticon authors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "glue.h" 29 | #include "qpanopticon.h" 30 | #include "qcontrolflowgraph.h" 31 | 32 | extern "C" void update_function_node(const char* uuid, uint32_t id, float x, float y, int8_t is_entry, const BasicBlockLine** lines) { 33 | QString uuid_str(uuid); 34 | std::lock_guard guard(QControlFlowGraph::allInstancesLock); 35 | 36 | for(auto cfg: QControlFlowGraph::allInstances) { 37 | QVector qobjs; 38 | size_t idx = 0; 39 | 40 | while(lines && lines[idx]) { 41 | const BasicBlockLine *line = lines[idx]; 42 | QBasicBlockLine* qobj = new QBasicBlockLine(*line); 43 | 44 | qobj->moveToThread(QGuiApplication::instance()->thread()); 45 | qobjs.append(qobj); 46 | ++idx; 47 | } 48 | 49 | if(!qobjs.empty()) { 50 | cfg->metaObject()->invokeMethod( 51 | cfg, 52 | "insertNode", 53 | Qt::QueuedConnection, 54 | Q_ARG(QString,uuid_str), 55 | Q_ARG(unsigned int,id), 56 | Q_ARG(float,x), 57 | Q_ARG(float,y), 58 | Q_ARG(bool,is_entry != 0), 59 | Q_ARG(QVector,qobjs)); 60 | } 61 | } 62 | } 63 | 64 | extern "C" void update_function_edges(const char* uuid, const uint32_t* ids, 65 | const char** labels,const char** kinds, 66 | const float* head_xs,const float* head_ys, 67 | const float* tail_xs,const float* tail_ys, 68 | const char* svg) { 69 | QString uuid_str(uuid); 70 | std::lock_guard guard(QControlFlowGraph::allInstancesLock); 71 | 72 | for(auto cfg: QControlFlowGraph::allInstances) { 73 | QVector heads; 74 | QVector tails; 75 | QVector label_vec; 76 | QVector kind_vec; 77 | QVector id_vec; 78 | size_t idx = 0; 79 | 80 | while(head_xs && head_ys && tail_xs && tail_ys && ids && labels && 81 | labels[idx] && kinds && kinds[idx]) 82 | { 83 | QPointF head(head_xs[idx],head_ys[idx]); 84 | QPointF tail(tail_xs[idx],tail_ys[idx]); 85 | QString label(labels[idx]); 86 | QString kind(kinds[idx]); 87 | unsigned int id = ids[idx]; 88 | 89 | heads.append(head); 90 | tails.append(tail); 91 | label_vec.append(label); 92 | kind_vec.append(kind); 93 | id_vec.append(id); 94 | 95 | ++idx; 96 | } 97 | 98 | if(!id_vec.empty()) { 99 | QSvgRenderer renderer; 100 | renderer.load(QByteArray(svg)); 101 | auto vp = renderer.viewBox(); 102 | QImage img(vp.width(),vp.height(),QImage::Format_ARGB32_Premultiplied); 103 | img.fill(Qt::transparent); 104 | QPainter painter(&img); 105 | renderer.render(&painter); 106 | 107 | cfg->metaObject()->invokeMethod( 108 | cfg, 109 | "insertEdges", 110 | Qt::QueuedConnection, 111 | Q_ARG(QString,uuid_str), 112 | Q_ARG(QVector,id_vec), 113 | Q_ARG(QVector,label_vec), 114 | Q_ARG(QVector,kind_vec), 115 | Q_ARG(QVector,heads), 116 | Q_ARG(QVector,tails), 117 | Q_ARG(QImage,img)); 118 | } 119 | } 120 | } 121 | 122 | extern "C" void update_sidebar_items(const SidebarItem** items) { 123 | size_t idx = 0; 124 | QPanopticon *panop = QPanopticon::staticInstance; 125 | if(!panop) return; 126 | 127 | QSidebar *sidebar = panop->getSidebar(); 128 | 129 | while(items && items[idx]) { 130 | const SidebarItem *item = items[idx]; 131 | QString title(item->title); 132 | QString subtitle(item->subtitle); 133 | QString uuid(item->uuid); 134 | 135 | sidebar->metaObject()->invokeMethod( 136 | sidebar, 137 | "insert", 138 | Qt::QueuedConnection, 139 | Q_ARG(QString,title), 140 | Q_ARG(QString,subtitle), 141 | Q_ARG(QString,uuid)); 142 | ++idx; 143 | } 144 | } 145 | 146 | extern "C" void update_undo_redo(int8_t undo, int8_t redo) { 147 | QPanopticon *panop = QPanopticon::staticInstance; 148 | 149 | if(panop) { 150 | panop->metaObject()->invokeMethod( 151 | panop, 152 | "updateUndoRedo", 153 | Qt::QueuedConnection, 154 | Q_ARG(bool,undo != 0), 155 | Q_ARG(bool,redo != 0)); 156 | } 157 | } 158 | 159 | extern "C" void update_current_session(const char* path) { 160 | QPanopticon *panop = QPanopticon::staticInstance; 161 | 162 | if(panop) { 163 | panop->metaObject()->invokeMethod( 164 | panop, 165 | "updateCurrentSession", 166 | Qt::QueuedConnection, 167 | Q_ARG(QString,QString(path))); 168 | } 169 | } 170 | 171 | extern "C" void update_layout_task(const char* task) { 172 | QPanopticon *panop = QPanopticon::staticInstance; 173 | 174 | if(panop) { 175 | panop->metaObject()->invokeMethod( 176 | panop, 177 | "updateLayoutTask", 178 | Qt::QueuedConnection, 179 | Q_ARG(QString,QString(task))); 180 | } 181 | } 182 | 183 | extern "C" void start_gui_loop(const char *dir, const char* f, const RecentSession** sess, 184 | GetFunctionFunc gf, SubscribeToFunc st, 185 | OpenProgramFunc op, SaveSessionFunc ss, 186 | CommentOnFunc co, RenameFunctionFunc rf, SetValueForFunc svf, 187 | UndoFunc u, RedoFunc r) { 188 | int argc = 1; 189 | char *argv[1] = { "Panopticon" }; 190 | 191 | // workaround for #246 192 | QGuiApplication::setDesktopSettingsAware(false); 193 | QGuiApplication app(argc,argv); 194 | 195 | QPanopticon::staticSubscribeTo = st; 196 | QPanopticon::staticGetFunction = gf; 197 | QPanopticon::staticOpenProgram = op; 198 | QPanopticon::staticSaveSession = ss; 199 | QPanopticon::staticCommentOn = co; 200 | QPanopticon::staticRenameFunction = rf; 201 | QPanopticon::staticSetValueFor = svf; 202 | QPanopticon::staticUndo = u; 203 | QPanopticon::staticRedo = r; 204 | QPanopticon::staticInitialFile = QString(f); 205 | 206 | for(size_t idx = 0; sess[idx]; ++idx) { 207 | QRecentSession *qobj = new QRecentSession(*sess[idx]); 208 | QPanopticon::staticRecentSessions.push_back(qobj); 209 | } 210 | 211 | qRegisterMetaType>(); 212 | qRegisterMetaType>(); 213 | qRegisterMetaType>(); 214 | qRegisterMetaType>(); 215 | qmlRegisterType("Panopticon", 1, 0, "ControlFlowGraph"); 216 | qmlRegisterSingletonType("Panopticon", 1, 0, "Panopticon", qpanopticon_provider); 217 | 218 | QQmlApplicationEngine engine; 219 | QString qmlDir(dir); 220 | 221 | engine.addImportPath(qmlDir); 222 | engine.load(qmlDir + QString("/Panopticon/Window.qml")); 223 | 224 | app.exec(); 225 | } 226 | --------------------------------------------------------------------------------