I'm using AFL++ 4.0c to fuzz my app. It basically wraps clang compiler too instrument my code with fuzzing shenanigans. As well I provide coverage flags:
--coverage -g -fprofile-instr-generate -fcoverage-mapping
Then I try to launch my app with fuzzer
env PARAM=paramstuff \ # setup some env
afl-fuzz -x dicts/dicts -f file.txt \ # setup afl flags
-i input -o output \ # input and output for afl
-- \
./myapp --flag --flag2 --flag3 # flags for my app
It fuzzes just fine, but coverage profile is written empty.
If some of my configuration is off and fuzzer fails to properly start the profile generated by coverage is not empty as well as .gcda output. How to allow fuzzer to trigger dump coverage as well?
if I launch my app with params profile also generated
Fuzzer works until stopped via CTRL+C. App stops the same way.
In my case AFL used fork server to fuzz parts of my app:
#ifdef __AFL_HAVE_MANUAL_CONTROL
SSH_TRACE(0, ("AFL INIT"));
__AFL_INIT();
while (__AFL_LOOP(1000)) {
#endif
/*
* regular code to fuzz goes here
*/
#ifdef __AFL_HAVE_MANUAL_CONTROL
}
#endif
So proper finalization never triggered and coverage data never dumped to profile.raw. So to force it to dump data manually I called __llvm_profile_write_file(); right after closing bracket of afl loop in the last #ifndef section. For gcc instrumentation exist similar function __gcov_flush().
Couple notes for those who fuzz things:
Don't put dump function inside fuzzing loop - it will drastically slow fuzzing performance and your profile will grow very rapidly. One such loop was able to spam about 1 GiB to profile. It probably will exhaust your disc space before you receive proper fuzzing results.
Put dump function into #ifndef guards otherwise it will mess up with regular coverage dump when you just run app. Unless you close your forked processes with __exit() and know what you are doing.
Related
For unit testing purposes, I want to be able to run a bare-metal binary with qemu and capture it's output.
Sample file:
#include <stdio.h>
#include <stdint.h>
static void qemu_exit() {
register uint32_t r0 __asm__("r0");
r0 = 0x18;
register uint32_t r1 __asm__("r1");
r1 = 0x20026;
__asm__ volatile("bkpt #0xAB");
}
int main(void) {
puts("This is some example text that I want to capture");
qemu_exit();
return 0;
}
Running with:
qemu-system-gnuarmeclipse --nographic --no-reboot \
--board STM32F4-Discovery --mcu STM32F429ZI \
--semihosting-config enable=on,target=native \
--image <binary>
Displayed to the console is:
QEMU 2.8.0-13 monitor - type 'help' for more information
(qemu) This is some example text that I want to capture
This 'example text' is generated within QEMU and so redirecting stdout to a file does not capture it (only: QEMU 2.8.0-13 monitor - type 'help' for more information
(qemu)). Looking at the available qemu logging options -d help does not offer anything as far as I can see.
EDIT
A hacky solution is to use script to capture terminal session:
script --quiet --command <qemu-shell-script-wrapper>
That's not an upstream QEMU, and 2.8 is also quite old, but hopefully the same things that work with upstream QEMU will work there.
Firstly, assuming you're not actually using the monitor, you can get rid of that part of the output by dropping '--nographic' and instead using '-display none'. (--nographic does a lot of things all at once, including both "no graphical display" and also "default serial output to the terminal, add a QEMU monitor and multiplex the monitor and the serial", among other things. It's convenient if that's what you want but sometimes it's less confusing to specify everything separately.)
Secondly, you say you're using semihosting output but is the guest's stdlib definitely using semihosting for its puts() string output and not serial port (UART) output? The output will come out on the terminal either way but how you tell QEMU to redirect it somewhere else will differ. (I suspect it may be using UART output, because if it were using semihosting output then the redirection of stdout that you tried should have worked.)
If the output from the guest is via the serial port then you can control where it goes using the '-serial' option (most simply, "-serial stdio" to send to stdout, but you can also do more complicated things like sending to files, pipes or TCP sockets.). If it's via semihosting then you can control where it goes using the 'chardev=id' suboption of -semihosting-config.
I am trying to fuzz pngquant using AFL and noticed that I am seeing the odd, check syntax! warning. A previous answer says that AFL is probably not reading the input file I specified. I am able to invoke pngquant by providing the png file located in the same input sample directory I used while fuzzing with AFL.
The AFL command I executed is:
afl-fuzz -i ./in-filtered -o ./out -x ./dictionary/png.dict -- pngquant ##
The AFL documentation mentions that the odd, check syntax! warning may pop up when AFL is not able to find new paths.
Additionally, I notice that the warning pops up as soon as AFL begins using the havoc fuzzing strategy, the images below show that the cycle counts start incrementing as soon as the fuzzer begins using havoc.
This is because of incorrect usage of pngquant.
When using pngquant, it produces an output file with your results, when you do it twice you will encounter an error:
➜ pngquant git:(master) ✗ ./pngquant ./test/img/metadata.png
➜ pngquant git:(master) ✗ ./pngquant ./test/img/metadata.png
error: './test/img/metadata-fs8.png' exists; not overwriting
AFL has no chance to explore the target, since it gets blocked every time.
After a quick look, the easiest fix is like this:
afl-fuzz -i ./in -o ./out -- ./pngquant -f -- ##
This forces pngquant to overwrite the resultfile and therefore enables afl-fuzz. However, be aware that this produces a lot of IO. So try to circumvent this using /dev/null or similar tricks.
Happy fuzzing!
I'm executing BANtest experiment provided in simulation example in Castalia 3.3 simulator. I'm exploring GTS in Contention Free Period (CFP) under beacon enable mode of IEEE 802.15.4 MAC. I want to change the configuration i.e. GTSon such a way that each individual node requests different GTS slots at command line. What do i need to change in configuration file ?
I read and understand the procedure to change configuration at command line from "section 3.5.3" at castalia user's manual. Currently, i'm able to change "equal" GTS request made by nodes in GTSon configuration at command line, but i am interested to get different GTS slots request form individual node.
Case-1: code for equal GTS request form all nodes
# Define as set of equal GTS request for all nodes in omnetpp.ini
[Config GTSon]
SN.node[*].Communication.MAC.requestGTS = ${GTS=1,2}
# Execute BANtest example- take request GTS from config file
$ Castalia -c ZigBeeMAC,[GTSon]
# Changing configuration (i.e. GTSon) form command line-run successfully
$ Castalia -c GTSon=\$\{GTS=0,3\}
Case-2: code for different GTS requests form nodes
# Define differnt GTS requests for nodes in omnetpp.ini
[Config GTSon]
SN.node[1].Communication.MAC.requestGTS = ${GTS1=0}
SN.node[2].Communication.MAC.requestGTS = ${GTS2=4}
SN.node[3].Communication.MAC.requestGTS = ${GTS3=3}
SN.node[4].Communication.MAC.requestGTS = ${GTS4=0}
SN.node[5].Communication.MAC.requestGTS = ${GTS5=0}
# Execute BANtest example- run successfully
$ Castalia -c ZigBeeMAC,[GTSon]
# Changing configuration (i.e.GTSon) form command line- showing error
$ Castalia -c GTSon=\$\{GTS1=0,GTS2=1,GTS3=5,GTS4=0,GTS5=0\}
The case-1 is running successfully, but case-2 have error,which is given below:
"ERROR: configuration 'GTSon' has more than one parameter and cannot be used with '=' syntax"
The error you are getting is simply a limitation of the Castalia script. Castalia's User manual is explicit about this limitation in section 3.5.3. You can also search for this string: has more than one parameter and cannot be used with '=' syntax" in the Castalia script to find out more details, or to think about how you could extend it to support multiple cmdline parameters per configuration.
But an extension of functionality is not really needed. One simple workaround would be to define individual configurations for each node. For example
[Config GTSon-n1]
SN.node[1].Communication.MAC.requestGTS = ${GTS1=0}
[Config GTSon-n2]
SN.node[2].Communication.MAC.requestGTS = ${GTS2=4}
...
Then you can use Castalia to run
$ Castalia -c ZigBeeMAC,GTSon-n1,GTSon-n2
Or change the parameter in the cmdline
$ Castalia -c ZigBeeMAC,GTSon-n1=3,GTSon-n2=5
In general, I'd like to suggest that changing the simulation parameters at command line is not a good idea (at least for your regular simulations). You should only use this feature to run throwaway exploratory simulations, where you quickly want to test the effect of a change, without having to edit the ini file. The added bonus here is that the command line is saved with the output file so you have some trace of how this output file was produced. That's why this feature was added in Castalia. However, for your regular simulations studies, you should have the parameter values (or range of values) in the ini file itself. In this way there is a proper record of what the simulation study is supposed to be. OMNeT++ ini files are quite versatile, and you can achieve a lot of with their syntax. Make sure you know about all that OMNeT has to offer by reading chapter 9 of the OMNeT++ 4.x manual.
I want to build a dedicated Linux system that only ever runs one binary program. This program takes control of the screen via the OpenGL driver and displays patterns. There needs to be keyboard input as well to configure the patterns. Since running this one program will be the sole purpose of the machine, I don't need any GUI, networking, etc. Also, I probably don't need any process scheduling in the kernel since only one process will ever run.
Is it possible to replace /sbin/init with my own binary to achieve this? After the kernel loads, it would then immediately execute my own binary, and that would run the entire time the machine was on. Basically, I want to emulate the way a microcontroller works, but with the benefit of being able to use an x86 CPU with different hardware devices and drivers.
Minimal init hello world program step-by-step
Compile a hello world without any dependencies that ends in an infinite loop. init.S:
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $message, %rsi
mov $message_len, %rdx
syscall
jmp .
message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
We cannot use sys_exit, or else the kernel panics.
Then:
mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
This creates a filesystem with our hello world at /init, which is the first userland program that the kernel will run. We could also have added more files to d/ and they would be accessible from the /init program when the kernel runs.
Then cd into the Linux kernel tree, build is as usual, and run it in QEMU:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
And you should see a line:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
on the emulator screen! Note that it is not the last line, so you have to look a bit further up.
You can also use C programs if you link them statically:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
with:
gcc -static init.c -o init
You can run on real hardware with a USB on /dev/sdX and:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Great source on this subject: http://landley.net/writing/rootfs-howto.html It also explains how to use gen_initramfs_list.sh, which is a script from the Linux kernel source tree to help automate the process.
Next step: setup BusyBox so you can interact with the system through a shell. Buildroot is a great way to do it.
Tested on Ubuntu 16.10, QEMU 2.6.1.
It might be possible to replace /sbin/init by your program, but you should be aware that process 1 has some specific duties. So I think it is not advisable to replace it.
Remember that a Linux kernel can also start some processes magically, outside of the usual fork from a process inherited by the init process. I'm thinking of things like /sbin/modprobe or /sbin/hotplug etc.
Also, udev (or systemd) have some special roles. On some systems, fan control was related to such things (I really forgot the details). If unlucky, you could burn your hardware if fan is not working well (but AFAIK this is no more true on recent hardware).
By seeking with string the vmlinux in a recent 3.15.3 kernel, I find that it knows about:
/bin/init
/bin/sh
/sbin/request-key
/sbin/tomoyo-init
/sbin/modprobe
/sbin/poweroff
/sbin/hotplug
I would recommend instead keeping some existing init program, and configure it to run only your program.
You can put your program to initrd, and then run it from initrd's init.
Simply use a boot paramter eg) init=/bin/bash
init is the process 1, used by kernel to start user space, which as a few specific duties like reaping children periodical to clean out zombies. Sounds like you don't even need that.
Linux Boot parameters you should know
The run configuration works for a given set of arguments while the debug configuration fails.
This is my build configuration for ffmpeg.c
http://pastebin.com/PFM4K4xF
you can view from the build configuration generated . i have set posix style paths for the ffmpeg source.
the debug/run arguments are as -i Debug/sample2.mpg -ab 56k -ar 22050 -b 512k -r 30 -s 320x240 Debug/out2.flv
This all works fine when i run the program. The output file is generated.
But when i try to debug the ffmpeg.c program
it keeps stopping/hanging at certain instructions and the step over option disables.
like show_banner() and parse_options. ( when i commented out show_banner() it stoped at parse_options.)
more so in show_banner() -> cmdutils-> stops when trying to print swscale
and in parse_options->cmdutils.c-> stops at instruction po->u.func_arg(arg);
upon further inspection of stepping through i find this going into an infinite loop .
what is this error ? How do i resume stepping over instructions.
Has any one been able to debug completely from start to finish the ffmpeg.c after giving it valid input ? This is to observe the flow of execution based on the input's given.