drrun.exe target offset question

121 views
Skip to first unread message

John

unread,
Jun 20, 2023, 4:17:03 PM6/20/23
to DynamoRIO Users
I have a question about the drrun command. When calling drrun using the -c winafl.dll argument, I pass the target_module and the target_offset arguments, so that the whole list of arguments is pretty long. I also pass pass the -debug flag, and reading the log I see the message which is quite similar to the one posted here: https://github.com/googleprojectzero/winafl/issues/248 . The log tells me that my offset might be wrong.

I have verified the offset using WinDbg and Ghidra, tried different versions of DynamoRIO, built it myself, disabled the compiler optimization in Visual Studio to avoid inlining, but the log continues to tell me that my offset might be wrong. I am struggling to understand what can I do at the moment and what the issue could be.

Would you have an idea of what I can try?


Derek Bruening

unread,
Jun 20, 2023, 9:52:46 PM6/20/23
to John, DynamoRIO Users
Either the address provided was not the offset from the module base, or that address was never reached during execution.  Providing details as in the issue you cite (windbg output) would help confirm the former.  Running without DR in windbg with a breakpoint on the address would be one way to check the latter.  You could also run under plain DR debug build and look at the log files (https://dynamorio.org/page_logging.html) to see what modules and block offsets it's running; or use the drcov tool to get the same.  Find the loaded base of the target module (in the process log file) and search for that in the thread log files, e.g.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/797fabc9-0b26-4265-8cf9-e3e16321177fn%40googlegroups.com.

John

unread,
Jun 21, 2023, 1:26:27 PM6/21/23
to DynamoRIO Users
Hello Derek, and thank you for your message. I must admit that I am new to these concepts and just wanted to explore the fascinating world of fuzzing. However, I have been spending a lot of time without successfully getting something to work properly. I'll describe to you what I've tried and I'd be grateful for your help.

1) I was guided by the following tutorial: [Fuzzing With WinAFL] How to fuzz a simple C program with WinAFL. This tutorial was valuable in the sense that it explained many concepts. However, it was less helpful because the author's video keeps freezing, making it difficult to follow along. Moreover, the source code presented there and in the corresponding GitHub repository (GitHub link) does not clone correctly, and there's no direct Windows code like the one presented in the video. Another source of confusion is that the program presented in the video targets a 32-bit system.

As a result, I had to rewrite it for my 64-bit system. The code defines a simplified image:

```
struct Image {
    char header[4] = “IMG”;
    int width;
    int height;
    char data[10];
};
```


Along with the functions `__declspec(noinline) int ProcessImage(TCHAR* filename)` and `int _tmain(int argc, TCHAR* argv[])`, it provides a simple program where `main` calls the `ProcessImage` function, and this `ProcessImage` function reads the file. This is aimed to be a target function for fuzzing. I wrote another function to create such a file format and it works correctly. Additionally, there are many vulnerabilities in the code to make it fun for the fuzzer.

I compiled the program in Visual Studio and it works well as a standalone. The project is called “Damn”, as an abbreviation of the original GitHub name, so that's why this word appears later in the text.

The tutorial provided two ways of invoking the program: one with the `drrun.exe` application, the other one with the `afl-fuzz.exe` application.

2) Based on the video, I used the following options for the `drrun.exe` call:

```
drrun.exe -c winafl.dll -debug -target_module Damn.exe -target_offset 0x14f00 -fuzz_iterations 10 -nargs 2 -- Damn.exe 1.img
```


In the log, I see that all the modules were loaded and the output matches exactly what was mentioned in the GitHub post from my initial message:

```
"WARNING: Target function was never called. Incorrect target_offset?
Coverage map follows:"
```


That's it. There's nothing else in the log.

3) Also based on the video, I used the following options to try the `afl-fuzz.exe` way:

```
afl-fuzz.exe -i inImage -o outImage -t 5000+ -D …<DynamoRIO folder>\bin64 -- -coverage_module Damn.exe -target_module Damn.exe -target_offset 0x14f00 -fuzz_iterations 5000 -call_convention thiscall -nargs 2 -covtype edge -- Damn.exe @@
```


This generates the following output:

```
WinAFL 1.16b by ...
Based on AFL 2.43b by ...

[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...
[!] WARNING: Test case results in a timeout (skipping)

[-] PROGRAM ABORT : All test cases time out, giving up!
         Location : perform_dry_run(), …\winafl\afl-fuzz.c:3330

0 processes nudged
nudge operation failed, verify permissions and parameters.
```


What's interesting here is that this message appears immediately, so it doesn't matter how large you set the timeout value. At this point, I don't fully understand what "nudging" means or what permissions or parameters I need to verify.

Following your message, I made the following steps:

4) I verified the offsets again. In WinDbg, I see that the offset 0x14f00 should be correct. In Ghidra, I see two offsets: 0x14f00 (imported function) and 0x11591 (thunk function). I tried both, but neither works. I thought that the function at 0x11591 might somehow be a starter for the function at 0x14f00, but I don't know why these two separate functions exist. According to your advice, I also debugged the program in WinDbg and Visual Studio, setting a breakpoint at the `ProcessImage` function. Both debuggers reach this code point, and every time I see the same value of 0x14f00 for the offset.

5) I built DynamoRIO in Debug mode. The page you referenced mentions a "loglevel" option if DynamoRIO is compiled in Debug mode. I tried it out, but the flag was ignored and I got the "UNRECOGNIZED OPTION: loglevel" output in my terminal. I looked into the `winafl.c` code and I see the following struct there:

