GithubHelp home page GithubHelp logo

driller's Introduction

Driller

Driller is an implementation of the driller paper. This implementation was built on top of AFL with angr being used as a symbolic tracer. Driller selectively traces inputs generated by AFL when AFL stops reporting any paths as 'favorites'. Driller will take all untraced paths which exist in AFL's queue and look for basic block transitions AFL failed to find satisfying inputs for. Driller will then use angr to synthesize inputs for these basic block transitions and present it to AFL for syncing. From here, AFL can determine if any paths generated by Driller are interesting, it will then go ahead and mutate these as normal in an attempt to find more paths.

The "Stuck" heuristic

Driller's symbolic execution component is invoked when AFL is 'stuck'. In this implementation, AFL's progress is determined by its 'pending_favs' attribute which can found in the fuzzer_stats file. When this attribute reaches 0, Driller is invoked. Other heuristics could also be used, and it's infact likely that better heuristics exist.

Use in the Cyber Grand Challenge

This same implementation of Driller was used team Shellphish in DARPA's Cyber Grand Challenge (CGC) to aid in the discovery of exploitable bugs. To see how Driller's invokation was scheduled for the CGC you can look at the Mechanical Phish's scheduler component 'meister'.

Current State and Caveats

The code currently supports three modes of operation:

  • A script that facilitates AFL and driller on one machine (over many cores if needed): https://github.com/shellphish/fuzzer/blob/master/shellphuzz
  • A monitor process watches over the fuzzer_stats file to determine when Driller should be invoked. When Driller looks like it could be useful, the monitor process schedules 'jobs' to work over all the inputs AFL has discovered / deemed interesting.
  • Celery tasks are assigned over a fleet of machines, some number of these tasks are assigned to fuzzing, some are assigned to drilling. Fuzzer tasks monitors the stats file, and invokes driller tasks when Driller looks like it could be useful. Redis is used to sync testcases to the filesystem of the fuzzer.

Driller was built and developed for DECREE binaries. While some support for other formats should work out-of-the-box, expect TracerMisfollowErrors to occur when unsupported or incorrectly implemented simprocedures are hit.

Example

Here is an example of using driller to find new testcases based off the trace of a single testcase.

import driller

d = driller.Driller("./CADET_00001",  # path to the target binary
                    "racecar", # initial testcase
                    "\xff" * 65535, # AFL bitmap with no discovered transitions
                   )

new_inputs = d.drill()

Dependencies

  • Mechaphish Fuzzer component
  • Mechaphish Tracer component

driller's People

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  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

driller's Issues

Question about the test input of driller

When testing program with AFL , the program must read a file as an input , thus AFL can do the mutation job with the input file. While driller‘s test input was from stdin,see ("#48").
But in the Driller paper, the CGC test program NRFIN_00017, reads an xml file as input ,so how can driller test this program reads a file as an input?

Vulnerabilities findings

Hi,

Can you please tell what can used for vulnerability findings in the binaries from the shellphish since the driller does not have methods for it.

Thanks.

How does afl-cgc deliver the input to the target program

I find that the afl-cgc start the target-program in qemu mode using parameters such as "/shellphish-afl/bin/afl-cgc/tracers/i386/afl-qemu-trace -- /binaries/tests/cgc/251abc02_01". But how does the afl-cgc give the input to the program? It does not add the location of the input file.
Thank you very much

AttributeError: 'module' object has no attribute 'Tracer'

Hello,
I want this err fix..

