Giter Site home page Giter Site logo

uroboros's Introduction

Uroboros: Infrastructure for Reassembleable Disassembling and Transformation (Version 0.5)

Installation

Docker

Uroboros is available as a docker image, you can check the details in Docker

Build

Before build Uroboros, you need to run the following command:

$ sudo apt-get install -y -q autoconf automake debianutils m4 build-essential python

Also, you need to obtain the OCaml compiler and libraries:

$ sudo apt-get install opam
$ opam init
$ opam switch create 4.01.0
$ opam install -y deriving.0.7 ocamlfind.1.5.5 parmap.1.0-rc6 batteries.2.3.1
$ eval $(opam env)

To build Uroboros, run the command below.

$ git clone https://github.com/s3team/uroboros.git /uroboros
$ cd /uroboros/src
$ ./build

Usage

Disassembling

Uroboros can take 64-bit and 32-bit ELF executable binaries as the input. To use Uroboros for disassembling:

$ python uroboros.py bzip

The disassembled output can be found at current dicrectory, named final.s. Uroboros will also assemble it back into an executable, a.out.

Python script uroboros.py provides multiple options to manipulate the disassembling process.

  1. -i (iteration):

    The disassemble-reassemble process can be iterated for multiple times. For example.

    $ python uroboros.py bzip -i 50
    
  2. -k (keep):

    This option will create a folder to store the assembly code and binary generated from each iteration. This is only effective together with -i.

    $ python uroboros.py bzip -i 50 -k
    

    A subfolder will be created in ./src folder, with input binary name and timestamp. For example: test_fold_bzip_2021-09-19_05:51:00

  3. -a (assumption):

    This option configures the three symbolization assumptions proposed in the original Uroboros paper [1]. Note that in the current version, the first assumption (n-byte alignment) are set by default. The other two assumptions can be set by users.

    Assumption two:

    $ python uroboros.py bzip -a 2
    

    Note that by accepting this assumption, we need to put data sections (.data, .rodata and .bss) to its original starting addresses. Linker scripts can be used during reassembling. For exmaple:

    $ gcc -Tld_gobmk.sty final.s
    

    Users may write their own linker script, some examples are given at ./src/ld_script folder.

    Assumption three:

    $ python uroboros.py bzip -a 3
    

    This assumption requires to know the function starting addresses. To obtain this information, Uroboros can take unstripped binaries as input. The function starting address information is obtained from the input, which is then stripped before disassembling.

    These assumptions can be used together.

    $ python uroboros.py bzip -a 3 -a 2
    

Instrument binaries

Instrumentation tools process the internal data structure of Uroboros. Some examples are shown in the plugins folder. You may start with mem_write.ml, which instruments every memory write operation.

To register instrumentation code:

$ cp plugins/mem_write.ml instrumentation_plugin.ml
$ ./build

Publications

@inproceedings {190920,
author = {Shuai Wang and Pei Wang and Dinghao Wu},
title = {Reassembleable Disassembling},
booktitle = {24th {USENIX} Security Symposium ({USENIX} Security 15)},
year = {2015},
isbn = {978-1-939133-11-3},
address = {Washington, D.C.},
pages = {627--642},
url = {https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/wang-shuai},
publisher = {{USENIX} Association},
month = aug,
}

uroboros's People

Contributors

ajaymas avatar computereasy avatar s3team avatar shipperzhang avatar wangshuai901 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  avatar  avatar

uroboros's Issues

building on debian 9

I'm having some trouble pulling together the ocaml build chain that seems to be needed for this.

I've tried:

sudo apt install libderiving-ocaml libfindlib-ocaml libparmap-ocaml ocaml-batteries-included
./build

But I get an error on build:

