GithubHelp home page GithubHelp logo

quarkslab / binbloom Goto Github PK

View Code? Open in Web Editor NEW
464.0 24.0 55.0 175 KB

Raw binary firmware analysis software

Home Page: https://www.quarkslab.com

License: Apache License 2.0

Makefile 0.13% C 99.22% M4 0.64%
binary-analysis embedded-systems firmware reverse-engineering

binbloom's Introduction

About

The purpose of this project is to analyse a raw binary firmware and determine automatically some of its features. This tool is compatible with all architectures as basically, it just does simple statistics on it.

Main features:

  • Loading address: binbloom can parse a raw binary firmware and determine its loading address.
  • Endianness: binbloom can use heuristics to determine the endianness of a firmware.
  • UDS Database: binbloom can parse a raw binary firmware and check if it contains an array containing UDS command IDs.

Download / Install

First, clone the git repository:

git clone https://github.com/quarkslab/binbloom.git
cd binbloom

To build the latest version (linux only):

autoreconf -i
./configure
make
sudo make install

Getting started

Determine the endianness and the base address of a firmware

binbloom firmware.bin

This command should give an output like this:

[i] 32-bit architecture selected.
[i] File read (20480 bytes)
[i] Endianness is LE                                
[i] 6 strings indexed                                    
[i] Found 3 base addresses to test                    
[i] Base address seems to be 0x60000000 (not sure)
 More base addresses to consider (just in case):
  0x005b5000 (0)
  0x0bcd0000 (0)

In this output, the third line displays the guessed endianness (LE, little-endian) and the sixth line gives the guessed address (0x60000000). 6 text strings and 3 possible base addresses have been identified. If architecture is not specified, 32-bit architecture is considered by default.

The value in parenthesis after each candidate address is the corresponding score. The higher the score, the likelier the address.

Determine the endianness and the base address of a 64-bit firmware

binbloom -a 64 firmware.bin
[i] 64-bit architecture selected.
[i] File read (327680 bytes)
[i] Endianness is LE                                
[i] 717 strings indexed                                  
[i] Found 7535 base addresses to test                 
[i] Base address found: 0x0000000000010000.                          
 More base addresses to consider (just in case):
  0x000000000000e000 (276)
  0x000000000000f000 (242)
  0x0000000000011000 (175)
  0x000000000000d000 (167)
  0x000000000000b000 (121)
  0x0000000000013000 (107)
  0x0000000000012000 (100)
  [...]

The -a option tells binbloom to consider a 64-bit firmware, the above output shows a guessed base address of 0x10000.

Force the endianness if binbloom does not get it right

When dealing with small firmwares (size < 10 Kbytes) binbloom endianness detection may not be reliable and give a false result that leads to unexpected base addresses. In this case, you can use the -e option to specify the endianness:

binbloom -e be firmware.bin

It then produces the following output:

[i] Selected big-endian architecture.
[i] File read (1048576 bytes)
[i] Endianness is BE
[i] 764 strings indexed                                  
[i] Found 18615 base addresses to test                
[i] Base address seems to be 0x00000000 (not sure).
 More base addresses to consider (just in case):
  0x3f740000 (121043)
  0x7ff48000 (61345)
  0x41140000 (59552)
  [...]

Endianness is then forced (in this case big-endian) and binbloom relies on this configuration to guess the base address.