```c
typedef struct _winafl_option_t {
    /* Use nudge to notify the process for termination so that
     * event_exit will be called.
     */
    bool nudge_kills;
    bool debug_mode;
    int persistence_mode;
    int coverage_kind;
    char logdir[MAXIMUM_PATH];
    target_module_t *target_modules;
    char fuzz_module[MAXIMUM_PATH];
    char fuzz_method[MAXIMUM_PATH];
    char pipe_name[MAXIMUM_PATH];
    char shm_name[MAXIMUM_PATH];
    unsigned long fuzz_offset;
    int fuzz_iterations;
    void **func_args;
    int num_fuz_args;
    drwrap_callconv_t callconv;
    bool thread_coverage;
    bool no_loop;
    bool dr_persist_cache;
} winafl_option_t;
```


If I'm not mistaken, there's no loglevel parameter there. So, I was unable to generate a more descriptive log.

6) I had to recompile DynamoRIO with the BUILD_TOOLS flag to get `drcov`. It created a large log file for me, which I couldn't read, because I needed the `drcov2lcov` tool. I used the tool, but without the `-src_filter` flag it generates an error later:

```
genhtml: ERROR: cannot read …/shared/winerror.h
```

With the `-src_filter` flag and pointing to the directory with the Damn project files, both `drcov2lcov` and `genhtml` work smoothly, but the resulting HTML file doesn't provide much information. It shows me that the coverage was 55.2% and that the code visited `ProcessImage`, but I don't see any functions in the file. So I'm not sure how I should use it and how this can help.

In summary, I just wanted to try WinAFL and understand how it works. Up to now, I don't understand the errors that occur. In the `drrun.exe` case, it tells me the offset is wrong, but I can verify the offset and see that the function was visited. In the `afl-fuzz.exe` case, it tells me that the timeout was reached, but the message appears immediately, so there was no chance for the timeout to be reached.

I would appreciate any help that could assist me in understanding the nature of these errors and getting started with the library. Please note, as mentioned, I have no experience with WinAFL or DynamoRIO and wanted to try it out. So I am merely hoping that all the command-line arguments I passed to the `afl-fuzz.exe` and `drrun.exe` applications are correct.

Thank you.

Derek Bruening

unread,
Jun 21, 2023, 2:55:26 PM6/21/23
to John, DynamoRIO Users
I would again suggest confirming the offset with windbg output: actual literal output.  Are you sure it is not the absolute value rather than the offset from the start?  We can't tell because you haven't provided the details; showing the module bounds and disasm as was done in the very bug you cited would help.

The same thing for the others -- provide more details. You say you built DR in "Debug mode" but there is no loglevel: that means it wasn't actually a debug build.  Providing the exact cmake configuration command would help.  It has to set DEBUG to ON as documented: https://dynamorio.org/page_building.html#autotoc_md76

John

unread,
Jul 12, 2023, 8:50:01 AM7/12/23
to DynamoRIO Users
Hello Derek,

I am sorry for the late response. 

Yes, attached is the Ghidra snapshot. The image of Damn.exe starts at 0x140000000, the address of ProcessImage is 0x140014f00, so the offset must be 0x14f00. Please correct me if I am wrong. 

Regarding the logging, I can only confirm that I did everything as written before. My cmake instructions are identical to those mentioned in  Building from Source (dynamorio.org) . In particular, I pass the -DDEBUG=ON flag, the build runs good. Then I pass this build to the WinAFL build, as well. 

When executing drrun.exe with the -debug flag, a log file gets created. The content is:

Module loaded, dynamorio.dll
Module loaded, MFC140ENU.DLL
Module loaded, winafl.dll
Module loaded, drx.dll
Module loaded, drreg.dll
Module loaded, drmgr.dll
Module loaded, drwrap.dll
Module loaded, Damn.exe
Module loaded, mfc140ud.dll
Module loaded, ucrtbased.dll
Module loaded, COMCTL32.dll
Module loaded, VCRUNTIME140D.dll
Module loaded, VCRUNTIME140_1D.dll
Module loaded, UxTheme.dll
Module loaded, gdi32full.dll
Module loaded, ucrtbase.dll
Module loaded, win32u.dll
Module loaded, KERNELBASE.dll
Module loaded, msvcp_win.dll
Module loaded, OLEAUT32.dll
Module loaded, SECHOST.dll
Module loaded, msvcrt.dll
Module loaded, combase.dll
Module loaded, ole32.dll
Module loaded, ADVAPI32.dll
Module loaded, USER32.dll
Module loaded, GDI32.dll
Module loaded, RPCRT4.dll
Module loaded, IMM32.dll
Module loaded, KERNEL32.dll
Module loaded, SHLWAPI.dll
Module loaded, ntdll.dll
Module loaded, AppCore.dll

WARNING: Target function was never called. Incorrect target_offset?
Coverage map follows:      
...

There is no coverage map there, and the message points me out, that the offset is wrong...

When trying to pass the -loglevel, I get the following error:
UNRECOGNIZED OPTION: "-loglevel"

Moreover, with the debug flag I get the errors similar to these:  Memory leak in winafl client · Issue #112 · googleprojectzero/winafl · GitHub
Those of mine say "WinAFL notice: memory leak: Client 6192 bytes not freed", then "WinAFL Notice: Damn.exe DynamoRIO usage error: memory leak detected", then once more "WinAFL Notice: Usage error: memory leak detected". The line I use for calling DynamoRIO is

<drrun.exe> -c <winafl.dll> -debug -target_module <Damn.exe> -target_offset 0x14f00 -fuzz_iterations 10 -nargs 2 -- <Damn.exe> <1.img>

When removing the debug flag I get an error "WinAFL Notice: winafl.c:822: false (error connecting to pipe)". 

So, having a bunch of this errors, I can hardly understand where to start and what is the problem.

ghidra_offset.png
Reply all
Reply to author
Forward
0 new messages