I tried these command

  • [ sudo pip install tracer]
  • [ git clone https://github.com/angr/tracer && pip install tracer]
  • [python test_driller]

How can i fix this err

Traceback (most recent call last):
  File "test_driller.py", line 34, in <module>
    run_all()
  File "test_driller.py", line 31, in run_all
    all_functions[f]()
  File "test_driller.py", line 19, in test_drilling_cgc
    new_inputs = d.drill()
  File "/root/.environments/angr/local/lib/python2.7/site-packages/driller/driller.py", line 113, in drill
    list(self._drill_input())
  File "/root/.environments/angr/local/lib/python2.7/site-packages/driller/driller.py", line 139, in _drill_input
    t = tracer.Tracer(self.binary, self.input, hooks=self._hooks, argv=self.argv)
**AttributeError: 'module' object has no attribute 'Tracer'**

attributeerr

please help me

Warning while determining the testcases

I am new to driller and has just started playing with it.

While running the script to determint the testcases, I amgetting output as below with some warnings. Can you help with it:

(driller) rborad@ESPRIMO-E920-Ubu:~/driller$ python test.py
WARNING | 2017-01-23 13:20:46,457 | tracer.cachemanager.LocalCacheManager | loading state from cache file /tmp/CADET_00001_32-7934338f631b910fbdf40caf20046c9f.tcache
WARNING | 2017-01-23 13:20:47,033 | angr.path_history | "max_size" has been deprecated in Path.step(). Please use "size" instead.
WARNING | 2017-01-23 13:20:47,037 | angr.path_history | "max_size" has been deprecated in Path.step(). Please use "size" instead.
ERROR | 2017-01-23 13:20:47,038 | tracer.Tracer | the dynamic trace and the symbolic trace disagreed
ERROR | 2017-01-23 13:20:47,038 | tracer.Tracer | [/home/rborad/driller/CADET_00001_32] dynamic [0x804858c], symbolic [0x8048655]
ERROR | 2017-01-23 13:20:47,038 | tracer.Tracer | inputs was 'racecar'
ERROR | 2017-01-23 13:20:47,038 | tracer.Tracer | TracerMisfollowError encountered
WARNING | 2017-01-23 13:20:47,038 | tracer.Tracer | entering no follow mode

what's the DrillerEnvironmentError?

Hello, guys.
I installed the Driller & tutorial.
but I have EnvironmentError :(. how can i fix this error
ubuntu 14.04(32bit) &error capture
driller-error

UnsupportedIROpError: floating point support disabled

When I run driller to test one of cgc binary named NRFIN_00017 with the command "shellphuzz -c 2 -d 2 -C NRFIN_00017 ", I get the following error, could you tell me what is wrong here? Thank you.
Traceback (most recent call last):
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/vex/irop.py", line 926, in translate_inner
raise UnsupportedIROpError("floating point support disabled")
UnsupportedIROpError: floating point support disabled

Attribute error due to lifter

Hi,

I am using driller under virtualenvironment. I have done installation of angr, tracer and other dependencies.

While using it my script stops with error. It is as below:
Traceback (most recent call last):
File "test.py", line 5, in
new_inputs = d.drill()
File "/home/rborad/driller/local/lib/python2.7/site-packages/driller/driller.py", line 103, in drill
list(self._drill_input())
File "/home/rborad/driller/local/lib/python2.7/site-packages/driller/driller.py", line 187, in _drill_input
branches = t.next_branch()
File "/home/rborad/driller/local/lib/python2.7/site-packages/tracer/tracer.py", line 322, in next_branch
except angr.lifter.AngrMemoryError:
AttributeError: 'module' object has no attribute 'lifter'

Can anyone please help me with it.

Thanks.

Drilling into angr extern?

In playing with driller, I've been noticing that it drills down into angr extern sections. Presumably this is just code that is only in angr itself and thus will never really be useful to drill. Am I understanding that correctly? Should driller add logic to ignore drilling into angr extern sections?

Driller fails to generate new inputs

As described in the title, driller fails to generate the new inputs for the following toy program (please remove .txt from all files, hello.txt is the binary). If you compile hello.c inside mechaphish container, driller does generate new inputs.

gcc version is gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406

drill.py.txt
hello.c.txt
hello.txt

driller-fuzzer interaction

Hi,

So I can run the test_fuzzer and the driller by themselves. I have also installed redis and claripy and can run the run.py in driller which seems to set things up for the driller to monitor the fuzzer. I also see where in tasks.py the pending_favs is monitored for the drilling to begin. My question is whether run.py should fire up the fuzzer by itself. It calls driller.tasks.fuzz.delay(binary) which never seems to call tasks.fuzz(binary) where all of the fuzzing and monitoring should happen, correct? What is the purpose of calling tasks.fuzz.delay instead of tasks.fuzz?

Thanks

Diverted state not satisfiable when using strncmp

Hi, I'm experimenting a bit with driller and I noticed that it fails dramatically when dealing with strncmp.
The diverted state is not satisfiable due to the symbolic length concretization (i think).
You are aware of this for sure and my question is: is there a workaround?

My test program is the following:

int main(int argc, char** argv) {
    char buf[100]; 
    memset(buf, 0, 100);
    read(0, buf, 100);
    fprintf(stderr, "%s\n", buf);
    if(strncmp(buf, "pippo", 5) == 0) {
        //0x4006ea
        if(strncmp((char*)buf +6, "franco", 6) == 0) {
            int i;
            int s = 0;
            for(i = 0; i < 12; ++i)
                s += buf[i];
            if(s == 1217)
                abort();
        }
    }
  return 0;
}

I invoke driller with:

d = driller.Driller("./test1", b"foo")
print(d.drill())

The relevant part of the logs are:

DEBUG   | 2019-02-03 11:05:44,316 | driller.driller | Drilling into b'foo'.
DEBUG   | 2019-02-03 11:05:44,316 | driller.driller | Input is b'foo'.
DEBUG   | 2019-02-03 11:05:44,631 | angr.exploration_techniques.driller_core | Found 0x4004d0 -> 0x4004e0 transition.
DEBUG   | 2019-02-03 11:05:44,631 | angr.exploration_techniques.driller_core | State at 0x4004e0 is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:05:44,641 | angr.exploration_techniques.driller_core | Found 0x4007c1 -> 0x4007e6 transition.
DEBUG   | 2019-02-03 11:05:44,641 | angr.exploration_techniques.driller_core | State at 0x4007e6 is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:05:44,669 | angr.exploration_techniques.driller_core | Found 0x4005c0 -> 0x4005df transition.
DEBUG   | 2019-02-03 11:05:44,669 | angr.exploration_techniques.driller_core | State at 0x4005df is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:05:44,689 | angr.exploration_techniques.driller_core | Found 0x4007dd -> 0x4007d0 transition.
DEBUG   | 2019-02-03 11:05:44,689 | angr.exploration_techniques.driller_core | State at 0x4007d0 is not satisfiable even remove preconstraints.
WARNING | 2019-02-03 11:05:44,817 | angr.state_plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
DEBUG   | 2019-02-03 11:05:44,877 | angr.exploration_techniques.driller_core | Found 0x4006e1 -> 0x4006ea transition.
DEBUG   | 2019-02-03 11:05:44,905 | angr.exploration_techniques.driller_core | State at 0x4006ea is not satisfiable.

The last state is the interesting one but driller fails.
On the other hand setting set_length=False in
s.preconstrainer.preconstrain_file(self.input, s.posix.stdin, True) (in Driller._drill_input) in order to avoid to concretize the length the state is inserted in the diverted stash but the generated input is wrong.

DEBUG   | 2019-02-03 11:26:54,536 | angr.exploration_techniques.driller_core | Found 0x4004d0 -> 0x4004e0 transition.
DEBUG   | 2019-02-03 11:26:54,536 | angr.exploration_techniques.driller_core | State at 0x4004e0 is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:26:54,546 | angr.exploration_techniques.driller_core | Found 0x4007c1 -> 0x4007e6 transition.
DEBUG   | 2019-02-03 11:26:54,546 | angr.exploration_techniques.driller_core | State at 0x4007e6 is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:26:54,573 | angr.exploration_techniques.driller_core | Found 0x4005c0 -> 0x4005df transition.
DEBUG   | 2019-02-03 11:26:54,573 | angr.exploration_techniques.driller_core | State at 0x4005df is not satisfiable even remove preconstraints.
DEBUG   | 2019-02-03 11:26:54,592 | angr.exploration_techniques.driller_core | Found 0x4007dd -> 0x4007d0 transition.
DEBUG   | 2019-02-03 11:26:54,592 | angr.exploration_techniques.driller_core | State at 0x4007d0 is not satisfiable even remove preconstraints.
WARNING | 2019-02-03 11:26:55,105 | angr.state_plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
DEBUG   | 2019-02-03 11:26:55,487 | angr.exploration_techniques.driller_core | Found 0x4006e1 -> 0x4006ea transition.
DEBUG   | 2019-02-03 11:26:55,534 | angr.exploration_techniques.driller_core | Found a completely new transition, putting into 'diverted' stash.
DEBUG   | 2019-02-03 11:26:55,534 | driller.driller | Found a diverted state, exploring to some extent.
DEBUG   | 2019-02-03 11:26:55,535 | driller.driller | [test1] dumping input for 0x4006e1 -> 0x4006ea.
DEBUG   | 2019-02-03 11:26:55,535 | driller.driller | Generated: b'70697000000000000000000000000000000000000000000000000000000000000000000000000000000000008080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f70'
DEBUG   | 2019-02-03 11:26:55,536 | driller.driller | [test1] started symbolic exploration at Sun Feb  3 11:26:55 2019.
DEBUG   | 2019-02-03 11:26:55,877 | driller.driller | [test1] stopped symbolic exploration at Sun Feb  3 11:26:55 2019.
DEBUG   | 2019-02-03 11:26:55,878 | driller.driller | [test1] dumping input for 0x4000058 -> 0x4000058.
DEBUG   | 2019-02-03 11:26:55,878 | driller.driller | Generated: b'70697000000000000000000000000000000000000000000000000000000000000000000000000000000000008080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808066406f70'
DEBUG   | 2019-02-03 11:26:55,879 | driller.driller | [test1] dumping input for 0x10406c0 -> 0x10406c0.
DEBUG   | 2019-02-03 11:26:55,879 | driller.driller | Generated: b'706970000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f636e617266206f70'
DEBUG   | 2019-02-03 11:26:55,880 | driller.driller | [test1] dumping input for 0x4000058 -> 0x4000058.
DEBUG   | 2019-02-03 11:26:55,880 | driller.driller | Generated: b'706970000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f636e617266406f70'

This is interesting because the generated input is almost right but the bytes are in the wrong place.

  • how is -> how should be
  • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80op -> pippo
  • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80f@op -> pippo@f
  • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80ocnarf op -> pippo franco
  • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80ocnarf@op -> pippo@franco

Another case is when i give an input with size > len("pippo") like "foooooooo" the results are correct also with the regular set_length=True

In this specific case filling with 0 is enough but in general this can alter the behaviour (think about a program that takes different paths using the return value of read) so I'd love to know if there is a more general workaround that you use.

I'm using angr from git (cloned yesterday).

Driller Interesting Branch

Hey guys, I hope you can help me to fully understand this tools.

I'm using Driller now but I still cannot figure it out, technically, how Driller choose a certain path to run Angr on it. Is it just based on hit counts? Or do you have any way to select interesting branches? (Interesting means that branch which has unexplored arm)

Content Disallowed Error with Celery

I am receiving the following error when running node.py from driller using redis and celery:

ContentDisallowed: Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)

I can provide the commands I used to set up redis and celery if needed. I am running rabbitmqctl as root and redis-server as a user (compiled from source). Could the permissions be wrong? Though, it looks like others have got it up and running without issue

Here are the relevant configuration settings for driller:

REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 1
BROKER_URL = 'pyamqp://myuser:mypasswd@localhost:5672/myvhost'
CELERY_ROUTES = {'driller.tasks.fuzz': {'queue': 'fuzzer'}, 'driller.tasks.drill': {'queue': 'driller'}}

Adding the following at the top of driller/tasks.py will fix this issue:

app.conf['CELERY_TASK_SERIALIZER'] = 'pickle'
app.conf['CELERY_RESULT_SERIALIZER'] = 'pickle'
app.conf['CELERY_ACCEPT_CONTENT'] = ['json', 'pickle']

Anyone have some insight? Thank you.

Is this show my driller successfully installed?

yzb@ubuntu:~/Downloads/driller-master/tests$ python test_driller.py
WARNING | 2017-03-30 04:31:28,820 | tracer.cachemanager.LocalCacheManager | caching state to /tmp/sc1_0b32aa01_01-8955a29d51c1edd39b0e53794ebcf464.tcache
Exception AttributeError: "'NoneType' object has no attribute 'release_handle'" in <bound method UcCleanupManager._finalizer of <unicorn.unicorn.UcCleanupManager object at 0x7fd665999e50>> ignored
screenshot from 2017-03-30 04 35 17

Why the result of the solver is wrong in this sample?

This is the tested sample in c code(data_flow.c).

#include <stdio.h>
#include <unistd.h>
#include <string.h>
char check(char*x,char*y)
{
	if(strcmp(x,y))
		return strcmp(x,y);
	else
		return strcmp(x,y);
}
int main(int argc, char*argv[])
{
	char x[100];
	read(0,x,100);
	if(check(x,"pwdpwdpwd\n")==0)
		printf("pwd cmd\n");
	else
		printf("no pwd cmd\n");
	if(check(x,"cwdcwdcwd\n")==0)
		printf("cwd cmd\n");
	else
		printf("no cwd cmd\n");
	return 1;
}

Compile it with the command: gcc -g -o data_flow data_flow.c
Fuzz it using the command: ./shellphuzz -c 1 -d 1 -f 10 --no-dictionary ../test/data_flow/data_flow
I find the solved value of the new sample by driller is wrong .
For example, it should be "pwdpwdpwd\n", but the solved value is "pwdp".
I print out the constraints( state.se.constraints), and I confirm that it should be "pwdpwdpwd\n" manually.
Is the solver wrong????
My github url is [email protected]:CAFA1/long-driller.git.

Dataset from Driller paper and apps that benefited from Driller

In the Driller paper, there are 13 applications that invoked and benefited from concolic execution. The public name for application with identifier 2b03cf01 is given as NRFIN_00017 for the case study, but I'm wondering how to resolve the identifier to a public name for the other 12: 2bda8e01, 5d469c01, 576b9101, 5e453901, 77263701, 17422001, d113bd01, f8271b01, 16d55a01, 6787bf01, 76ddd501, f5adc401. They look like CRC32 hashes, but what was being hashed?

If you have the public name for each hash, that would be perfect. Even a binary sample might be sufficient so that I could run strings on it to find the public name.

I'd like to study more about these programs and how they would run on a native Linux environment with real libc functions. Any help would be appreciated! Thank you!

How new inputs generated by driller are passed to AFL?

Hello, I have been using driller. I look into the schedule of celery, but there is one question confusing me.
When driller generates new inputs, it will pass the new input through redis publish/subscribe to AFL output directory, which is binary/sync/driller/queue. But then how can AFL read these inputs? Normally the queue directory here should be binary/sync/fuzzer-master/queue.
So, I think maybe you changed the AFL source code. I have noticed that driller-afl is tailored for driller's use in analyzing cgc binaries, which really adds some operation of driller. But, I just want to use driller for unix binary, then how AFL reads inputs from driller? Thanks :)

How to run driller

Hello,
Could someone explain me how to run Driller?
When I execute the run.py script, Driller listens for crashes but the fuzzer doesn't seem to start fuzzing.
Thank you in advance.

$ python2 ~/software/driller/run.py bin/
INFO    | 2017-04-05 13:29:15,025 | driller | 1 binaries found
INFO    | 2017-04-05 13:29:15,025 | driller | 1 binaries found
INFO    | 2017-04-05 13:29:15,025 | driller | going to work on 1
INFO    | 2017-04-05 13:29:15,074 | driller | listening for crashes..

Simuvex Error

Hey Guys,

I'm trying to get into driller. I wrote a simple program (example.txt).

When running driller, I get the following output:

In [13]: d = driller.Driller("ex.run", "input", "\xff" * 65535)

In [14]: new = d.drill()
WARNING | 2017-06-30 16:06:40,422 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
WARNING | 2017-06-30 16:06:41,279 | tracer.Tracer | Our base address doesn't match QEMU's. Changing ours to 0x4000000000
ERROR   | 2017-06-30 16:06:43,223 | simuvex.vex.irop | Unsupported operation: Iop_InterleaveHI32x4

In [15]: new
Out[15]: set()

Am I doing something wrong here?

Cheers

First Found?

As you get deeper into drilling into the binaries, Driller itself takes quite a while to come back. Since this would be a bit of an architecture change, what are your thoughts on an option in driller that allows an "early exit".

Basically, be able to return on the first new path found. The hope would be you would then toss that new path into your fuzzer and let it hopefully find you more instead of waiting around for the entire code path to be drilled.

Some questions about the usage of driller

Hello guys, I need some help. I have some question about driller want to ask.
First, I followed the example https://github.com/shellphish/driller#example to run the driller. I print the new_inputs, and the result shows below
set([((7, 134513087, 134513100), '^\xfe\xfe\xfe\xfe^\xfe'), ((7, 134513409, 134513424), '^\xff\x01\xfe\xf7\xa1\xfe'), ((7, 134513100, 134513087), '^\x01\x01\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\x01\x01\xfe\xfe\xfe\xfe'), ((7, 134513100, 134513087), '\xfe\xfe\xfe\xfe\xfe\xfe\xfe'), ((7, 134513100, 134513087), '^\xfe\x01\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\x01\xfe\xfe\xfe\xfe\xfe'), ((7, 134513210L, 134513263), '\x00\x00\x00\x00\x00\x00\x00'), ((7, 134513100, 134513087), '^\x01\xfe\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\xfe\x01\xfe\xfe\xfe\xfe'), ((7, 134513719L, 167772168), '^\xff\x01\xfe\xf7\xa1\xfe'), ((7, 134513348, 134513388), '\xfe\xfe\xfe\xfe\xfe\xfe\xfe'), ((7, 134513719L, 167772168), '\x00\x00\x00\x00\x00\x00\x00')])
Could someone help me explain the meaning of these messages? Thanks!

Second, I follow the code https://github.com/shellphish/driller/blob/master/driller/driller.py#L30, and I found that the second parameter of running driller.Driller(...) is input string. The input string for ./CADET_00001 is racecar. My question is how do I know what input string should be fed into the binary? Thanks!

basic block tracing broken

I already asked for help on this topic before in the slack help
channel
. Then I
tried to use driller for Linux ELF binaries. Now I am running it against the
CGC challenge and also documented the process a lot more verbose.

The official driller example looks
similar to the code snipped I used. In order to test different binaries the
path to the target binary has to be changed accordingly.

#!/usr/bin/env python3

import driller
import logging

logging.getLogger('driller.driller').setLevel('DEBUG')
logging.getLogger('angr.exploration_techniques.tracer').setLevel('DEBUG')

d = driller.Driller("./CADET_00001",  # path to the target binary
                    b"racecar", # initial testcase
                    b"\xff" * 65535, # AFL bitmap with no discovered transitions
                   )

new_inputs = d.drill()

print("new_inputs", new_inputs)

Everything works nice when I use the
CADET_00001
challenge binary taken from the angr-doc repo.

Now. This is not true for CADET_00001.2018-12-03(see attached).
This binary was built using the cgc-linux-dev box from darpa cgc repo.

DEBUG   | 2018-12-09 11:13:53,779 | driller.driller | [CADET_00001.2018-12-03] drilling started on Sun Dec  9 11:13:53 2018.
WARNING | 2018-12-09 11:13:53,780 | driller.driller | Debug directory is not set. Will not log fuzzing bitmap.
DEBUG   | 2018-12-09 11:13:53,947 | driller.driller | Drilling into b'racecar'.
DEBUG   | 2018-12-09 11:13:53,948 | driller.driller | Input is b'racecar'.
DEBUG   | 2018-12-09 11:13:53,955 | angr.exploration_techniques.tracer | Trace: 1/241
DEBUG   | 2018-12-09 11:13:53,966 | angr.exploration_techniques.tracer | Trace: 2/241
DEBUG   | 2018-12-09 11:13:53,982 | angr.exploration_techniques.tracer | Trace: 3/241
DEBUG   | 2018-12-09 11:13:53,990 | angr.exploration_techniques.tracer | Trace: 4/241
DEBUG   | 2018-12-09 11:13:54,031 | angr.exploration_techniques.tracer | Trace: 5/241
DEBUG   | 2018-12-09 11:13:54,031 | driller.driller | Found a diverted state, exploring to some extent.
DEBUG   | 2018-12-09 11:13:54,032 | driller.driller | [CADET_00001.2018-12-03] dumping input for 0x8048716 -> 0x8048601.
DEBUG   | 2018-12-09 11:13:54,032 | driller.driller | Generated: b''
DEBUG   | 2018-12-09 11:13:54,033 | driller.driller | [CADET_00001.2018-12-03] started symbolic exploration at Sun Dec  9 11:13:54 2018.
DEBUG   | 2018-12-09 11:13:56,330 | driller.driller | [CADET_00001.2018-12-03] stopped symbolic exploration at Sun Dec  9 11:13:56 2018.
DEBUG   | 2018-12-09 11:13:56,344 | angr.exploration_techniques.tracer | Trace: 6/241
Traceback (most recent call last):
  File "./doit1.py", line 14, in <module>
    new_inputs = d.drill()
  File "/home/phil/src/angr-dev/driller/driller/driller_main.py", line 85, in drill
    list(self._drill_input())
  File "/home/phil/src/angr-dev/driller/driller/driller_main.py", line 141, in _drill_input
    simgr.step()
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/driller_core.py", line 39, in step
    simgr.step(stash=stash, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/tracer.py", line 115, in step
    return simgr.step(stash=stash, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 80, in __call__
    return self.func(*args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/sim_manager.py", line 344, in step
    successors = self.step_state(state, successor_func=successor_func, **run_args)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/tracer.py", line 146, in step_state
    assert len(succs_dict[None]) == 1
AssertionError

After I added some extra debug output it looks like this.

DEBUG   | 2018-12-09 21:23:04,365 | driller.driller | [CADET_00001.2018-12-03] drilling started on Sun Dec  9 21:23:04 2018.
WARNING | 2018-12-09 21:23:04,365 | driller.driller | Debug directory is not set. Will not log fuzzing bitmap.
DEBUG   | 2018-12-09 21:23:04,510 | driller.driller | Drilling into b'racecar'.
DEBUG   | 2018-12-09 21:23:04,510 | driller.driller | Input is b'racecar'.
DEBUG   | 2018-12-09 21:23:04,517 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool file_0_stdin_6_6_8{UNINITIALIZED} == 114>
DEBUG   | 2018-12-09 21:23:04,518 | angr.exploration_techniques.tracer | Trace: 1/241 (0x8048705)
DEBUG   | 2018-12-09 21:23:04,527 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool file_0_stdin_6_6_8{UNINITIALIZED} == 114>
DEBUG   | 2018-12-09 21:23:04,528 | angr.exploration_techniques.tracer | Trace: 2/241 (0x8048735)
DEBUG   | 2018-12-09 21:23:04,542 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool file_0_stdin_6_6_8{UNINITIALIZED} == 114>
DEBUG   | 2018-12-09 21:23:04,543 | angr.exploration_techniques.tracer | Trace: 3/241 (0x804874c)
DEBUG   | 2018-12-09 21:23:04,550 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool file_0_stdin_6_6_8{UNINITIALIZED} == 114>
DEBUG   | 2018-12-09 21:23:04,550 | angr.exploration_techniques.tracer | Trace: 4/241 (0x8048716)
DEBUG   | 2018-12-09 21:23:04,586 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool file_0_stdin_6_6_8{UNINITIALIZED} == 114>
DEBUG   | 2018-12-09 21:23:04,586 | angr.exploration_techniques.tracer | Trace: 5/241 (0x8048731)
DEBUG   | 2018-12-09 21:23:04,587 | driller.driller | Found a diverted state, exploring to some extent.
DEBUG   | 2018-12-09 21:23:04,587 | driller.driller | [CADET_00001.2018-12-03] dumping input for 0x8048716 -> 0x8048601.
DEBUG   | 2018-12-09 21:23:04,587 | driller.driller | Generated: b''
DEBUG   | 2018-12-09 21:23:04,588 | driller.driller | [CADET_00001.2018-12-03] started symbolic exploration at Sun Dec  9 21:23:04 2018.
DEBUG   | 2018-12-09 21:23:06,662 | driller.driller | [CADET_00001.2018-12-03] stopped symbolic exploration at Sun Dec  9 21:23:06 2018.
DEBUG   | 2018-12-09 21:23:06,673 | angr.exploration_techniques.tracer | state.history.events[-1].constant.ast <Bool False>
DEBUG   | 2018-12-09 21:23:06,674 | angr.exploration_techniques.tracer | Trace: 6/241 (0x8048601)
Traceback (most recent call last):
  File "./doit1.py", line 16, in <module>
    new_inputs = d.drill()
  File "/home/phil/src/angr-dev/driller/driller/driller_main.py", line 85, in drill
    list(self._drill_input())
  File "/home/phil/src/angr-dev/driller/driller/driller_main.py", line 141, in _drill_input
    simgr.step()
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/driller_core.py", line 39, in step
    simgr.step(stash=stash, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/tracer.py", line 115, in step
    return simgr.step(stash=stash, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 80, in __call__
    return self.func(*args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/sim_manager.py", line 344, in step
    successors = self.step_state(state, successor_func=successor_func, **run_args)
  File "/home/phil/src/angr-dev/angr/angr/misc/hookset.py", line 75, in __call__
    result = current_hook(self.func.__self__, *args, **kwargs)
  File "/home/phil/src/angr-dev/angr/angr/exploration_techniques/tracer.py", line 154, in step_state
    assert len(succs_dict[None]) == 1
AssertionError

rhelmot wrote "if the constraint is False it means it was a false comparison
between two concrete values, which is very scary".

A False constraint appears before we even enter the main function.

In the CADET_00001.2018-12-03 binary the main function is not at the entry
point, but there is some init function before it. For the testcase binary
CADET_00001 the entrypoint points sits right on it's main function.

I patched CADET_00001.2018-12-03 entrypoint from 0x080485fc to 0x08048601
(now refered to as CADET_00001.2018-12-03.fix). This will skip the init
function and go right into the main.

Driller seems to work fine on CADET_00001.2018-12-03.fix.

All the init stub does is:

  1. call a subroutine with static arguments that effectively does nothing.
  2. zero out the parity flag, zero flag, sign flag
  3. return 0

To my understanding only the lowest address of a basic block should be in the
trace. The last non-False entry in the log points at 0x08048731, this area does not
look like the beginning or end of a basic block.

0x0804872f      50             push eax
0x08048730      9d             popfd
0x08048731      6a00           push 0

The qemu trace logs 0x08048731.

Trace 0x55c7453ec350 [080485fc]
Trace 0x55c7453ec3a0 [08048705]
Trace 0x55c7453ec420 [08048735]
Trace 0x55c7453ec4e0 [0804874c]
Trace 0x55c7453ec540 [08048716]
Trace 0x55c7453ec650 [08048731]
Trace 0x55c7453ec6a0 [08048601]
[...]

When the push eax; popfd get nopped out everything works fine.

If we leave the binary untouched but remove the address 0x08048731 from the
qemu_runner trace it works too.

So I guess driller/angr/vex/... don't like it when they get fed basic blocks
that aren't basic blocks? Where would I have to look next in order to fix this issue or
get it fixed?

Environment

I am using angr-dev, so the version of driller and its dependencies should be
fairly recent. The OS is Ubuntu 18.04 on amd64.

Files

zip contains all the mentioned CADET binaries
CADET_00001.zip

Commits lost in rebase

It appears the driller repo was rebased recently, and some of the commits on the previous master branch are missing from the current one. Is that intentional? The commits in question can be seen here: master...3e974f6

How to stop the workers from celery?

Hi:
I use 'celery -A tasks worker ---loglevel=info' to start wokers drilling into binaryies, but how can I stop these workers?
I just press "ctrl+c" in the terminal, which starts the tasks, but it does not work.
I run "pkill -9 -f 'celery' " to stop the process, but it would resume automately the next time I run 'celery -A tasks worker ---loglevel=info' without starting the driller.
Even I restart the computer, and I run 'celery -A tasks worker ---loglevel=info', without starting the driller, it would restart the workers automately.
How could I stop the workers?

Unable to correct discrepancy between qemu and angr.

Hi, all.
I am testing the driller with CGC binaries that are compiled for x86.
Unfortunately, when I run the driller, I got an error "Unable to correct discrepancy between qemu and angr."
I am not sure it is normal or I make some mistakes.

import driller

d = driller.Driller("./CROMU_00005",
                        '6,0 5,21,6 1,55,2 6,42,6 2,56,4 4,50,6 0,54,5 6,61,5 1,46,6 7,89')
new_inputs = d.drill()

Here is the binary. I only changed syscall to equivalent x86 syscall.
CROMU_00005.zip

Thanks.

AttributeError: 'module' object has no attribute 'UNICORN_HANDLE_TRANSMIT_SYSCALL'

Hi,
I get the following error when I run Driller, I'm not able to figure out what is the problem.

import driller
d = driller.Driller("./test","a"*1024,"\xff" * 65535)
n = d.drill()
Traceback (most recent call last):
  File "test-driller.py", line 4, in <module>
    n = d.drill()
  File "/usr/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
    list(self._drill_input())
  File "/usr/lib/python2.7/site-packages/driller/driller.py", line 136, in _drill_input
    t = tracer.Tracer(self.binary, self.input, hooks=self._hooks)
  File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 216, in __init__
    self.path_group = self._prepare_paths()
  File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 921, in _prepare_paths
    return self._linux_prepare_paths()
  File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 1081, in _linux_prepare_paths
    options.add(so.UNICORN_HANDLE_TRANSMIT_SYSCALL)
AttributeError: 'module' object has no attribute 'UNICORN_HANDLE_TRANSMIT_SYSCALL'

Thank you for your help.

About some interesting results from the driller paper

Hi guys,

One of the results in your Driller paper (https://www.internetsociety.org/sites/default/files/blogs-media/driller-augmenting-fuzzing-through-selective-symbolic-execution.pdf) is quite interesting.
That is in figure-7, you mentioned about the number of times that concolic execution is invoked.
I wonder what are the exact cgc binaries in this figure. It would be very interesting to see which binaries requires the aid of concolic execution and which do not.
Can you guys share with us more details about those cgc binaries involved in this figure?

Figure-7

How to make Driller works on Linux x86 binary file?

Hi guys...,

I'm just wondering because I think Driller should be a powerfull tools. Angr can works on binary X86 and AFL too but I found out Driller cannot do that. I tried to see into the Driller's code but cannot find out. Just found that there is a piece of code to make sure the binary input is CGC. I also read the issue related about it but the explanation that I got just because the environment didn't support it. My question are (1) Is the ANGR's environment didn't support to analyze x86? Is it because ANGR that used in DRILLER already have the library about CGC? (2) Is it possible to try make it works for x86? (3) Do u have any suggestion what I should learn about and focus on if I wanna try to run Driller works on x86? Thanks before. Sorry if my question is too shallow, I'm just starting to learnt Driller.

angr.exploration_techniques.Tracer() got an unexpected keyword argument 'copy_states'

When I run shellphuzz I get the following:

WARNING | 2018-11-28 13:11:27,135 | local_callback | starting drilling of buggy, id:000000,orig:seed-0 Traceback (most recent call last): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/local_callback.py", line 122, in <module> for new_input in d.drill_generator(): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/driller_main.py", line 101, in drill_generator for i in self._drill_input(): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/driller_main.py", line 128, in _drill_input t = angr.exploration_techniques.Tracer(trace=r.trace, crash_addr=r.crash_addr, copy_states=True) TypeError: __init__() got an unexpected keyword argument 'copy_states' (b'', None)

I assume the version of tracer.py is wrong under angr/exploration_techniques/. I installed angr using command pip install angr. When I use python setup.py install within angr repo folder, I get correct tracer.py, but then lib/angr_native.so is missing.
Any suggestions on how to fix all this, and what needs to be installed/reinstalled? Thanks

self.trace "list index out of range" error

Here is a demo program so you can reproduce the results:

#!/usr/bin/env python
from driller.driller import Driller, l
from logging import DEBUG
from traceback import print_exc
l.setLevel(DEBUG)
target = "/home/grimm/targets/xz-5.2.3/src/xz/.libs/xz"
afl_input_filename = "a.xz"
with open(afl_input_filename, "rb") as f:
        afl_input = f.read()
d = Driller(target, afl_input)
try:
        solutions = d.drill()
except Exception as e:
        print_exc()

The base64 encoded contents of a.xz:
/Td6WFoAAATm1rRGCgAhAeAAFwAHXQAg7gQKAAAAAADUnPZFGuu6oQABIxgcWkONH7bzfQEAAAA=

The output of the demo listed above:

$ ./demo.py 
INFO    | 2017-03-16 19:28:11,350 | driller.Driller | [xz] drilling started on Thu Mar 16 19:28:11 2017
WARNING | 2017-03-16 19:28:11,350 | driller.Driller | Debug directory is not set. Will not log fuzzing bitmap.
Traceback (most recent call last):
  File "./demo.py", line 13, in <module>
    solutions = d.drill()
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
    list(self._drill_input())
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 136, in _drill_input
    t = tracer.Tracer(self.binary, self.input, hooks=self._hooks)
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/tracer-0.1-py2.7.egg/tracer/tracer.py", line 216, in __init__
    self.path_group = self._prepare_paths()
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/tracer-0.1-py2.7.egg/tracer/tracer.py", line 910, in _prepare_paths
    return self._linux_prepare_paths()
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/tracer-0.1-py2.7.egg/tracer/tracer.py", line 1099, in _linux_prepare_paths
    if pg.active[0].addr != self.trace[0]:
IndexError: list index out of range

The error is pretty straight forward: line 1099 accesses self.trace[0] without checking to see if there is at least one entry in self.trace (I checked, it is in fact self.trace, not pg.active). I can patch that up and submit a pull request without any problem, but the real question is why there aren't any traces. I have to suspect this is related to shared libraries not being loaded in xz due to them not being in standard paths. To give a concrete example:

$ /home/grimm/targets/xz-5.2.3/src/xz/.libs/xz --help
/home/grimm/targets/xz-5.2.3/src/xz/.libs/xz: /lib/x86_64-linux-gnu/liblzma.so.5: version `XZ_5.2' not found (required by /home/grimm/targets/xz-5.2.3/src/xz/.libs/xz)
$ LD_PRELOAD="/home/grimm/targets/xz-5.2.3/src/liblzma/.libs/liblzma.so.5" /home/grimm/targets/xz-5.2.3/src/xz/.libs/xz --help
<output as expected>

To attempt to test if this was the problem, I hacked in from os import environ, set environ['LD_PRELOAD'] = "/home/grimm/targets/xz-5.2.3/src/liblzma/.libs/liblzma.so.5", and added env=environ to the Popen calls in dynamic_trace(). This did not make a difference.

If the LD_PRELOAD issue is actually the cause of my problem, how can this be handled by Driller? Anyone have any tips on where I should look to test/debug this faster?

how AFL utilize the test-cases generated by symbolic execution

hi guys,
When execute the run.py in driller, it actually generates some test-cases, and the listen.py will save the them into the /driller/queue catalog. But how would AFL utilize these test-cases for Fuzzing? I could not find the related code, So may you help me something about this problem?
Thank you!

AttributeError: startswith

I'm back, and this time I'm drilling a binary which doesn't need any LD_PRELOAD junk, it's just a normal executable. This time I eventually get what looks to be a type confusion bug (b/c it looks like "name" should be a string, more specifically a filename), however it looks like the real problem might have happened quite a bit earlier...

<snip>
DEBUG   | 2017-03-21 17:47:29,144 | driller.Driller | found 409e50 -> 409e64 transition
DEBUG   | 2017-03-21 17:47:29,144 | driller.Driller | 409e50 -> 409e64 has already been encountered
ERROR   | 2017-03-21 17:47:29,339 | tracer.Tracer | the dynamic trace and the symbolic trace disagreed
ERROR   | 2017-03-21 17:47:29,339 | tracer.Tracer | [../targets/tcpdump-4.9.0_non-instumented/tcpdump] dynamic [0x409e64], symbolic [0x409ec7]
ERROR   | 2017-03-21 17:47:29,339 | tracer.Tracer | inputs was 'id:0'
ERROR   | 2017-03-21 17:47:29,339 | tracer.Tracer | TracerMisfollowError encountered
WARNING | 2017-03-21 17:47:29,340 | tracer.Tracer | entering no follow mode
DEBUG   | 2017-03-21 17:47:29,397 | driller.Driller | found 20bd070 -> 20bd3d8 transition
DEBUG   | 2017-03-21 17:47:29,397 | driller.Driller | 20bd070 -> 20bd3d8 has already been encountered
<snip>
DEBUG   | 2017-03-21 17:47:37,427 | driller.Driller | found 2079a40 -> 2079ac0 transition
DEBUG   | 2017-03-21 17:47:37,427 | driller.Driller | 2079a40 -> 2079ac0 has already been encountered
CRITICAL | 2017-03-21 17:47:37,449 | drill_it | startswith
Traceback (most recent call last):
  File "./drill_it.py", line 101, in <module>
    solutions = d.drill()
  File "/home/anon/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
    list(self._drill_input())
  File "/home/anon/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 194, in _drill_input
    branches = t.next_branch()
  File "/home/anon/.virtualenvs/driller/local/lib/python2.7/site-packages/tracer-0.1-py2.7.egg/tracer/tracer.py", line 339, in next_branch
    self.path_group = self.path_group.step(size=bbl_max_bytes)
  File "build/bdist.linux-x86_64/egg/angr/path_group.py", line 540, in step
    pg = pg._one_step(stash=stash, selector_func=selector_func, successor_func=successor_func, check_func=check_func, **kwargs)
  File "build/bdist.linux-x86_64/egg/angr/path_group.py", line 322, in _one_step
    r = self._one_path_step(a, successor_func=successor_func, check_func=check_func, **kwargs)
  File "build/bdist.linux-x86_64/egg/angr/path_group.py", line 212, in _one_path_step
    successors = a.step(**kwargs)
  File "build/bdist.linux-x86_64/egg/angr/path.py", line 205, in step
    self._make_successors(throw=throw)
  File "build/bdist.linux-x86_64/egg/angr/path.py", line 238, in _make_successors
    self._run = self._project.factory.successors(self.state, **self._run_args)
  File "build/bdist.linux-x86_64/egg/angr/factory.py", line 77, in successors
    r = engine.process(state, inline=inline,**kwargs)
  File "build/bdist.linux-x86_64/egg/angr/engines.py", line 88, in process
    ret_to=ret_to)
  File "build/bdist.linux-x86_64/egg/angr/engines.py", line 143, in process
    force_addr=force_addr)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/engines/procedure.py", line 34, in process
    force_addr=force_addr)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/engines/engine.py", line 44, in process
    self._process(new_state, successors, *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/angr/engines.py", line 173, in _process
    return super(SimEngineHook, self)._process(state, successors, procedure, **kwargs)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/engines/procedure.py", line 71, in _process
    procedure.execute(state, successors, ret_to=ret_to)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/s_procedure.py", line 145, in execute
    r = run_func(*sim_args, **self.kwargs)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/procedures/syscalls/open.py", line 13, in run
    return self.state.posix.open(path, flags)
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/plugins/posix.py", line 168, in open
    elif self.concrete_fs and not os.path.abspath(name).startswith("/dev"):
  File "/home/anon/.virtualenvs/driller/lib/python2.7/posixpath.py", line 360, in abspath
    if not isabs(path):
  File "/home/anon/.virtualenvs/driller/lib/python2.7/posixpath.py", line 54, in isabs
    return s.startswith('/')
  File "/home/anon/.virtualenvs/driller/lib/python2.7/site-packages/simuvex-6.7.1.31-py2.7.egg/simuvex/s_action_object.py", line 87, in __getattr__
    f = getattr(self.ast, attr)
  File "build/bdist.linux-x86_64/egg/claripy/ast/base.py", line 931, in __getattr__
    raise AttributeError(a)
AttributeError: startswith

I included the error which is where we seem to start going off the rails. I say this because my base address is 0x400000 and all the shared objects are above that... 20bd070 is unmapped memory (according to gdb when I manually run/debug this binary outside the whole Driller ecosystem). So I took a closer look at the instruction where this transition error occurred. Here's the relevant code:

0000000000409e50 <gmt2local>:
  409e50:       41 55                   push   r13
  409e52:       41 54                   push   r12
  409e54:       55                      push   rbp
  409e55:       53                      push   rbx
  409e56:       48 83 ec 18             sub    rsp,0x18
  409e5a:       48 85 ff                test   rdi,rdi
  409e5d:       48 89 7c 24 08          mov    QWORD PTR [rsp+0x8],rdi
  409e62:       74 5c                   je     409ec0 <gmt2local+0x70>

When I put a breakpoint on *0x409e50 and run the app in gdb, rdi is zero and so the jump should be taken and we should be at 0x409ec0. This is where gdb goes. The dynamic appears to go to 0x409e64 (doesn't take the jump), which seems wrong. This breakpoint is only hit once, and when I look at the stacktrace it came from tcpdump.c:1533 which is timezone_offset = gmt2local(0);. Ergo we know that this will never go to 0x409e64. Furthermore, this is the only place in the source where gmt2local() is ever called, which means if we got here an rdi isn't zero, something has gone terribly wrong.

For the symbolic side, it went to 0x409ec7, which is in the same neighborhood as 0x409ec0, but not quite right either. For context, here's the jump target:

   0x0000000000409ec0 <+112>:   xor    edi,edi
   0x0000000000409ec2 <+114>:   call   0x402ac0 <time@plt>
   0x0000000000409ec7 <+119>:   mov    QWORD PTR [rsp+0x8],rax
   0x0000000000409ecc <+124>:   jmp    0x409e64 <gmt2local+20>

So I think we have some important questions about the dynamic and symbolic targets, however the biggest question of all is: How on Earth did we get to 0x2079a40?!

After scanning back in the logs a little bit, I noticed that this is not the first time we've been in the 2000000 range. Here's the first time I start seeing that address. So maybe this is some expected artifact of how driller does the dynamic execution...?

DEBUG   | 2017-03-21 17:47:27,656 | driller.Driller | found 404e16 -> 404e19 transition
DEBUG   | 2017-03-21 17:47:27,656 | driller.Driller | 404e16 -> 404e19 has already been encountered
DEBUG   | 2017-03-21 17:47:27,676 | driller.Driller | found 404e16 -> 404e16 transition
DEBUG   | 2017-03-21 17:47:27,677 | driller.Driller | 404e16 -> 404e16 has already been encountered
DEBUG   | 2017-03-21 17:47:27,759 | driller.Driller | found 208c850 -> 208ca70 transition
DEBUG   | 2017-03-21 17:47:27,760 | driller.Driller | 208c850 -> 208ca70 has already been encountered
DEBUG   | 2017-03-21 17:47:27,799 | driller.Driller | found 208c875 -> 208c896 transition
DEBUG   | 2017-03-21 17:47:27,799 | driller.Driller | 208c875 -> 208c896 has already been encountered
DEBUG   | 2017-03-21 17:47:27,892 | driller.Driller | found 208c8b0 -> 208c940 transition
DEBUG   | 2017-03-21 17:47:27,893 | driller.Driller | 208c8b0 -> 208c940 has already been encountered
DEBUG   | 2017-03-21 17:47:27,913 | driller.Driller | found 208c924 -> 208ca60 transition
DEBUG   | 2017-03-21 17:47:27,913 | driller.Driller | 208c924 -> 208ca60 has already been encountered
DEBUG   | 2017-03-21 17:47:27,964 | driller.Driller | found 404e3c -> 405762 transition
DEBUG   | 2017-03-21 17:47:27,964 | driller.Driller | 404e3c -> 405762 has already been encountered

In any case, I could use some help with some context here so I can get to the bottom of this and get the issue fixed, whatever it might be.

A senario where symbolic execution may be improved ?

In the architecture of Driller, AFL component is augmented by angr. And generally only one path is investigated by the angr component at a time, contrary to purely utilizing angr for testing where all the possible paths can be explored.
Recently I encountered the following scenario where symbolic execution is not very efficient and intelligent:

void foo(char* str)
{
    int n = 0;
    for(int i = 0;i < 10;i++)
    {
        if('A' == str[i])    // symbolic comparison
        {
              n++;
        }
    }
    if(8 == n)   // key point
    {
         /*bug code*/
    }
}

Assume str is a symbolic input. Driller actually cannot calculate the key point comparison because the value of n is constant and key point condition is unsolvable, although it is dependent on the symbolic variable str. Of course the bug code can still be explored after many rounds of interactions between angr and AFL because the condition at the symbolic comparison will be negated many times. But are there any algorithms with which the key point condition can become sovable and be solved at one time ? I think this may greatly improve the efficiency of the symbolic execution engine.

Exception AttributeError: Uc is NoneType?

I test driller by the example
`import driller

d = driller.Driller("./CADET_00001", # path to the target binary
"racecar", # initial testcase
"\xff" * 65535, # AFL bitmap with no discovered transitions
)

new_inputs = d.drill()

print repr(new_inputs)`

I get the new_inputs successfully. but It generate a error output. It may the Uc is NoneType?

WARNING | 2017-03-27 04:51:05,224 | tracer.cachemanager.LocalCacheManager | loading state from cache file /tmp/CADET_00001-8955a29d51c1edd39b0e53794ebcf464.tcache set([((7, 134513087, 134513100), '^\xfe\xfe\xfe\xfe^\xfe'), ((7, 134513409, 134513424), '^\xff\x01\xfe\xf7\xa1\xfe'), ((7, 134513100, 134513087), '^\x01\x01\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\x01\x01\xfe\xfe\xfe\xfe'), ((7, 134513100, 134513087), '\xfe\xfe\xfe\xfe\xfe\xfe\xfe'), ((7, 134513100, 134513087), '^\xfe\x01\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\x01\xfe\xfe\xfe\xfe\xfe'), ((7, 134513210L, 134513263), '\x00\x00\x00\x00\x00\x00\x00'), ((7, 134513100, 134513087), '^\x01\xfe\xfe\xfe^\xfe'), ((7, 134513087, 134513100), '\xfe\xfe\x01\xfe\xfe\xfe\xfe'), ((7, 134513719L, 167772168), '^\xff\x01\xfe\xf7\xa1\xfe'), ((7, 134513348, 134513388), '\xfe\xfe\xfe\xfe\xfe\xfe\xfe'), ((7, 134513719L, 167772168), '\x00\x00\x00\x00\x00\x00\x00')]) Exception AttributeError: "'NoneType' object has no attribute 'release_handle'" in <bound method UcCleanupManager._finalizer of <unicorn.unicorn.UcCleanupManager object at 0x7f8769321090>> ignored

driller/run.py dies with exception: redis.exceptions.ResponseError: invalid DB index

Running driller via driller/run.py, it dies with an "invalid DB index" response from Redis when attempting to subscribe to the crashes channel:

driller@4f039bfa4c56:~$ driller/run.py /binaries
INFO    | 2016-09-06 18:57:42,921 | driller | 2 binaries found
INFO    | 2016-09-06 18:57:42,921 | driller | 2 binaries found
INFO    | 2016-09-06 18:57:42,921 | driller | going to work on 2
INFO    | 2016-09-06 18:57:42,951 | driller | listening for crashes..
Traceback (most recent call last):
  File "driller/run.py", line 87, in <module>
    sys.exit(main(sys.argv))
  File "driller/run.py", line 84, in main
    start(binary_dir)
  File "driller/run.py", line 68, in start
    p.subscribe("crashes")
  File "/usr/local/lib/python2.7/site-packages/redis/client.py", line 2229, in subscribe
    ret_val = self.execute_command('SUBSCRIBE', *iterkeys(new_channels))
  File "/usr/local/lib/python2.7/site-packages/redis/client.py", line 2161, in execute_command
    self._execute(connection, connection.send_command, *args)
  File "/usr/local/lib/python2.7/site-packages/redis/client.py", line 2165, in _execute
    return command(*args)
  File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 563, in send_command
    self.send_packed_command(self.pack_command(*args))
  File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 538, in send_packed_command
    self.connect()
  File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 446, in connect
    self.on_connect()
  File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 520, in on_connect
    if nativestr(self.read_response()) != 'OK':
  File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 582, in read_response
    raise response
redis.exceptions.ResponseError: invalid DB index

Removing the db= argument to redis.Redis() appears to fix the problem.

This issue was observed on Debian 8 (jessie), with Python 2.7.12 and redis-py 2.10.5.

How Driller controls Angr?

Hi guys, I'm stuck in a question how driller controls angr.
As my understanding after AFL get stuck it will invokes Angr in order to give the AFL new interesting input. But here, I don't know the exactly when Angr stops and give the new input. Do you guys just let the Angr run till it can't find new path? Or do u limit how far Angr can go to prevent Angr go through the function that can makes path explosion? I tried to read ur paper but still can't understand this part. Thanks for the answer

Out of paths

I'm not sure if this issue belongs here or in the angr repo, but here's the error I'm getting:

Traceback (most recent call last):
  File "./demo.py", line 17, in <module>
    solutions = d.drill()
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
    list(self._drill_input())
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 138, in _drill_input
    self._set_concretizations(t)
  File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 244, in _set_concretizations
    state = t.path_group.one_active.state
  File "build/bdist.linux-x86_64/egg/angr/path_group.py", line 381, in __getattr__
    return self.stashes[k[4:]][0]
IndexError: list index out of range

Here's the demo program that I'm using to create this error:

#!/usr/bin/env python
from driller.driller import Driller
from logging import DEBUG, getLogger
from os import environ
from traceback import print_exc

getLogger("tracer.Tracer").setLevel(DEBUG)
getLogger("angr.path_group").setLevel(DEBUG)

target = "/home/grimm/targets/xz-5.2.3/src/xz/.libs/xz"
afl_input_filename = "a.xz"
with open(afl_input_filename, "rb") as f:
        afl_input = f.read()
environ['LD_PRELOAD'] = "/home/grimm/targets/xz-5.2.3/src/liblzma/.libs/liblzma.so.5"
d = Driller(target, afl_input)
try:
        solutions = d.drill()
except Exception as e:
        print_exc()

The debugging output from path_group is extremely helpful in telling us that there are no active paths. This explains why we get the unhandled exception.

<snip>
DEBUG   | 2017-03-20 16:56:43,073 | angr.path_group | Round 72: stepping <PathGroup with 39 unsat, 1 active, 2 errored>
DEBUG   | 2017-03-20 16:56:43,074 | angr.path_group | Out of paths in stash active
<Traceback>

It seems path_group's getattr assumes that if the caller is accessing one_active, then self.stashes['active'] must have a length > 0.

I feel like the "right" thing to do in getattr is to return None in this case, but I'm not familiar enough with the code base to know if this is a reasonable way to handle this. More importantly, I don't understand why the path exploration can't find its way to the entry point! Presumably it's related to the LD_PRELOAD, but I'm not sure how. Whatever ingests the executable should be getting a snapshot of memory with the library loaded...

You guys have been giving me great support. Any pointers on this one?

Driller not generating valid inputs

I have been playing with Driller for a bit, and I noticed something that looks weird when drilling certain inputs. I wrote a toy program to illustrate this (below).

Basically, I ran driller using AFL to fuzz it first with the seed fuzzmesoftly here. AFL ran for a while and sent a few inputs to drill. However, the drilled input in question is Aset option\x00. Since AFL had already explored some paths, it modified its bitmap, so I had to capture both the bitmap and input to reproduce the result.

What I was expecting was driller to generate an output that makes the program crash. However, none of the generated output will make the toy program crash, and AFL wasn't smart enough to combine the results from driller and its own findings.

The generated output 00bada552100000000000000 from transition 4006d8 -> 4006dd contains the crash string, but it lacks the 'A' magic number prefix that would make the program crash during a real run.

$ echo -e "\x00\xba\xda\x55!" | ./listing_stdin
Bad magic number

vs.

$ echo -e "A\xba\xda\x55!" | ./listing_stdin
Segmentation fault

I am wondering how I could fix this? I looked a bit, and I think it comes down to this code in the tracer when it removes the preconstraints. It looks like it removes the 'A' because it was preconstrained when the tracer was initialized, but that constraint is necessary to even check for the crash string.

Thank you for the help!! Let me know if anything isn't clear.

Resources

Here are the resources: test script, input file, program, program source and binary, and output log. I'm pretty sure I tested on this commit (unless I've messed something up in my workspace...)

Test Script

import driller
import listing_stdin_c13fd238a6ed9a0311be4cd5426bb42f as in_data

import logging
l = logging.getLogger("driller.Driller")
l.setLevel(logging.DEBUG)

binary = "./listing_stdin"
d = driller.Driller(binary, in_data.input, in_data.fuzz_bitmap, "whatever~")

new_inputs = d.drill()

Input File

Here: listing_stdin_c13fd238a6ed9a0311be4cd5426bb42f.py.zip. It contains the binary path, input used, time run, and fuzz bitmap.

Program Source and Binary

I compiled this on Ubuntu 16.04 with gcc listing_stdin.c -o listing_stdin. Here is the compiled binary in case the fuzzing bitmap causes problems with a recompilation... listing_stdin.zip

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAGICNUMBER 'A'
#define OPTION_STR "set option"

int main(int argc, char *argv[]) {
    int* null_ptr = NULL;
    char config[20];
    read(0, config, sizeof(config));

    if (!config) {
        puts("Configuration syntax error");
        return 1;
    }
    if (config[0] != MAGICNUMBER) {
        puts("Bad magic number");
        return 2;
    }

    // Increment to next character
    char *directive = config + 1;
    if (strstr(directive, "\xba\xda\x55!")) {
    //if (strstr(directive, "badass!")) {
        int k = *null_ptr;
    }
    else if (!memcmp(directive, OPTION_STR, strlen(OPTION_STR))) {
        char *option = directive + strlen(OPTION_STR);
        puts(option);
    }
    else {
        puts("Unknown");
    }
    return 0;
}

Output

[23:55:06] $ python test_proof.py
INFO    | 2017-03-08 23:55:12,177 | driller.Driller | [listing_stdin] drilling started on Wed Mar  8 23:55:12 2017
DEBUG   | 2017-03-08 23:55:18,033 | driller.Driller | drilling into 'Aset option\x00'
DEBUG   | 2017-03-08 23:55:18,033 | driller.Driller | input is 'Aset option\x00'
DEBUG   | 2017-03-08 23:55:18,657 | driller.Driller | found 4004d0 -> 4004e0 transition
DEBUG   | 2017-03-08 23:55:18,657 | driller.Driller | 4004d0 -> 4004e0 has already been encountered
DEBUG   | 2017-03-08 23:55:18,677 | driller.Driller | found 400781 -> 4007a6 transition
DEBUG   | 2017-03-08 23:55:18,677 | driller.Driller | 400781 -> 4007a6 has already been encountered
DEBUG   | 2017-03-08 23:55:18,705 | driller.Driller | found 400640 -> 400650 transition
DEBUG   | 2017-03-08 23:55:18,705 | driller.Driller | 400640 -> 400650 has already been encountered
DEBUG   | 2017-03-08 23:55:18,727 | driller.Driller | found 4005e0 -> 400603 transition
DEBUG   | 2017-03-08 23:55:18,727 | driller.Driller | 4005e0 -> 400603 has already been encountered
DEBUG   | 2017-03-08 23:55:18,748 | driller.Driller | found 40079d -> 400790 transition
DEBUG   | 2017-03-08 23:55:18,748 | driller.Driller | 40079d -> 400790 has already been encountered
DEBUG   | 2017-03-08 23:55:18,832 | driller.Driller | found 4006a2 -> 4006aa transition
INFO    | 2017-03-08 23:55:18,849 | driller.Driller | found a completely new transition, exploring to some extent
INFO    | 2017-03-08 23:55:18,851 | driller.Driller | [listing_stdin] dumping input for 4006a2 -> 4006aa
INFO    | 2017-03-08 23:55:18,851 | driller.Driller | generated: be0000000000000000000000
INFO    | 2017-03-08 23:55:20,509 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:20 2017
INFO    | 2017-03-08 23:55:20,658 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:20 2017
INFO    | 2017-03-08 23:55:20,659 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
INFO    | 2017-03-08 23:55:20,660 | driller.Driller | generated: be0000000000000000000000
DEBUG   | 2017-03-08 23:55:20,723 | driller.Driller | found 4006d8 -> 4006dd transition
INFO    | 2017-03-08 23:55:20,782 | driller.Driller | found a completely new transition, exploring to some extent
INFO    | 2017-03-08 23:55:20,785 | driller.Driller | [listing_stdin] dumping input for 4006d8 -> 4006dd
INFO    | 2017-03-08 23:55:20,785 | driller.Driller | generated: 00bada552100000000000000
INFO    | 2017-03-08 23:55:21,821 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:21 2017
INFO    | 2017-03-08 23:55:21,858 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:21 2017
INFO    | 2017-03-08 23:55:21,860 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
INFO    | 2017-03-08 23:55:21,860 | driller.Driller | generated: 00bada552100000000000000
DEBUG   | 2017-03-08 23:55:21,907 | driller.Driller | found 4006fe -> 40071c transition
INFO    | 2017-03-08 23:55:21,945 | driller.Driller | found a completely new transition, exploring to some extent
INFO    | 2017-03-08 23:55:21,948 | driller.Driller | [listing_stdin] dumping input for 4006fe -> 40071c
INFO    | 2017-03-08 23:55:21,948 | driller.Driller | generated: 008c9a89df808f8b96909100
INFO    | 2017-03-08 23:55:22,978 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:22 2017
INFO    | 2017-03-08 23:55:23,028 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:23 2017
INFO    | 2017-03-08 23:55:23,030 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
INFO    | 2017-03-08 23:55:23,030 | driller.Driller | generated: 008c9a89df808f8b96909100
WARNING | 2017-03-08 23:55:23,061 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
DEBUG   | 2017-03-08 23:55:23,094 | driller.Driller | found 400726 -> 40073a transition
DEBUG   | 2017-03-08 23:55:23,095 | driller.Driller | 400726 -> 40073a has already been encountered

driller.driller.DrillerEnvironmentError

I tried to run driller starter code below with CADET_00001 file that i downloaded from https://github.com/angr/angr-doc/tree/master/examples/CADET_00001 (there are two types of binary files in here) but it cannot running well for those binary files with code error like picture below

import driller
d = driller.Driller("./CADET_00001", # path to the target binary
"racecar", # initial testcase
"\xff" * 65535, # AFL bitmap with no discovered transitions
)
new_inputs = d.drill()

screenshot from 2018-01-25 14-11-52

Is there anyone can solve this problem?

Update on Tutorials?

Hello. I am thinking about using driller for a project that I am working on and would like to know if there are any tutorials and documentation on how to start off with driller. Any suggestion is much appreciated! Thanks!

how AFL engine utilize the testcases generated by symbolic execution?

Hi, guys
When running the afl-cgc, it puzzles me very much that what parameter should I set for the varialbe driller_path, which means the the location of driller executable. Is that the run.py in the driller module?

Also, there is not a '-D' paremeter in "_start_afl_instance" function, to start an AFL instance, which belongs to Class Fuzzer in the Fuzzer module. That's so odd!

And I have run the run.py, but it just generates some testcases by symbolic exectuion, how would the AFL engine utilize these testcases?

Can you give some information about these questions? Thank you very much!

Testing driller with a program that reads a file

Hi, all. I want to test the driller with a program that reads a file, like djpeg.
First, I want to test a very simple example,

#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char** argv) {
  int fd = open(argv[1], O_RDONLY);
  int input = 0;
  read(fd, &input, sizeof(input));

  if (input == 0xdeadbeef)
    printf("Good");

  close(fd);
}

To do it, I modified the following line to get fs, and argv.

        s = p.factory.tracer_state(input_content=self.input, magic_content=r.magic, args=self.argv, fs=self._fs)                                                                                            

And run the driller as follows

    input_file = 'sample/input.bin'                                                                                                                                                                         
    binary = 'sample/main'                                                                                                                                                                                  
                                                                                                                                                                                                            
    with open(input_file, 'rb') as f:                                                                                                                                                                       
        inputs = f.read()                                                                                                                                                                                   
                                                                                                                                                                                                            
    fs = {input_file: simuvex.storage.file.SimFile(input_file, "rb", size=os.path.getsize(input_file))}                                                                                                     
    d = driller.Driller(binary, inputs, argv=[binary, input_file], fs=fs)                                                                                                                                   
    for drilled in d.drill_generator():                                                                                                                                                                     
        print(drilled)        

The input_file is just "AAAA". But unfortunately, I couldn't get 0xdeadbeef.
Driller generates a testcase, but it was just empty string.
I checked that open() returns SimFile.
Could you let me know where do I have to take a look?
Thanks.

some problem about the options auto_load_libcs

I have two questions about this option.
when auto_load_libcs = True, for example, we use the "chmod" function which not in simvuex/procedures/libc__so__6 or simvuex/procedures/syscalls,it will have AssertionError,assert len(self.path_group.active)<2,it will stop work,and can't have a result.but I use ll to see the file ,it already been changed!I can't understand why it changed successful ?
when auto_load_libcs = False, the same example, we use the "chmod" function which not in simvuex/procedures/libc__so__6 or simvuex/procedures/syscalls,it will not have Error,and it will get the right result.but which I can't understand is that why it jump to 0x10000xx when we call "chmod",it don't have a simulate procedure. and the file also been changed!

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.