summaryrefslogtreecommitdiff
path: root/examples/print_syscalls
diff options
context:
space:
mode:
authorBambu <arewehuman@hotmail.com>2016-08-25 22:04:12 -0400
committerBambu <arewehuman@hotmail.com>2016-08-25 22:04:12 -0400
commit5a42aec73a77a3a54baf054cde9047533709be31 (patch)
tree66c875b90a8d89cb323aa6b9e329a851098a39f6 /examples/print_syscalls
parent3e5ce8d9f21378cd6453b6d5106a1acce675ffe1 (diff)
Removed dynamic linking. Added c++ version of arm-syscall python plugin. Renamed it since it works for more than just arm
Diffstat (limited to 'examples/print_syscalls')
-rw-r--r--examples/print_syscalls/Makefile54
-rw-r--r--examples/print_syscalls/src/arm-syscall.cpp115
2 files changed, 169 insertions, 0 deletions
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 <sys/stat.h>
+
+#include <iostream>
+#include <cstdlib>
+
+#include "binaryninjacore.h"
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+#ifndef __WIN32__
+#include <libgen.h>
+#include <dlfcn.h>
+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] << " <file_name>" << 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;
+}