Skip to main content
added 160 characters in body; edited title
Source Link

Understanding AFL behaviour for fork and execvexecv; Why `/proc/<pid>/maps` does not show the loaded binary

TL;DR Why process map in /proc/<pid>/maps does not show where the executed binary is loaded?

I am trying to do some post-mortem analysis of the fuzzed program once it finishes.

Basically what I am seeing is that /proc/<pid>/maps shows what looks to be the memory map of the parent instead of the child. I was unable to replicate the behavior on a smaller scale but I'll provide a patch to github.com/google/AFL. (Add an empty raw after the else last row if patch fails)

diff --git a/afl-fuzz.c b/afl-fuzz.c
index 46a216c..e31125f 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -2283,6 +2283,14 @@ EXP_ST void init_forkserver(char** argv) {

 }

+static void read_map(int pid, char *map) {
+    FILE *proc;
+    char path[50];
+    sprintf(path, "/proc/%d/maps", pid);
+    proc = fopen(path, "r");
+    fread(map, 4096, 1, proc);
+    fclose(proc);
+}

 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update trace_bits[]. */
@@ -2423,7 +2431,14 @@ static u8 run_target(char** argv, u32 timeout) {

   if (dumb_mode == 1 || no_forkserver) {

-    if (waitpid(child_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
+    int res;
+    char map[4096];
+    while (!(res = waitpid(child_pid, &status, WNOHANG))) {
+        if (res < 0)
+            PFATAL("waitpid() failed");
+        read_map(child_pid, map);
+    }
+    printf("%s\n", map);

   } else { 

After applying the patch you can run the following to check things out

mkdir input output
echo "hello" > input/test1
./afl-fuzz -i input -o output -n -- /bin/ls

What you'll probably is the map for afl-fuzz? The patch is waiting for the execv to finish while reading the /proc/<pid>/maps, once it's finished prints the last map that was read. I'm curious what I am missing in me reading the map or what triggers this. (Also I don't think this is regarding AFL itself is just where I've seen this, it would be nice to see a smaller program that replicates the behavior since I was unable to replicate it)

Understanding AFL behaviour for fork and execv

I am trying to do some post-mortem analysis of the fuzzed program once it finishes.

Basically what I am seeing is that /proc/<pid>/maps shows what looks to be the memory map of the parent instead of the child. I was unable to replicate the behavior on a smaller scale but I'll provide a patch to github.com/google/AFL.

diff --git a/afl-fuzz.c b/afl-fuzz.c
index 46a216c..e31125f 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -2283,6 +2283,14 @@ EXP_ST void init_forkserver(char** argv) {

 }

+static void read_map(int pid, char *map) {
+    FILE *proc;
+    char path[50];
+    sprintf(path, "/proc/%d/maps", pid);
+    proc = fopen(path, "r");
+    fread(map, 4096, 1, proc);
+    fclose(proc);
+}

 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update trace_bits[]. */
@@ -2423,7 +2431,14 @@ static u8 run_target(char** argv, u32 timeout) {

   if (dumb_mode == 1 || no_forkserver) {

-    if (waitpid(child_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
+    int res;
+    char map[4096];
+    while (!(res = waitpid(child_pid, &status, WNOHANG))) {
+        if (res < 0)
+            PFATAL("waitpid() failed");
+        read_map(child_pid, map);
+    }
+    printf("%s\n", map);

   } else {

After applying the patch you can run the following to check things out

mkdir input output
echo "hello" > input/test1
./afl-fuzz -i input -o output -n -- /bin/ls

What you'll probably is the map for afl-fuzz? The patch is waiting for the execv to finish while reading the /proc/<pid>/maps, once it's finished prints the last map that was read. I'm curious what I am missing in me reading the map or what triggers this. (Also I don't think this is regarding AFL itself is just where I've seen this, it would be nice to see a smaller program that replicates the behavior since I was unable to replicate it)

Understanding AFL behaviour for fork and execv; Why `/proc/<pid>/maps` does not show the loaded binary

TL;DR Why process map in /proc/<pid>/maps does not show where the executed binary is loaded?

I am trying to do some post-mortem analysis of the fuzzed program once it finishes.

Basically what I am seeing is that /proc/<pid>/maps shows what looks to be the memory map of the parent instead of the child. I was unable to replicate the behavior on a smaller scale but I'll provide a patch to github.com/google/AFL. (Add an empty raw after the else last row if patch fails)

diff --git a/afl-fuzz.c b/afl-fuzz.c
index 46a216c..e31125f 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -2283,6 +2283,14 @@ EXP_ST void init_forkserver(char** argv) {

 }

+static void read_map(int pid, char *map) {
+    FILE *proc;
+    char path[50];
+    sprintf(path, "/proc/%d/maps", pid);
+    proc = fopen(path, "r");
+    fread(map, 4096, 1, proc);
+    fclose(proc);
+}

 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update trace_bits[]. */
@@ -2423,7 +2431,14 @@ static u8 run_target(char** argv, u32 timeout) {

   if (dumb_mode == 1 || no_forkserver) {

-    if (waitpid(child_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
+    int res;
+    char map[4096];
+    while (!(res = waitpid(child_pid, &status, WNOHANG))) {
+        if (res < 0)
+            PFATAL("waitpid() failed");
+        read_map(child_pid, map);
+    }
+    printf("%s\n", map);

   } else { 

After applying the patch you can run the following to check things out

mkdir input output
echo "hello" > input/test1
./afl-fuzz -i input -o output -n -- /bin/ls

What you'll probably is the map for afl-fuzz? The patch is waiting for the execv to finish while reading the /proc/<pid>/maps, once it's finished prints the last map that was read. I'm curious what I am missing in me reading the map or what triggers this. (Also I don't think this is regarding AFL itself is just where I've seen this, it would be nice to see a smaller program that replicates the behavior since I was unable to replicate it)

Source Link

Understanding AFL behaviour for fork and execv

I am trying to do some post-mortem analysis of the fuzzed program once it finishes.

Basically what I am seeing is that /proc/<pid>/maps shows what looks to be the memory map of the parent instead of the child. I was unable to replicate the behavior on a smaller scale but I'll provide a patch to github.com/google/AFL.

diff --git a/afl-fuzz.c b/afl-fuzz.c
index 46a216c..e31125f 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -2283,6 +2283,14 @@ EXP_ST void init_forkserver(char** argv) {

 }

+static void read_map(int pid, char *map) {
+    FILE *proc;
+    char path[50];
+    sprintf(path, "/proc/%d/maps", pid);
+    proc = fopen(path, "r");
+    fread(map, 4096, 1, proc);
+    fclose(proc);
+}

 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update trace_bits[]. */
@@ -2423,7 +2431,14 @@ static u8 run_target(char** argv, u32 timeout) {

   if (dumb_mode == 1 || no_forkserver) {

-    if (waitpid(child_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
+    int res;
+    char map[4096];
+    while (!(res = waitpid(child_pid, &status, WNOHANG))) {
+        if (res < 0)
+            PFATAL("waitpid() failed");
+        read_map(child_pid, map);
+    }
+    printf("%s\n", map);

   } else {

After applying the patch you can run the following to check things out

mkdir input output
echo "hello" > input/test1
./afl-fuzz -i input -o output -n -- /bin/ls

What you'll probably is the map for afl-fuzz? The patch is waiting for the execv to finish while reading the /proc/<pid>/maps, once it's finished prints the last map that was read. I'm curious what I am missing in me reading the map or what triggers this. (Also I don't think this is regarding AFL itself is just where I've seen this, it would be nice to see a smaller program that replicates the behavior since I was unable to replicate it)