Find the UDS database (for an ECU's firmware)

binbloom -a 32 -e be -b 0x0 firmware.bin
[i] 32-bit architecture selected.
[i] Selected big-endian architecture.
[i] Base address 0x0000000000000000 provided.
[i] 764 strings indexed                                  
Most probable UDS DB is located at @000ee8c8, found 7 different UDS RID
Identified structure:
struct {
	code *p_field_0;
	code *p_field_1;
	uint32_t dw_2;
}

This analysis is based on heuristics so it can give false positives. You have to read the list of potential UDS databases found by binbloom and check and see which one is the correct one, if any. Binbloom provides the identified structure in its output, allowing some disassemblers to parse the memory following the structure declaration.

Advanced options

You can speed up the base address lookup process by enabling multi-threading with the -t option. By default, a single thread is used.

binbloom -t 8 firmware.bin

A deep search mode, enable with the -d option, is also implemented but is still experimental. This mode may be useful in very rare occasions as it may find a valid base address when nothing else works, but it is a slower mode that may take some time to complete.

If you want the tool to display more information, use one or more -v options.

About

Authors

License

binbloom is provided under the Apache 2.0 license.

binbloom's People

Contributors

doegox avatar erdnaxe avatar liyansong2018 avatar virtualabs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

binbloom's Issues

Memory allocation problem

I just tried to test the tool on a Linux VM with a limited amount of RAM (4GB).
Whatever the binary I try to analyze, it always returns the same error:
binbloom: [...]/binbloom.c:592: main: Assertion `score_base_address' failed.

The reason is that, at line 591, the code unconditionally tries to allocate 4GB of RAM (minus 4 bytes).
591: score_base_address = (uint32_t *)calloc(1024 * 1024 * 1024 - 1, sizeof(uint32_t));
592: assert(score_base_address);

The calloc call fails, then program is aborted on line 592.

Null pointer and floating point exception due to unchecked file length.

Hi,

Because binbloom uses file_len/100 or file_len/1000, a divide by 0 error will occur when the length of the target file is less than 1000. In addition, there are additional null pointer errors in the 32-bit architecture.

PoC

Null pointer

$ ./src/binbloom -a 32 ~/poc 
[i] 32-bit architecture selected.
[i] File read (4 bytes)
AddressSanitizer:DEADLYSIGNAL                                                                                              
=================================================================
==5482==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x5605c7707d24 bp 0x0c3a00000012 sp 0x7ffd95573e30 T0)                                                                                                                    
==5482==The signal is caused by a READ memory access.                                                                      
==5482==Hint: address points to the zero page.
    #0 0x5605c7707d24 in detect_endianness /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1482
    #1 0x5605c770a7c2 in find_base_address /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1650
    #2 0x5605c76e6c87 in main /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:2069
    #3 0x7f34994017ec in __libc_start_main ../csu/libc-start.c:332
    #4 0x5605c76e74f9 in _start (/home/lys/Documents/workspace/my/binbloom/src/binbloom+0x74f9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1482 in detect_endianness
==5482==ABORTING

Floating point exception

$ ./src/binbloom -a 64 ~/poc                                                                                         1 ⨯
[i] 64-bit architecture selected.
[i] File read (4 bytes)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==5486==ERROR: AddressSanitizer: FPE on unknown address 0x559bc06a9a07 (pc 0x559bc06a9a07 bp 0xfffffffffffffffe sp 0x7fff96c4dab0 T0)                                                                                                                 
    #0 0x559bc06a9a07 in detect_endianness /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1440                   
    #1 0x559bc06ac7c2 in find_base_address /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1650
    #2 0x559bc0688c87 in main /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:2069
    #3 0x7f6bd81927ec in __libc_start_main ../csu/libc-start.c:332
    #4 0x559bc06894f9 in _start (/home/lys/Documents/workspace/my/binbloom/src/binbloom+0x74f9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/lys/Documents/workspace/my/binbloom/src/binbloom.c:1440 in detect_endianness
==5486==ABORTING

Memory leaks in endianness detection

:) Hi, binbloom registers masked addresses (LE and BE) in guessing endianness. However, these malloced addrtree_node will not be freed.

PoC

$ ./src/binbloom -a 32 ./src/binbloom
[i] 32-bit architecture selected.
[i] File read (486392 bytes)
[i] Endianness is LE                                                                                                       
[i] 1183 strings indexed                                                                                                   
[i] Found 11048 base addresses to test                                                                                     
[i] Base address seems to be 0x00000000 (not sure).                                                                        
 More base addresses to consider (just in case):
  0x249f1000 (0.50)
  0x081ea000 (0.13)
  0x8b442000 (0.11)
  0x00002000 (0.10)
  0x00001000 (0.06)
  0x00006000 (0.06)
  0x00007000 (0.05)
  0x00005000 (0.05)
  0x00008000 (0.05)
  0x00fc2000 (0.05)
  0x001b3000 (0.02)
  0x00196000 (0.02)
  0x000b2000 (0.01)
  0x01fc2000 (0.01)
  0x02fc2000 (0.00)
  0x03fc2000 (0.00)
  0x54fa4000 (0.00)
  0x54fa6000 (0.00)
  0x011f2000 (0.00)
  0x90622000 (0.00)
  0xf2fc2000 (0.00)
  0xf2fc3000 (0.00)
  0xe8fc2000 (0.00)
  0x90615000 (0.00)
  0x7ffba000 (0.00)
  0x5bfa4000 (0.00)
  0x5bfa6000 (0.00)
  0x0efad000 (0.00)
  0x47fc2000 (0.00)

=================================================================
==7815==ERROR: LeakSanitizer: detected memory leaks
                                                                                                                           
Direct leak of 4128 byte(s) in 2 object(s) allocated from:
    #0 0x7f6b0bd03e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145                  
    #1 0x55c776d05675 in addrtree_node_alloc /home/lys/Documents/workspace/my/binbloom/src/addrtree.c:12

Indirect leak of 21329376 byte(s) in 10334 object(s) allocated from:
    #0 0x7f6b0bd03e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145                  
    #1 0x55c776d06349 in addrtree_node_alloc /home/lys/Documents/workspace/my/binbloom/src/addrtree.c:12
    #2 0x55c776d06349 in addrtree_register_address /home/lys/Documents/workspace/my/binbloom/src/addrtree.c:77

SUMMARY: AddressSanitizer: 21333504 byte(s) leaked in 10336 allocation(s).

[Enhancement] Add support to more kinds of firmware

I found that if the correct base address is 0x08004800,binbloom can only find address just like 0x?????000,So I fix that as my PR。
But there is a new issue,when the correct base address is 0x3f80,binbloom failed too,and use the same way to fix can only make binbloom run overtime。
I think we can solve the problem by referring to https://github.com/soyersoyer/basefind2 ,i use this method on my ida script https://github.com/RandLily/iBAS ,it's nice。

byteswap.h is missing

Hi

I gave a quick try at binbloom on macOS and was pleasantly surprised on how effective it is with Mach-O slices!

Would you please be so kind to consider making it "accessible" to BSD users by removing Linux only header file byteswap.h dependency?

Thank you!

Receiving weird "Best loading address"

Apologies in advance, as I might have missed something.

I have a firmware binary (.bin format, ARMv6-M, Cortex-M0, LE) with a size of 0x322a0 that, upon running binbloom -f firmware.bin -e, then immediately following with binbloom -f firmware.bin -b, I receive Best loading address: fffdfe6a, which doesn't seem right.

Here's the full output for binbloom -f firmware.bin -b:

Loaded /home/user/firmware.bin, size:205472, bit:fffc0000, 0003ffff, nb_segments:16384, shift:18
End address:000322a0
Determining the endianness
Computing heuristics in big endian order:
Base: 00000000: unique pointers:1129, number of array elements:40654
Base: 00200000: unique pointers:382, number of array elements:224
40878
Computing score in little endian order:
Base: 00000000: unique pointers:1516, number of array elements:208048
Base: 20000000: unique pointers:561, number of array elements:236
208284
This firmware seems to be LITTLE ENDIAN
loaded 493 functions
Best scores for the loading address:
Base address:fffdfe6a, score:9
Base address:ffff6946, score:5

Best loading address: fffdfe6a
Saving function pointers for this base address...
Done.

Problems:

1. Obviously IDA will not allow me to load the firmware at that address as that's much larger than the size of the firmware. What happened? Fixed. Seemed to be running the tag_code() script incorrectly somehow.
2. When following your video here, I don't get the same output. For example, @44:20, notice the line Scanning with stride n. I don't have that. Would that be due to differences in architectures?

I've read over the readme a fair amount of times, but I'm not sure what I'm doing wrong.

Thanks for the assistance!

Does not compile on OSX

Feeling lazy for a PR with the proper ifdefs, but you get the idea:

$ git diff
diff --git a/binbloom.c b/binbloom.c
index 171765c..6a6f31b 100644
--- a/binbloom.c
+++ b/binbloom.c
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
-#include <malloc.h>
+#include <malloc/malloc.h>
 #include <assert.h>
 #include <unistd.h>
 #include <sys/types.h>

Otherwise:

$ make
gcc -O3 -Wall -Wextra binbloom.c -o binbloom
binbloom.c:21:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
         ^~~~~~~~~~
1 error generated.
make: *** [binbloom] Error 1

A heap-buffer-overflow has occurred in function read_pointer at binbloom-master/src/helpers.c:67:24.

Description

Some crashes occurred in function read_pointer at binbloom-master/src/helpers.c:67:24 when running program binbloom, this can reproduce on the latest commit.

Version

Binbloom 2.0
latest commithttps://github.com/quarkslab/binbloom/commit/b9aada98fa98924d7d3d90e638e865df9f9a2e53
Linux 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Command

./binbloom ./POC

Crashe

==487329==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x631000010f90 at pc 0x0000004d3963 bp 0x7ffece9f22d0 sp 0x7ffece9f22c8
READ of size 4 at 0x631000010f90 thread T0
#0 0x4d3962 in read_pointer /home/hjsz/fuzz_software/binbloom-master/src/helpers.c:67:24
#1 0x4cc0e5 in compute_candidates /home/hjsz/fuzz_software/binbloom-master/src/binbloom.c:1134:21
#2 0x4d0131 in find_base_address /home/hjsz/fuzz_software/binbloom-master/src/binbloom.c
#3 0x4d2127 in main /home/hjsz/fuzz_software/binbloom-master/src/binbloom.c:2102:17
#4 0x7f9ffd152082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
#5 0x41c3ed in _start (/home/hjsz/fuzz_software/binbloom-master/src/binbloom+0x41c3ed)

0x631000010f91 is located 0 bytes to the right of 67473-byte region [0x631000000800,0x631000010f91)
allocated by thread T0 here:
#0 0x494b2d in malloc (/home/hjsz/fuzz_software/binbloom-master/src/binbloom+0x494b2d)
#1 0x4cfd95 in find_base_address /home/hjsz/fuzz_software/binbloom-master/src/binbloom.c:1655:39
#2 0x7f9ffd152082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hjsz/fuzz_software/binbloom-master/src/helpers.c:67:24 in read_pointer
Shadow bytes around the buggy address:
0x0c627fffa1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627fffa1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627fffa1c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627fffa1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627fffa1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c627fffa1f0: 00 00[01]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627fffa200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627fffa210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627fffa220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627fffa230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627fffa240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==487329==ABORTING

Crashes and POC

POC.zip
Crashes.zip
Report of the Information Security Laboratory of Ocean University of China @OUC_ISLOUC @OUC_Blue_Whale

[Enhancement] Limit point of interest being processed

For big firmware ( > 100 MB ) binbloom takes really (really) long to process. It would be great to have an option to limit the amount of points of interest being taking into account to compute candidate. The same way we can limit the amount of strings being taken into account in rbasefind using the length.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.