From 5a42aec73a77a3a54baf054cde9047533709be31 Mon Sep 17 00:00:00 2001 From: Bambu Date: Thu, 25 Aug 2016 22:04:12 -0400 Subject: Removed dynamic linking. Added c++ version of arm-syscall python plugin. Renamed it since it works for more than just arm --- examples/print_syscalls/Makefile | 54 +++++++++++++ examples/print_syscalls/src/arm-syscall.cpp | 115 ++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 examples/print_syscalls/Makefile create mode 100644 examples/print_syscalls/src/arm-syscall.cpp (limited to 'examples/print_syscalls') diff --git a/examples/print_syscalls/Makefile b/examples/print_syscalls/Makefile new file mode 100644 index 00000000..54fd1237 --- /dev/null +++ b/examples/print_syscalls/Makefile @@ -0,0 +1,54 @@ +# Path to prebuilt libbinaryninjaapi.a +BINJA_API_A := ../../bin/libbinaryninjaapi.a + +# Path to binaryninjaapi.h and json +INC := -I../../ + +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) + # Path to binaryninja install + BINJAPATH := $(HOME)/binaryninja/ + CC := g++ +else + BINJAPATH := /Applications/Binary\ Ninja.app/Contents/MacOS + CC := $(shell xcrun -f clang++) +endif + +SRCDIR := src +BUILDDIR := build +TARGETDIR := bin + +TARGETNAME := print_syscalls +TARGET := $(TARGETDIR)/$(TARGETNAME) + +SRCEXT := cpp +SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT)) +OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o)) + +LIBS := -L $(BINJAPATH) -lbinaryninjacore +CFLAGS := -c -std=gnu++11 -O2 -Wall -W -fPIC -pipe -ggdb +ifeq ($(UNAME_S),Darwin) + CFLAGS += -arch x86_64 -pipe -stdlib=libc++ +endif + +all: $(TARGET) + +ifeq ($(UNAME_S),Linux) +$(TARGET): $(OBJECTS) + @mkdir -p $(TARGETDIR) + $(CC) $^ $(BINJA_API_A) $(LIBS) -Wl,-rpath=$(BINJAPATH) -ldl -o $@ +else +$(TARGET): $(OBJECTS) + @mkdir -p $(TARGETDIR) + $(CC) $^ $(BINJA_API_A) $(LIBS) -o $@ + install_name_tool -change @rpath/libbinaryninjacore.dylib $(BINJAPATH)/libbinaryninjacore.dylib $@ +endif + +$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT) + @mkdir -p $(BUILDDIR) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + $(RM) -r $(BUILDDIR) $(TARGETDIR) + +.PHONY: clean diff --git a/examples/print_syscalls/src/arm-syscall.cpp b/examples/print_syscalls/src/arm-syscall.cpp new file mode 100644 index 00000000..3424619b --- /dev/null +++ b/examples/print_syscalls/src/arm-syscall.cpp @@ -0,0 +1,115 @@ +/* + * Outputs the syscall numbers called by a binary. + */ + +#include + +#include +#include + +#include "binaryninjacore.h" +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + +#ifndef __WIN32__ +#include +#include +string get_plugins_directory() +{ + Dl_info info; + if (!dladdr((void *)BNGetBundledPluginDirectory, &info)) + return NULL; + + stringstream ss; + ss << dirname((char *)info.dli_fname) << "/plugins/"; + return ss.str(); +} +#else +string get_plugins_directory() +{ + return "C:\\Program Files\\Vector35\\Binary Ninja\\plugins\\"; +} +#endif + +bool is_file(char *fname) +{ + struct stat buf; + if (stat(fname, &buf) == 0 && (buf.st_mode & S_IFREG) == S_IFREG) + return true; + + return false; +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + cerr << "USAGE: " << argv[0] << " " << endl; + exit(-1); + } + + char *fname = argv[1]; + if (!is_file(fname)) { + cerr << "Error: " << fname << " is not a regular file" << endl; + exit(-1); + } + + /* In order to initiate the bundled plugins properly, the location + * of where bundled plugins directory is must be set. Since + * libbinaryninjacore is in the path get the path to it and use it to + * determine the plugins directory */ + SetBundledPluginDirectory(get_plugins_directory()); + InitCorePlugins(); + InitUserPlugins(); + + auto bd = BinaryData(new FileMetadata(), fname); + BinaryView *bv = 0; + + for (auto type : BinaryViewType::GetViewTypesForData(&bd)) { + if (type->GetName() != "Raw") { + bv = type->Create(&bd); + break; + } + } + + if (!bv || bv->GetTypeName() == "Raw"){ + cerr << "Error: Unable to get any other view type besides Raw"; + exit(-1); + } + + bv->UpdateAnalysis(); + while (bv->GetAnalysisProgress().state != IdleState); + + auto arch = bv->GetDefaultArchitecture(); + auto platform = bv->GetDefaultPlatform(); + + auto cc = platform->GetSystemCallConvention(); + if (!cc) { + cerr << "Error: No system call conventions found for " + << platform->GetName() << endl; + exit(-1); + } + + auto reg = cc->GetIntegerArgumentRegisters()[0]; + + for (Function *func : bv->GetAnalysisFunctionList()) { + auto il_func = func->GetLowLevelIL(); + + for (size_t i = 0; i < il_func->GetInstructionCount(); i++) { + auto instr = (*il_func)[il_func->GetIndexForInstruction(i)]; + + if (instr.operation == LLIL_SYSCALL) { + auto reg_value = func->GetRegisterValueAtLowLevelILInstruction(i, reg); + + cout << "System call address: 0x" + << hex << instr.address + << " - " + << dec << reg_value.value + << endl; + } + } + } + + return 0; +} -- cgit v1.3.1 From 1f7523ce2b1edac1014d781fc771d5b82568e2f1 Mon Sep 17 00:00:00 2001 From: Andrew Lamoureux Date: Wed, 15 Mar 2017 18:13:07 -0400 Subject: build explanation, windows make files --- Makefile.win | 23 +++++++++++++++++++++++ README.md | 13 +++++++++++++ examples/bin-info/Makefile.win | 9 +++++++++ examples/breakpoint/Makefile.win | 16 ++++++++++++++++ examples/print_syscalls/Makefile.win | 9 +++++++++ 5 files changed, 70 insertions(+) create mode 100644 Makefile.win create mode 100644 examples/bin-info/Makefile.win create mode 100644 examples/breakpoint/Makefile.win create mode 100644 examples/print_syscalls/Makefile.win (limited to 'examples/print_syscalls') diff --git a/Makefile.win b/Makefile.win new file mode 100644 index 00000000..ea95ba7b --- /dev/null +++ b/Makefile.win @@ -0,0 +1,23 @@ +CFLAGS = /EHsc /DWIN32 + +TARGETDIR = bin +TARGETNAME = libbinaryninjaapi.lib +TARGET = .\$(TARGETDIR)\$(TARGETNAME) + +OBJS = architecture.obj backgroundtask.obj basicblock.obj binaryninjaapi.obj binaryreader.obj binaryview.obj binaryviewtype.obj binarywriter.obj callingconvention.obj databuffer.obj demangle.obj fileaccessor.obj filemetadata.obj function.obj functiongraph.obj functiongraphblock.obj functionrecognizer.obj interaction.obj log.obj lowlevelil.obj mainthread.obj platform.obj plugin.obj scriptingprovider.obj tempfile.obj transform.obj type.obj update.obj jsoncpp.obj + +$(TARGET): $(OBJS) + if not exist $(TARGETDIR) mkdir $(TARGETDIR) + lib $(OBJS) /OUT:$(TARGET) + +jsoncpp.obj: json\jsoncpp.cpp + cl $(CFLAGS) /I. /c json\jsoncpp.cpp + +# nmake "inference rules" are gnu make "pattern rules" +.cpp.obj: + cl $(CFLAGS) /c $< + +clean: + if exist *.obj del *.obj + if exist $(TARGETDIR) del /Q /S $(TARGETDIR) + diff --git a/README.md b/README.md index 0bb4ee9b..be6c0b47 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,16 @@ If interested in contributing, first please read and sign the [Contribution Lice The issue tracker for this repository tracks not only issues with the source code contained here but also the broader Binary Ninja product. +## Building + +Starting mid March 2017, the C++ portion of this API can be built into a static library (.a, .lib) that binary plugins can link against. Use Makefile on MacOS, Linux, and Windows mingw environments, and Makefile.win (nmake file) for Windows Visual Studio environment (nmake -f). + +The compiled API contains names and functions you can use from your plugins, but most of the implementation is missing until you link up against libbinaryninjacore.dylib or libbinaryninjacore.dll (via import file libbinaryninjacore.lib). See the ./examples. + +Since BinaryNinja is a 64-bit only product, ensure that you are using a 64-bit compiling and linking environment. Errors on windows like LNK1107 might indicate that your bits don't match. + +## Examples + +* bin-info is a standalone executable that prints some information about a given binary to stdout +* breakpoint is a plugin that allows you to select a region within an x86 binary and use the context menu to fill it with breakpoint bytes +* print_syscalls is a standalone executable that prints the syscalls used in a given binary diff --git a/examples/bin-info/Makefile.win b/examples/bin-info/Makefile.win new file mode 100644 index 00000000..b65bfb86 --- /dev/null +++ b/examples/bin-info/Makefile.win @@ -0,0 +1,9 @@ +BINJA_API_INC_PATH = ..\..\ +BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib +BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib" + +FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB) + +bininfo: ./src/bin-info.cpp + if not exist bin mkdir bin + cl ./src/bin-info.cpp $(FLAGS) /Fe:.\bin\bininfo diff --git a/examples/breakpoint/Makefile.win b/examples/breakpoint/Makefile.win new file mode 100644 index 00000000..00cbbfa1 --- /dev/null +++ b/examples/breakpoint/Makefile.win @@ -0,0 +1,16 @@ +BINJA_API_INC_PATH = ..\..\ +BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib +BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib" + +FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB) + +bininfo.dll: ./src/breakpoint.cpp + if not exist bin mkdir bin + cl ./src/breakpoint.cpp /LD $(FLAGS) /OUT:.\bin\breakpoint.dll + +clean: + if exist *.obj del *.obj + if exist *.exp del *.exp + if exist *.lib del *.lib + if exist *.dll del *.dll + if exist .\bin del /S /Q bin diff --git a/examples/print_syscalls/Makefile.win b/examples/print_syscalls/Makefile.win new file mode 100644 index 00000000..afc0cbd8 --- /dev/null +++ b/examples/print_syscalls/Makefile.win @@ -0,0 +1,9 @@ +BINJA_API_INC_PATH = ..\..\ +BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib +BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib" + +FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB) + +print_syscalls: ./src/arm-syscall.cpp + if not exist bin mkdir bin + cl ./src/arm-syscall.cpp $(FLAGS) /Fe:.\bin\print_syscalls -- cgit v1.3.1