summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-08-23 19:46:30 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-08-23 19:46:30 (GMT)
commit3c5bdffd74d21f6c156730a91d3c78b59eb83b42 (patch)
treeaf5f6fd7ef987ce2668c32feecb4bca2cb96ce91
parent27d9a07db9d3bc2027003ba218acee940ae7ed3f (diff)
Added binary diffing examples.
-rw-r--r--misc/Makefile16
-rw-r--r--misc/elf2diff.c16
-rw-r--r--python/alla_net.py4
-rw-r--r--python/diffing_dex.py226
-rw-r--r--python/diffing_elf.py222
5 files changed, 482 insertions, 2 deletions
diff --git a/misc/Makefile b/misc/Makefile
new file mode 100644
index 0000000..a087b0b
--- /dev/null
+++ b/misc/Makefile
@@ -0,0 +1,16 @@
+
+BINARIES=elf2diff1 elf2diff2 hole
+
+all: $(BINARIES)
+
+hole: hole.cpp
+ g++ -o $@ $<
+
+elf2diff1: elf2diff.c
+ arm-linux-gnueabi-gcc -o $@ -DNUMBER=1 $<
+
+elf2diff2: elf2diff.c
+ arm-linux-gnueabi-gcc -o $@ -DNUMBER=2 $<
+
+clean:
+ rm -f $(BINARIES) *~
diff --git a/misc/elf2diff.c b/misc/elf2diff.c
new file mode 100644
index 0000000..1057d3c
--- /dev/null
+++ b/misc/elf2diff.c
@@ -0,0 +1,16 @@
+
+#include <stdio.h>
+
+static void show_me(int n)
+{
+ printf("Hello World %d\n", n);
+
+}
+
+int main(void)
+{
+ show_me(NUMBER);
+
+ return 0;
+
+}
diff --git a/python/alla_net.py b/python/alla_net.py
index 02c5f8d..78c0510 100644
--- a/python/alla_net.py
+++ b/python/alla_net.py
@@ -65,7 +65,7 @@ class NeuralNetwork():
self._o_error = y - o
self._o_delta = self._o_error * self.sigmoidPrime(o)
- # How much the hidden layer weights contributed to output error?
+ # How much the hidden layer weights contributed to output error?
self._z2_error = self._o_delta.dot(self._w2.T)
self._z2_delta = self._z2_error * self.sigmoidPrime(self._z2)
@@ -215,7 +215,7 @@ class DeepLearning():
inputs.append( self._vectorize_string(raw) )
- outputs.append( [ 1.0 if encrypted else 0.1 ] )
+ outputs.append( [ 1.0 if encrypted else 0.0 ] )
return inputs, outputs
diff --git a/python/diffing_dex.py b/python/diffing_dex.py
new file mode 100644
index 0000000..8eba15d
--- /dev/null
+++ b/python/diffing_dex.py
@@ -0,0 +1,226 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import argparse
+import sys
+import pychrysalide
+from pychrysalide.analysis.contents import FileContent
+from pychrysalide.analysis import LoadedBinary
+from pychrysalide.analysis.diffing import BinDiff, FingerprintList
+from pychrysalide.format.dex import DexFormat
+
+
+def display_matches(matches, methods):
+ """Show the matching routines."""
+
+ routine_a_name_len = len('Routine A')
+ routine_a_addr_len = len('Phys addr.')
+ routine_b_name_len = len('Routine B')
+ routine_b_addr_len = len('Phys addr.')
+
+ # Length computing
+
+ for match in matches:
+
+ routine_name = match['routine'].label
+
+ if len(routine_name) > routine_a_name_len:
+ routine_a_name_len = len(routine_name)
+
+ phys = '0x%x' % match['routine'].range.addr.phys
+
+ if len(phys) > routine_a_addr_len:
+ routine_a_addr_len = len(phys)
+
+ matching = match['matching']
+
+ for i in range(len(matching)):
+
+ routine_name = matching[i]['other'].label
+
+ if len(routine_name) > routine_b_name_len:
+ routine_b_name_len = len(routine_name)
+
+ phys = '0x%x' % matching[i]['other'].range.addr.phys
+
+ if len(phys) > routine_b_addr_len:
+ routine_b_addr_len = len(phys)
+
+ line = ' {:<%u} | {:>%u} | {:<%u} | {:>%u} | {:^%u}' \
+ % (routine_a_name_len, routine_a_addr_len, routine_b_name_len, routine_b_addr_len, len('Similarity'))
+
+ for meth in methods:
+
+ length = len(meth.name)
+
+ line += ' | {:^%u}' % length
+
+ # Columns display
+
+ names = []
+
+ for meth in methods:
+ names.append(meth.name)
+
+ header = line.format('Routine A', 'Phys addr.', 'Routine B', 'Phys addr.', 'Similarity', *names)
+
+ print(header)
+
+ print('-' * (len(header) + 2))
+
+ # Matches display
+
+ for match in matches:
+
+ matching = match['matching']
+
+ for i in range(len(matching)):
+
+ routine_a_name = match['routine'].label if i == 0 else ''
+
+ if i == 0:
+ phys_a = '0x%x' % match['routine'].range.addr.phys
+ else:
+ phys_a = ''
+
+ routine_b_name = matching[i]['other'].label
+
+ if i == 0:
+ phys_b = '0x%x' % matching[i]['other'].range.addr.phys
+ else:
+ phys_b = ''
+
+ similarity = '%.2f' % matching[i]['similarity']
+
+ values = [ 'X' if v else '' for v in list(matching[i]['values']) ]
+
+ print(line.format(routine_a_name, phys_a, routine_b_name, phys_b, similarity, *values))
+
+
+def display_unmatches(routines):
+ """Show the unmatching routines."""
+
+ name_len = len('Routine')
+ addr_len = len('Phys addr.')
+
+ # Length computing
+
+ for r in routines:
+
+ name = r.label
+
+ if len(name) > name_len:
+ name_len = len(name)
+
+ phys = '0x%x' % r.range.addr.phys
+
+ if len(phys) > addr_len:
+ addr_len = len(phys)
+
+ line = ' {:<%u} | {:>%u}' % (name_len, addr_len)
+
+ # Columns display
+
+ header = line.format('Routine', 'Phys addr.')
+
+ print(header)
+
+ print('-' * (len(header) + 2))
+
+ # Matches display
+
+ for r in routines:
+
+ phys = '0x%x' % r.range.addr.phys
+
+ print(line.format(r.label, phys))
+
+
+if __name__ == '__main__':
+ """Entry point."""
+
+ parser = argparse.ArgumentParser(description='readdex - Displays information about DEX files.', add_help=False)
+
+ parser.add_argument('-h', '--help', action='store_true', help='Display the command line options.')
+
+ parser.add_argument('dexfile1', type=str, help='The first object file to be examined')
+ parser.add_argument('dexfile2', type=str, help='The second object file to be examined')
+
+ args = parser.parse_args()
+
+ if args.help:
+ parser.print_help()
+ sys.exit(1)
+
+ cnt = FileContent(args.dexfile1)
+ fmt = DexFormat(cnt)
+ binary1 = LoadedBinary(fmt)
+
+ binary1.analyze_and_wait()
+
+ cnt = FileContent(args.dexfile2)
+ fmt = DexFormat(cnt)
+ binary2 = LoadedBinary(fmt)
+
+ binary2.analyze_and_wait()
+
+ fingerlist1 = FingerprintList(None, binary1, True)
+ print("list 1 ok")
+ fingerlist2 = FingerprintList(None, binary2, True)
+ print("list 1 ok")
+
+ diff = BinDiff(fingerlist1, fingerlist2)
+
+ print("analyzing...")
+
+ diff.analyze_and_wait()
+
+ print()
+
+ matches = diff.single_matches
+
+ if len(matches) > 0:
+
+ print('Single match routines')
+ print('=====================')
+ print()
+
+ display_matches(matches, fingerlist1.methods)
+
+ print()
+
+ matches = diff.multi_matches
+
+ if len(matches) > 0:
+
+ print('Multi match routines')
+ print('====================')
+ print()
+
+ display_matches(matches, fingerlist1.methods)
+
+ print()
+
+ unmatched = diff.first_unmatches
+
+ if len(unmatched) > 0:
+
+ print('First binary unmatched routines')
+ print('===============================')
+ print()
+
+ display_unmatches(unmatched)
+
+ print()
+
+ unmatched = diff.second_unmatches
+
+ if len(unmatched) > 0:
+
+ print('Second binary unmatched routines')
+ print('================================')
+ print()
+
+ display_unmatches(unmatched)
+
+ print()
diff --git a/python/diffing_elf.py b/python/diffing_elf.py
new file mode 100644
index 0000000..ccaaaa1
--- /dev/null
+++ b/python/diffing_elf.py
@@ -0,0 +1,222 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import argparse
+import sys
+import pychrysalide
+from pychrysalide.analysis.contents import FileContent
+from pychrysalide.analysis import LoadedBinary
+from pychrysalide.analysis.diffing import BinDiff, FingerprintList
+from pychrysalide.format.elf import ElfFormat
+
+
+def display_matches(matches, methods):
+ """Show the matching routines."""
+
+ routine_a_name_len = len('Routine A')
+ routine_a_addr_len = len('Virt addr.')
+ routine_b_name_len = len('Routine B')
+ routine_b_addr_len = len('Virt addr.')
+
+ # Length computing
+
+ for match in matches:
+
+ routine_name = match['routine'].label
+
+ if len(routine_name) > routine_a_name_len:
+ routine_a_name_len = len(routine_name)
+
+ virt = '0x%x' % match['routine'].range.addr.virt
+
+ if len(virt) > routine_a_addr_len:
+ routine_a_addr_len = len(virt)
+
+ matching = match['matching']
+
+ for i in range(len(matching)):
+
+ routine_name = matching[i]['other'].label
+
+ if len(routine_name) > routine_b_name_len:
+ routine_b_name_len = len(routine_name)
+
+ virt = '0x%x' % matching[i]['other'].range.addr.virt
+
+ if len(virt) > routine_b_addr_len:
+ routine_b_addr_len = len(virt)
+
+ line = ' {:<%u} | {:>%u} | {:<%u} | {:>%u} | {:^%u}' \
+ % (routine_a_name_len, routine_a_addr_len, routine_b_name_len, routine_b_addr_len, len('Similarity'))
+
+ for meth in methods:
+
+ length = len(meth.name)
+
+ line += ' | {:^%u}' % length
+
+ # Columns display
+
+ names = []
+
+ for meth in methods:
+ names.append(meth.name)
+
+ header = line.format('Routine A', 'Virt addr.', 'Routine B', 'Virt addr.', 'Similarity', *names)
+
+ print(header)
+
+ print('-' * (len(header) + 2))
+
+ # Matches display
+
+ for match in matches:
+
+ matching = match['matching']
+
+ for i in range(len(matching)):
+
+ routine_a_name = match['routine'].label if i == 0 else ''
+
+ if i == 0:
+ virt_a = '0x%x' % match['routine'].range.addr.virt
+ else:
+ virt_a = ''
+
+ routine_b_name = matching[i]['other'].label
+
+ if i == 0:
+ virt_b = '0x%x' % matching[i]['other'].range.addr.virt
+ else:
+ virt_b = ''
+
+ similarity = '%.2f' % matching[i]['similarity']
+
+ values = [ 'X' if v else '' for v in list(matching[i]['values']) ]
+
+ print(line.format(routine_a_name, virt_a, routine_b_name, virt_b, similarity, *values))
+
+
+def display_unmatches(routines):
+ """Show the unmatching routines."""
+
+ name_len = len('Routine')
+ addr_len = len('Virt addr.')
+
+ # Length computing
+
+ for r in routines:
+
+ name = r.label
+
+ if len(name) > name_len:
+ name_len = len(name)
+
+ virt = '0x%x' % r.range.addr.virt
+
+ if len(virt) > addr_len:
+ addr_len = len(virt)
+
+ line = ' {:<%u} | {:>%u}' % (name_len, addr_len)
+
+ # Columns display
+
+ header = line.format('Routine', 'Virt addr.')
+
+ print(header)
+
+ print('-' * (len(header) + 2))
+
+ # Matches display
+
+ for r in routines:
+
+ virt = '0x%x' % r.range.addr.virt
+
+ print(line.format(r.label, virt))
+
+
+if __name__ == '__main__':
+ """Entry point."""
+
+ parser = argparse.ArgumentParser(description='readelf - Displays information about ELF files.', add_help=False)
+
+ parser.add_argument('-h', '--help', action='store_true', help='Display the command line options.')
+
+ parser.add_argument('elffile1', type=str, help='The first object file to be examined')
+ parser.add_argument('elffile2', type=str, help='The second object file to be examined')
+
+ args = parser.parse_args()
+
+ if args.help:
+ parser.print_help()
+ sys.exit(1)
+
+ cnt = FileContent(args.elffile1)
+ fmt = ElfFormat(cnt)
+ binary1 = LoadedBinary(fmt)
+
+ binary1.analyze_and_wait()
+
+ cnt = FileContent(args.elffile2)
+ fmt = ElfFormat(cnt)
+ binary2 = LoadedBinary(fmt)
+
+ binary2.analyze_and_wait()
+
+ fingerlist1 = FingerprintList(None, binary1, True)
+ fingerlist2 = FingerprintList(None, binary2, True)
+
+ diff = BinDiff(fingerlist1, fingerlist2)
+
+ diff.analyze_and_wait()
+
+ print()
+
+ matches = diff.single_matches
+
+ if len(matches) > 0:
+
+ print('Single match routines')
+ print('=====================')
+ print()
+
+ display_matches(matches, fingerlist1.methods)
+
+ print()
+
+ matches = diff.multi_matches
+
+ if len(matches) > 0:
+
+ print('Multi match routines')
+ print('====================')
+ print()
+
+ display_matches(matches, fingerlist1.methods)
+
+ print()
+
+ unmatched = diff.first_unmatches
+
+ if len(unmatched) > 0:
+
+ print('First binary unmatched routines')
+ print('===============================')
+ print()
+
+ display_unmatches(unmatched)
+
+ print()
+
+ unmatched = diff.second_unmatches
+
+ if len(unmatched) > 0:
+
+ print('Second binary unmatched routines')
+ print('================================')
+ print()
+
+ display_unmatches(unmatched)
+
+ print()