mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-07-30 07:18:37 -09:00
Merge remote-tracking branch 'origin/ghidra1_Emulator'
Conflicts: gradle/root/eclipse.gradle
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
Module.manifest||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
data/cabextract-1.6.tar.gz||GPL 3||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
||||
0
GPL/CabExtract/settings.gradle
Normal file
0
GPL/CabExtract/settings.gradle
Normal file
@@ -1,13 +1,13 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"
|
||||
|
||||
rootProject.assembleDistribution {
|
||||
|
||||
doLast {
|
||||
// eliminate standard module lib directory
|
||||
def assemblePath = destinationDir.path + "/" + getZipPath(this.project)
|
||||
println "DELETE: ${assemblePath}/lib"
|
||||
delete assemblePath + "/lib"
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ eclipse.project.name = 'GPL DMG'
|
||||
*
|
||||
*********************************************************************************/
|
||||
sourceSets {
|
||||
|
||||
dmg {
|
||||
java {
|
||||
srcDir 'src/dmg/java'
|
||||
|
||||
@@ -16,3 +16,4 @@ data/os/win64/llio_amd64.dll||GPL 3||||END|
|
||||
data/os/win64/llio_i386.dll||GPL 3||||END|
|
||||
data/os/win64/llio_ia64.dll||GPL 3||||END|
|
||||
data/server_memory.cfg||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
||||
0
GPL/DMG/settings.gradle
Normal file
0
GPL/DMG/settings.gradle
Normal file
@@ -1,3 +1,4 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
##MODULE IP: Public Domain
|
||||
Module.manifest||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
src/demangler_gnu/README.txt||Public Domain||||END|
|
||||
|
||||
0
GPL/DemanglerGnu/settings.gradle
Normal file
0
GPL/DemanglerGnu/settings.gradle
Normal file
0
GPL/GnuDisassembler/Module.manifest
Normal file
0
GPL/GnuDisassembler/Module.manifest
Normal file
20
GPL/GnuDisassembler/README.txt
Normal file
20
GPL/GnuDisassembler/README.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
The GnuDisassembler extension module must be built using gradle prior to its' use within Ghidra.
|
||||
|
||||
This module provides the ability to leverage the binutils disassembler capabilities
|
||||
for various processors as a means of verifying Sleigh disassembler output syntax.
|
||||
|
||||
To build this extension for Linux or Mac OS X:
|
||||
|
||||
1. If building for an installation of Ghidra, copy the appropriate source distribution of
|
||||
binutils into this module's root directory. If building within a git clone of the full
|
||||
Ghidra source, copy binutils source distribution file into the ghidra.bin/GPL/GnuDisassembler
|
||||
directory.
|
||||
|
||||
The supported version and archive format is identified within the build.gradle file.
|
||||
If a different binutils distribution is used the build.gradle and/or buildGdis.gradle
|
||||
may require modification.
|
||||
|
||||
2. Run gradle from the module's root directory (see top of build.gradle file for
|
||||
specific instructions).
|
||||
|
||||
This resulting gdis executable will be located in build/os/<platform>.
|
||||
81
GPL/GnuDisassembler/build.gradle
Normal file
81
GPL/GnuDisassembler/build.gradle
Normal file
@@ -0,0 +1,81 @@
|
||||
// If extension module does not reside within the Ghidra GPL directory, the Ghidra installation directory
|
||||
// must be specified either by setting the GHIDRA_INSTALL_DIR environment variable or Gradle
|
||||
// project property:
|
||||
//
|
||||
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
|
||||
// > gradle build
|
||||
//
|
||||
// or
|
||||
//
|
||||
// > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra> build
|
||||
//
|
||||
// In addition, the appropriate binutils source distribution archive must be placed
|
||||
// within this module's directory (see below for binutils version and archive file naming.
|
||||
//
|
||||
// Gradle should be invoked from the directory of the extension module to build. Please see the
|
||||
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
|
||||
// for the correction version of Gradle to use for the Ghidra installation you specify.
|
||||
//
|
||||
// Build Prerequisite:
|
||||
// The appropriate binutils source distribution archive (see version and naming below) must be
|
||||
// obtained and placed appropriately prior to building the gdis executable. If working with
|
||||
// a full source distribution of Ghidra the binutils archive should be placed within the module's
|
||||
// shadow directory located within ghidra.bin (ghidra.bin/GPL/GnuDisassembler/). If building within
|
||||
// an unpacked distribution of Ghidra it should be placed directly within the module
|
||||
// directory once the extension has been installed/unpacked by Ghidra. The binutils referenced
|
||||
// by the script below may be downloaded from the following URL:
|
||||
//
|
||||
// https://ftp.gnu.org/pub/gnu/binutils/binutils-2.29.1.tar.bz2
|
||||
//
|
||||
|
||||
ext.binutils = "binutils-2.29.1"
|
||||
ext.binutilsDistro = "${binutils}.tar.bz2"
|
||||
|
||||
ext.ghidraInstallDir = null;
|
||||
|
||||
if (file("../gpl.gradle").exists()) {
|
||||
// Module is located within the Ghidra GPL directory
|
||||
ext.ghidraInstallDir = file("../..").getCanonicalPath()
|
||||
ext.binutilsLocation = file("${ghidraInstallDir}/../ghidra.bin/GPL/${name}").getCanonicalPath()
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
}
|
||||
else {
|
||||
// various module placements for Ghidra installations
|
||||
ext.binutilsLocation = projectDir
|
||||
if (file("../../../GPL/gpl.gradle").exists()) {
|
||||
// Handle GPL extension install within Ghidra Extensions directory
|
||||
ext.ghidraInstallDir = file("../../..").getCanonicalPath()
|
||||
}
|
||||
else {
|
||||
// Handle extension install outside of Ghidra installation - must specify Ghidra install path
|
||||
if (System.env.GHIDRA_INSTALL_DIR) {
|
||||
ext.ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
|
||||
}
|
||||
else if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
|
||||
ext.ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
|
||||
}
|
||||
}
|
||||
if (ghidraInstallDir) {
|
||||
if (ghidraInstallDir.replace("\\","/").endsWith("/")) {
|
||||
ext.ghidraInstallDir = ghidraInstallDir.substring(0, ghidraInstallDir.length()-1)
|
||||
}
|
||||
println "Building with Ghidra installation at $ghidraInstallDir"
|
||||
apply from: new File(ghidraInstallDir).getCanonicalPath() + "/GPL/gpl.gradle"
|
||||
}
|
||||
else {
|
||||
throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
|
||||
}
|
||||
}
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
// Handle integrated Ghidra build - do not build gdis native
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLExtension.gradle"
|
||||
delete file("build/os"); // remove any prior build of gdis
|
||||
}
|
||||
else {
|
||||
apply from: "${ghidraInstallDir}/GPL/nativeBuildProperties.gradle"
|
||||
apply from: "buildGdis.gradle"
|
||||
}
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Xtra GPL GnuDisassembler'
|
||||
169
GPL/GnuDisassembler/buildGdis.gradle
Normal file
169
GPL/GnuDisassembler/buildGdis.gradle
Normal file
@@ -0,0 +1,169 @@
|
||||
/*******************************************************************************************
|
||||
* build.gradle file that applies this script must define two properties
|
||||
* 1) binutilsLocation - the folder where the original binutils.zip lives
|
||||
* 2) binutilsPrebuiltPath - the folder where the custom prebuilt binutils lives or will be built to
|
||||
*******************************************************************************************/
|
||||
|
||||
defaultTasks 'assemble'
|
||||
|
||||
ext.supportedPlatforms = ['osx64', 'linux64']
|
||||
|
||||
ext.binutilsResource = new File("${binutilsLocation}/${binutils}.tar.bz2")
|
||||
|
||||
def binutilsUnpackDir = file("${project.buildDir}/${binutils}/")
|
||||
|
||||
/******************************************************************************************
|
||||
*
|
||||
* For each supported platform build the following tasks:
|
||||
* buildBinutils_<platform> builds binutils for the platform
|
||||
* packageBinutilsDev_<platform> creates the built bundle of stuf we need to build gdis
|
||||
* unpackBinutilsPrebuilt_<platform> unpacks the built bundle to be used to build gdis
|
||||
*
|
||||
******************************************************************************************/
|
||||
|
||||
model {
|
||||
platforms {
|
||||
linux64 {
|
||||
architecture 'x86_64'
|
||||
operatingSystem 'linux'
|
||||
}
|
||||
osx64 {
|
||||
architecture 'x86_64'
|
||||
operatingSystem 'osx'
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
|
||||
gdis(NativeExecutableSpec) {
|
||||
|
||||
// NOTE: Windows build requires Mingw and is very very slow and touchy
|
||||
supportedPlatforms.each { targetPlatform it}
|
||||
|
||||
sources {
|
||||
c {
|
||||
source {
|
||||
srcDir "src/gdis/c"
|
||||
include "disasm_1.c"
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries {
|
||||
all {
|
||||
def binutilsArtifactsDir = file("build/binutils/${targetPlatform.name}")
|
||||
if ((toolChain in Gcc) || (toolChain in Clang)) {
|
||||
cCompiler.args "-I${binutilsArtifactsDir}/include", "-I${binutilsArtifactsDir}/bfd"
|
||||
linker.args "-L${binutilsArtifactsDir}/lib", "-lopcodes", "-lbfd", "-liberty", "-lz", "-ldl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileGdisOsx64ExecutableGdisC {
|
||||
dependsOn 'copyBinutilsArtifcats_osx64'
|
||||
}
|
||||
tasks.compileGdisLinux64ExecutableGdisC {
|
||||
dependsOn 'copyBinutilsArtifcats_linux64'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// change gdis linker output directory to build/os/<platform>
|
||||
gradle.taskGraph.whenReady {
|
||||
def p = this.project
|
||||
p.tasks.withType(LinkExecutable).each { t ->
|
||||
File f = t.linkedFile.getAsFile().get()
|
||||
String filename = f.getName()
|
||||
NativePlatform platform = t.targetPlatform.get()
|
||||
String osName = platform.getName()
|
||||
t.linkedFile = p.file("build/os/${osName}/$filename")
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************************
|
||||
* Task to unpack the standard binutils zip file
|
||||
*******************************************************************************************/
|
||||
task binutilsUnpack {
|
||||
description "Unpack binutils (for building gdis)"
|
||||
group "Native Build Dependencies"
|
||||
outputs.file { binutilsUnpackDir }
|
||||
onlyIf { !binutilsUnpackDir.exists() }
|
||||
|
||||
doFirst {
|
||||
if (!binutilsResource.exists()) {
|
||||
throw new GradleException("${binutilsResource.getCanonicalPath()} not found")
|
||||
}
|
||||
}
|
||||
|
||||
doLast {
|
||||
copy {
|
||||
from tarTree(resources.bzip2("${binutilsResource}"))
|
||||
into file("build")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
supportedPlatforms.each { platform ->
|
||||
|
||||
def buildName = "buildBinutils_${platform}"
|
||||
def postBuildName = "copyBinutilsArtifcats_${platform}"
|
||||
|
||||
def configDir = file("build/config/${platform}")
|
||||
def artifactsDir = file("build/binutils/${platform}")
|
||||
|
||||
task(buildName) {
|
||||
description "Configure and make binutils for $platform (for building gdis)"
|
||||
group "Native Prebuild Dependencies"
|
||||
|
||||
onlyIf { !configDir.exists() }
|
||||
|
||||
dependsOn binutilsUnpack
|
||||
|
||||
inputs.dir binutilsUnpackDir
|
||||
outputs.dir configDir
|
||||
|
||||
doLast {
|
||||
|
||||
File binutilsDir = binutilsUnpackDir
|
||||
delete configDir
|
||||
|
||||
println "Configuring binutils - config directory: $configDir"
|
||||
println "${binutilsDir}/configure --prefix=\"${configDir}\" --enable-targets=all --with-zlib=no --disable-nls --disable-werror"
|
||||
configDir.mkdirs();
|
||||
exec {
|
||||
workingDir configDir
|
||||
commandLine "${binutilsDir}/configure", "--prefix=${configDir}", "--enable-targets=all", "--with-zlib=no", "--disable-nls", "--disable-werror"
|
||||
}
|
||||
|
||||
println "Building binutils - config directory: $configDir"
|
||||
exec {
|
||||
commandLine "make", "-C", "${configDir}", "all"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task(postBuildName, type: Copy) {
|
||||
description "Copy binutil artifcacts for $platform (for building gdis)"
|
||||
group "Native Prebuild Dependencies"
|
||||
|
||||
dependsOn buildName
|
||||
|
||||
destinationDir = artifactsDir
|
||||
|
||||
into("/include") {
|
||||
from("${binutilsUnpackDir}/include")
|
||||
include "**/*.h"
|
||||
}
|
||||
into("/bfd") {
|
||||
from "${configDir}/bfd"
|
||||
include "**/*.h"
|
||||
}
|
||||
into("/lib") {
|
||||
from "${configDir}/bfd/libbfd.a"
|
||||
from "${configDir}/libiberty/libiberty.a"
|
||||
from "${configDir}/opcodes/libopcodes.a"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
13
GPL/GnuDisassembler/certification.manifest
Normal file
13
GPL/GnuDisassembler/certification.manifest
Normal file
@@ -0,0 +1,13 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: GPL 2
|
||||
##MODULE IP: Public Domain
|
||||
.project||GHIDRA||||END|
|
||||
Module.manifest||Public Domain||||END|
|
||||
README.txt||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
buildGdis.gradle||Public Domain||||END|
|
||||
data/arm_test1.s||Public Domain||||END|
|
||||
data/big.elf||Public Domain||||END|
|
||||
data/little.elf||Public Domain||||END|
|
||||
extension.properties||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
7
GPL/GnuDisassembler/data/arm_test1.s
Normal file
7
GPL/GnuDisassembler/data/arm_test1.s
Normal file
@@ -0,0 +1,7 @@
|
||||
.text
|
||||
__start:
|
||||
lw $t0, #4
|
||||
li $t1, #0
|
||||
add $t2, $t0, $t1
|
||||
done
|
||||
|
||||
BIN
GPL/GnuDisassembler/data/big.elf
Normal file
BIN
GPL/GnuDisassembler/data/big.elf
Normal file
Binary file not shown.
BIN
GPL/GnuDisassembler/data/little.elf
Normal file
BIN
GPL/GnuDisassembler/data/little.elf
Normal file
Binary file not shown.
6
GPL/GnuDisassembler/extension.properties
Normal file
6
GPL/GnuDisassembler/extension.properties
Normal file
@@ -0,0 +1,6 @@
|
||||
name=GnuDisassembler
|
||||
description=GNU Disassembler. Extension is delivered unbuilt. See module README.txt for build instructions.
|
||||
author=Ghidra Team
|
||||
createdOn=6/18/2019
|
||||
version=@extversion@
|
||||
gpl=true
|
||||
0
GPL/GnuDisassembler/settings.gradle
Normal file
0
GPL/GnuDisassembler/settings.gradle
Normal file
457
GPL/GnuDisassembler/src/gdis/c/disasm_1.c
Normal file
457
GPL/GnuDisassembler/src/gdis/c/disasm_1.c
Normal file
@@ -0,0 +1,457 @@
|
||||
/* ###
|
||||
* IP: Public Domain
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "bfd.h"
|
||||
#include "dis-asm.h"
|
||||
// #include "bucomm.h" // for set_default_bfd_target()
|
||||
|
||||
#include "gdis.h"
|
||||
|
||||
#define MAX_ASCII_CHAR_BYTE_STRING 256
|
||||
|
||||
|
||||
void listSupportedArchMachTargets(void)
|
||||
{
|
||||
const char** targetList;
|
||||
const char** archList;
|
||||
int i, j;
|
||||
|
||||
targetList = bfd_target_list();
|
||||
if(targetList != NULL){
|
||||
for(i=0, j=0; targetList[i] !=0; i++){
|
||||
printf("Supported Target: %s\n", targetList[i]);
|
||||
}
|
||||
}
|
||||
printf("\ndone with targetList.\n");
|
||||
|
||||
archList = bfd_arch_list();
|
||||
if(archList != NULL){
|
||||
for(i=0, j=0; archList[i] !=0; i++){
|
||||
printf("Supported Arch: %s\n", archList[i]);
|
||||
}
|
||||
}
|
||||
printf("\ndone with archList.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* sprintf to a "stream". */
|
||||
int objdump_sprintf (SFILE *f, const char *format, ...)
|
||||
{
|
||||
|
||||
int i;
|
||||
size_t n;
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
n = vsnprintf (f->buffer + f->pos, BUFF_SIZE, format, args);
|
||||
strncat(disassembled_buffer, f->buffer, n);
|
||||
va_end (args);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void configureDisassembleInfo(bfd* abfd,
|
||||
disassemble_info* info,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian end)
|
||||
{
|
||||
|
||||
memset(sfile.buffer, 0x00, BUFF_SIZE);
|
||||
|
||||
INIT_DISASSEMBLE_INFO(*info, stdout, objdump_sprintf);
|
||||
info->arch = (enum bfd_architecture) arch;
|
||||
info->mach = mach;
|
||||
info->flavour = bfd_get_flavour(abfd);
|
||||
info->endian = end;
|
||||
info->stream = (FILE*)&sfile; // set up our "buffer stream"
|
||||
info->display_endian = BFD_ENDIAN_LITTLE;
|
||||
/* Allow the target to customize the info structure. */
|
||||
disassemble_init_for_target(info);
|
||||
}
|
||||
|
||||
disassembler_ftype configureBfd(bfd* abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian endian,
|
||||
disassemble_info* DI,
|
||||
disassembler_ftype* disassemble_fn)
|
||||
{
|
||||
struct bfd_target *xvec;
|
||||
|
||||
abfd->flags |= EXEC_P;
|
||||
|
||||
|
||||
// set up xvec byteorder.
|
||||
xvec = (struct bfd_target *) malloc (sizeof (struct bfd_target));
|
||||
memset(xvec, 0x00, sizeof (struct bfd_target));
|
||||
memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
|
||||
xvec->byteorder = endian;
|
||||
abfd->xvec = xvec;
|
||||
|
||||
configureDisassembleInfo(abfd, DI, arch, mach, endian);
|
||||
if(endian == BFD_ENDIAN_BIG){
|
||||
bfd_big_endian(abfd);
|
||||
DI->display_endian = DI->endian = BFD_ENDIAN_BIG;
|
||||
}
|
||||
else{
|
||||
bfd_little_endian(abfd);
|
||||
DI->display_endian = DI->endian = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
|
||||
/*
|
||||
bfd_error_type err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
/* Use libopcodes to locate a suitable disassembler. */
|
||||
*disassemble_fn = NULL;
|
||||
*disassemble_fn = disassembler (arch, endian == BFD_ENDIAN_BIG, mach, abfd);
|
||||
if (!*disassemble_fn){
|
||||
printf("can't disassemble for arch 0x%08X, mach 0x%08lX\n", arch, mach);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return *disassemble_fn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
||||
disassemble_info *info,
|
||||
int* offset,
|
||||
PDIS_INFO pDisInfo)
|
||||
{
|
||||
int i, j, size = 0;
|
||||
int len = 0;
|
||||
|
||||
while ( *offset < info->buffer_length ) {
|
||||
/* call the libopcodes disassembler */
|
||||
memset(pDisInfo->disassemblyString, 0x00, MAX_DIS_STRING);
|
||||
|
||||
/* set the insn_info_valid bit to 0, as explained in BFD's
|
||||
* include/dis-asm.h. The bit will then be set to tell us
|
||||
* whether the decoder supports "extra" information about the
|
||||
* instruction.
|
||||
*/
|
||||
info->insn_info_valid = 0;
|
||||
|
||||
size = (*disassemble_fn)(info->buffer_vma + *offset, info);
|
||||
/* -- analyze disassembled instruction here -- */
|
||||
/* -- print any symbol names as labels here -- */
|
||||
|
||||
/* save off corresponding hex bytes */
|
||||
for ( j= 0,i = 0; i < 8; i++, j+=3) {
|
||||
if ( i < size ){
|
||||
sprintf(&(pDisInfo->bytesBufferAscii[j]), "%02X ", info->buffer[*offset + i]);
|
||||
pDisInfo->bytesBufferBin[i] = info->buffer[*offset + i];
|
||||
}
|
||||
}
|
||||
|
||||
/* add the augmented information to our disassembly info struct */
|
||||
pDisInfo->count = size;
|
||||
pDisInfo->insn_info_valid = info->insn_info_valid;
|
||||
pDisInfo->branch_delay_insns = info->branch_delay_insns;
|
||||
pDisInfo->data_size = info->data_size;
|
||||
pDisInfo->insn_type = info->insn_type;
|
||||
pDisInfo->target = info->target;
|
||||
pDisInfo->target2 = info->target2;
|
||||
|
||||
strcat(&(pDisInfo->disassemblyString[0]), disassembled_buffer);
|
||||
memset(disassembled_buffer, 0x00, BUFF_SIZE);
|
||||
|
||||
if(size != 0){
|
||||
*offset += size; /* advance position in buffer */
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
return size;
|
||||
}
|
||||
|
||||
void processBuffer(unsigned char* buff,
|
||||
int buff_len,
|
||||
bfd_vma buff_vma,
|
||||
disassembler_ftype disassemble_fn,
|
||||
struct disassemble_info* DI)
|
||||
{
|
||||
int bytesConsumed = -1;
|
||||
int offset = 0;
|
||||
int numDisassemblies = 0;
|
||||
int i;
|
||||
|
||||
DI->buffer = buff; /* buffer of bytes to disassemble */
|
||||
DI->buffer_length = buff_len; /* size of buffer */
|
||||
DI->buffer_vma = buff_vma; /* base RVA of buffer */
|
||||
|
||||
memset(disassemblyInfoBuffer, 0x00, sizeof(DIS_INFO)*MAX_NUM_ENTRIES);
|
||||
|
||||
while((buff_len - offset) > 0 && bytesConsumed != 0 && numDisassemblies < MAX_NUM_ENTRIES){
|
||||
bytesConsumed = disassemble_buffer( disassemble_fn, DI, &offset, &(disassemblyInfoBuffer[numDisassemblies++]));
|
||||
}
|
||||
for (i = 0; i < numDisassemblies; i++) {
|
||||
printf("%s\nInfo: %d,%d,%d,%d,%d\n", disassemblyInfoBuffer[i].disassemblyString,
|
||||
disassemblyInfoBuffer[i].count,
|
||||
disassemblyInfoBuffer[i].insn_info_valid,
|
||||
disassemblyInfoBuffer[i].branch_delay_insns,
|
||||
disassemblyInfoBuffer[i].data_size,
|
||||
disassemblyInfoBuffer[i].insn_type);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
struct disassemble_info DI;
|
||||
enum bfd_architecture arch;
|
||||
struct bfd_arch_info ai;
|
||||
unsigned long mach;
|
||||
enum bfd_endian endian;
|
||||
unsigned int end;
|
||||
bfd_vma offset;
|
||||
disassembler_ftype disassemble_fn;
|
||||
char *target = default_target;
|
||||
bfd *bfdfile;
|
||||
unsigned long a,m;
|
||||
char* byteString;
|
||||
char elf_file_location[MAX_ELF_FILE_PATH_LEN];
|
||||
char arch_str[256];
|
||||
char mach_str[256];
|
||||
|
||||
if ( argc < 8) {
|
||||
fprintf(stderr, "Usage: %s target-str, arch, mach, disassembly base-addr (for rel offsets instrs), full-path to Little and Big Elfs, big/little ascii-byte-string up to %d chars\n", argv[0], MAX_ASCII_CHAR_BYTE_STRING);
|
||||
listSupportedArchMachTargets();
|
||||
const char** archList = bfd_arch_list();
|
||||
const bfd_arch_info_type* ait;
|
||||
while(*archList != NULL){
|
||||
printf("checking against architecture: %s.\n", *archList);
|
||||
ait = NULL;
|
||||
ait = bfd_scan_arch(*archList);
|
||||
if(ait != NULL){
|
||||
printf("archname: %s arch: 0x%08X, mach: 0x%08lX.\n", ait->arch_name, ait->arch, ait->mach);
|
||||
}
|
||||
archList++;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
end = 0x00000000;
|
||||
endian = (enum bfd_endian) 0x00;
|
||||
mach = 0x00000000;
|
||||
arch = (enum bfd_architecture) 0x00;
|
||||
offset = 0x00000000;
|
||||
|
||||
sscanf(argv[2], "%128s", arch_str);
|
||||
sscanf(argv[3], "%18lX", &mach);
|
||||
sscanf(argv[4], "%10X", &end);
|
||||
sscanf(argv[5], "%18lX", &offset);
|
||||
|
||||
// if arch starts with 0x, then parse a number
|
||||
// else lookup the string in the table to get the arch, ignore the mach
|
||||
if (arch_str[0] == '0' && arch_str[1] == 'x') {
|
||||
sscanf(arch_str, "%10X", &arch);
|
||||
} else {
|
||||
const char** archList = bfd_arch_list();
|
||||
const bfd_arch_info_type* ait;
|
||||
while(*archList != NULL){
|
||||
ait = bfd_scan_arch(*archList);
|
||||
if(strcmp(arch_str, *archList)== 0){
|
||||
arch = ait->arch;
|
||||
mach = ait->mach;
|
||||
break;
|
||||
}
|
||||
ait = NULL;
|
||||
archList++;
|
||||
}
|
||||
if (ait == NULL) {
|
||||
printf("Couldn't find arch %s\n", arch_str);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
endian = (enum bfd_endian) end;
|
||||
/* open a correct type of file to fill in most of the required data. */
|
||||
|
||||
// printf("Arch is: 0x%08X, Machine is: 0x%08lX Endian is: 0x%02X.\n", arch, mach, endian);
|
||||
|
||||
memset(elf_file_location, 0x00, MAX_ELF_FILE_PATH_LEN);
|
||||
strncpy(elf_file_location, argv[6], MAX_ELF_FILE_PATH_LEN-sizeof(LITTLE_ELF_FILE)-2); // actual file name and nulls
|
||||
|
||||
// arg[7] is either a hex string or the string "stdin", which
|
||||
// triggers reading line by line from stdin.
|
||||
|
||||
byteString = argv[7];
|
||||
int stdin_mode = 2; // use CLI
|
||||
if (strcmp(byteString, "stdin") == 0) {
|
||||
stdin_mode = 1; // use STDIN
|
||||
}
|
||||
|
||||
unsigned char byteBuffer[BYTE_BUFFER_SIZE];
|
||||
char byteStringBuffer[(BYTE_BUFFER_SIZE*2)];
|
||||
|
||||
char addressStringBuffer[128];
|
||||
|
||||
if (endian == BFD_ENDIAN_BIG){
|
||||
strcat(elf_file_location, BIG_ELF_FILE);
|
||||
}
|
||||
else {
|
||||
strcat(elf_file_location, LITTLE_ELF_FILE);
|
||||
}
|
||||
|
||||
while (stdin_mode) {
|
||||
|
||||
// convert user input AsciiHex to Binary data for processing
|
||||
char tmp[3];
|
||||
unsigned int byteValue;
|
||||
tmp[0] = tmp[1] = tmp[2] = 0x00;
|
||||
|
||||
if (stdin_mode == 1) { // use stdin
|
||||
// read in the address
|
||||
if (fgets(addressStringBuffer, sizeof(addressStringBuffer), stdin)) {
|
||||
|
||||
//fprintf(stderr, "read: %s\n", addressStringBuffer);
|
||||
//char *p = strchr(addressStringBuffer, '\n');
|
||||
//if (p) {
|
||||
// *p = '\0';
|
||||
//}
|
||||
|
||||
sscanf(addressStringBuffer, "%18lX", &offset);
|
||||
}
|
||||
//getchar();
|
||||
// read in the ASCII hex string from stdin
|
||||
if (fgets(byteStringBuffer, sizeof(byteStringBuffer), stdin)) {
|
||||
|
||||
//fprintf(stderr, "read: %s\n", byteStringBuffer);
|
||||
// remove trailing newline
|
||||
char *p = strchr(byteStringBuffer, '\n');
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
}
|
||||
//if (strcmp(byteStringBuffer, "EOF") == 0) {
|
||||
//return 0; // terminate on EOF string
|
||||
//}
|
||||
} else {
|
||||
fprintf(stderr, "exiting, no ASCII hex found\n");
|
||||
return 0; // finished! #TODO
|
||||
}
|
||||
|
||||
} else {
|
||||
if(strlen(byteString) > BYTE_BUFFER_SIZE*2) {
|
||||
fprintf(stderr, "Max ascii string size is %d you provided: %lu chars. Exiting.\n", BYTE_BUFFER_SIZE*2,
|
||||
strlen(byteString));
|
||||
exit(-1);
|
||||
}
|
||||
strncpy(byteStringBuffer, byteString, BYTE_BUFFER_SIZE*2);
|
||||
stdin_mode = 0; // break out of the while loop
|
||||
}
|
||||
|
||||
int size = strlen(byteStringBuffer);
|
||||
if((size % 2) != 0){
|
||||
fprintf(stderr, "need even-number of ascii chars for byte-stream: (offset: %08lx, %s, %ld)\n", offset, byteStringBuffer, strlen(byteStringBuffer));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(byteBuffer, 0x00, BYTE_BUFFER_SIZE);
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// check to make sure chars are only valid HEX.
|
||||
//
|
||||
int i, j;
|
||||
for(i=j=0; (i < size) && (j < BYTE_BUFFER_SIZE); i+=2, j++){
|
||||
tmp[0] = byteStringBuffer[i];
|
||||
tmp[1] = byteStringBuffer[i+1];
|
||||
tmp[2] = 0;
|
||||
sscanf(tmp, "%02X", &byteValue);
|
||||
byteBuffer[j] = (unsigned char)byteValue;
|
||||
}
|
||||
|
||||
/*
|
||||
for(j=0; j < BYTE_BUFFER_SIZE; j++){
|
||||
printf("0x%02X ", byteBuffer[j]);
|
||||
}
|
||||
*/
|
||||
|
||||
bfd_init( );
|
||||
target = argv[1];
|
||||
bfd_set_default_target(target);
|
||||
|
||||
// printf("Debug: BFD sample file: %s\n", elf_file_location);
|
||||
// printf("Debug: LITTLE: %s\n", LITTLE_ELF_FILE);
|
||||
// printf("Debug: BIG: %s\n", BIG_ELF_FILE);
|
||||
|
||||
if(endian == BFD_ENDIAN_BIG){
|
||||
bfdfile = bfd_openr(elf_file_location, target );
|
||||
if ( ! bfdfile ) {
|
||||
printf("Error opening BIG ELF file: %s\n", elf_file_location);
|
||||
bfd_perror( "Error on bfdfile" );
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
else{
|
||||
bfdfile = bfd_openr(elf_file_location, target );
|
||||
if ( ! bfdfile ) {
|
||||
printf("Error opening LITTLE ELF file: %s\n", elf_file_location);
|
||||
// bfdfile = bfd_openr(elf_file_location, target );
|
||||
bfd_perror( "Error on bfdfile" );
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
|
||||
memset((void*) &DI, 0x00, sizeof(struct disassemble_info));
|
||||
|
||||
disassemble_fn = NULL;
|
||||
|
||||
// important set up!
|
||||
//---------------------------------------
|
||||
ai.arch = arch;
|
||||
ai.mach = mach;
|
||||
bfd_set_arch_info(bfdfile, &ai);
|
||||
//---------------------------------------
|
||||
|
||||
/*
|
||||
bfd_error_type err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
configureBfd(bfdfile, arch, mach, endian, &DI, &disassemble_fn);
|
||||
|
||||
/*
|
||||
err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
if (disassemble_fn == NULL){
|
||||
fprintf(stderr, "Error: disassemble_fn is NULL. Nothing I can do.\n");
|
||||
exit(1);
|
||||
}
|
||||
else{
|
||||
/*
|
||||
printf("the disassemble_fn func pointer is: 0x%08X.\n", disassemble_fn);
|
||||
printf("We can try to disassemble for this arch/mach. calling disassemble_init_for_target().\n");
|
||||
*/
|
||||
disassemble_init_for_target(&DI);
|
||||
|
||||
// go diassemble the buffer and build up the result in a accumulator string buffer.
|
||||
processBuffer(byteBuffer, size >> 1, offset, disassemble_fn, &DI); //
|
||||
|
||||
}
|
||||
|
||||
free((void*)bfdfile->xvec);
|
||||
bfd_close(bfdfile);
|
||||
|
||||
printf("EOF\n");
|
||||
fflush(stdout);
|
||||
|
||||
} // while loop on lines of stdin
|
||||
|
||||
return 0;
|
||||
}
|
||||
94
GPL/GnuDisassembler/src/gdis/c/gdis.h
Normal file
94
GPL/GnuDisassembler/src/gdis/c/gdis.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* ###
|
||||
* IP: Public Domain
|
||||
*/
|
||||
#ifndef _GDIS_H_
|
||||
#define _GDIS_H_
|
||||
|
||||
#define BYTE_BUFFER_SIZE 128
|
||||
|
||||
#define LITTLE_ELF_FILE "little.elf" // built for intel x64
|
||||
#define BIG_ELF_FILE "big.elf"
|
||||
|
||||
#define BUFF_SIZE 128
|
||||
|
||||
#define MAX_DIS_STRING 128
|
||||
#define MAX_BYTES_STRING 64
|
||||
#define MAX_BYTES 64
|
||||
#define MAX_NUM_ENTRIES 64
|
||||
#define MAX_ELF_FILE_PATH_LEN 512
|
||||
|
||||
|
||||
typedef struct _DIS_INFO_{
|
||||
char disassemblyString[MAX_DIS_STRING];
|
||||
char bytesBufferAscii[MAX_BYTES_STRING];
|
||||
unsigned char bytesBufferBin[MAX_BYTES];
|
||||
|
||||
int count; /* Number of bytes consumed */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
} DIS_INFO, *PDIS_INFO;
|
||||
|
||||
static DIS_INFO disassemblyInfoBuffer[MAX_NUM_ENTRIES];
|
||||
|
||||
char mnemonic[32] = {0}, src[32] = {0}, dest[32] = {0}, arg[32] = {0};
|
||||
char disassembled_buffer[BUFF_SIZE];
|
||||
|
||||
|
||||
/* Pseudo FILE object for strings. */
|
||||
typedef struct
|
||||
{
|
||||
// char *buffer;
|
||||
char buffer[BUFF_SIZE];
|
||||
size_t pos;
|
||||
size_t alloc;
|
||||
} SFILE;
|
||||
|
||||
|
||||
static SFILE sfile;
|
||||
|
||||
static char *default_target = NULL; /* Default at runtime. */
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void listSupportedArchMachTargets(void);
|
||||
|
||||
int objdump_sprintf (SFILE *f, const char *format, ...);
|
||||
|
||||
void configureDisassembleInfo(bfd* abfd,
|
||||
disassemble_info* info,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian end);
|
||||
|
||||
disassembler_ftype configureBfd(bfd* abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian endian,
|
||||
disassemble_info* DI,
|
||||
disassembler_ftype* disassemble_fn);
|
||||
|
||||
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
||||
disassemble_info *info,
|
||||
int* offset,
|
||||
PDIS_INFO pDisInfo);
|
||||
|
||||
void processBuffer(unsigned char* buff,
|
||||
int buff_len,
|
||||
bfd_vma buff_vma,
|
||||
disassembler_ftype disassemble_fn,
|
||||
struct disassemble_info* DI);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: Public Domain
|
||||
build.gradle||Public Domain||||END|
|
||||
gpl.gradle||Public Domain||||END|
|
||||
nativeBuildProperties.gradle||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
project.ext.BIN_REPO = file("${projectDir}/../../ghidra.bin").absolutePath
|
||||
|
||||
// BIN_REPO only useable in full Ghidra source configuration
|
||||
project.ext.BIN_REPO = file("../../../ghidra.bin").absolutePath
|
||||
|
||||
project.ext.set("OS_NAMES", ["osx64", "win32", "win64", "linux64"])
|
||||
|
||||
/*********************************************************************************
|
||||
* Returns the local platform name.
|
||||
*********************************************************************************/
|
||||
String getCurrentPlatformName() {
|
||||
ext.getCurrentPlatformName = {
|
||||
|
||||
String osName = System.getProperty("os.name")
|
||||
String archName = System.getProperty("os.arch")
|
||||
@@ -37,10 +39,13 @@ String getCurrentPlatformName() {
|
||||
* Helper method that returns a file that is the same relative location in the bin repo
|
||||
* as the given project is in its repo.
|
||||
******************************************************************************************/
|
||||
File getProjectLocationInBinRepo(Project p) {
|
||||
String relativePath = getGhidraRelativePath(p)
|
||||
|
||||
ext.getProjectLocationInBinRepo = {
|
||||
String relativePath = getGhidraRelativePath(this.project)
|
||||
println("RELATIVE: $relativePath")
|
||||
File binRepoRootProject = new File("${BIN_REPO}")
|
||||
if (!binRepoRootProject.isDirectory()) {
|
||||
throw new GradleException("Task requires Ghidra source and ghidra.bin")
|
||||
}
|
||||
return new File(binRepoRootProject, relativePath)
|
||||
}
|
||||
/****************************************************************************************
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
include "DemanglerGnu"
|
||||
include "DMG"
|
||||
include "CabExtract"
|
||||
Reference in New Issue
Block a user