microsoft / Detours

Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.
MIT License
5.18k stars 1.01k forks source link

Hooking CopyFileA/W #126

Closed RomanLuchyshyn closed 4 years ago

RomanLuchyshyn commented 4 years ago

Hi, I try to hook CopyFileA globally. I used sample 'simple' and added CopyFileA hook. After installing dll it started hooking. But only SleepEx. CopyFileA hasn't been hooked instead of I called CopyFileA directly from my application. What the specific feature for CopyFileA for Detours?

My code.

simple.cpp.txt

bgianfo commented 4 years ago

I made your example compile in the detours project, and it works as expected.

Here's the working output, where "repro64.dll" is your example code:

C:\src\detours\samples\simple>nmake test-repro

Microsoft (R) Program Maintenance Utility Version 14.27.29111.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-------- Should load repro64.dll dynamically using withdll.exe----------
        ..\..\bin.X64\withdll.exe -d:..\..\bin.X64\repro64.dll ..\..\bin.X64\sleep5.exe
withdll.exe: Starting: `..\..\bin.X64\sleep5.exe'
withdll.exe:   with `C:\src\detours\bin.X64\repro64.dll'
simple64.dll: Starting.
simple64.dll: Detoured SleepEx().
simple64.dll: Detoured CopyFileA().
sleep5.exe: Starting.
Detour: "TimeSleepEx" being executed!
Detour: "HookCopyFileA" being executed!
sleep5.exe: Done sleeping.

Here's the diff you can apply locally to have it work in your clone of the detours project:

diff --git a/samples/simple/Makefile b/samples/simple/Makefile
index 1597519..f0bd411 100644
--- a/samples/simple/Makefile
+++ b/samples/simple/Makefile
@@ -15,10 +15,12 @@ LIBS=$(LIBS) kernel32.lib

 all: dirs \
     $(BIND)\simple$(DETOURS_BITS).dll \
+    $(BIND)\repro$(DETOURS_BITS).dll \
     $(BIND)\sleep5.exe \
     \
 !IF $(DETOURS_SOURCE_BROWSING)==1
     $(OBJD)\simple$(DETOURS_BITS).bsc \
+    $(OBJD)\repro$(DETOURS_BITS).bsc \
     $(OBJD)\sleep5.bsc \
 !ENDIF
     option
@@ -31,8 +33,22 @@ dirs:

 $(OBJD)\simple.obj : simple.cpp

+$(OBJD)\repro.obj : repro.cpp
+
 $(OBJD)\simple.res : simple.rc

+
+$(BIND)\repro$(DETOURS_BITS).dll $(BIND)\repro$(DETOURS_BITS).lib: \
+        $(OBJD)\repro.obj $(OBJD)\simple.res $(DEPS)
+    cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
+        $(OBJD)\repro.obj $(OBJD)\simple.res \
+        /link $(LINKFLAGS) /subsystem:console \
+        /export:DetourFinishHelperProcess,@1,NONAME \
+        /export:TimedSleepEx \
+        /export:HookCopyFileA \
+        $(LIBS)
+
+
 $(BIND)\simple$(DETOURS_BITS).dll $(BIND)\simple$(DETOURS_BITS).lib: \
         $(OBJD)\simple.obj $(OBJD)\simple.res $(DEPS)
     cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
@@ -113,6 +129,11 @@ test: all
     $(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
     @echo.

+test-repro: all
+    @echo -------- Should load repro$(DETOURS_BITS).dll dynamically using withdll.exe----------
+    $(BIND)\withdll.exe -d:$(BIND)\repro$(DETOURS_BITS).dll $(BIND)\sleep5.exe
+    @echo.
+
 debug: all
     windbg -o $(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe

diff --git a/samples/simple/repro.cpp b/samples/simple/repro.cpp
new file mode 100644
index 0000000..8cdf20c
--- /dev/null
+++ b/samples/simple/repro.cpp
@@ -0,0 +1,83 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//  Detours Test Program (repro.cpp of repro.dll)
+//
+//  Microsoft Research Detours Package
+//
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+//
+//  This DLL will detour the Windows SleepEx and CopyFileA APIs.
+//
+#include <stdio.h>
+#include <windows.h>
+#include "detours.h"
+
+static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
+static BOOL (WINAPI* TrueCopyFileA)(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _In_ BOOL bFailIfExists) = CopyFileA;
+
+BOOL WINAPI HookCopyFileA(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _In_ BOOL bFailIfExists)
+{
+    printf("Detour: \"HookCopyFileA\" being executed!\n");
+    return TrueCopyFileA(lpExistingFileName, lpNewFileName, bFailIfExists);
+}
+
+DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
+{
+    printf("Detour: \"TimeSleepEx\" being executed!\n");
+
+    return TrueSleepEx(dwMilliseconds, bAlertable);
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
+{
+    LONG error;
+    (void)hinst;
+    (void)reserved;
+
+    if (DetourIsHelperProcess()) {
+        return TRUE;
+    }
+
+    if (dwReason == DLL_PROCESS_ATTACH) {
+        DetourRestoreAfterWith();
+
+        printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
+               " Starting.\n");
+        fflush(stdout);
+
+        DetourTransactionBegin();
+        DetourUpdateThread(GetCurrentThread());
+        DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        DetourAttach(&(PVOID&)TrueCopyFileA, HookCopyFileA);
+
+        error = DetourTransactionCommit();
+
+        if (error == NO_ERROR) {
+            printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
+                   " Detoured SleepEx().\n");
+            printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
+                   " Detoured CopyFileA().\n");
+        }
+        else {
+            printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
+                   " Error detouring SleepEx(): %d\n", error);
+            printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
+                   " Error detouring CopyFileA(): %d\n", error);
+        }
+    }
+    else if (dwReason == DLL_PROCESS_DETACH) {
+        DetourTransactionBegin();
+        DetourUpdateThread(GetCurrentThread());
+        DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        DetourDetach(&(PVOID&)TrueCopyFileA, HookCopyFileA);
+
+
+        error = DetourTransactionCommit();
+
+        fflush(stdout);
+    }
+    return TRUE;
+}
+
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/samples/simple/sleep5.cpp b/samples/simple/sleep5.cpp
index bb28226..1ee6ec4 100644
--- a/samples/simple/sleep5.cpp
+++ b/samples/simple/sleep5.cpp
@@ -21,6 +21,8 @@ int __cdecl main(int argc, char ** argv)

         Sleep(5000);

+        CopyFileA(NULL, NULL, FALSE);
+
         printf("sleep5.exe: Done sleeping.\n");
     }
     return 0;
bgianfo commented 4 years ago

Closing this issue, feel free to re-open if you have more questions. Thanks!