diff --git a/README.md b/README.md
index 4eb32073..25578ceb 100644
--- a/README.md
+++ b/README.md
@@ -210,6 +210,8 @@ Triage crashes after Sharpfuzz fuzzing with casr-afl:
     $ casr-afl -i casr/tests/casr_tests/casrep/afl-out-sharpfuzz -o casr/tests/tmp_tests_casr/casr_afl_csharp_out
     $ # You may force your own run arguments using --ignore-cmdline
     $ casr-afl --ignore-cmdline -i casr/tests/casr_tests/casrep/afl-out-sharpfuzz -o casr/tests/tmp_tests_casr/casr_afl_csharp_out -- dotnet run --no-build --project /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj @@
+    $ # If you use vanilla AFL for fuzzing with Sharpfuzz, provide --afl-dir flag
+    $ casr-afl --afl-dir -i casr/tests/casr_tests/casrep/afl-out-sharpfuzz -o casr/tests/tmp_tests_casr/casr_afl_csharp_out/afl_main-worker -- dotnet run --no-build --project /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj @@
 
 Triage libFuzzer crashes with casr-libfuzzer:
 
diff --git a/casr/src/bin/casr-afl.rs b/casr/src/bin/casr-afl.rs
index 02a20cee..3a99b7ba 100644
--- a/casr/src/bin/casr-afl.rs
+++ b/casr/src/bin/casr-afl.rs
@@ -97,6 +97,12 @@ fn main() -> Result<()> {
                 .long("ignore-cmdline")
                 .help("Force <ARGS> usage to run target instead of searching for cmdline files in AFL fuzzing directory")
         )
