diff --git a/docs/installation/README.md b/docs/installation/README.md
index 9bf189e..64502dd 100644
--- a/docs/installation/README.md
+++ b/docs/installation/README.md
@@ -113,14 +113,20 @@ kafl gui -w work
# 7. How to reproduce bugs
----------------------------------
-kAFL includes a replay utility to rerun a specific payload against your driver:
+kAFL includes a replay utility to rerun a specific payload against your driver.
+`replay.cpp` uses the Windows API (`CreateFileW`, `DeviceIoControl`), therefore it has to be
+built as a Windows binary and executed inside the Windows guest, not on the Linux host:
```bash
-# Build and run the replay tool
-cd $kAFL/docs/installation
-[you compiler] replay.cpp -o replay
+# Install the MinGW-w64 C++ cross-compiler
+sudo apt-get install g++-mingw-w64-x86-64
+# Build the replay tool on the host
+cd ~/kAFL/docs/installation
+x86_64-w64-mingw32-g++ replay.cpp -o replay.exe -static
+
+# Copy replay.exe into the guest, then run it there
# Usage:
-./replay
+replay.exe
```

diff --git a/docs/installation/replay.cpp b/docs/installation/replay.cpp
index bb63094..ddc21d0 100644
--- a/docs/installation/replay.cpp
+++ b/docs/installation/replay.cpp
@@ -7,6 +7,7 @@
char* payload = NULL;
char* output = NULL;
+DWORD outputSize = 0;
DWORD byteRead = NULL;
uint32_t u32(unsigned char* data) {
@@ -42,6 +43,11 @@ int wmain(int argc, wchar_t* argv[]) {
payload = (char*)VirtualAlloc(NULL, ((dFileSize + 0x1000 - 1) / 0x1000) * 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
output = (char*)VirtualAlloc(NULL, BUF_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ if (payload == NULL || output == NULL) {
+ printf("Buffer alloc fail..\n");
+ return 0;
+ }
+ outputSize = BUF_SIZE;
if (!ReadFile(hFile, payload, (DWORD)fileSize.QuadPart, &byteRead, NULL) || byteRead != fileSize.QuadPart) {
printf("File read fail..\n");
@@ -67,11 +73,21 @@ int wmain(int argc, wchar_t* argv[]) {
char* input = &payload[start + 16];
+ if (outbuffer_length > outputSize) {
+ VirtualFree(output, 0, MEM_RELEASE);
+ output = (char*)VirtualAlloc(NULL, outbuffer_length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ if (output == NULL) {
+ printf("Output buffer alloc fail..\n");
+ return 0;
+ }
+ outputSize = outbuffer_length;
+ }
+ memset(output, 0, outputSize);
+
NTSTATUS res = DeviceIoControl(hDriver, ioctl_code, input, inbuffer_length, output, outbuffer_length, &byteRead, 0);
printf("IOCTL: %lx, inputLen: %lx, outputLen: %lx success: %d\n", ioctl_code & 0xffffffff, inbuffer_length & 0xffffffff, outbuffer_length & 0xffffffff, res);
start = start + inbuffer_length + 16;
- memset(output, 0, BUF_SIZE);
}
system("pause");