+ ocamlfind ocamldep -package deriving,deriving.syntax -syntax camlp4o -package batteries,parmap -modules type.ml > type.ml.depends
ocamlfind: Package `deriving.syntax' not found
Command exited with code 2.
Compilation unsuccessful after building 1 target (0 cached) in 00:00:00.

What else should I get?

Does it actually work with 64-bit elf?

Cannot get work Uroboros with 64-bit elfs. It works only if the number of iterations is 1. If it is more than one, I get segmentation fault (core dump).
Anyone was able to get it work with 64?

Also, when I run tier_test, I get this:
"rm: cannot remove useless_func.info': No such file or directory rm: cannot remove inline_symbols.txt': No such file or directory"
Even for 32-bit. Everything else looks fine

Originally posted by @nadiakarichev in #5 (comment)

Dissassembly does not work

The binary that I used is bzip2.
Dump on running

python2 uroboros.py /usr/bin/bzip2

rm: cannot remove 'final_data.s': No such file or directory

rm: cannot remove 'useless_func.info': No such file or directory

rm: cannot remove 'main.info': No such file or directory

Traceback (most recent call last):
File "main_discover.py", line 79, in
main_symbol =main_symbol.split('0x')[1]

IndexError: list index out of range

rm: cannot remove 'final.s': No such file or directory

rm: cannot remove 'inline_symbols.txt': No such file or directory

objdump: section '.plt' mentioned in a -j option, but not found in any input file

1: linearly disassemble
func number 1
2: disassembly validates -->
no disassembly error detects
func number 1
3: analysis
user defined func number
0
Fatal error: exception Invalid_argument("String.sub / Bytes.sub")
exception, processing failed

No License Stated in Repo

There's no license stated in this repository for uroboros, meaning it defaults to under GitHub's logic for such a situation terms where you can view the code, but not download or use it. Given there are build instructions, I am guessing this was not the intent.

Could you add your intended license to this repository?

Any options for normal AT&T?

I'm using the assembly file generated by uroboros. But it seems that the assembly format is unprefixed AT&T. It's not easy for me to edit the assembly files because gcc don't accept assembly codes mixed normal AT&T and unprefixed one.
An example assembly file followed.

.globl S_0x8048310
S_0x8048310:
# note that there is no suffix like 'b','w','l','q' on operators.
# first operand is the source. the second is destination.
xor %ebp,%ebp
pop %esi
mov %esp,%ecx
and $0xFFFFFFF0,%esp
push %eax
push %esp
push %edx
call S_0x8048343
add $_GLOBAL_OFFSET_TABLE_,%ebx
lea S_0x8048690,%eax
push %eax
lea S_0x8048630,%eax
push %eax
push %ecx
push %esi
mov $S_0x8048569,%eax
push main
call __libc_start_main

Any options can generate normal AT&T?

ocamlbuild "-ocamlopt" option with newer ocamlbuild

This afternoon I tried building Uroboros using a generally similar but newer system than the recommended one: 64-bit Ubuntu 14.04, with a locally-compiled OCaml 4.05.0, and the library dependencies installed using a locally-compiled OPAM. (The local compilation is because this is a centrally-administered machine where we don't want to hassle the sysadmins to install every package we might want for research.) Once I got all the dependencies, there was just one more hiccup getting the compile to work.

The "src/build" script passes the "-ocamlopt" option to ocamlbuild twice; from context it seems like the intent of this option is to supply extra options to ocamlopt:

 ... -ocamlopt "-inline 20" -ocamlopt -nodynlink

However that didn't seem to have the desired effect with my current version of ocamlbuild (version 0.12.0, compiled outside OPAM because camlp4 needs it and also needs to be compiled outside OPAM). As far as I can see, the meaning of the -ocamlopt option in this version is a string to be used as the name of the ocamlopt program, and if it's repeated, only the last occurrence takes effect. So the supplied build file has the effect of replacing "ocamlopt" with "-nodynlink" in the ocamlfind command, which causes the native compilation steps to produce a somewhat strange ocamlfind command-line syntax error.

My guess at an option that would have the desired effect was:

 ... -ocamlopt "ocamlopt -inline 20 -nodynlink"

After making that change, the compilation seemed to complete successfully. Though I should also mention it seemed to compile OK if I removed the -ocamlopt option entirely; I think these options just control optimizations.

I haven't figured out when the behavior of ocamlbuild changed; I presume the authors will want to check what options will work on their older build system to find the most compatible fix.

Can't find main symbol

Hi,

I've tried to reassemble Coreutils binaries with Uroboros, but it doesn't work.
The first problem I've met was Uroboros is not able to find main function if it dosn't have specific assembly patterns.

The below is my Coreutils binary's _start function:

08048e30 <_start>:
 8048e30:       31 ed                   xor    %ebp,%ebp
 8048e32:       5e                      pop    %esi
 8048e33:       89 e1                   mov    %esp,%ecx
 8048e35:       83 e4 f0                and    $0xfffffff0,%esp
 8048e38:       50                      push   %eax
 8048e39:       54                      push   %esp
 8048e3a:       52                      push   %edx
 8048e3b:       e8 23 00 00 00          call   8048e63 <_start+0x33>
 8048e40:       81 c3 c0 a1 00 00       add    $0xa1c0,%ebx
 8048e46:       8d 83 30 b7 ff ff       lea    -0x48d0(%ebx),%eax
 8048e4c:       50                      push   %eax
 8048e4d:       8d 83 d0 b6 ff ff       lea    -0x4930(%ebx),%eax
 8048e53:       50                      push   %eax
 8048e54:       51                      push   %ecx
 8048e55:       56                      push   %esi
 8048e56:       c7 c0 35 b0 04 08       mov    $0x804b035,%eax
 8048e5c:       50                      push   %eax
 8048e5d:       e8 7e fe ff ff          call   8048ce0 <__libc_start_main@plt>
 8048e62:       f4                      hlt

If Uroboros track eax register, it can easily find the main is at 0x804b035.

Do you have a plan to use any simple data flow analysis to find main symbol so that it can find main function more generally?

Thank you.

Only support dynamic?

hi gays
Are the tools only support the dynamic ELF files? Do you have plan to support the static?If i want to binary rewrite the linux kernel vmlinux,do you have any suggestions?
thanks a lot

Build on lunix failed

I have cloned the code for uroboros and installed all the required packages like opam, ocaml, batteries etc
But while running ./build file the operation is failing.

How to use plugins? Specifically, the mem_write plugin.

Hello, I do not understand how use the plugins. Specifically, I want to use the mem_write plugin. I have edited the source of 'src/ail.ml' and uncommented the following lines:

let open Mem_write in
let module MW = Mem_write in
let il' = MW.process il in

What do I do at this point? I have re-ran the Uroboros program via python uroboros.py /bin/ls but I do not see any output nor any relevant output files related to the plugin.

I see the mem_write.ml inside of the plugins folder however I don't know if I need to do anything with those files specifically to get the plugin to work. I also see the mem_write.native executable and have ran it but it doesn't seem to produce any output with any of the arguments I've tried giving it.

The environment I am using is a Ubuntu 12.04 VM with Ocaml 4.01.0 and all the plugins as stated in the README.

Thanks for any help.

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.