+        .arg(
+            Arg::new("afl-dir")
+                .action(ArgAction::SetTrue)
+                .long("afl-dir")
+                .help("Indicate that vanilla AFL directory is given as input (if set, --ignore-cmdline flag is set automatically)")
+        )
         .arg(
             Arg::new("no-cluster")
                 .action(ArgAction::SetTrue)
@@ -134,16 +140,21 @@ fn main() -> Result<()> {
         Vec::new()
     };
 
-    if args.is_empty() && matches.get_flag("ignore-cmdline") {
-        bail!("ARGS is empty, but \"ignore-cmdline\" option is provided.");
-    }
-
     let hint = matches.get_one::<String>("hint").unwrap();
+    let afl_dir = matches.get_flag("afl-dir");
+    let ignore_cmdline = matches.get_flag("ignore-cmdline") || afl_dir;
+
+    if args.is_empty() && ignore_cmdline {
+        bail!("ARGS is empty, but \"ignore-cmdline\" or \"afl-dir\" option is provided.");
+    }
 
     // Get all crashes.
     let mut crashes: HashMap<String, CrashInfo> = HashMap::new();
     for node_dir in fs::read_dir(matches.get_one::<PathBuf>("input").unwrap())? {
-        let path = node_dir?.path();
+        let mut path = node_dir?.path();
+        if afl_dir {
+            path.pop();
+        }
         if !path.is_dir() {
             continue;
         }
@@ -152,7 +163,7 @@ fn main() -> Result<()> {
         let mut crash_info = casr::triage::CrashInfo {
             ..Default::default()
         };
-        crash_info.target_args = if matches.get_flag("ignore-cmdline") {
+        crash_info.target_args = if ignore_cmdline {
             args.clone()
         } else {
             let cmdline_path = path.join("cmdline");
@@ -219,7 +230,7 @@ fn main() -> Result<()> {
         }
     }
 
-    if matches.get_flag("ignore-cmdline") || !is_casr_gdb {
+    if ignore_cmdline || !is_casr_gdb {
         args = Vec::new();
     }
 
diff --git a/casr/tests/tests.rs b/casr/tests/tests.rs
index 6f39105a..bee0074b 100644
--- a/casr/tests/tests.rs
+++ b/casr/tests/tests.rs
@@ -6164,6 +6164,121 @@ fn test_casr_afl_csharp_ignore_cmd() {
     let _ = fs::remove_dir_all(&paths[5]);
 }
 
+#[test]
+#[cfg(target_arch = "x86_64")]
+fn test_casr_afl_csharp_afl_dir() {
+    use std::collections::HashMap;
+
+    let paths = [
+        abs_path("tests/casr_tests/casrep/afl-out-sharpfuzz/afl_main-worker"),
+        abs_path("tests/tmp_tests_casr/casr_afl_csharp_afl_dir_out"),
+        abs_path("tests/casr_tests/csharp/test_casr_afl_csharp"),
+        abs_path("tests/casr_tests/csharp/test_casr_afl_csharp_module"),
+        abs_path("tests/tmp_tests_casr/test_casr_afl_csharp"),
+        abs_path("tests/tmp_tests_casr/test_casr_afl_csharp_module"),
+    ];
+
+    let _ = fs::remove_dir_all(&paths[1]);
+    let _ = fs::remove_dir_all(&paths[4]);
+    let _ = fs::remove_dir_all(&paths[5]);
+    let _ = fs::create_dir(abs_path("tests/tmp_tests_casr"));
+    let _ = copy_dir(&paths[2], &paths[4]).unwrap();
+    let _ = copy_dir(&paths[3], &paths[5]).unwrap();
+    let Ok(dotnet_path) = which::which("dotnet") else {
+        panic!("No dotnet is found.");
+    };
+
+    let _ = Command::new(dotnet_path.to_str().unwrap())
+        .args([
+            "build",
+            &format!("{}/test_casr_afl_csharp.csproj", &paths[4]),
+        ])
+        .output()
+        .expect("dotnet build crashed");
+
+    let bins = Path::new(*EXE_CASR_AFL.read().unwrap()).parent().unwrap();
+    let mut output = Command::new(*EXE_CASR_AFL.read().unwrap());
+    output
+        .args([
+            "--afl-dir",
+            "-i",
+            &paths[0],
+            "-o",
+            &paths[1],
+            "--",
+            (dotnet_path.to_str().unwrap()),
+            "run",
+            "--no-build",
+            "--project",
+            &format!("{}/test_casr_afl_csharp.csproj", &paths[4]),
+            "@@",
+        ])
+        .env(
+            "PATH",
+            format!("{}:{}", bins.display(), std::env::var("PATH").unwrap()),
+        );
+
+    let output = output.output().expect("casr-afl crashed");
+
+    assert!(
+        output.status.success(),
+        "Stdout {}.\n Stderr: {}",
+        String::from_utf8_lossy(&output.stdout),
+        String::from_utf8_lossy(&output.stderr)
+    );
+    let res = String::from_utf8_lossy(&output.stderr);
+
+    assert!(!res.is_empty());
+
+    let re = Regex::new(r"Number of reports after deduplication: (?P<unique>\d+)").unwrap();
+    let unique_cnt = re
+        .captures(&res)
+        .unwrap()
+        .name("unique")
+        .map(|x| x.as_str())
+        .unwrap()
+        .parse::<u32>()
+        .unwrap();
+
+    assert_eq!(unique_cnt, 3, "Invalid number of deduplicated reports");
+
+    let re = Regex::new(r"Number of clusters: (?P<clusters>\d+)").unwrap();
+    let clusters_cnt = re
+        .captures(&res)
+        .unwrap()
+        .name("clusters")
+        .map(|x| x.as_str())
+        .unwrap()
+        .parse::<u32>()
+        .unwrap();
+
+    assert_eq!(clusters_cnt, 3, "Invalid number of clusters");
+
+    let mut storage: HashMap<String, u32> = HashMap::new();
+    for entry in fs::read_dir(&paths[1]).unwrap() {
+        let e = entry.unwrap().path();
+        let fname = e.file_name().unwrap().to_str().unwrap();
+        if fname.starts_with("cl") && e.is_dir() {
+            for file in fs::read_dir(e).unwrap() {
+                let mut e = file.unwrap().path();
+                if e.is_file() && e.extension().is_some() && e.extension().unwrap() == "casrep" {
+                    e = e.with_extension("");
+                }
+                let fname = e.file_name().unwrap().to_str().unwrap();
+                if let Some(v) = storage.get_mut(fname) {
+                    *v += 1;
+                } else {
+                    storage.insert(fname.to_string(), 1);
+                }
+            }
+        }
+    }
+
+    assert!(storage.values().all(|x| *x > 1));
+    let _ = fs::remove_dir_all(&paths[4]);
+    let _ = fs::remove_dir_all(&paths[5]);
+}
+
 #[test]
 #[cfg(target_arch = "x86_64")]
 fn test_casr_libfuzzer_libafl() {
diff --git a/docs/usage.md b/docs/usage.md
index 0032d8f9..4853ce95 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -463,6 +463,8 @@ Triage crashes found by AFL++/Sharpfuzz
       -f, --force-remove              Remove output project directory if it exists
           --ignore-cmdline            Force <ARGS> usage to run target instead of searching
                                       for cmdline files in AFL fuzzing directory
+          --afl-dir                   Indicate that vanilla AFL directory is given as input
+                                      (if set, --ignore-cmdline flag is set automatically)
           --no-cluster                Do not cluster CASR reports
           --hint <HINT>               Hint to force run casr-HINT tool to analyze crashes
                                       [default: auto] [possible values: auto, gdb, san,
@@ -571,7 +573,14 @@ Sharpfuzz example (with --ignore-cmdline):
     $ dotnet publish /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj -c Debug -o /tmp/test_casr_afl_csharp/bin
     $ casr-afl --ignore-cmdline -i casr/tests/casr_tests/casrep/afl-out-sharpfuzz -o casr/tests/tmp_tests_casr/casr_afl_csharp_out -- dotnet run --no-build --project /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj @@
 
-**NOTE:** if you run `casr-afl` for Sharpfuzz pipeline using `--ignore-cmdline` with `dotnet run`, build
+Sharpfuzz example (with --afl-dir):
+
+    $ cp -r casr/tests/casr_tests/csharp/test_casr_afl_csharp /tmp/test_casr_afl_csharp
+    $ cp -r casr/tests/casr_tests/csharp/test_casr_afl_csharp_module /tmp/test_casr_afl_csharp_module
+    $ dotnet publish /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj -c Debug -o /tmp/test_casr_afl_csharp/bin
+    $ casr-afl --afl-dir -i casr/tests/casr_tests/casrep/afl-out-sharpfuzz/afl_main-worker -o casr/tests/tmp_tests_casr/casr_afl_csharp_out -- dotnet run --no-build --project /tmp/test_casr_afl_csharp/test_casr_afl_csharp.csproj @@
+
+**NOTE:** if you run `casr-afl` for Sharpfuzz pipeline using `--ignore-cmdline` or `afl-dir` with `dotnet run`, build
 your project before (via `dotnet build` or `dotnet publish`) and specify `--no-build` option for `dotnet run`.
 
 ## casr-libfuzzer