├── .gitignore ├── GUI_PROTO.png ├── LICENSE ├── README.md ├── lib └── dockfx-0.1-SNAPSHOT.jar ├── pom.xml ├── scripts ├── build.bat ├── build.sh ├── run.bat └── run.sh └── src ├── main ├── java │ ├── capstone │ │ ├── .gitignore │ │ ├── Arm.java │ │ ├── Arm64.java │ │ ├── Arm64_const.java │ │ ├── Arm_const.java │ │ ├── Capstone.java │ │ ├── Mips.java │ │ ├── Mips_const.java │ │ ├── Ppc.java │ │ ├── Ppc_const.java │ │ ├── Sparc.java │ │ ├── Sparc_const.java │ │ ├── Systemz.java │ │ ├── Sysz_const.java │ │ ├── X86.java │ │ ├── X86_const.java │ │ ├── Xcore.java │ │ └── Xcore_const.java │ └── redress │ │ ├── Main.java │ │ ├── abi │ │ ├── generic │ │ │ ├── AbstractABI.java │ │ │ ├── AbstractHeader.java │ │ │ ├── AbstractLoadCommand.java │ │ │ ├── AbstractSection.java │ │ │ ├── AbstractSegment.java │ │ │ ├── AbstractTable.java │ │ │ ├── AbstractText.java │ │ │ ├── IAddressable.java │ │ │ ├── IContainer.java │ │ │ ├── ILoadable.java │ │ │ ├── ILoader.java │ │ │ ├── IStructure.java │ │ │ ├── IVisitable.java │ │ │ ├── enums │ │ │ │ ├── ABIArch.java │ │ │ │ └── ABIType.java │ │ │ └── visitors │ │ │ │ ├── AbstractContainerVisitor.java │ │ │ │ ├── AbstractStructureVisitor.java │ │ │ │ ├── DataCollectVisitor.java │ │ │ │ ├── IVisitor.java │ │ │ │ └── LoadVisitor.java │ │ └── mach │ │ │ ├── Loader.java │ │ │ ├── Mach.java │ │ │ ├── MachO32.java │ │ │ ├── MachO64.java │ │ │ └── parse │ │ │ ├── Reader.java │ │ │ ├── x86 │ │ │ └── MachParser32.java │ │ │ └── x86_64 │ │ │ ├── MachParser64.java │ │ │ ├── ParseCommand64.java │ │ │ ├── ParseHeader64.java │ │ │ └── ParseSegSec64.java │ │ ├── gui │ │ ├── CodePaneController.java │ │ ├── LeftPane.java │ │ ├── MainController.java │ │ ├── MenuBarController.java │ │ └── RightPane.java │ │ ├── memory │ │ ├── address │ │ │ ├── AbstractAddress.java │ │ │ ├── Address16.java │ │ │ ├── Address32.java │ │ │ └── Address64.java │ │ └── data │ │ │ ├── AbstractData.java │ │ │ ├── DWord.java │ │ │ ├── QWord.java │ │ │ ├── Range.java │ │ │ ├── Text.java │ │ │ ├── Word.java │ │ │ └── view │ │ │ ├── Color.java │ │ │ └── TableSeperator.java │ │ └── util │ │ ├── B.java │ │ └── T.java └── resources │ ├── darwin │ └── libcapstone.dylib │ ├── linux-x86-64 │ └── libcapstone.so │ ├── redress │ └── gui │ │ ├── MainController.fxml │ │ └── mach_bin.out │ └── win32-x86-64 │ └── capstone.dll └── test └── java ├── capstone ├── Test.java ├── TestArm.java ├── TestArm64.java ├── TestMips.java ├── TestPpc.java ├── TestSparc.java ├── TestSystemz.java ├── TestX86.java └── TestXcore.java └── redress └── memory ├── TestAddress16.java ├── TestAddress32.java ├── TestAddress64.java ├── TestDWord.java ├── TestQWord.java └── TestWord.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.idea 3 | *.DS_Store 4 | target 5 | 6 | -------------------------------------------------------------------------------- /GUI_PROTO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/GUI_PROTO.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redress Disassembler 2 | Redress is a cross platform binary disassembler written in Java/JavaFX with [Capstone bindings](https://github.com/aquynh/capstone/tree/master/bindings/java) 3 | 4 | MachO 64bit ABI support is in the works. Future plans include ELF and PE ABIs as well as lldb integration. Disassembling compiled text is made possible by the [Capstone project](http://www.capstone-engine.org/) and its Java bindings. Redress also uses [DockFX](https://github.com/RobertBColton/DockFX) for its detachable pane system. 5 | 6 | This project is still under heavy development (just started on it). Redress is a project I started because I was bored and wanted to better understand reverse engineering. Feel free to fork and/or contribute (I do need someone on PE and ELF). 7 | 8 | Heres a screenshot of the working prototype. It is able to read and decompile basic Mach-O 64bit binaries 9 | 10 | ![alt text](GUI_PROTO.png "gui prototype") 11 | 12 | 13 | #####To Build via CLI: 14 | Linux/OSX: Install maven. Run the scripts/build.sh shell script 15 | Windows: Install maven. Run the scripts/build.bat batch file 16 | 17 | #####To Run via CLI: 18 | Linux/OSX: Build the project first. Run the scripts/run.sh shell script 19 | Windows: Build the project first. Run the scripts/run.bat batch file 20 | 21 | #####To Build via IDE: 22 | All: Import Redress as a maven project. Add lib/dockfx-0.1-SNAPSHOT.jar as a project dependency. 23 | 24 | 25 | -------------------------------------------------------------------------------- /lib/dockfx-0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/lib/dockfx-0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | Redress 8 | redress 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | org.apache.maven.plugins 15 | maven-compiler-plugin 16 | 3.5.1 17 | 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-jar-plugin 25 | 26 | 27 | 28 | true 29 | redress.Main 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-assembly-plugin 37 | 2.4.1 38 | 39 | 40 | 41 | jar-with-dependencies 42 | 43 | 44 | 45 | 46 | redress.Main 47 | 48 | 49 | 50 | 51 | 52 | 53 | make-assembly 54 | package 55 | 56 | single 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | net.java.dev.jna 67 | jna 68 | 4.2.1 69 | 70 | 71 | commons-io 72 | commons-io 73 | 2.4 74 | 75 | 76 | org.dockfx 77 | dockfx 78 | 0.1-SNAPSHOT 79 | 80 | 81 | -------------------------------------------------------------------------------- /scripts/build.bat: -------------------------------------------------------------------------------- 1 | cd .. & mvn install:install-file -Dfile=lib/dockfx-0.1-SNAPSHOT.jar -DgroupId=org.dockfx -DartifactId=dockfx -Dversion=0.1-SNAPSHOT -Dpackaging=jar & mvn package & pause 2 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd .. 3 | mvn install:install-file -Dfile=lib/dockfx-0.1-SNAPSHOT.jar -DgroupId=org.dockfx -DartifactId=dockfx -Dversion=0.1-SNAPSHOT -Dpackaging=jar 4 | mvn package 5 | -------------------------------------------------------------------------------- /scripts/run.bat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | java -jar ../target/redress-1.0-SNAPSHOT-jar-with-dependencies.jar & pause -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | java -jar ../target/redress-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /src/main/java/capstone/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/src/main/java/capstone/.gitignore -------------------------------------------------------------------------------- /src/main/java/capstone/Arm.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Arm_const.*; 13 | 14 | public class Arm { 15 | 16 | public static class MemType extends Structure { 17 | public int base; 18 | public int index; 19 | public int scale; 20 | public int disp; 21 | 22 | @Override 23 | public List getFieldOrder() { 24 | return Arrays.asList("base", "index", "scale", "disp"); 25 | } 26 | } 27 | 28 | public static class OpValue extends Union { 29 | public int reg; 30 | public int imm; 31 | public double fp; 32 | public MemType mem; 33 | public int setend; 34 | 35 | @Override 36 | public List getFieldOrder() { 37 | return Arrays.asList("reg", "imm", "fp", "mem", "setend"); 38 | } 39 | } 40 | 41 | public static class OpShift extends Structure { 42 | public int type; 43 | public int value; 44 | 45 | @Override 46 | public List getFieldOrder() { 47 | return Arrays.asList("type","value"); 48 | } 49 | } 50 | 51 | public static class Operand extends Structure { 52 | public int vector_index; 53 | public OpShift shift; 54 | public int type; 55 | public OpValue value; 56 | public boolean subtracted; 57 | 58 | public void read() { 59 | readField("vector_index"); 60 | readField("type"); 61 | if (type == ARM_OP_MEM) 62 | value.setType(MemType.class); 63 | if (type == ARM_OP_FP) 64 | value.setType(Double.TYPE); 65 | if (type == ARM_OP_PIMM || type == ARM_OP_IMM || type == ARM_OP_CIMM) 66 | value.setType(Integer.TYPE); 67 | if (type == ARM_OP_REG) 68 | value.setType(Integer.TYPE); 69 | if (type == ARM_OP_INVALID) 70 | return; 71 | readField("value"); 72 | readField("shift"); 73 | readField("subtracted"); 74 | } 75 | 76 | @Override 77 | public List getFieldOrder() { 78 | return Arrays.asList("vector_index", "shift", "type", "value", "subtracted"); 79 | } 80 | } 81 | 82 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 83 | public boolean usermode; 84 | public int vector_size; 85 | public int vector_data; 86 | public int cps_mode; 87 | public int cps_flag; 88 | public int cc; 89 | public byte update_flags; 90 | public byte writeback; 91 | public byte mem_barrier; 92 | public byte op_count; 93 | 94 | public Operand [] op; 95 | 96 | public UnionOpInfo() { 97 | op = new Operand[36]; 98 | } 99 | 100 | public void read() { 101 | readField("usermode"); 102 | readField("vector_size"); 103 | readField("vector_data"); 104 | readField("cps_mode"); 105 | readField("cps_flag"); 106 | readField("cc"); 107 | readField("update_flags"); 108 | readField("writeback"); 109 | readField("mem_barrier"); 110 | readField("op_count"); 111 | op = new Operand[op_count]; 112 | if (op_count != 0) 113 | readField("op"); 114 | } 115 | 116 | @Override 117 | public List getFieldOrder() { 118 | return Arrays.asList("usermode", "vector_size", "vector_data", 119 | "cps_mode", "cps_flag", "cc", "update_flags", "writeback", "mem_barrier", "op_count", "op"); 120 | } 121 | } 122 | 123 | public static class OpInfo extends Capstone.OpInfo { 124 | public boolean usermode; 125 | public int vectorSize; 126 | public int vectorData; 127 | public int cpsMode; 128 | public int cpsFlag; 129 | public int cc; 130 | public boolean updateFlags; 131 | public boolean writeback; 132 | public int memBarrier; 133 | public Operand [] op = null; 134 | 135 | public OpInfo(UnionOpInfo op_info) { 136 | usermode = op_info.usermode; 137 | vectorSize = op_info.vector_size; 138 | vectorData = op_info.vector_data; 139 | cpsMode = op_info.cps_mode; 140 | cpsFlag = op_info.cps_flag; 141 | cc = op_info.cc; 142 | updateFlags = (op_info.update_flags > 0); 143 | writeback = (op_info.writeback > 0); 144 | memBarrier = op_info.mem_barrier; 145 | op = op_info.op; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/capstone/Arm64.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Arm64_const.*; 13 | 14 | public class Arm64 { 15 | 16 | public static class MemType extends Structure { 17 | public int base; 18 | public int index; 19 | public int disp; 20 | 21 | @Override 22 | public List getFieldOrder() { 23 | return Arrays.asList("base", "index", "disp"); 24 | } 25 | } 26 | 27 | public static class OpValue extends Union { 28 | public int reg; 29 | public long imm; 30 | public double fp; 31 | public MemType mem; 32 | public int pstate; 33 | public int sys; 34 | public int prefetch; 35 | public int barrier; 36 | 37 | @Override 38 | public List getFieldOrder() { 39 | return Arrays.asList("reg", "imm", "fp", "mem", "pstate", "sys", "prefetch", "barrier"); 40 | } 41 | } 42 | 43 | public static class OpShift extends Structure { 44 | public int type; 45 | public int value; 46 | 47 | @Override 48 | public List getFieldOrder() { 49 | return Arrays.asList("type","value"); 50 | } 51 | } 52 | 53 | public static class Operand extends Structure { 54 | public int vector_index; 55 | public int vas; 56 | public int vess; 57 | public OpShift shift; 58 | public int ext; 59 | public int type; 60 | public OpValue value; 61 | 62 | public void read() { 63 | readField("type"); 64 | if (type == ARM64_OP_MEM) 65 | value.setType(MemType.class); 66 | if (type == ARM64_OP_FP) 67 | value.setType(Double.TYPE); 68 | if (type == ARM64_OP_IMM || type == ARM64_OP_CIMM || type == ARM64_OP_REG || type == ARM64_OP_REG_MRS || type == ARM64_OP_REG_MSR || type == ARM64_OP_PSTATE || type == ARM64_OP_SYS || type == ARM64_OP_PREFETCH || type == ARM64_OP_BARRIER) 69 | value.setType(Integer.TYPE); 70 | if (type == ARM64_OP_INVALID) 71 | return; 72 | readField("value"); 73 | readField("ext"); 74 | readField("shift"); 75 | readField("vess"); 76 | readField("vas"); 77 | readField("vector_index"); 78 | } 79 | 80 | @Override 81 | public List getFieldOrder() { 82 | return Arrays.asList("vector_index", "vas", "vess", "shift", "ext", "type", "value"); 83 | } 84 | } 85 | 86 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 87 | public int cc; 88 | public byte _update_flags; 89 | public byte _writeback; 90 | public byte op_count; 91 | 92 | public Operand [] op; 93 | 94 | public UnionOpInfo() { 95 | op = new Operand[8]; 96 | } 97 | 98 | public void read() { 99 | readField("cc"); 100 | readField("_update_flags"); 101 | readField("_writeback"); 102 | readField("op_count"); 103 | op = new Operand[op_count]; 104 | if (op_count != 0) 105 | readField("op"); 106 | } 107 | 108 | @Override 109 | public List getFieldOrder() { 110 | return Arrays.asList("cc", "_update_flags", "_writeback", "op_count", "op"); 111 | } 112 | } 113 | 114 | public static class OpInfo extends Capstone.OpInfo { 115 | public int cc; 116 | public boolean updateFlags; 117 | public boolean writeback; 118 | public Operand [] op = null; 119 | 120 | public OpInfo(UnionOpInfo op_info) { 121 | cc = op_info.cc; 122 | updateFlags = (op_info._update_flags > 0); 123 | writeback = (op_info._writeback > 0); 124 | op = op_info.op; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/capstone/Mips.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Mips_const.*; 13 | 14 | public class Mips { 15 | 16 | public static class MemType extends Structure { 17 | public int base; 18 | public long disp; 19 | 20 | @Override 21 | public List getFieldOrder() { 22 | return Arrays.asList("base", "disp"); 23 | } 24 | } 25 | 26 | public static class OpValue extends Union { 27 | public int reg; 28 | public long imm; 29 | public MemType mem; 30 | 31 | @Override 32 | public List getFieldOrder() { 33 | return Arrays.asList("reg", "imm", "mem"); 34 | } 35 | } 36 | 37 | public static class Operand extends Structure { 38 | public int type; 39 | public OpValue value; 40 | 41 | public void read() { 42 | super.read(); 43 | if (type == MIPS_OP_MEM) 44 | value.setType(MemType.class); 45 | if (type == MIPS_OP_IMM) 46 | value.setType(Long.TYPE); 47 | if (type == MIPS_OP_REG) 48 | value.setType(Integer.TYPE); 49 | if (type == MIPS_OP_INVALID) 50 | return; 51 | readField("value"); 52 | } 53 | @Override 54 | public List getFieldOrder() { 55 | return Arrays.asList("type", "value"); 56 | } 57 | } 58 | 59 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 60 | public byte op_count; 61 | public Operand [] op; 62 | 63 | public UnionOpInfo() { 64 | op = new Operand[8]; 65 | } 66 | 67 | public void read() { 68 | readField("op_count"); 69 | op = new Operand[op_count]; 70 | if (op_count != 0) 71 | readField("op"); 72 | } 73 | 74 | @Override 75 | public List getFieldOrder() { 76 | return Arrays.asList("op_count", "op"); 77 | } 78 | } 79 | 80 | public static class OpInfo extends Capstone.OpInfo { 81 | 82 | public Operand [] op; 83 | 84 | public OpInfo(UnionOpInfo e) { 85 | op = e.op; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/capstone/Ppc.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Ppc_const.*; 13 | 14 | public class Ppc { 15 | 16 | public static class MemType extends Structure { 17 | public int base; 18 | public int disp; 19 | 20 | @Override 21 | public List getFieldOrder() { 22 | return Arrays.asList("base", "disp"); 23 | } 24 | } 25 | 26 | public static class CrxType extends Structure { 27 | public int scale; 28 | public int reg; 29 | public int cond; 30 | 31 | @Override 32 | public List getFieldOrder() { 33 | return Arrays.asList("scale", "reg", "cond"); 34 | } 35 | } 36 | 37 | public static class OpValue extends Union { 38 | public int reg; 39 | public int imm; 40 | public MemType mem; 41 | public CrxType crx; 42 | } 43 | 44 | public static class Operand extends Structure { 45 | public int type; 46 | public OpValue value; 47 | 48 | public void read() { 49 | readField("type"); 50 | if (type == PPC_OP_MEM) 51 | value.setType(MemType.class); 52 | if (type == PPC_OP_CRX) 53 | value.setType(CrxType.class); 54 | if (type == PPC_OP_IMM || type == PPC_OP_REG) 55 | value.setType(Integer.TYPE); 56 | if (type == PPC_OP_INVALID) 57 | return; 58 | readField("value"); 59 | } 60 | 61 | @Override 62 | public List getFieldOrder() { 63 | return Arrays.asList("type", "value"); 64 | } 65 | } 66 | 67 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 68 | public int bc; 69 | public int bh; 70 | public byte update_cr0; 71 | public byte op_count; 72 | 73 | public Operand [] op; 74 | 75 | public UnionOpInfo() { 76 | op = new Operand[8]; 77 | } 78 | 79 | public void read() { 80 | readField("bc"); 81 | readField("bh"); 82 | readField("update_cr0"); 83 | readField("op_count"); 84 | op = new Operand[op_count]; 85 | if (op_count != 0) 86 | readField("op"); 87 | } 88 | 89 | @Override 90 | public List getFieldOrder() { 91 | return Arrays.asList("bc", "bh", "update_cr0", "op_count", "op"); 92 | } 93 | } 94 | 95 | public static class OpInfo extends Capstone.OpInfo { 96 | public int bc; 97 | public int bh; 98 | public boolean updateCr0; 99 | 100 | public Operand [] op; 101 | 102 | public OpInfo(UnionOpInfo op_info) { 103 | bc = op_info.bc; 104 | bh = op_info.bh; 105 | updateCr0 = (op_info.update_cr0 > 0); 106 | op = op_info.op; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/capstone/Sparc.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Sparc_const.*; 13 | 14 | public class Sparc { 15 | 16 | public static class MemType extends Structure { 17 | public byte base; 18 | public byte index; 19 | public int disp; 20 | 21 | @Override 22 | public List getFieldOrder() { 23 | return Arrays.asList("base", "index", "disp"); 24 | } 25 | } 26 | 27 | public static class OpValue extends Union { 28 | public int reg; 29 | public int imm; 30 | public MemType mem; 31 | } 32 | 33 | public static class Operand extends Structure { 34 | public int type; 35 | public OpValue value; 36 | 37 | public void read() { 38 | readField("type"); 39 | if (type == SPARC_OP_MEM) 40 | value.setType(MemType.class); 41 | if (type == SPARC_OP_IMM || type == SPARC_OP_REG) 42 | value.setType(Integer.TYPE); 43 | if (type == SPARC_OP_INVALID) 44 | return; 45 | readField("value"); 46 | } 47 | 48 | @Override 49 | public List getFieldOrder() { 50 | return Arrays.asList("type", "value"); 51 | } 52 | } 53 | 54 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 55 | public int cc; 56 | public int hint; 57 | public byte op_count; 58 | 59 | public Operand [] op; 60 | 61 | public UnionOpInfo() { 62 | op = new Operand[4]; 63 | } 64 | 65 | public void read() { 66 | readField("cc"); 67 | readField("hint"); 68 | readField("op_count"); 69 | op = new Operand[op_count]; 70 | if (op_count != 0) 71 | readField("op"); 72 | } 73 | 74 | @Override 75 | public List getFieldOrder() { 76 | return Arrays.asList("cc", "hint", "op_count", "op"); 77 | } 78 | } 79 | 80 | public static class OpInfo extends Capstone.OpInfo { 81 | public int cc; 82 | public int hint; 83 | 84 | public Operand [] op; 85 | 86 | public OpInfo(UnionOpInfo op_info) { 87 | cc = op_info.cc; 88 | hint = op_info.hint; 89 | op = op_info.op; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/capstone/Systemz.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.Sysz_const.*; 13 | 14 | public class Systemz { 15 | 16 | public static class MemType extends Structure { 17 | public byte base; 18 | public byte index; 19 | public long length; 20 | public long disp; 21 | 22 | @Override 23 | public List getFieldOrder() { 24 | return Arrays.asList("base", "index", "length", "disp"); 25 | } 26 | } 27 | 28 | public static class OpValue extends Union { 29 | public int reg; 30 | public long imm; 31 | public MemType mem; 32 | } 33 | 34 | public static class Operand extends Structure { 35 | public int type; 36 | public OpValue value; 37 | 38 | public void read() { 39 | readField("type"); 40 | if (type == SYSZ_OP_MEM) 41 | value.setType(MemType.class); 42 | if (type == SYSZ_OP_IMM) 43 | value.setType(Long.TYPE); 44 | if (type == SYSZ_OP_REG || type == SYSZ_OP_ACREG) 45 | value.setType(Integer.TYPE); 46 | if (type == SYSZ_OP_INVALID) 47 | return; 48 | readField("value"); 49 | } 50 | 51 | @Override 52 | public List getFieldOrder() { 53 | return Arrays.asList("type", "value"); 54 | } 55 | } 56 | 57 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 58 | public int cc; 59 | public byte op_count; 60 | 61 | public Operand [] op; 62 | 63 | public UnionOpInfo() { 64 | op = new Operand[6]; 65 | } 66 | 67 | public void read() { 68 | readField("cc"); 69 | readField("op_count"); 70 | op = new Operand[op_count]; 71 | if (op_count != 0) 72 | readField("op"); 73 | } 74 | 75 | @Override 76 | public List getFieldOrder() { 77 | return Arrays.asList("cc", "op_count", "op"); 78 | } 79 | } 80 | 81 | public static class OpInfo extends Capstone.OpInfo { 82 | public int cc; 83 | 84 | public Operand [] op; 85 | 86 | public OpInfo(UnionOpInfo op_info) { 87 | cc = op_info.cc; 88 | op = op_info.op; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/capstone/X86.java: -------------------------------------------------------------------------------- 1 | // Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | package capstone; 5 | 6 | import com.sun.jna.Structure; 7 | import com.sun.jna.Union; 8 | 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | import static capstone.X86_const.*; 13 | 14 | public class X86 { 15 | 16 | public static class MemType extends Structure { 17 | public int segment; 18 | public int base; 19 | public int index; 20 | public int scale; 21 | public long disp; 22 | 23 | @Override 24 | public List getFieldOrder() { 25 | return Arrays.asList("segment", "base", "index", "scale", "disp"); 26 | } 27 | } 28 | 29 | public static class OpValue extends Union { 30 | public int reg; 31 | public long imm; 32 | public double fp; 33 | public MemType mem; 34 | 35 | @Override 36 | public List getFieldOrder() { 37 | return Arrays.asList("reg", "imm", "fp", "mem"); 38 | } 39 | } 40 | 41 | public static class Operand extends Structure { 42 | public int type; 43 | public OpValue value; 44 | public byte size; 45 | public int avx_bcast; 46 | public boolean avx_zero_opmask; 47 | 48 | public void read() { 49 | super.read(); 50 | if (type == X86_OP_MEM) 51 | value.setType(MemType.class); 52 | if (type == X86_OP_FP) 53 | value.setType(Double.TYPE); 54 | if (type == X86_OP_IMM) 55 | value.setType(Long.TYPE); 56 | if (type == X86_OP_REG) 57 | value.setType(Integer.TYPE); 58 | if (type == X86_OP_INVALID) 59 | return; 60 | readField("value"); 61 | } 62 | 63 | @Override 64 | public List getFieldOrder() { 65 | return Arrays.asList("type", "value", "size", "avx_bcast", "avx_zero_opmask"); 66 | } 67 | } 68 | 69 | public static class UnionOpInfo extends Capstone.UnionOpInfo { 70 | public byte [] prefix; 71 | public byte [] opcode; 72 | public byte rex; 73 | public byte addr_size; 74 | public byte modrm; 75 | public byte sib; 76 | public int disp; 77 | public int sib_index; 78 | public byte sib_scale; 79 | public int sib_base; 80 | public int sse_cc; 81 | public int avx_cc; 82 | public byte avx_sae; 83 | public int avx_rm; 84 | 85 | public byte op_count; 86 | 87 | public Operand [] op; 88 | 89 | public UnionOpInfo() { 90 | op = new Operand[8]; 91 | opcode = new byte[4]; 92 | prefix = new byte[4]; 93 | } 94 | 95 | @Override 96 | public List getFieldOrder() { 97 | return Arrays.asList("prefix", "opcode", "rex", "addr_size", 98 | "modrm", "sib", "disp", "sib_index", "sib_scale", "sib_base", "sse_cc", "avx_cc", "avx_sae", "avx_rm", "op_count", "op"); 99 | } 100 | } 101 | 102 | public static class OpInfo extends Capstone.OpInfo { 103 | public byte [] prefix; 104 | public byte [] opcode; 105 | public byte opSize; 106 | public byte rex; 107 | public byte addrSize; 108 | public byte dispSize; 109 | public byte immSize; 110 | public byte modrm; 111 | public byte sib; 112 | public int disp; 113 | public int sibIndex; 114 | public byte sibScale; 115 | public int sibBase; 116 | public int sseCC; 117 | public int avxCC; 118 | public boolean avxSae; 119 | public int avxRm; 120 | 121 | public Operand[] op; 122 | 123 | public OpInfo(UnionOpInfo e) { 124 | prefix = e.prefix; 125 | opcode = e.opcode; 126 | rex = e.rex; 127 | addrSize = e.addr_size; 128 | modrm = e.modrm; 129 | sib = e.sib; 130 | disp = e.disp; 131 | sibIndex = e.sib_index; 132 | sibScale = e.sib_scale; 133 | sibBase = e.sib_base; 134 | sseCC = e.sse_cc; 135 | avxCC = e.avx_cc; 136 | avxSae = e.avx_sae > 0; 137 | avxRm = e.avx_rm; 138 | op = new Operand[e.op_count]; 139 | for (int i=0; i children = new LinkedList<>(); 26 | protected final IStructure parent = null; 27 | protected AbstractAddress beginAddress; 28 | protected AbstractAddress endAddress; 29 | protected final HashSet comment = new HashSet<>(); 30 | public byte[] getRaw(){return raw;} 31 | 32 | public AbstractSegment getSegment(String name){ 33 | for(IStructure s : getChildren()){ 34 | if(s instanceof AbstractSegment && ((AbstractSegment) s).getName().equals(name)){ 35 | return (AbstractSegment)s; 36 | } 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | public int compareTo(IAddressable o) { 43 | if(o == null) 44 | return 0; 45 | 46 | return this.beginAddress.compareTo(o.getBeginAddress()); 47 | } 48 | 49 | @Override 50 | public void accept(AbstractStructureVisitor visitor) { 51 | if(visitor.preVisit()) 52 | visitor.visit(this); 53 | visitor.postVisit(); 54 | for(IStructure child : getChildren()){ 55 | child.accept(visitor); 56 | } 57 | } 58 | 59 | @Override 60 | public IStructure getParent() { 61 | return parent; 62 | } 63 | 64 | @Override 65 | public LinkedList getChildren() { 66 | return children; 67 | } 68 | 69 | @Override 70 | public AbstractAddress getBeginAddress() { 71 | return beginAddress; 72 | } 73 | 74 | @Override 75 | public AbstractAddress getEndAddress() { 76 | return endAddress; 77 | } 78 | 79 | @Override 80 | public void setBeginAddress(AbstractAddress in){ 81 | this.beginAddress = in; 82 | } 83 | 84 | @Override 85 | public void setEndAddress(AbstractAddress in){ 86 | this.endAddress = in; 87 | } 88 | 89 | @Override 90 | public void addComments(String... comment) { 91 | for(String s:comment) 92 | this.comment.add(s); 93 | } 94 | 95 | @Override 96 | public HashSet getComments() { 97 | return comment; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractHeader.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.AbstractStructureVisitor; 4 | import redress.memory.address.AbstractAddress; 5 | 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by jamesrichardson on 2/23/16. 11 | */ 12 | public abstract class AbstractHeader implements IStructure, ILoadable { 13 | protected final LinkedList children = new LinkedList<>(); 14 | protected final IStructure parent; 15 | protected AbstractAddress beginAddress; 16 | protected AbstractAddress endAddress; 17 | protected final HashSet comment = new HashSet<>(); 18 | protected ILoader load; 19 | 20 | protected AbstractHeader(IStructure parent) { 21 | this.parent = parent; 22 | } 23 | 24 | @Override 25 | public void accept(AbstractStructureVisitor visitor) { 26 | if(visitor.preVisit()) 27 | visitor.visit(this); 28 | visitor.postVisit(); 29 | for(IStructure child : getChildren()){ 30 | child.accept(visitor); 31 | } 32 | } 33 | 34 | @Override 35 | public void setLoader(ILoader loader){ 36 | this.load = loader; 37 | } 38 | 39 | @Override 40 | public ILoader getLoader(){ 41 | return this.load; 42 | } 43 | 44 | @Override 45 | public int compareTo(IAddressable o) { 46 | if(o == null) 47 | return 0; 48 | 49 | return this.beginAddress.compareTo(o.getBeginAddress()); 50 | } 51 | 52 | @Override 53 | public IStructure getParent() { 54 | return parent; 55 | } 56 | 57 | @Override 58 | public LinkedList getChildren() { 59 | return children; 60 | } 61 | 62 | @Override 63 | public AbstractAddress getBeginAddress() { 64 | return beginAddress; 65 | } 66 | 67 | @Override 68 | public AbstractAddress getEndAddress() { 69 | return endAddress; 70 | } 71 | 72 | @Override 73 | public void setBeginAddress(AbstractAddress in){ 74 | this.beginAddress = in; 75 | } 76 | 77 | @Override 78 | public void setEndAddress(AbstractAddress in){ 79 | this.endAddress = in; 80 | } 81 | 82 | @Override 83 | public void addComments(String... comment) { 84 | for(String s:comment) 85 | this.comment.add(s); 86 | } 87 | 88 | @Override 89 | public HashSet getComments() { 90 | return comment; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractLoadCommand.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | 4 | import redress.abi.generic.visitors.AbstractStructureVisitor; 5 | import redress.memory.address.AbstractAddress; 6 | 7 | import java.util.HashSet; 8 | import java.util.LinkedList; 9 | 10 | /** 11 | * Created by jamesrichardson on 2/23/16. 12 | */ 13 | public abstract class AbstractLoadCommand implements IStructure, ILoadable { 14 | 15 | protected final LinkedList children = new LinkedList<>(); 16 | protected final IStructure parent; 17 | protected AbstractAddress beginAddress; 18 | protected AbstractAddress endAddress; 19 | protected final HashSet comment = new HashSet<>(); 20 | protected ILoader load; 21 | 22 | protected AbstractLoadCommand(IStructure parent) { 23 | this.parent = parent; 24 | } 25 | 26 | @Override 27 | public void accept(AbstractStructureVisitor visitor) { 28 | if(visitor.preVisit()) 29 | visitor.visit(this); 30 | visitor.postVisit(); 31 | for(IStructure child : getChildren()){ 32 | child.accept(visitor); 33 | } 34 | } 35 | 36 | @Override 37 | public void setLoader(ILoader loader){ 38 | this.load = loader; 39 | } 40 | 41 | @Override 42 | public ILoader getLoader(){ 43 | return this.load; 44 | } 45 | 46 | @Override 47 | public int compareTo(IAddressable o) { 48 | if(o == null) 49 | return 0; 50 | 51 | return this.beginAddress.compareTo(o.getBeginAddress()); 52 | } 53 | 54 | @Override 55 | public IStructure getParent() { 56 | return parent; 57 | } 58 | 59 | @Override 60 | public LinkedList getChildren() { 61 | return children; 62 | } 63 | 64 | @Override 65 | public AbstractAddress getBeginAddress() { 66 | return beginAddress; 67 | } 68 | 69 | @Override 70 | public AbstractAddress getEndAddress() { 71 | return endAddress; 72 | } 73 | 74 | @Override 75 | public void setBeginAddress(AbstractAddress in){ 76 | this.beginAddress = in; 77 | } 78 | 79 | @Override 80 | public void setEndAddress(AbstractAddress in){ 81 | this.endAddress = in; 82 | } 83 | 84 | @Override 85 | public void addComments(String... comment){ 86 | for(String s : comment) 87 | this.comment.add(s); 88 | } 89 | 90 | @Override 91 | public HashSet getComments(){ 92 | return comment; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractSection.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.AbstractStructureVisitor; 4 | import redress.memory.address.AbstractAddress; 5 | 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by jamesrichardson on 2/23/16. 11 | */ 12 | public abstract class AbstractSection implements IStructure, ILoadable { 13 | 14 | protected final LinkedList children = new LinkedList<>(); 15 | protected final IStructure parent; 16 | protected AbstractAddress beginAddress; 17 | protected AbstractAddress endAddress; 18 | protected String name = ""; 19 | protected final HashSet comment = new HashSet<>(); 20 | protected ILoader load; 21 | 22 | protected AbstractSection(IStructure parent) { 23 | this.parent = parent; 24 | } 25 | 26 | public String getName(){return this.name;} 27 | 28 | public void setName(String name){this.name=name;} 29 | 30 | @Override 31 | public void accept(AbstractStructureVisitor visitor) { 32 | if(visitor.preVisit()) 33 | visitor.visit(this); 34 | visitor.postVisit(); 35 | for(IStructure child : getChildren()){ 36 | child.accept(visitor); 37 | } 38 | } 39 | 40 | @Override 41 | public void setLoader(ILoader loader){ 42 | this.load = loader; 43 | } 44 | 45 | @Override 46 | public ILoader getLoader(){ 47 | return this.load; 48 | } 49 | 50 | @Override 51 | public int compareTo(IAddressable o) { 52 | if(o == null) 53 | return 0; 54 | 55 | return this.beginAddress.compareTo(o.getBeginAddress()); 56 | } 57 | 58 | @Override 59 | public IStructure getParent() { 60 | return parent; 61 | } 62 | 63 | @Override 64 | public LinkedList getChildren() { 65 | return children; 66 | } 67 | 68 | @Override 69 | public AbstractAddress getBeginAddress() { 70 | return beginAddress; 71 | } 72 | 73 | @Override 74 | public AbstractAddress getEndAddress() { 75 | return endAddress; 76 | } 77 | 78 | @Override 79 | public void setBeginAddress(AbstractAddress in){ 80 | this.beginAddress = in; 81 | } 82 | 83 | @Override 84 | public void setEndAddress(AbstractAddress in){ 85 | this.endAddress = in; 86 | } 87 | 88 | @Override 89 | public void addComments(String... comment){ 90 | for(String s : comment) 91 | this.comment.add(s); 92 | } 93 | 94 | @Override 95 | public HashSet getComments(){ 96 | return comment; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractSegment.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | 4 | import redress.abi.generic.visitors.AbstractStructureVisitor; 5 | import redress.memory.address.AbstractAddress; 6 | 7 | import java.util.HashSet; 8 | import java.util.LinkedList; 9 | 10 | /** 11 | * Created by jamesrichardson on 2/23/16. 12 | */ 13 | public abstract class AbstractSegment implements IStructure, ILoadable{ 14 | 15 | protected final LinkedList children = new LinkedList<>(); 16 | protected final IStructure parent; 17 | protected AbstractAddress beginAddress; 18 | protected AbstractAddress endAddress; 19 | protected String name = ""; 20 | protected final HashSet comment = new HashSet<>(); 21 | protected ILoader load; 22 | 23 | protected AbstractSegment(IStructure parent) { 24 | this.parent = parent; 25 | } 26 | 27 | public String getName(){return this.name;} 28 | 29 | public void setName(String name){this.name=name;} 30 | 31 | @Override 32 | public void accept(AbstractStructureVisitor visitor) { 33 | if(visitor.preVisit()) 34 | visitor.visit(this); 35 | visitor.postVisit(); 36 | for(IStructure child : getChildren()){ 37 | child.accept(visitor); 38 | } 39 | 40 | } 41 | 42 | @Override 43 | public void setLoader(ILoader loader){ 44 | this.load = loader; 45 | } 46 | 47 | @Override 48 | public ILoader getLoader(){ 49 | return this.load; 50 | } 51 | 52 | @Override 53 | public IStructure getParent() { 54 | return parent; 55 | } 56 | 57 | @Override 58 | public LinkedList getChildren() { 59 | return children; 60 | } 61 | 62 | @Override 63 | public LinkedList getStructureData() { 64 | return null; 65 | } 66 | 67 | @Override 68 | public AbstractAddress getBeginAddress() { 69 | return beginAddress; 70 | } 71 | 72 | @Override 73 | public AbstractAddress getEndAddress() { 74 | return endAddress; 75 | } 76 | 77 | @Override 78 | public void setBeginAddress(AbstractAddress in){ 79 | this.beginAddress = in; 80 | } 81 | 82 | @Override 83 | public void setEndAddress(AbstractAddress in){ 84 | this.endAddress = in; 85 | } 86 | 87 | @Override 88 | public void addComments(String... comment){ 89 | for(String s : comment) 90 | this.comment.add(s); 91 | } 92 | 93 | @Override 94 | public HashSet getComments(){ 95 | return comment; 96 | } 97 | 98 | @Override 99 | public int compareTo(IAddressable o) { 100 | if(o == null) 101 | return 0; 102 | 103 | return this.beginAddress.compareTo(o.getBeginAddress()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractTable.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.AbstractStructureVisitor; 4 | import redress.memory.address.AbstractAddress; 5 | 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by jamesrichardson on 2/23/16. 11 | */ 12 | public abstract class AbstractTable implements IStructure { 13 | 14 | protected final LinkedList children = new LinkedList<>(); 15 | protected final IStructure parent; 16 | protected AbstractAddress beginAddress; 17 | protected AbstractAddress endAddress; 18 | protected final HashSet comment = new HashSet<>(); 19 | protected byte[] container; 20 | 21 | protected AbstractTable(IStructure parent) { 22 | this.parent = parent; 23 | 24 | } 25 | 26 | public void setContiner(byte[] in){ 27 | this.container = in; 28 | } 29 | 30 | @Override 31 | public void accept(AbstractStructureVisitor visitor) { 32 | if(visitor.preVisit()) 33 | visitor.visit(this); 34 | visitor.postVisit(); 35 | for(IStructure child : getChildren()){ 36 | child.accept(visitor); 37 | } 38 | } 39 | 40 | @Override 41 | public IStructure getParent() { 42 | return parent; 43 | } 44 | 45 | @Override 46 | public LinkedList getChildren() { 47 | return children; 48 | } 49 | 50 | @Override 51 | public AbstractAddress getBeginAddress() { 52 | return beginAddress; 53 | } 54 | 55 | @Override 56 | public AbstractAddress getEndAddress() { 57 | return endAddress; 58 | } 59 | 60 | @Override 61 | public void setBeginAddress(AbstractAddress in){ 62 | this.beginAddress = in; 63 | } 64 | 65 | @Override 66 | public void setEndAddress(AbstractAddress in){ 67 | this.endAddress = in; 68 | } 69 | 70 | @Override 71 | public void addComments(String... comment){ 72 | for(String s : comment) 73 | this.comment.add(s); 74 | } 75 | 76 | @Override 77 | public HashSet getComments(){ 78 | return comment; 79 | } 80 | 81 | @Override 82 | public int compareTo(IAddressable o) { 83 | if(o == null) 84 | return 0; 85 | 86 | return this.beginAddress.compareTo(o.getBeginAddress()); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/AbstractText.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import capstone.Capstone; 4 | import redress.abi.generic.visitors.AbstractContainerVisitor; 5 | import redress.abi.generic.visitors.AbstractStructureVisitor; 6 | import redress.memory.address.AbstractAddress; 7 | import redress.memory.data.AbstractData; 8 | import redress.memory.data.QWord; 9 | import redress.util.B; 10 | 11 | import java.nio.ByteOrder; 12 | import java.util.HashSet; 13 | import java.util.LinkedList; 14 | 15 | /** 16 | * Created by jamesrichardson on 2/23/16. 17 | */ 18 | public abstract class AbstractText implements IContainer { 19 | 20 | protected final LinkedList children = new LinkedList<>(); 21 | protected final IStructure parent; 22 | protected IContainer previousSibling; 23 | protected IContainer nextSibling; 24 | protected AbstractAddress beginAddress; 25 | protected AbstractAddress endAddress; 26 | protected final HashSet comment = new HashSet<>(); 27 | protected final Capstone.CsInsn instruction; 28 | protected byte[] container; 29 | protected ByteOrder order; 30 | protected final String instructionStringValue; 31 | protected String segment = ""; 32 | protected String section = ""; 33 | 34 | public AbstractText(IStructure parent,AbstractAddress begin,AbstractAddress end,byte[] content,Capstone.CsInsn ins,String builtInstruction) { 35 | this.parent = parent; 36 | this.instruction = ins; 37 | this.beginAddress = begin; 38 | this.endAddress = end; 39 | this.container = new byte[content.length]; 40 | for(int i=0;i getChildren() { 134 | return children; 135 | } 136 | 137 | public AbstractAddress getBeginAddress() { 138 | return beginAddress; 139 | } 140 | 141 | public AbstractAddress getEndAddress() { 142 | return endAddress; 143 | } 144 | 145 | public void setBeginAddress(AbstractAddress in){ 146 | this.beginAddress = in; 147 | } 148 | 149 | public void setEndAddress(AbstractAddress in){ 150 | this.endAddress = in; 151 | } 152 | 153 | public void addComments(String... comment){ 154 | for(String s : comment) 155 | this.comment.add(s); 156 | } 157 | 158 | public HashSet getComments(){ 159 | return comment; 160 | } 161 | 162 | public int compareTo(IAddressable o) { 163 | if(o == null) 164 | return 0; 165 | 166 | return this.beginAddress.compareTo(o.getBeginAddress()); 167 | } 168 | 169 | @Override 170 | public String toString(){ 171 | return this.instructionStringValue; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/IAddressable.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.memory.address.AbstractAddress; 4 | 5 | import java.util.HashSet; 6 | 7 | /** 8 | * Created by jamesrichardson on 2/11/16. 9 | */ 10 | public interface IAddressable extends Comparable{ 11 | public AbstractAddress getBeginAddress(); 12 | public AbstractAddress getEndAddress(); 13 | 14 | public void setBeginAddress(AbstractAddress in); 15 | public void setEndAddress(AbstractAddress in); 16 | 17 | public void addComments(String... comment); 18 | public HashSet getComments(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/IContainer.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.AbstractContainerVisitor; 4 | 5 | import java.nio.ByteOrder; 6 | 7 | /** 8 | * Created by jamesrichardson on 2/23/16. 9 | */ 10 | public interface IContainer extends IVisitable { 11 | public byte[] getContainer(); 12 | public ByteOrder getByteOrder(); 13 | 14 | public IContainer getNextSibling(); 15 | public IContainer getPreviousSibling(); 16 | public IStructure getParent(); 17 | 18 | public IContainer flipByteOrder(); 19 | public IContainer clone(); 20 | 21 | public void add(IContainer i); 22 | public void add(int i); 23 | 24 | public void subtract(IContainer i); 25 | public void subtract(int i); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/ILoadable.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | 4 | /** 5 | * Created by jamesrichardson on 2/23/16. 6 | */ 7 | public interface ILoadable{ 8 | public void setLoader(ILoader loader); 9 | public ILoader getLoader(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/ILoader.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | 4 | import java.util.LinkedList; 5 | 6 | /** 7 | * Created by jamesrichardson on 2/23/16. 8 | */ 9 | public interface ILoader { 10 | public LinkedList load(AbstractABI in); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/IStructure.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.AbstractStructureVisitor; 4 | 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * Created by jamesrichardson on 2/10/16. 9 | * 10 | * This is a super class for all data structures in ABIs 11 | * eg. Segments, Sections, Versions, Load Commands, etc.. 12 | * See redress.abi.mach.Loader 13 | * 14 | */ 15 | public interface IStructure extends IAddressable, IVisitable { 16 | public IStructure getParent(); 17 | public LinkedList getChildren(); 18 | public LinkedList getStructureData(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/IVisitable.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic; 2 | 3 | import redress.abi.generic.visitors.IVisitor; 4 | 5 | /** 6 | * Created by jamesrichardson on 2/24/16. 7 | */ 8 | public interface IVisitable { 9 | 10 | public void accept(T visitor); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/enums/ABIArch.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.enums; 2 | 3 | /** 4 | * Created by jamesrichardson on 2/19/16. 5 | */ 6 | public enum ABIArch { 7 | ARM, 8 | ARM64, 9 | MIPS, 10 | PPC, 11 | SPARC, 12 | SYSZ, 13 | X86, 14 | XCORE 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/enums/ABIType.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.enums; 2 | 3 | /** 4 | * Created by jamesrichardson on 2/10/16. 5 | */ 6 | public enum ABIType { 7 | MACH_64, 8 | MACH_32, 9 | ELF_32, 10 | ELF_64, 11 | PE_32, 12 | PE_64 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/visitors/AbstractContainerVisitor.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.visitors; 2 | 3 | import redress.abi.mach.Loader; 4 | import redress.memory.data.*; 5 | 6 | /** 7 | * Created by jamesrichardson on 3/3/16. 8 | */ 9 | public abstract class AbstractContainerVisitor implements IVisitor{ 10 | public boolean preVisit(){return true;} 11 | public void postVisit(){} 12 | public void visit(Word in){} 13 | public void visit(DWord in){} 14 | public void visit(QWord in){} 15 | public void visit(Text in){} 16 | public void visit(Range in){} 17 | public void visit(Loader.char16 in){} 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/visitors/AbstractStructureVisitor.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.visitors; 2 | 3 | import redress.abi.generic.*; 4 | 5 | /** 6 | * Created by jamesrichardson on 2/24/16. 7 | */ 8 | public abstract class AbstractStructureVisitor implements IVisitor{ 9 | 10 | public boolean preVisit(){return true;} 11 | public void postVisit(){} 12 | public void visit(AbstractSegment in){} 13 | public void visit(AbstractSection in){} 14 | public void visit(AbstractLoadCommand in){} 15 | public void visit(AbstractHeader in){} 16 | public void visit(AbstractABI in){} 17 | public void visit(AbstractText in){} 18 | public void visit(AbstractTable in){} 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/visitors/DataCollectVisitor.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.visitors; 2 | 3 | import redress.abi.generic.*; 4 | 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * Created by jamesrichardson on 2/24/16. 9 | */ 10 | public class DataCollectVisitor extends AbstractStructureVisitor { 11 | private final LinkedList allData = new LinkedList<>(); 12 | 13 | @Override 14 | public boolean preVisit(){ 15 | return true; 16 | } 17 | 18 | @Override 19 | public void postVisit() { 20 | 21 | } 22 | 23 | @Override 24 | public void visit(AbstractSegment in){ 25 | if(in.getStructureData() != null) { 26 | allData.addAll(in.getStructureData()); 27 | } 28 | } 29 | @Override 30 | public void visit(AbstractSection in){ 31 | if(in.getStructureData() != null) { 32 | allData.addAll(in.getStructureData()); 33 | } 34 | } 35 | @Override 36 | public void visit(AbstractLoadCommand in){ 37 | if(in.getStructureData() != null) { 38 | allData.addAll(in.getStructureData()); 39 | } 40 | } 41 | @Override 42 | public void visit(AbstractHeader in){ 43 | if(in.getStructureData() != null) { 44 | allData.addAll(in.getStructureData()); 45 | } 46 | } 47 | @Override 48 | public void visit(AbstractABI in){ 49 | if(in.getStructureData() != null) { 50 | allData.addAll(in.getStructureData()); 51 | } 52 | } 53 | 54 | @Override 55 | public void visit(AbstractTable in){ 56 | if(in.getStructureData() != null) { 57 | allData.addAll(in.getStructureData()); 58 | } 59 | } 60 | public LinkedList getData(){ 61 | return allData; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/visitors/IVisitor.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.visitors; 2 | 3 | import redress.abi.generic.*; 4 | import redress.memory.data.*; 5 | 6 | /** 7 | * Created by jamesrichardson on 2/23/16. 8 | */ 9 | public interface IVisitor { 10 | 11 | public boolean preVisit(); 12 | public void postVisit(); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/generic/visitors/LoadVisitor.java: -------------------------------------------------------------------------------- 1 | package redress.abi.generic.visitors; 2 | 3 | import redress.abi.generic.*; 4 | 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * Created by jamesrichardson on 2/24/16. 9 | */ 10 | public class LoadVisitor extends AbstractStructureVisitor { 11 | 12 | private final AbstractABI abi; 13 | private final LinkedList loadedContents = new LinkedList<>(); 14 | 15 | public LoadVisitor(AbstractABI abi){ 16 | this.abi=abi; 17 | } 18 | 19 | @Override 20 | public boolean preVisit(){ 21 | return true; 22 | } 23 | 24 | @Override 25 | public void postVisit() { 26 | 27 | } 28 | 29 | public LinkedList getData(){ 30 | return loadedContents; 31 | } 32 | 33 | @Override 34 | public void visit(AbstractSegment in){ 35 | final ILoader loader = in.getLoader(); 36 | if(loader != null) { 37 | loadedContents.addAll(loader.load(abi)); 38 | } 39 | } 40 | 41 | @Override 42 | public void visit(AbstractSection in){ 43 | final ILoader loader = in.getLoader(); 44 | if(loader != null) { 45 | loadedContents.addAll(loader.load(abi)); 46 | } 47 | } 48 | 49 | @Override 50 | public void visit(AbstractLoadCommand in){ 51 | final ILoader loader = in.getLoader(); 52 | if(loader != null) { 53 | loadedContents.addAll(loader.load(abi)); 54 | } 55 | } 56 | 57 | @Override 58 | public void visit(AbstractHeader in){ 59 | final ILoader loader = in.getLoader(); 60 | if(loader != null) { 61 | loadedContents.addAll(loader.load(abi)); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/Mach.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach; 2 | 3 | 4 | import redress.abi.generic.AbstractABI; 5 | import redress.memory.data.DWord; 6 | import redress.memory.data.AbstractData; 7 | 8 | import java.nio.ByteOrder; 9 | 10 | /** 11 | * Created by jamesrichardson on 2/10/16. 12 | */ 13 | public abstract class Mach extends AbstractABI { 14 | public static final DWord MACH_ID_32 = new DWord("0xfeedface", AbstractData.Type.DATA_BYTE,ByteOrder.BIG_ENDIAN); 15 | public static final DWord MACH_DI_32 = new DWord("0xcefaedfe", AbstractData.Type.DATA_BYTE,ByteOrder.BIG_ENDIAN); 16 | public static final DWord MACH_ID_64 = new DWord("0xfeedfacf", AbstractData.Type.DATA_BYTE,ByteOrder.BIG_ENDIAN); 17 | public static final DWord MACH_DI_64 = new DWord("0xcffaedfe", AbstractData.Type.DATA_BYTE,ByteOrder.BIG_ENDIAN); 18 | 19 | 20 | public Mach(byte[] raw) { 21 | super(raw); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/MachO32.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach; 2 | 3 | import redress.abi.generic.IContainer; 4 | import redress.abi.generic.enums.ABIArch; 5 | import redress.abi.generic.enums.ABIType; 6 | 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by jamesrichardson on 2/10/16. 11 | */ 12 | public class MachO32 extends Mach { 13 | 14 | public MachO32(byte[] raw) { 15 | super(raw); 16 | } 17 | 18 | @Override 19 | public ABIType getType() { 20 | return null; 21 | } 22 | 23 | @Override 24 | public ABIArch getArch() { 25 | return null; 26 | } 27 | 28 | @Override 29 | public LinkedList getStructureData() { 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/MachO64.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach; 2 | 3 | import redress.abi.generic.IContainer; 4 | import redress.abi.generic.enums.ABIArch; 5 | import redress.abi.generic.enums.ABIType; 6 | 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by jamesrichardson on 2/10/16. 11 | */ 12 | public class MachO64 extends Mach{ 13 | 14 | public MachO64(byte[] raw) { 15 | super(raw); 16 | } 17 | 18 | @Override 19 | public ABIType getType() { 20 | return ABIType.MACH_64; 21 | } 22 | 23 | @Override 24 | public ABIArch getArch() { 25 | return ABIArch.X86; 26 | } 27 | 28 | @Override 29 | public LinkedList getStructureData() { 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/parse/Reader.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach.parse; 2 | 3 | 4 | import org.apache.commons.io.IOUtils; 5 | import redress.memory.address.Address64; 6 | import redress.memory.data.DWord; 7 | import redress.abi.mach.Loader; 8 | import redress.abi.mach.Mach; 9 | import redress.abi.mach.MachO32; 10 | import redress.abi.mach.MachO64; 11 | import redress.abi.mach.parse.x86.MachParser32; 12 | import redress.abi.mach.parse.x86_64.MachParser64; 13 | import redress.memory.data.AbstractData; 14 | import redress.util.B; 15 | 16 | import java.io.File; 17 | import java.io.FileInputStream; 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.nio.ByteOrder; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | /** 25 | * Created by jamesrichardson on 2/10/16. 26 | */ 27 | public class Reader { 28 | 29 | private final static Logger LOGGER = Logger.getLogger(Reader.class.getName()); 30 | 31 | private Reader(){} 32 | 33 | public static Mach Read(final File in) throws Exception{ 34 | 35 | final FileInputStream fis = new FileInputStream(in); 36 | 37 | return Read(fis); 38 | } 39 | 40 | public static Mach Read(final InputStream inputStream) throws Exception{ 41 | 42 | LOGGER.log(Level.INFO,"Reading binary"); 43 | 44 | final byte[] binary = IOUtils.toByteArray(inputStream); 45 | 46 | return getMach(binary); 47 | } 48 | 49 | private static Mach getMach(byte[] binary) throws Exception { 50 | final DWord dWordAtAddress = B.getDWordAtAddress(binary, new Address64("0x0000000000000000"), null, AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 51 | 52 | if(dWordAtAddress == null) 53 | return null; 54 | 55 | Mach ret = null; 56 | 57 | if(Loader.MH_MAGIC_64.equals(dWordAtAddress) || Loader.MH_CIGAM_64.equals(dWordAtAddress)){ 58 | ret = new MachO64(binary); 59 | MachParser64.parse((MachO64) ret); 60 | } else if(Loader.MH_MAGIC.equals(dWordAtAddress) || Loader.MH_CIGAM.equals(dWordAtAddress)){ 61 | ret = new MachO32(binary); 62 | MachParser32.parse((MachO32) ret); 63 | } 64 | 65 | return ret; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/parse/x86/MachParser32.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach.parse.x86; 2 | 3 | import redress.abi.mach.MachO32; 4 | 5 | /** 6 | * Created by jamesrichardson on 2/10/16. 7 | */ 8 | public class MachParser32 { 9 | 10 | private MachParser32() { 11 | 12 | } 13 | 14 | public static void parse(MachO32 model) { 15 | 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/parse/x86_64/MachParser64.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach.parse.x86_64; 2 | 3 | import redress.abi.mach.MachO64; 4 | 5 | import java.util.logging.Level; 6 | import java.util.logging.Logger; 7 | 8 | /** 9 | * Created by jamesrichardson on 2/10/16. 10 | */ 11 | public class MachParser64{ 12 | private final static Logger LOGGER = Logger.getLogger(MachParser64.class.getName()); 13 | 14 | private MachParser64(){ 15 | } 16 | 17 | public static void parse(MachO64 model) throws Exception{ 18 | LOGGER.log(Level.INFO,"Parsing header"); 19 | ParseHeader64.parse(model); 20 | LOGGER.log(Level.INFO,"Parsing load commands"); 21 | ParseCommand64.parse(model); 22 | 23 | System.out.println(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/parse/x86_64/ParseHeader64.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach.parse.x86_64; 2 | 3 | import redress.memory.address.Address32; 4 | import redress.memory.address.Address64; 5 | import redress.abi.mach.Loader; 6 | import redress.abi.mach.MachO64; 7 | import redress.memory.data.AbstractData; 8 | import redress.util.B; 9 | 10 | import java.nio.ByteOrder; 11 | 12 | /** 13 | * Created by jamesrichardson on 2/10/16. 14 | */ 15 | public class ParseHeader64 { 16 | 17 | private ParseHeader64() { 18 | } 19 | 20 | public static void parse(MachO64 model){ 21 | 22 | try { 23 | Loader.mach_header_64 mach_header_64 = new Loader.mach_header_64(model); 24 | 25 | mach_header_64.setBeginAddress(new Address64("0x0000000000000000")); 26 | mach_header_64.setEndAddress(new Address64("0x0000000000000020")); 27 | 28 | mach_header_64.magic = B.getDWordAtAddress(model.getRaw(),mach_header_64.getBeginAddress(), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 29 | mach_header_64.cputype = B.getDWordAtAddress(model.getRaw(),new Address32("0x00000004"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 30 | mach_header_64.cpusubtype = B.getDWordAtAddress(model.getRaw(), new Address32("0x00000008"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 31 | mach_header_64.filetype = B.getDWordAtAddress(model.getRaw(), new Address32("0x0000000C"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 32 | mach_header_64.ncmds = B.getDWordAtAddress(model.getRaw(), new Address32("0x00000010"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 33 | mach_header_64.sizeofcmds = B.getDWordAtAddress(model.getRaw(), new Address32("0x00000014"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 34 | mach_header_64.flags = B.getDWordAtAddress(model.getRaw(), new Address32("0x00000018"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 35 | mach_header_64.reserved = B.getDWordAtAddress(model.getRaw(), new Address32("0x0000001C"), mach_header_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 36 | mach_header_64.addComments("MACH_HEADER_64"); 37 | 38 | model.getChildren().add(mach_header_64); 39 | 40 | }catch(Exception e){ 41 | e.printStackTrace(); 42 | } 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/redress/abi/mach/parse/x86_64/ParseSegSec64.java: -------------------------------------------------------------------------------- 1 | package redress.abi.mach.parse.x86_64; 2 | 3 | import redress.abi.generic.IContainer; 4 | import redress.memory.data.view.Color; 5 | import redress.memory.data.view.TableSeperator; 6 | import redress.memory.address.Address64; 7 | import redress.memory.data.AbstractData; 8 | import redress.abi.generic.IStructure; 9 | import redress.memory.address.Address32; 10 | import redress.abi.mach.Loader; 11 | import redress.abi.mach.MachO64; 12 | import redress.memory.data.Range; 13 | import redress.util.B; 14 | import redress.util.T; 15 | 16 | import java.nio.ByteOrder; 17 | import java.util.LinkedList; 18 | 19 | /** 20 | * Created by jamesrichardson on 2/10/16. 21 | */ 22 | public class ParseSegSec64 { 23 | 24 | private ParseSegSec64() {} 25 | 26 | public static Loader.section_64 parse(MachO64 in,Address32 pointer,IStructure parent){ 27 | // pointer.add(new Word("0x0050", ByteOrder.BIG_ENDIAN)); 28 | Loader.section_64 section_64 = new Loader.section_64(parent); 29 | 30 | section_64.setBeginAddress(pointer.clone()); 31 | final byte[] container = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN).getContainer(); 32 | final byte[] container2 = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN).getContainer(); 33 | section_64.sectname = new Loader.char16(B.mergeBytes(container, container2),section_64, AbstractData.Type.DATA_CHAR,ByteOrder.LITTLE_ENDIAN); 34 | section_64.sectname.setBeginAddress(section_64.getBeginAddress().clone()); 35 | section_64.sectname.setEndAddress(pointer.clone()); 36 | final byte[] container3 = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN).getContainer(); 37 | final byte[] container4 = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN).getContainer(); 38 | section_64.segname = new Loader.char16(B.mergeBytes(container3, container4),section_64, AbstractData.Type.DATA_CHAR,ByteOrder.LITTLE_ENDIAN); 39 | section_64.segname.setBeginAddress(section_64.getBeginAddress().clone()); 40 | section_64.segname.setEndAddress(pointer.clone()); 41 | section_64.addr = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 42 | section_64.size = B.getQWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 43 | section_64.offset = B.getDWordAtAddressAndIncrement(in.getRaw(), pointer,section_64, AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 44 | section_64.align = B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 45 | section_64.reloff = B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 46 | section_64.nreloc = B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 47 | section_64.flags = B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 48 | section_64.reserved1=B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 49 | section_64.reserved2=B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 50 | section_64.reserved3=B.getDWordAtAddressAndIncrement(in.getRaw(), pointer, section_64,AbstractData.Type.DATA_BYTE, ByteOrder.LITTLE_ENDIAN); 51 | section_64.setEndAddress(pointer.clone()); 52 | 53 | 54 | 55 | 56 | boolean strings = false; 57 | String flags = ""; 58 | 59 | if(section_64.sectname.value.contains("__cfstring")){ 60 | setAlignedStringLoader(in, section_64,8); 61 | strings=true; 62 | } 63 | 64 | if(Loader.SECTION_TYPE.and(section_64.flags)) { 65 | flags+="SECTION_TYPE, "; 66 | } if(Loader.SECTION_ATTRIBUTES.and(section_64.flags)){ 67 | flags+="SECTION_ATTRIBUTES, "; 68 | } if(Loader.S_REGULAR.and(section_64.flags)){ 69 | flags+="S_REGULAR, "; 70 | } if(Loader.S_ZEROFILL.and(section_64.flags)){ 71 | flags+="S_ZEROFILL, "; 72 | } if(Loader.S_CSTRING_LITERALS.and(section_64.flags)){ 73 | flags+="S_CSTRING_LITERALS, "; 74 | setCStringLoader(in, section_64); 75 | strings=true; 76 | } if(Loader.S_4BYTE_LITERALS.and(section_64.flags)){ 77 | flags+="S_4BYTE_LITERALS, "; 78 | setAlignedStringLoader(in,section_64,4); 79 | strings=true; 80 | } if(Loader.S_8BYTE_LITERALS.and(section_64.flags)){ 81 | flags+="S_8BYTE_LITERALS, "; 82 | setAlignedStringLoader(in,section_64,8); 83 | strings=true; 84 | } if(Loader.S_LITERAL_POINTERS.and(section_64.flags)){ 85 | flags+="S_LITERAL_POINTERS, "; 86 | setCStringLoader(in, section_64); 87 | strings=true; 88 | } if(Loader.S_NON_LAZY_SYMBOL_POINTERS.and(section_64.flags)){ 89 | flags+="S_NON_LAZY_SYMBOL_POINTERS, "; 90 | } if(Loader.S_LAZY_SYMBOL_POINTERS.and(section_64.flags)){ 91 | flags+="S_LAZY_SYMBOL_POINTERS, "; 92 | } if(Loader.S_SYMBOL_STUBS.and(section_64.flags)){ 93 | flags+="S_SYMBOL_STUBS, "; 94 | } if(Loader.S_MOD_INIT_FUNC_POINTERS.and(section_64.flags)){ 95 | flags+="S_MOD_INIT_FUNC_POINTERS, "; 96 | } if(Loader.S_MOD_TERM_FUNC_POINTERS.and(section_64.flags)){ 97 | flags+="S_MOD_TERM_FUNC_POINTERS, "; 98 | } if(Loader.S_COALESCED.and(section_64.flags)){ 99 | flags+="S_COALESCED, "; 100 | } if(Loader.S_GB_ZEROFILL.and(section_64.flags)){ 101 | flags+="S_GB_ZEROFILL, "; 102 | } if(Loader.S_INTERPOSING.and(section_64.flags)){ 103 | flags+="S_INTERPOSING, "; 104 | } if(Loader.S_16BYTE_LITERALS.and(section_64.flags)){ 105 | flags+="S_16BYTE_LITERALS, "; 106 | } if(Loader.S_DTRACE_DOF.and(section_64.flags)){ 107 | flags+="S_DTRACE_DOF, "; 108 | } if(Loader.S_LAZY_DYLIB_SYMBOL_POINTERS.and(section_64.flags)){ 109 | flags+="S_LAZY_DYLIB_SYMBOL_POINTERS, "; 110 | } if(Loader.SECTION_ATTRIBUTES_USR.and(section_64.flags)){ 111 | flags+="SECTION_ATTRIBUTES_USR, "; 112 | } if(Loader.S_ATTR_PURE_INSTRUCTIONS.and(section_64.flags)){ 113 | flags+="S_ATTR_PURE_INSTRUCTIONS, "; 114 | } if(Loader.S_ATTR_NO_TOC.and(section_64.flags)){ 115 | flags+="S_ATTR_NO_TOC, "; 116 | } if(Loader.S_ATTR_STRIP_STATIC_SYMS.and(section_64.flags)){ 117 | flags+="S_ATTR_STRIP_STATIC_SYMS, "; 118 | } if(Loader.S_ATTR_NO_DEAD_STRIP.and(section_64.flags)){ 119 | flags+="S_ATTR_NO_DEAD_STRIP, "; 120 | } if(Loader.S_ATTR_LIVE_SUPPORT.and(section_64.flags)){ 121 | flags+="S_ATTR_LIVE_SUPPORT, "; 122 | } if(Loader.S_ATTR_SELF_MODIFYING_CODE.and(section_64.flags)){ 123 | flags+="S_ATTR_SELF_MODIFYING_CODE, "; 124 | } if(Loader.S_THREAD_LOCAL_REGULAR.and(section_64.flags)){ 125 | flags+="S_THREAD_LOCAL_REGULAR, "; 126 | } if(Loader.S_THREAD_LOCAL_ZEROFILL.and(section_64.flags)){ 127 | flags+="S_THREAD_LOCAL_ZEROFILL, "; 128 | } if(Loader.S_THREAD_LOCAL_VARIABLES.and(section_64.flags)){ 129 | flags+="S_THREAD_LOCAL_VARIABLES, "; 130 | } if(Loader.S_THREAD_LOCAL_VARIABLE_POINTERS.and(section_64.flags)){ 131 | flags+="S_THREAD_LOCAL_VARIABLE_POINTERS, "; 132 | } if(Loader.S_THREAD_LOCAL_INIT_FUNCTION_POINTERS.and(section_64.flags)){ 133 | flags+="S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, "; 134 | } if(Loader.S_ATTR_DEBUG.and(section_64.flags)){ 135 | flags+="S_ATTR_DEBUG, "; 136 | } if(Loader.SECTION_ATTRIBUTES_SYS.and(section_64.flags)){ 137 | flags+="SECTION_ATTRIBUTES_SYS, "; 138 | } if(Loader.S_ATTR_SOME_INSTRUCTIONS.and(section_64.flags)){ 139 | flags+="S_ATTR_SOME_INSTRUCTIONS, "; 140 | } if(Loader.S_ATTR_EXT_RELOC.and(section_64.flags)){ 141 | flags+="S_ATTR_EXT_RELOC, "; 142 | } if(Loader.S_ATTR_LOC_RELOC.and(section_64.flags)) { 143 | flags+="S_ATTR_LOC_RELOC, "; 144 | } if(flags.equals("")){ 145 | flags="NONE"; 146 | } 147 | 148 | 149 | section_64.addComments("Section Name: " + section_64.sectname.value + " Segment Name: " + section_64.segname.value + " Type: " + flags); 150 | section_64.flags.addComments("Flags: "+flags); 151 | 152 | //TODO - parse sections based on section type 153 | //TODO - Right now every section is treated as compiled text 154 | 155 | if(!strings){ 156 | setDecompileLoader(in, section_64); 157 | } 158 | 159 | return section_64; 160 | } 161 | 162 | private static void setAlignedStringLoader(MachO64 in, Loader.section_64 section_64,int align) { 163 | section_64.setLoader(abi->{ 164 | final LinkedList ret = new LinkedList<>(); 165 | final Address64 begin64 = B.qWordToAddr64(section_64.addr); 166 | final Address64 end64 = (Address64)B.qWordToAddr64(section_64.size); 167 | end64.add(begin64); 168 | begin64.subtract(new Address64("0x0000000100000000")); 169 | end64.subtract(new Address64("0x0000000100000000")); 170 | 171 | final int length = end64.getIntValue() - begin64.getIntValue(); 172 | 173 | Range range = B.getRangeAtAddress(in.getRaw(),section_64,begin64,end64, ByteOrder.LITTLE_ENDIAN); 174 | 175 | ret.add(new TableSeperator("Seg: "+section_64.segname.value,"Sec: "+section_64.sectname.value,"Procedure Start, Length: " + length + " bytes","",Color.rgba(255,28,0,0.43))); 176 | ret.addAll(T.deCompileStringsAligned(align,range, in)); 177 | ret.add(new TableSeperator("","","Procedure End, Length: " + length + " bytes","", Color.rgba(255,28,0,0.43))); 178 | 179 | return ret; 180 | }); 181 | } 182 | 183 | private static void setCStringLoader(MachO64 in, Loader.section_64 section_64) { 184 | section_64.setLoader(abi->{ 185 | final LinkedList ret = new LinkedList<>(); 186 | final Address64 begin64 = B.qWordToAddr64(section_64.addr); 187 | final Address64 end64 = (Address64)B.qWordToAddr64(section_64.size); 188 | end64.add(begin64); 189 | begin64.subtract(new Address64("0x0000000100000000")); 190 | end64.subtract(new Address64("0x0000000100000000")); 191 | 192 | final int length = end64.getIntValue() - begin64.getIntValue(); 193 | 194 | Range range = B.getRangeAtAddress(in.getRaw(),section_64,begin64,end64, ByteOrder.LITTLE_ENDIAN); 195 | 196 | ret.add(new TableSeperator("Seg: "+section_64.segname.value,"Sec: "+section_64.sectname.value,"Procedure Start, Length: " + length + " bytes","",Color.rgba(255,28,0,0.43))); 197 | ret.addAll(T.deCompileCStrings(range, in)); 198 | ret.add(new TableSeperator("","","Procedure End, Length: " + length + " bytes","",Color.rgba(255,28,0,0.43))); 199 | 200 | return ret; 201 | }); 202 | } 203 | 204 | private static void setDecompileLoader(MachO64 in, Loader.section_64 section_64) { 205 | section_64.setLoader(abi->{ 206 | final LinkedList ret = new LinkedList<>(); 207 | final Address64 begin64 = B.qWordToAddr64(section_64.addr); 208 | final Address64 end64 = (Address64)B.qWordToAddr64(section_64.size); 209 | end64.add(begin64); 210 | begin64.subtract(new Address64("0x0000000100000000")); 211 | end64.subtract(new Address64("0x0000000100000000")); 212 | 213 | final int length = end64.getIntValue() - begin64.getIntValue(); 214 | 215 | Range range = B.getRangeAtAddress(in.getRaw(),section_64,begin64,end64, ByteOrder.LITTLE_ENDIAN); 216 | 217 | ret.add(new TableSeperator("Seg: "+section_64.segname.value,"Sec: "+section_64.sectname.value,"Procedure Start, Length: " + length + " bytes","",Color.rgba(255,28,0,0.43))); 218 | ret.addAll(T.deCompileText(range, in)); 219 | ret.add(new TableSeperator("","","Procedure End, Length: " + length + " bytes","",Color.rgba(255,28,0,0.43))); 220 | 221 | return ret; 222 | }); 223 | } 224 | 225 | 226 | } 227 | -------------------------------------------------------------------------------- /src/main/java/redress/gui/CodePaneController.java: -------------------------------------------------------------------------------- 1 | package redress.gui; 2 | 3 | import javafx.beans.property.SimpleStringProperty; 4 | import redress.abi.generic.IContainer; 5 | import redress.memory.data.AbstractData; 6 | import javafx.collections.FXCollections; 7 | import javafx.collections.ObservableList; 8 | import javafx.scene.control.TableColumn; 9 | import javafx.scene.control.TableRow; 10 | import javafx.scene.control.TableView; 11 | import javafx.scene.control.cell.PropertyValueFactory; 12 | import redress.memory.data.Text; 13 | import redress.memory.data.view.TableSeperator; 14 | 15 | import java.util.*; 16 | import java.util.logging.Logger; 17 | 18 | /** 19 | * Created by jamesrichardson on 2/16/16. 20 | */ 21 | public class CodePaneController extends TableView { 22 | private final static Logger LOGGER = Logger.getLogger(CodePaneController.class.getName()); 23 | private final TableColumn addressColumn = new TableColumn<>("Address"); 24 | private final TableColumn dataTypeColumn = new TableColumn<>("DataType"); 25 | private final TableColumn codeColumn = new TableColumn<>("Code"); 26 | private final TableColumn commentColumn = new TableColumn<>("Comment"); 27 | 28 | public CodePaneController(){ 29 | this.widthProperty().addListener(c->{ 30 | final double w = this.getWidth(); 31 | addressColumn.setPrefWidth(w/6); 32 | dataTypeColumn.setPrefWidth(w/6); 33 | codeColumn.setPrefWidth(w/6); 34 | commentColumn.setPrefWidth(w / 2); 35 | }); 36 | addressColumn.setCellValueFactory(new PropertyValueFactory<>("address")); 37 | dataTypeColumn.setCellValueFactory(new PropertyValueFactory<>("informationType")); 38 | codeColumn.setCellValueFactory(new PropertyValueFactory<>("text")); 39 | commentColumn.setCellValueFactory(new PropertyValueFactory<>("comment")); 40 | 41 | this.setRowFactory(tableView -> { 42 | TableRow row = new TableRow<>(); 43 | row.itemProperty().addListener((obs, prev, cur) -> { 44 | row.setStyle(""); 45 | if (cur == null) 46 | return; 47 | if(cur.getData() instanceof TableSeperator){ 48 | row.setStyle("-fx-background-color: "+((TableSeperator)cur.getData()).getColor()); 49 | } 50 | }); 51 | return row; 52 | }); 53 | this.getColumns().addAll(addressColumn,dataTypeColumn, codeColumn, commentColumn); 54 | } 55 | 56 | public void set(LinkedList in){ 57 | final List tmp = new LinkedList<>(); 58 | in.forEach(e-> tmp.add(new DisplaySet(e))); 59 | final ObservableList wrapped = FXCollections.observableList(tmp); 60 | this.setItems(wrapped); 61 | } 62 | 63 | public class DisplaySet implements Comparable{ 64 | private final SimpleStringProperty address; 65 | private final SimpleStringProperty text; 66 | private final SimpleStringProperty comment; 67 | private final SimpleStringProperty informationType; 68 | private final IContainer data; 69 | 70 | public DisplaySet(IContainer in){ 71 | if(in instanceof AbstractData) { 72 | this.address = new SimpleStringProperty(((AbstractData) in).getBeginAddress().toString()); 73 | this.text = new SimpleStringProperty(in.toString()); 74 | this.comment = new SimpleStringProperty(generateCommentString(((AbstractData) in).getComments())); 75 | this.informationType = new SimpleStringProperty(((AbstractData) in).getDataType().toString()); 76 | }else if(in instanceof TableSeperator) { 77 | this.address = new SimpleStringProperty(((TableSeperator) in).getAddressCell()); 78 | this.text = new SimpleStringProperty(((TableSeperator) in).getcodeCell()); 79 | this.comment = new SimpleStringProperty(((TableSeperator) in).getcommentCell()); 80 | this.informationType = new SimpleStringProperty(((TableSeperator) in).gettypeCell()); 81 | }else if(in instanceof Text) { 82 | this.address = new SimpleStringProperty(((Text) in).getBeginAddress().toString()); 83 | this.text = new SimpleStringProperty(in.toString()); 84 | this.comment = new SimpleStringProperty(generateCommentString(((Text) in).getComments())); 85 | this.informationType = new SimpleStringProperty(((Text) in).getDataType().toString()); 86 | }else{ 87 | this.address = new SimpleStringProperty(""); 88 | this.text = new SimpleStringProperty(in.toString()); 89 | this.comment = new SimpleStringProperty(""); 90 | this.informationType = new SimpleStringProperty(""); 91 | } 92 | this.data = in; 93 | } 94 | 95 | private String generateCommentString(HashSet in){ 96 | if(in == null) 97 | return ""; 98 | String ret = ""; 99 | for(String s : in){ 100 | ret+=s+"\n"; 101 | } 102 | return ret; 103 | } 104 | 105 | public String getAddress(){return address.get();} 106 | public void setAddress(String in){address.set(in);} 107 | 108 | public String getText(){return text.get();} 109 | public void setText(String in){text.set(in);} 110 | 111 | public String getComment(){return comment.get();} 112 | public void setComment(String in){comment.set(in);} 113 | 114 | public String getInformationType(){ 115 | return informationType.get(); 116 | } 117 | public void setInformationType(String type){ 118 | this.informationType.set(type); 119 | } 120 | 121 | public IContainer getData(){ 122 | return data; 123 | } 124 | 125 | 126 | @Override 127 | public int compareTo(AbstractData o) { 128 | if(o == null || o.getBeginAddress() == null) 129 | return 0; 130 | 131 | if(o.getDataType() == AbstractData.Type.COMMENT) 132 | return 0; 133 | 134 | if(this.getData() instanceof AbstractData) 135 | return ((AbstractData)this.getData()).getBeginAddress().compareTo(o.getBeginAddress()); 136 | else return 0; 137 | } 138 | } 139 | 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/redress/gui/LeftPane.java: -------------------------------------------------------------------------------- 1 | package redress.gui; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.control.ListView; 5 | import javafx.scene.control.TextArea; 6 | import javafx.scene.layout.AnchorPane; 7 | import javafx.scene.layout.Pane; 8 | import javafx.scene.text.Text; 9 | import javafx.stage.Stage; 10 | import org.dockfx.DockNode; 11 | import org.dockfx.DockPos; 12 | 13 | /** 14 | * Created by jamesrichardson on 2/16/16. 15 | */ 16 | public class LeftPane extends Pane { 17 | 18 | private final DockNode dockNode; 19 | private final ListView stringsView; 20 | 21 | public LeftPane(){ 22 | dockNode = new DockNode(this); 23 | dockNode.setPrefSize(300, 100); 24 | 25 | stringsView = new ListView<>(); 26 | stringsView.prefWidthProperty().bind(dockNode.prefWidthProperty()); 27 | stringsView.layoutYProperty().bind(dockNode.prefHeightProperty().divide(2)); 28 | stringsView.setPrefHeight(200); 29 | stringsView.getItems().addAll("Test","ewfwefwefewfewfwefewfwefwef"); 30 | 31 | // stringsView.widthProperty().addListener((o,w,a)->{System.out.println("StringsView: "+a);}); 32 | // dockNode.prefWidthProperty().addListener((o,w,a)->{System.out.println("DockNode: "+a);}); 33 | 34 | this.getChildren().addAll(new Text("Left Pane Stuff"),stringsView); 35 | } 36 | public DockNode getDockNode(){ 37 | return dockNode; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/redress/gui/MainController.java: -------------------------------------------------------------------------------- 1 | package redress.gui; 2 | 3 | import redress.abi.generic.AbstractABI; 4 | import redress.abi.generic.IContainer; 5 | import redress.abi.generic.visitors.LoadVisitor; 6 | import redress.memory.data.AbstractData; 7 | import javafx.application.Application; 8 | import javafx.beans.property.SimpleBooleanProperty; 9 | import javafx.beans.value.ChangeListener; 10 | import javafx.fxml.FXML; 11 | import javafx.fxml.FXMLLoader; 12 | import javafx.scene.control.MenuBar; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.image.ImageView; 15 | import javafx.scene.layout.AnchorPane; 16 | import javafx.stage.Stage; 17 | import org.dockfx.*; 18 | import org.dockfx.demo.DockFX; 19 | import redress.abi.generic.visitors.DataCollectVisitor; 20 | 21 | import java.io.IOException; 22 | import java.util.*; 23 | import java.util.logging.Logger; 24 | 25 | /** 26 | * Created by jamesrichardson on 2/15/16. 27 | */ 28 | public class MainController extends AnchorPane { 29 | public static final String CODEWINDOW_NAME = "Code Window"; 30 | 31 | private final static Logger LOGGER = Logger.getLogger(MainController.class.getName()); 32 | private static MainController mainController; 33 | 34 | private final SimpleBooleanProperty loadedProperty = new SimpleBooleanProperty(false); 35 | 36 | private RightPane rp; 37 | private LeftPane lp; 38 | private AbstractABI abi; 39 | private CodePaneController codePaneController; 40 | private MenuBarController menuBarController; 41 | private DockNode codePaneDock; 42 | private Stage primaryStage; 43 | 44 | @FXML 45 | private AnchorPane content; 46 | @FXML 47 | private MenuBar menuBar; 48 | 49 | public static MainController getSharedMainController(){ 50 | if(mainController == null) { 51 | mainController = new MainController(); 52 | } 53 | return mainController; 54 | } 55 | 56 | private MainController(){ 57 | FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainController.fxml")); 58 | fxmlLoader.setRoot(this); 59 | fxmlLoader.setController(this); 60 | try { 61 | fxmlLoader.load(); 62 | } catch (IOException exception) { 63 | //noinspection ProhibitedExceptionThrown 64 | throw new RuntimeException(exception); 65 | } 66 | } 67 | 68 | @FXML 69 | public void initialize() { 70 | DockPane dockPane = new DockPane(); 71 | dockPane.prefWidthProperty().bind(content.widthProperty()); 72 | dockPane.prefHeightProperty().bind(content.heightProperty()); 73 | 74 | codePaneController= new CodePaneController(); 75 | menuBarController = new MenuBarController(menuBar); 76 | 77 | codePaneDock = new DockNode(codePaneController,CODEWINDOW_NAME); 78 | codePaneDock.setDockTitleBar(null); 79 | codePaneDock.setPrefSize(300, 100); 80 | codePaneDock.dock(dockPane, DockPos.BOTTOM); 81 | 82 | 83 | lp = new LeftPane(); 84 | 85 | lp.getDockNode().dock(dockPane, DockPos.LEFT); 86 | // dockPane.widthProperty().addListener((o,w,a)->{System.out.println("DockPane: "+a);}); 87 | // lp.widthProperty().addListener((o,w,a)->{System.out.println("LeftPane : "+a);}); 88 | // lp.getDockNode().widthProperty().addListener((o,w,a)->{System.out.println("DockNode: "+a);}); 89 | 90 | rp = new RightPane(); 91 | DockNode rpdn = new DockNode(rp); 92 | rpdn.setPrefSize(300, 100); 93 | rpdn.dock(dockPane, DockPos.RIGHT); 94 | 95 | Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA); 96 | DockPane.initializeDefaultUserAgentStylesheet(); 97 | 98 | content.getChildren().add(dockPane); 99 | 100 | } 101 | public void registerLoadListener(ChangeListener in){ 102 | loadedProperty.addListener(in); 103 | } 104 | 105 | public boolean isLoaded(){return loadedProperty.get();} 106 | public Stage getPrimaryStage(){return primaryStage;} 107 | public void setPrimaryStage(Stage stage){this.primaryStage = stage;} 108 | public AbstractABI getABI(){return abi;} 109 | public void setABI(AbstractABI abi){ 110 | this.abi = abi; 111 | 112 | final LinkedList tableData = new LinkedList<>(); 113 | final DataCollectVisitor v = new DataCollectVisitor(); 114 | final LoadVisitor lv = new LoadVisitor(abi); 115 | 116 | abi.accept(v); 117 | tableData.addAll(v.getData()); 118 | 119 | abi.accept(lv); 120 | tableData.addAll(lv.getData()); 121 | 122 | this.codePaneController.set(tableData); 123 | this.loadedProperty.set(true); 124 | } 125 | 126 | public CodePaneController getCodePaneController(){return codePaneController;} 127 | 128 | public MenuBarController getMenuBarController(){return menuBarController;} 129 | 130 | public class AddrComparator implements Comparator{ 131 | @Override 132 | public int compare(AbstractData o1, AbstractData o2) { 133 | if(o1 == null || o2 == null) 134 | return 0; 135 | if(o1.getBeginAddress() == null || o2.getBeginAddress() == null) 136 | return 0; 137 | return o1.getBeginAddress().compareTo(o2.getBeginAddress()); 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/redress/gui/MenuBarController.java: -------------------------------------------------------------------------------- 1 | package redress.gui; 2 | 3 | import redress.abi.generic.AbstractABI; 4 | 5 | import javafx.scene.control.Menu; 6 | import javafx.scene.control.MenuBar; 7 | import javafx.scene.control.MenuItem; 8 | import javafx.scene.input.KeyCombination; 9 | import javafx.stage.FileChooser; 10 | import redress.abi.mach.parse.Reader; 11 | 12 | import java.io.File; 13 | import java.io.FileInputStream; 14 | import java.io.InputStream; 15 | import java.util.logging.Level; 16 | import java.util.logging.Logger; 17 | 18 | /** 19 | * Created by jamesrichardson on 2/16/16. 20 | */ 21 | public class MenuBarController { 22 | private final static Logger LOGGER = Logger.getLogger(MenuBarController.class.getName()); 23 | 24 | public static final String MENU_FILE = "File"; 25 | public static final String MENU_EDIT = "Edit"; 26 | public static final String MENU_HELP = "Help"; 27 | public static final String MENU_WINDOW = "Window"; 28 | public static final String OPEN = "Open..."; 29 | public static final String OPEN_TEST = "Open Test Bin"; 30 | public static final String SAVE = "Save..."; 31 | public static final String PREFERENCES = "Preferences..."; 32 | public static final String QUIT = "Quit"; 33 | public static final String DELETE = "Delete"; 34 | public static final String CODEWINDOW = "Code Window"; 35 | public static final String LEFTWINDOW = "Left Pane"; 36 | public static final String RIGHTWINDOW = "Right Pane"; 37 | public static final String ABOUT = "About" ; 38 | 39 | private final MenuBar menuBar; 40 | private final Menu fileMenu = new Menu(MENU_FILE); 41 | private final Menu editMenu = new Menu(MENU_EDIT); 42 | private final Menu helpMenu = new Menu(MENU_HELP); 43 | private final Menu windowMenu = new Menu(MENU_WINDOW); 44 | private final MenuItem openMenuItem = new MenuItem(OPEN); 45 | private final MenuItem openTestMenuItem = new MenuItem(OPEN_TEST); 46 | private final MenuItem saveMenuItem = new MenuItem(SAVE); 47 | private final MenuItem preferencesMenuItem = new MenuItem(PREFERENCES); 48 | private final MenuItem quitMenuItem = new MenuItem(QUIT); 49 | private final MenuItem deleteMenuItem = new MenuItem(DELETE); 50 | private final MenuItem codeWindowMenuItem = new MenuItem(CODEWINDOW); 51 | private final MenuItem leftWindowMenuItem = new MenuItem(LEFTWINDOW); 52 | private final MenuItem rightWindowMenuItem = new MenuItem(RIGHTWINDOW); 53 | private final MenuItem aboutMenuItem = new MenuItem(ABOUT); 54 | 55 | public MenuBarController(MenuBar in){ 56 | this.menuBar=in; 57 | 58 | initFileMenu(); 59 | initEditMenu(); 60 | initWindowMenu(); 61 | initHelpMenu(); 62 | 63 | fileMenu.getItems().addAll(openTestMenuItem,openMenuItem,saveMenuItem,preferencesMenuItem,quitMenuItem); 64 | editMenu.getItems().addAll(deleteMenuItem); 65 | windowMenu.getItems().addAll(codeWindowMenuItem,leftWindowMenuItem,rightWindowMenuItem); 66 | helpMenu.getItems().addAll(aboutMenuItem); 67 | menuBar.getMenus().addAll(fileMenu,editMenu,windowMenu,helpMenu); 68 | } 69 | 70 | private void initFileMenu(){ 71 | openMenuItem.setAccelerator(KeyCombination.keyCombination(KeyCombination.META_DOWN+"+o")); 72 | openMenuItem.setOnAction((ae) -> { 73 | FileChooser fileChooser = new FileChooser(); 74 | fileChooser.setTitle("Open Binary"); 75 | fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); 76 | InputStream resourceAsStream = null; 77 | try { 78 | resourceAsStream = new FileInputStream(fileChooser.showOpenDialog(MainController.getSharedMainController().getPrimaryStage())); 79 | }catch(Exception e){ 80 | LOGGER.log(Level.SEVERE,"Unable to open file: "+e); 81 | } 82 | openStream(resourceAsStream); 83 | }); 84 | openTestMenuItem.setAccelerator(KeyCombination.keyCombination(KeyCombination.META_DOWN+"+"+KeyCombination.SHIFT_ANY+"+o")); 85 | openTestMenuItem.setOnAction((ae)->{ 86 | final InputStream resourceAsStream = MenuBarController.class.getResourceAsStream("mach_bin.out"); 87 | openStream(resourceAsStream); 88 | }); 89 | } 90 | 91 | private void openStream(final InputStream stream){ 92 | if (stream == null) { 93 | LOGGER.log(Level.SEVERE,"Unable to open file!"); 94 | return; 95 | } 96 | 97 | AbstractABI read = null; 98 | try { 99 | read = Reader.Read(stream); 100 | }catch(Exception e){ 101 | e.printStackTrace(); 102 | } 103 | 104 | if(read == null){ 105 | LOGGER.log(Level.SEVERE,"Unable to parse ABI!"); 106 | return; 107 | } 108 | 109 | MainController.getSharedMainController().setABI(read); 110 | } 111 | 112 | private void initEditMenu(){ 113 | 114 | } 115 | private void initWindowMenu(){ 116 | 117 | } 118 | private void initHelpMenu(){ 119 | 120 | } 121 | 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/redress/gui/RightPane.java: -------------------------------------------------------------------------------- 1 | package redress.gui; 2 | 3 | import javafx.scene.layout.Pane; 4 | import javafx.scene.text.Text; 5 | 6 | /** 7 | * Created by jamesrichardson on 2/16/16. 8 | */ 9 | public class RightPane extends Pane{ 10 | public RightPane(){ 11 | this.getChildren().add(new Text("Right Pane Stuff")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/redress/memory/address/AbstractAddress.java: -------------------------------------------------------------------------------- 1 | package redress.memory.address; 2 | 3 | import redress.abi.generic.IContainer; 4 | import redress.abi.generic.IStructure; 5 | import redress.abi.generic.visitors.AbstractContainerVisitor; 6 | import redress.memory.data.AbstractData; 7 | import redress.memory.data.QWord; 8 | import redress.util.B; 9 | 10 | import java.nio.ByteOrder; 11 | import java.util.Arrays; 12 | 13 | /** 14 | * Created by jamesrichardson on 2/11/16. 15 | * Addresses are always big endian in my world 16 | */ 17 | public abstract class AbstractAddress implements IContainer,Comparable { 18 | 19 | protected final int BYTES; 20 | protected final ByteOrder BYTEORDER; 21 | protected final byte[] container; 22 | 23 | public AbstractAddress(int bytes){ 24 | this.BYTES = bytes; 25 | this.BYTEORDER = ByteOrder.BIG_ENDIAN; 26 | container = new byte[BYTES]; 27 | } 28 | @Override 29 | public void accept(AbstractContainerVisitor visitor) { 30 | 31 | } 32 | @Override 33 | public abstract AbstractAddress clone(); 34 | 35 | @Override 36 | public ByteOrder getByteOrder(){return BYTEORDER;} 37 | 38 | @Override 39 | public byte[] getContainer(){return container;} 40 | 41 | @Override 42 | public int compareTo(AbstractAddress o) { 43 | if(o == null) 44 | return 0; 45 | 46 | if(o.getIntValue() == this.getIntValue()){ 47 | return 0; 48 | } 49 | 50 | if(o.getIntValue() > this.getIntValue()){ 51 | return -1; 52 | } 53 | 54 | if(o.getIntValue() < this.getIntValue()){ 55 | return 1; 56 | } 57 | 58 | return 0; 59 | } 60 | 61 | public void add(IContainer in){ 62 | B.add(this,in); 63 | } 64 | 65 | public void add(int i){ 66 | QWord w = new QWord(B.intToBytes(i,ByteOrder.BIG_ENDIAN), AbstractData.Type.DATA_NULL,ByteOrder.BIG_ENDIAN); 67 | add(w); 68 | } 69 | 70 | public void subtract(IContainer in){ 71 | B.subtract(this,in); 72 | } 73 | 74 | public void subtract(int i){ 75 | QWord w = new QWord(B.intToBytes(i,ByteOrder.BIG_ENDIAN), AbstractData.Type.DATA_NULL,ByteOrder.BIG_ENDIAN); 76 | subtract(w); 77 | } 78 | 79 | public int getIntValue(){ 80 | return B.bytesToInt(container, BYTEORDER); 81 | } 82 | 83 | public String getStringValue(){ 84 | return B.bytesToHexString(container); 85 | } 86 | 87 | @Override 88 | public boolean equals(Object o){ 89 | if(!(o instanceof IContainer)) 90 | return false; 91 | return equals((IContainer) o, false); 92 | } 93 | 94 | public boolean equals(IContainer o, boolean ignoreLength){ 95 | IContainer tmp; 96 | if(this.BYTEORDER == o.getByteOrder()){ 97 | tmp = o; 98 | }else{ 99 | tmp = o.flipByteOrder(); 100 | } 101 | 102 | if(ignoreLength){ 103 | if(this.BYTES <= tmp.getContainer().length){ 104 | for(int i=0;i comment = new HashSet<>(); 48 | 49 | 50 | protected AbstractData(int bytes, IStructure parent, Type type, ByteOrder order){ 51 | BYTES=bytes; 52 | BYTEORDER=order; 53 | container = new byte[BYTES]; 54 | this.type = type; 55 | this.parent = parent; 56 | } 57 | 58 | @Override 59 | public IStructure getParent(){ 60 | return parent; 61 | } 62 | 63 | public void setNextSibling(IContainer c){ 64 | this.nextSibling = c; 65 | } 66 | 67 | @Override 68 | public IContainer getNextSibling() { 69 | return nextSibling; 70 | } 71 | 72 | public void setPreviousSibling(IContainer c){ 73 | this.previousSibling = c; 74 | } 75 | 76 | @Override 77 | public IContainer getPreviousSibling() { 78 | return previousSibling; 79 | } 80 | 81 | public byte[] getContainer(){return container;} 82 | 83 | public ByteOrder getByteOrder(){return BYTEORDER;} 84 | 85 | public Type getDataType(){ 86 | return this.type; 87 | } 88 | 89 | public void add(IContainer in){ 90 | B.add(this,in); 91 | } 92 | 93 | public void add(int i){ 94 | QWord w = new QWord(B.intToBytes(i,ByteOrder.BIG_ENDIAN),Type.DATA_NULL,ByteOrder.BIG_ENDIAN); 95 | add(w); 96 | } 97 | 98 | public void subtract(IContainer in){ 99 | B.subtract(this,in); 100 | } 101 | 102 | public void subtract(int i){ 103 | QWord w = new QWord(B.intToBytes(i,ByteOrder.BIG_ENDIAN), AbstractData.Type.DATA_NULL,ByteOrder.BIG_ENDIAN); 104 | subtract(w); 105 | } 106 | 107 | public void setDataType(Type type){ 108 | this.type = type; 109 | } 110 | 111 | public void setUserData(Object in){this.userData = in;} 112 | 113 | public Object getUserData(){return userData;} 114 | 115 | public int getIntValue(){ 116 | return B.bytesToInt(container, BYTEORDER); 117 | } 118 | 119 | public BigInteger getIntegerValue(){ 120 | return new BigInteger(1,container); 121 | } 122 | 123 | public String getStringValue(){ 124 | return B.bytesToHexString(container); 125 | } 126 | 127 | public long getLongValue(){ 128 | return B.bytesToLong(container,BYTEORDER); 129 | } 130 | 131 | public double getDoubleValue(){return B.bytesToDouble(container,BYTEORDER);} 132 | 133 | public char[] getCharValue(){ 134 | 135 | String g = new String(container); 136 | char[] o = g.toCharArray(); 137 | 138 | return o; 139 | } 140 | 141 | public byte getLeastSignificantByte(){ 142 | if(BYTEORDER == ByteOrder.LITTLE_ENDIAN){ 143 | return container[0]; 144 | } 145 | return container[BYTES-1]; 146 | } 147 | 148 | public byte getMostSignificantByte(){ 149 | if(BYTEORDER == ByteOrder.LITTLE_ENDIAN){ 150 | return container[BYTES-1]; 151 | } 152 | return container[0]; 153 | } 154 | 155 | public byte getByteAtOffset(int offset){ 156 | if(offset >= BYTES){ 157 | return (byte)0x00; 158 | } 159 | 160 | if(BYTEORDER == ByteOrder.LITTLE_ENDIAN){ 161 | return container[BYTES-offset]; 162 | } 163 | return container[offset]; 164 | } 165 | 166 | @Override 167 | public int compareTo(IAddressable o) { 168 | if(o == null) 169 | return 0; 170 | 171 | return this.beginAddress.compareTo(o.getBeginAddress()); 172 | } 173 | 174 | @Override 175 | public boolean equals(Object o){ 176 | if(!(o instanceof AbstractData)) 177 | return false; 178 | return equals((AbstractData) o, false); 179 | } 180 | 181 | @Override 182 | public int hashCode() { 183 | int result = this.parent != null ? this.parent.hashCode() : 0; 184 | result = 31 * result + (this.previousSibling != null ? this.previousSibling.hashCode() : 0); 185 | result = 31 * result + (this.nextSibling != null ? this.nextSibling.hashCode() : 0); 186 | result = 31 * result + (this.beginAddress != null ? this.beginAddress.hashCode() : 0); 187 | result = 31 * result + (this.endAddress != null ? this.endAddress.hashCode() : 0); 188 | result = 31 * result + Arrays.hashCode(this.container); 189 | result = 31 * result + (this.BYTEORDER != null ? this.BYTEORDER.hashCode() : 0); 190 | result = 31 * result + this.BYTES; 191 | result = 31 * result + (this.userData != null ? this.userData.hashCode() : 0); 192 | result = 31 * result + (this.type != null ? this.type.hashCode() : 0); 193 | result = 31 * result + (this.comment != null ? this.comment.hashCode() : 0); 194 | return result; 195 | } 196 | 197 | public boolean and(IContainer in){ 198 | final byte[] container1; 199 | 200 | if(this.getByteOrder() != in.getByteOrder()) 201 | container1 = in.flipByteOrder().getContainer(); 202 | else 203 | container1 = in.getContainer(); 204 | 205 | if(container1.length >= container.length){ 206 | for(int i=0;i getComments(){ 279 | return comment; 280 | } 281 | 282 | public abstract AbstractData clone(); 283 | 284 | @Override 285 | public String toString(){ 286 | switch(type){ 287 | case DATA_NULL: 288 | return getStringValue(); 289 | case DATA_BYTE: 290 | return getStringValue(); 291 | case DATA_CHAR: 292 | return new String(getCharValue()); 293 | case DATA_U_INT: 294 | return String.valueOf(getIntValue()); 295 | case DATA_INT: 296 | return String.valueOf(getIntValue()); 297 | case DATA_FLOAT:break; 298 | case DATA_DOUBLE:break; 299 | case DATA_LONG:break; 300 | case DATA_BOOL:break; 301 | case COMMENT: 302 | return ""; 303 | default:break; 304 | } 305 | return getStringValue()+" "+BYTEORDER; 306 | } 307 | 308 | 309 | } 310 | -------------------------------------------------------------------------------- /src/main/java/redress/memory/data/DWord.java: -------------------------------------------------------------------------------- 1 | package redress.memory.data; 2 | 3 | import redress.abi.generic.IContainer; 4 | import redress.abi.generic.IStructure; 5 | import redress.abi.generic.visitors.AbstractContainerVisitor; 6 | import redress.abi.generic.visitors.AbstractStructureVisitor; 7 | import redress.memory.address.AbstractAddress; 8 | import redress.memory.address.Address32; 9 | import redress.util.B; 10 | 11 | import java.nio.ByteOrder; 12 | 13 | /** 14 | * Created by jamesrichardson on 2/11/16. 15 | */ 16 | public class DWord extends AbstractData { 17 | public static final Word SIZEOF_B = new Word("0x0004", AbstractData.Type.DATA_BYTE,ByteOrder.BIG_ENDIAN); 18 | public static final Word SIZEOF_L = new Word("0x0400", AbstractData.Type.DATA_BYTE,ByteOrder.LITTLE_ENDIAN); 19 | public static final DWord NULL = new DWord(); 20 | 21 | public DWord(){ 22 | super(0,null,Type.DATA_NULL ,ByteOrder.BIG_ENDIAN); 23 | } 24 | 25 | public DWord(byte[] in,Type type,ByteOrder order){ 26 | this(in,Address32.NULL,null,type,order); 27 | } 28 | public DWord(byte[] in,AbstractAddress beginAddress,IStructure parent, Type type,ByteOrder order){ 29 | super(4,parent,type,order); 30 | this.beginAddress=beginAddress; 31 | this.endAddress=beginAddress.clone(); 32 | B.add(this.endAddress,new Address32("0x00000004")); 33 | if(in.length != BYTES){ 34 | return; 35 | } 36 | for(int i=0;i deCompileStringsAligned(int aligned, Range text, AbstractABI abi){ 30 | final LinkedList ret = new LinkedList<>(); 31 | final int length = text.getEndAddress().getIntValue()-text.getBeginAddress().getIntValue(); 32 | LOGGER.log(Level.INFO,"Decompiling {4} byte aligned Strings {0} bytes from {1} to {2}, first byte {3}",new Object[]{length, text.getBeginAddress().toString(),text.getEndAddress().toString(), B.bytesToHexString(new byte[]{text.getContainer()[0]}),aligned}); 33 | 34 | int count=0; 35 | for(int i=0;i deCompileCStrings(Range text, AbstractABI abi){ 63 | final LinkedList ret = new LinkedList<>(); 64 | final int length = text.getEndAddress().getIntValue()-text.getBeginAddress().getIntValue(); 65 | LOGGER.log(Level.INFO,"Decompiling CStrings {0} bytes from {1} to {2}, first byte {3}",new Object[]{length, text.getBeginAddress().toString(),text.getEndAddress().toString(), B.bytesToHexString(new byte[]{text.getContainer()[0]})}); 66 | 67 | int previousEnd = -1; 68 | for(int i=1;ipreviousEnd;j--){ 75 | str[j]=text.getContainer()[j]; 76 | beg=j; 77 | } 78 | 79 | final AbstractAddress strBegin = text.getBeginAddress().clone(); 80 | strBegin.subtract(beg); 81 | final AbstractAddress strEnd = text.getBeginAddress().clone(); 82 | strEnd.add(i); 83 | 84 | previousEnd = i; 85 | 86 | final Range range = new Range(str, strBegin, strEnd, text.getParent(), AbstractData.Type.DATA_CHAR, ByteOrder.LITTLE_ENDIAN); 87 | String rets = ""; 88 | for(String s : B.bytesToPrettyHexString(str)){ 89 | rets+=s; 90 | } 91 | range.addComments("Hex Representation: "+rets); 92 | 93 | ret.add(range); 94 | } 95 | } 96 | return ret; 97 | } 98 | 99 | public static LinkedList deCompileText(Range text, AbstractABI abi){ 100 | final LinkedList ret = new LinkedList<>(); 101 | final int length = text.getEndAddress().getIntValue()-text.getBeginAddress().getIntValue(); 102 | final Capstone cs = getCapstone(abi.getType(), abi.getArch()); 103 | 104 | LOGGER.log(Level.INFO,"Decompiling Code {0} bytes from {1} to {2}, first byte {3}",new Object[]{length, text.getBeginAddress().toString(),text.getEndAddress().toString(), B.bytesToHexString(new byte[]{text.getContainer()[0]})}); 105 | 106 | try { 107 | final Capstone.CsInsn[] disasm = cs.disasm(text.getContainer(), text.getBeginAddress().getIntValue()); 108 | for (Capstone.CsInsn csin : disasm) { 109 | ret.add(print_ins_detail(csin, cs, abi,text.getParent())); 110 | } 111 | }catch(Exception e){ 112 | e.printStackTrace(); 113 | } 114 | 115 | return ret; 116 | } 117 | 118 | private static Capstone getCapstone(ABIType fileType, ABIArch abiArch) { 119 | Capstone cs = null; 120 | if(fileType == ABIType.MACH_64 || fileType == ABIType.PE_64 || fileType == ABIType.ELF_64){ 121 | if(abiArch == ABIArch.X86) { 122 | cs = new Capstone(Capstone.CS_ARCH_X86, Capstone.CS_MODE_64); 123 | } 124 | }else if(fileType == ABIType.MACH_32 || fileType == ABIType.PE_32 || fileType == ABIType.ELF_32) { 125 | if (abiArch == ABIArch.X86) { 126 | cs = new Capstone(Capstone.CS_ARCH_X86, Capstone.CS_MODE_32); 127 | } 128 | } 129 | return cs; 130 | } 131 | 132 | /** 133 | * Code adapted from Capstone project 134 | */ 135 | private static Text print_ins_detail(Capstone.CsInsn ins,Capstone cs,AbstractABI abi,IStructure parent) { 136 | final StringBuilder comment = new StringBuilder(); 137 | 138 | //TODO - comment is instruction string 139 | //TODO - container is instruction raw 140 | //TODO - get raw inst from abi raw 141 | //TODO - get proper addr size from abi 142 | // final byte[] lengthOfInstruction = B.intToBytes(B.shortToInt(ins.size), ByteOrder.BIG_ENDIAN); 143 | // final Address begin = new Address32(B.intToBytes(B.longToInt(ins.address),ByteOrder.BIG_ENDIAN)); 144 | // final Address end = (Address)begin.clone().add(new Address32(lengthOfInstruction)); 145 | // final byte[] rawInst = B.getRangeAtAddress(abi.getRaw(),begin,end); 146 | //final Range range = new Range(rawInst,begin,end,Data.Type.TEXT_DECOMPILED, ByteOrder.BIG_ENDIAN); 147 | 148 | final Address32 begin = new Address32(B.intToBytes(B.longToInt(ins.address), ByteOrder.BIG_ENDIAN)); 149 | final Range range = new Range(new byte[0],begin,Address32.NULL, parent,AbstractData.Type.TEXT_DECOMPILED, ByteOrder.BIG_ENDIAN); 150 | 151 | 152 | comment.append(ins.mnemonic); 153 | comment.append(" "); 154 | comment.append(ins.opStr); 155 | 156 | X86.OpInfo operands = (X86.OpInfo) ins.operands; 157 | 158 | if(operands != null) { 159 | comment.append("Prefix: "); 160 | comment.append(B.bytesToHexString(operands.prefix)); 161 | comment.append("\n"); 162 | 163 | comment.append("Opcode:"); 164 | comment.append(B.bytesToHexString(operands.opcode)); 165 | comment.append("\n"); 166 | 167 | // print REX prefix (non-zero value is relevant for x86_64) 168 | comment.append("rex: "); 169 | comment.append(operands.rex); 170 | comment.append("\n"); 171 | 172 | // print address size 173 | comment.append("addr_size: "); 174 | comment.append(operands.addrSize); 175 | comment.append("\n"); 176 | 177 | // print modRM byte 178 | comment.append("modrm: "); 179 | comment.append(operands.modrm); 180 | comment.append("\n"); 181 | 182 | // print displacement value 183 | comment.append("disp: 0x%x"); 184 | comment.append(operands.disp); 185 | comment.append("\n"); 186 | 187 | // SIB is not available in 16-bit mode 188 | if ((cs.mode & Capstone.CS_MODE_16) == 0) { 189 | // print SIB byte 190 | comment.append("sib: "); 191 | comment.append(operands.sib); 192 | if (operands.sib != 0) { 193 | comment.append("\tsib_base: "); 194 | comment.append(ins.regName(operands.sibBase)); 195 | comment.append("\n"); 196 | comment.append("\tsib_index: "); 197 | comment.append(ins.regName(operands.sibIndex)); 198 | comment.append("\n"); 199 | comment.append("\tsib_scale: "); 200 | comment.append(operands.sibScale); 201 | comment.append("\n"); 202 | } 203 | } 204 | 205 | if (operands.sseCC != 0) { 206 | comment.append("sse_cc: "); 207 | comment.append(operands.sseCC); 208 | comment.append("\n"); 209 | } 210 | 211 | if (operands.avxCC != 0) { 212 | comment.append("avx_cc: "); 213 | comment.append(operands.avxCC); 214 | comment.append("\n"); 215 | } 216 | 217 | if (operands.avxSae) { 218 | comment.append("avx_sae: TRUE\n"); 219 | } 220 | 221 | if (operands.avxRm != 0) { 222 | comment.append("avx_rm: "); 223 | comment.append(operands.avxRm); 224 | comment.append("\n"); 225 | } 226 | 227 | int count = ins.opCount(capstone.X86_const.X86_OP_IMM); 228 | if (count > 0) { 229 | comment.append("imm_count: "); 230 | comment.append(count); 231 | comment.append("\n"); 232 | for (int i = 0; i < count; i++) { 233 | int index = ins.opIndex(capstone.X86_const.X86_OP_IMM, i + 1); 234 | comment.append("\timms"); 235 | comment.append(i); 236 | comment.append("]: "); 237 | comment.append(operands.op[index].value.imm); 238 | comment.append("\n"); 239 | } 240 | } 241 | 242 | if (operands.op.length != 0) { 243 | comment.append("op_count:"); 244 | comment.append(operands.op.length); 245 | for (int c = 0; c < operands.op.length; c++) { 246 | X86.Operand i = (X86.Operand) operands.op[c]; 247 | String imm = String.valueOf(i.value.imm); 248 | if (i.type == capstone.X86_const.X86_OP_REG) { 249 | comment.append("\toperands[" + c + "].type: REG = "); 250 | comment.append(ins.regName(i.value.reg)); 251 | comment.append("\n"); 252 | } 253 | if (i.type == capstone.X86_const.X86_OP_IMM) { 254 | comment.append("\toperands[" + c + "].type: IMM = "); 255 | comment.append(i.value.imm); 256 | comment.append("\n"); 257 | } 258 | if (i.type == capstone.X86_const.X86_OP_FP) { 259 | comment.append("\toperands[" + c + "].type: FP = "); 260 | comment.append(i.value.fp); 261 | comment.append("\n"); 262 | } 263 | if (i.type == capstone.X86_const.X86_OP_MEM) { 264 | comment.append("\toperands[" + c + "].type: MEM\n"); 265 | String segment = ins.regName(i.value.mem.segment); 266 | String base = ins.regName(i.value.mem.base); 267 | String index = ins.regName(i.value.mem.index); 268 | if (segment != null) { 269 | comment.append("\t\toperands[" + c + "].mem.segment: REG = "); 270 | comment.append(segment); 271 | comment.append("\n"); 272 | } 273 | if (base != null) { 274 | comment.append("\t\toperands[" + c + "].mem.base: REG = "); 275 | comment.append(base); 276 | comment.append("\n"); 277 | } 278 | if (index != null) { 279 | comment.append("\t\toperands[" + c + "].mem.index: REG = "); 280 | comment.append(index); 281 | comment.append("\n"); 282 | } 283 | if (i.value.mem.scale != 1) { 284 | comment.append("\t\toperands[" + c + "].mem.scale: "); 285 | comment.append(i.value.mem.scale); 286 | comment.append("\n"); 287 | } 288 | if (i.value.mem.disp != 0) { 289 | comment.append("\t\toperands[" + c + "].mem.disp: "); 290 | comment.append(i.value.mem.disp); 291 | comment.append("\n"); 292 | } 293 | } 294 | 295 | // AVX broadcast type 296 | if (i.avx_bcast != capstone.X86_const.X86_AVX_BCAST_INVALID) { 297 | comment.append("\toperands[" + c + "].avx_bcast: "); 298 | comment.append(i.avx_bcast); 299 | comment.append("\n"); 300 | } 301 | 302 | // AVX zero opmask {z} 303 | if (i.avx_zero_opmask) { 304 | comment.append("\toperands[" + c + "].avx_zero_opmask: TRUE\n"); 305 | } 306 | 307 | comment.append("\toperands[" + c + "].size: "); 308 | comment.append(i.size); 309 | comment.append("\n"); 310 | } 311 | } 312 | } 313 | 314 | return new Text(range,ins,comment.toString()); 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /src/main/resources/darwin/libcapstone.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/src/main/resources/darwin/libcapstone.dylib -------------------------------------------------------------------------------- /src/main/resources/linux-x86-64/libcapstone.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/src/main/resources/linux-x86-64/libcapstone.so -------------------------------------------------------------------------------- /src/main/resources/redress/gui/MainController.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/resources/redress/gui/mach_bin.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/src/main/resources/redress/gui/mach_bin.out -------------------------------------------------------------------------------- /src/main/resources/win32-x86-64/capstone.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binarybird/Redress-Disassembler/5f825e2f3fd01dd51f763f991f640a7aeaafe761/src/main/resources/win32-x86-64/capstone.dll -------------------------------------------------------------------------------- /src/test/java/capstone/Test.java: -------------------------------------------------------------------------------- 1 | package capstone;/* Capstone Disassembler Engine */ 2 | /* By Nguyen Anh Quynh , 2013> */ 3 | 4 | public class Test { 5 | public static class platform { 6 | public int arch; 7 | public int mode; 8 | public int syntax; 9 | public byte[] code; 10 | public String comment; 11 | 12 | public platform(int a, int m, int syt, byte[] c, String s) { 13 | arch = a; 14 | mode = m; 15 | code = c; 16 | comment = s; 17 | syntax = syt; 18 | } 19 | 20 | public platform(int a, int m, byte[] c, String s) { 21 | arch = a; 22 | mode = m; 23 | code = c; 24 | comment = s; 25 | } 26 | }; 27 | 28 | static public String stringToHex(byte[] code) { 29 | StringBuilder buf = new StringBuilder(200); 30 | for (byte ch: code) { 31 | if (buf.length() > 0) 32 | buf.append(' '); 33 | buf.append(String.format("0x%02x", ch)); 34 | } 35 | return buf.toString(); 36 | } 37 | 38 | public static final byte[] PPC_CODE = new byte[] {(byte)0x80, (byte)0x20, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x3f, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x43, (byte)0x23, (byte)0x0e, (byte)0xd0, (byte)0x44, (byte)0x00, (byte)0x80, (byte)0x4c, (byte)0x43, (byte)0x22, (byte)0x02, (byte)0x2d, (byte)0x03, (byte)0x00, (byte)0x80, (byte)0x7c, (byte)0x43, (byte)0x20, (byte)0x14, (byte)0x7c, (byte)0x43, (byte)0x20, (byte)0x93, (byte)0x4f, (byte)0x20, (byte)0x00, (byte)0x21, (byte)0x4c, (byte)0xc8, (byte)0x00, (byte)0x21 }; 39 | public static final byte[] X86_CODE = new byte[] { (byte)0x8d, (byte)0x4c, (byte)0x32, (byte)0x08, (byte)0x01, (byte)0xd8, (byte)0x81, (byte)0xc6, (byte)0x34, (byte)0x12, (byte)0x00, (byte)0x00 }; 40 | public static final byte[] SPARC_CODE = new byte[] { (byte)0x80, (byte)0xa0, (byte)0x40, (byte)0x02, (byte)0x85, (byte)0xc2, (byte)0x60, (byte)0x08, (byte)0x85, (byte)0xe8, (byte)0x20, (byte)0x01, (byte)0x81, (byte)0xe8, (byte)0x00, (byte)0x00, (byte)0x90, (byte)0x10, (byte)0x20, (byte)0x01, (byte)0xd5, (byte)0xf6, (byte)0x10, (byte)0x16, (byte)0x21, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x86, (byte)0x00, (byte)0x40, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0xbf, (byte)0xff, (byte)0xff, (byte)0x10, (byte)0xbf, (byte)0xff, (byte)0xff, (byte)0xa0, (byte)0x02, (byte)0x00, (byte)0x09, (byte)0x0d, (byte)0xbf, (byte)0xff, (byte)0xff, (byte)0xd4, (byte)0x20, (byte)0x60, (byte)0x00, (byte)0xd4, (byte)0x4e, (byte)0x00, (byte)0x16, (byte)0x2a, (byte)0xc2, (byte)0x80, (byte)0x03 }; 41 | public static final byte[] SYSZ_CODE = new byte[] { (byte)0xed, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1a, (byte)0x5a, (byte)0x0f, (byte)0x1f, (byte)0xff, (byte)0xc2, (byte)0x09, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x07, (byte)0xf7, (byte)0xeb, (byte)0x2a, (byte)0xff, (byte)0xff, (byte)0x7f, (byte)0x57, (byte)0xe3, (byte)0x01, (byte)0xff, (byte)0xff, (byte)0x7f, (byte)0x57, (byte)0xeb, (byte)0x00, (byte)0xf0, (byte)0x00, (byte)0x00, (byte)0x24, (byte)0xb2, (byte)0x4f, (byte)0x00, (byte)0x78 }; 42 | public static final byte[] SPARCV9_CODE = new byte[] { (byte)0x81, (byte)0xa8, (byte)0x0a, (byte)0x24, (byte)0x89, (byte)0xa0, (byte)0x10, (byte)0x20, (byte)0x89, (byte)0xa0, (byte)0x1a, (byte)0x60, (byte)0x89, (byte)0xa0, (byte)0x00, (byte)0xe0 }; 43 | public static final byte[] XCORE_CODE = new byte[] { (byte)0xfe, (byte)0x0f, (byte)0xfe, (byte)0x17, (byte)0x13, (byte)0x17, (byte)0xc6, (byte)0xfe, (byte)0xec, (byte)0x17, (byte)0x97, (byte)0xf8, (byte)0xec, (byte)0x4f, (byte)0x1f, (byte)0xfd, (byte)0xec, (byte)0x37, (byte)0x07, (byte)0xf2, (byte)0x45, (byte)0x5b, (byte)0xf9, (byte)0xfa, (byte)0x02, (byte)0x06, (byte)0x1b, (byte)0x10 }; 44 | 45 | static public void main(String argv[]) { 46 | platform[] platforms = { 47 | new platform( 48 | Capstone.CS_ARCH_X86, 49 | Capstone.CS_MODE_16, 50 | Capstone.CS_OPT_SYNTAX_INTEL, 51 | new byte[] { (byte)0x8d, (byte)0x4c, (byte)0x32, (byte)0x08, (byte)0x01, (byte)0xd8, (byte)0x81, (byte)0xc6, (byte)0x34, (byte)0x12, (byte)0x00, (byte)0x00 }, 52 | "X86 16bit (Intel syntax)" 53 | ), 54 | new platform( 55 | Capstone.CS_ARCH_X86, 56 | Capstone.CS_MODE_32, 57 | Capstone.CS_OPT_SYNTAX_ATT, 58 | X86_CODE, 59 | "X86 32bit (ATT syntax)" 60 | ), 61 | new platform( 62 | Capstone.CS_ARCH_X86, 63 | Capstone.CS_MODE_32, 64 | X86_CODE, 65 | "X86 32 (Intel syntax)" 66 | ), 67 | new platform( 68 | Capstone.CS_ARCH_X86, 69 | Capstone.CS_MODE_64, 70 | new byte[] {(byte)0x55, (byte)0x48, (byte)0x8b, (byte)0x05, (byte)0xb8, (byte)0x13, (byte)0x00, (byte)0x00 }, 71 | "X86 64 (Intel syntax)" 72 | ), 73 | new platform( 74 | Capstone.CS_ARCH_ARM, 75 | Capstone.CS_MODE_ARM, 76 | new byte[] { (byte)0xED, (byte)0xFF, (byte)0xFF, (byte)0xEB, (byte)0x04, (byte)0xe0, (byte)0x2d, (byte)0xe5, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xe0, (byte)0x83, (byte)0x22, (byte)0xe5, (byte)0xf1, (byte)0x02, (byte)0x03, (byte)0x0e, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe3, (byte)0x02, (byte)0x30, (byte)0xc1, (byte)0xe7, (byte)0x00, (byte)0x00, (byte)0x53, (byte)0xe3 }, 77 | "ARM" 78 | ), 79 | new platform( 80 | Capstone.CS_ARCH_ARM, 81 | Capstone.CS_MODE_THUMB, 82 | new byte[] {(byte)0x4f, (byte)0xf0, (byte)0x00, (byte)0x01, (byte)0xbd, (byte)0xe8, (byte)0x00, (byte)0x88, (byte)0xd1, (byte)0xe8, (byte)0x00, (byte)0xf0 }, 83 | "THUMB-2" 84 | ), 85 | new platform( 86 | Capstone.CS_ARCH_ARM, 87 | Capstone.CS_MODE_ARM, 88 | new byte[] {(byte)0x10, (byte)0xf1, (byte)0x10, (byte)0xe7, (byte)0x11, (byte)0xf2, (byte)0x31, (byte)0xe7, (byte)0xdc, (byte)0xa1, (byte)0x2e, (byte)0xf3, (byte)0xe8, (byte)0x4e, (byte)0x62, (byte)0xf3 }, 89 | "ARM: Cortex-A15 + NEON" 90 | ), 91 | new platform( 92 | Capstone.CS_ARCH_ARM, 93 | Capstone.CS_MODE_THUMB, 94 | new byte[] {(byte)0x70, (byte)0x47, (byte)0xeb, (byte)0x46, (byte)0x83, (byte)0xb0, (byte)0xc9, (byte)0x68 }, 95 | "THUMB" 96 | ), 97 | new platform( 98 | Capstone.CS_ARCH_MIPS, 99 | Capstone.CS_MODE_MIPS32 + Capstone.CS_MODE_BIG_ENDIAN, 100 | new byte[] {(byte)0x0C, (byte)0x10, (byte)0x00, (byte)0x97, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x24, (byte)0x02, (byte)0x00, (byte)0x0c, (byte)0x8f, (byte)0xa2, (byte)0x00, (byte)0x00, (byte)0x34, (byte)0x21, (byte)0x34, (byte)0x56 }, 101 | "MIPS-32 (Big-endian)" 102 | ), 103 | new platform( 104 | Capstone.CS_ARCH_MIPS, 105 | Capstone.CS_MODE_MIPS64+ Capstone.CS_MODE_LITTLE_ENDIAN, 106 | new byte[] {(byte)0x56, (byte)0x34, (byte)0x21, (byte)0x34, (byte)0xc2, (byte)0x17, (byte)0x01, (byte)0x00 }, 107 | "MIPS-64-EL (Little-endian)" 108 | ), 109 | new platform( 110 | Capstone.CS_ARCH_ARM64, 111 | Capstone.CS_MODE_ARM, 112 | new byte [] { 0x21, 0x7c, 0x02, (byte)0x9b, 0x21, 0x7c, 0x00, 0x53, 0x00, 0x40, 0x21, 0x4b, (byte)0xe1, 0x0b, 0x40, (byte)0xb9 }, 113 | "ARM-64" 114 | ), 115 | new platform ( 116 | Capstone.CS_ARCH_PPC, 117 | Capstone.CS_MODE_BIG_ENDIAN, 118 | PPC_CODE, 119 | "PPC-64" 120 | ), 121 | new platform ( 122 | Capstone.CS_ARCH_PPC, 123 | Capstone.CS_MODE_BIG_ENDIAN, 124 | Capstone.CS_OPT_SYNTAX_NOREGNAME, 125 | PPC_CODE, 126 | "PPC-64, print register with number only" 127 | ), 128 | new platform ( 129 | Capstone.CS_ARCH_SPARC, 130 | Capstone.CS_MODE_BIG_ENDIAN, 131 | SPARC_CODE, 132 | "Sparc" 133 | ), 134 | new platform ( 135 | Capstone.CS_ARCH_SPARC, 136 | Capstone.CS_MODE_BIG_ENDIAN + Capstone.CS_MODE_V9, 137 | SPARCV9_CODE, 138 | "SparcV9" 139 | ), 140 | new platform ( 141 | Capstone.CS_ARCH_SYSZ, 142 | 0, 143 | SYSZ_CODE, 144 | "SystemZ" 145 | ), 146 | new platform ( 147 | Capstone.CS_ARCH_XCORE, 148 | 0, 149 | XCORE_CODE, 150 | "XCore" 151 | ), 152 | }; 153 | 154 | for (int j = 0; j < platforms.length; j++) { 155 | System.out.println("****************"); 156 | System.out.println(String.format("Platform: %s", platforms[j].comment)); 157 | System.out.println(String.format("Code: %s", stringToHex(platforms[j].code))); 158 | System.out.println("Disasm:"); 159 | 160 | Capstone cs = new Capstone(platforms[j].arch, platforms[j].mode); 161 | if (platforms[j].syntax != 0) 162 | cs.setSyntax(platforms[j].syntax); 163 | 164 | Capstone.CsInsn[] all_insn = cs.disasm(platforms[j].code, 0x1000); 165 | 166 | for (int i = 0; i < all_insn.length; i++) { 167 | System.out.println(String.format("0x%x: \t%s\t%s", all_insn[i].address, 168 | all_insn[i].mnemonic, all_insn[i].opStr)); 169 | } 170 | System.out.printf("0x%x:\n\n", all_insn[all_insn.length-1].address + all_insn[all_insn.length-1].size); 171 | 172 | // Close when done 173 | cs.close(); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/test/java/capstone/TestArm.java: -------------------------------------------------------------------------------- 1 | package capstone;// Capstone Java binding 2 | // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 | 4 | import static capstone.Arm_const.*; 5 | 6 | public class TestArm { 7 | 8 | static byte[] hexString2Byte(String s) { 9 | // from http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java 10 | int len = s.length(); 11 | byte[] data = new byte[len / 2]; 12 | for (int i = 0; i < len; i += 2) { 13 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 14 | + Character.digit(s.charAt(i+1), 16)); 15 | } 16 | return data; 17 | } 18 | 19 | static final String ARM_CODE = "EDFFFFEB04e02de500000000e08322e5f102030e0000a0e30230c1e7000053e3000201f10540d0e8"; 20 | static final String ARM_CODE2 = "d1e800f0f02404071f3cf2c000004ff00001466c"; 21 | static final String THUMB_CODE2 = "4ff00001bde80088d1e800f018bfadbff3ff0b0c86f3008980f3008c4ffa99f6d0ffa201"; 22 | static final String THUMB_CODE = "7047eb4683b0c9681fb130bfaff32084"; 23 | 24 | public static Capstone cs; 25 | 26 | private static String hex(int i) { 27 | return Integer.toString(i, 16); 28 | } 29 | 30 | private static String hex(long i) { 31 | return Long.toString(i, 16); 32 | } 33 | 34 | public static void print_ins_detail(Capstone.CsInsn ins) { 35 | System.out.printf("0x%x:\t%s\t%s\n", ins.address, ins.mnemonic, ins.opStr); 36 | 37 | Arm.OpInfo operands = (Arm.OpInfo) ins.operands; 38 | 39 | if (operands.op.length != 0) { 40 | System.out.printf("\top_count: %d\n", operands.op.length); 41 | for (int c=0; c 0) 72 | System.out.printf("\t\t\toperands[%d].vector_index = %d\n", c, (i.vector_index)); 73 | if (i.shift.type != ARM_SFT_INVALID && i.shift.value > 0) 74 | System.out.printf("\t\t\tShift: %d = %d\n", i.shift.type, i.shift.value); 75 | if (i.subtracted) 76 | System.out.printf("\t\t\toperands[%d].subtracted = True\n", c); 77 | } 78 | } 79 | if (operands.writeback) 80 | System.out.println("\tWrite-back: True"); 81 | 82 | if (operands.updateFlags) 83 | System.out.println("\tUpdate-flags: True"); 84 | 85 | if (operands.cc != ARM_CC_AL && operands.cc != ARM_CC_INVALID) 86 | System.out.printf("\tCode condition: %d\n", operands.cc); 87 | 88 | if (operands.cpsMode > 0) 89 | System.out.printf("\tCPSI-mode: %d\n", operands.cpsMode); 90 | 91 | if (operands.cpsFlag > 0) 92 | System.out.printf("\tCPSI-flag: %d\n", operands.cpsFlag); 93 | 94 | if (operands.vectorData > 0) 95 | System.out.printf("\tVector-data: %d\n", operands.vectorData); 96 | 97 | if (operands.vectorSize > 0) 98 | System.out.printf("\tVector-size: %d\n", operands.vectorSize); 99 | 100 | if (operands.usermode) 101 | System.out.printf("\tUser-mode: True\n"); 102 | } 103 | 104 | public static void main(String argv[]) { 105 | 106 | final Test.platform[] all_tests = { 107 | new Test.platform(Capstone.CS_ARCH_ARM, Capstone.CS_MODE_ARM, hexString2Byte(ARM_CODE), "ARM"), 108 | new Test.platform(Capstone.CS_ARCH_ARM, Capstone.CS_MODE_THUMB, hexString2Byte(THUMB_CODE), "Thumb"), 109 | new Test.platform(Capstone.CS_ARCH_ARM, Capstone.CS_MODE_THUMB, hexString2Byte(ARM_CODE2), "Thumb-mixed"), 110 | new Test.platform(Capstone.CS_ARCH_ARM, Capstone.CS_MODE_THUMB, Capstone.CS_OPT_SYNTAX_NOREGNAME, hexString2Byte(THUMB_CODE2), "Thumb-2 & register named with numbers"), 111 | }; 112 | 113 | for (int i=0; i 0) 70 | System.out.printf("\t\t\tShift: type = %d, value = %d\n", i.shift.type, i.shift.value); 71 | if (i.ext != ARM64_EXT_INVALID) 72 | System.out.printf("\t\t\tExt: %d\n", i.ext); 73 | if (i.vas != ARM64_VAS_INVALID) 74 | System.out.printf("\t\t\tVector Arrangement Specifier: 0x%x\n", i.vas); 75 | if (i.vess != ARM64_VESS_INVALID) 76 | System.out.printf("\t\t\tVector Element Size Specifier: %d\n", i.vess); 77 | if (i.vector_index != -1) 78 | System.out.printf("\t\t\tVector Index: %d\n", i.vector_index); 79 | 80 | } 81 | } 82 | 83 | if (operands.writeback) 84 | System.out.println("\tWrite-back: True"); 85 | 86 | if (operands.updateFlags) 87 | System.out.println("\tUpdate-flags: True"); 88 | 89 | if (operands.cc != ARM64_CC_AL && operands.cc != ARM64_CC_INVALID) 90 | System.out.printf("\tCode-condition: %d\n", operands.cc); 91 | 92 | } 93 | 94 | public static void main(String argv[]) { 95 | 96 | final Test.platform[] all_tests = { 97 | new Test.platform(Capstone.CS_ARCH_ARM64, Capstone.CS_MODE_ARM, hexString2Byte(ARM64_CODE), "ARM-64"), 98 | }; 99 | 100 | for (int i=0; i 0) { 84 | System.out.printf("\timm_count: %d\n", count); 85 | for (int i=0; i