168 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			168 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Detour Test Program (wrotei.cpp of wrotei.dll)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Microsoft Research Detours Package
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Copyright (c) Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  An example dynamically detouring a function.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  WARNING:
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  CINTERFACE must be defined so that the lpVtbl pointer is visible
							 | 
						||
| 
								 | 
							
								//  on COM interfaces.  However, once we've defined it, we must use
							 | 
						||
| 
								 | 
							
								//  coding conventions when accessing interface members, for example:
							 | 
						||
| 
								 | 
							
								//      i->lpVtbl->Write
							 | 
						||
| 
								 | 
							
								//  instead of the C++ syntax:
							 | 
						||
| 
								 | 
							
								//      i->Write.
							 | 
						||
| 
								 | 
							
								//  We must also pass the implicit "this" parameter explicitly:
							 | 
						||
| 
								 | 
							
								//      i->lpVtbl->Write(i, pb, 0, NULL)
							 | 
						||
| 
								 | 
							
								//  instead of the C++ syntax:
							 | 
						||
| 
								 | 
							
								//      i->Write(pb, 0, NULL)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								#define CINTERFACE
							 | 
						||
| 
								 | 
							
								#include <ole2.h>
							 | 
						||
| 
								 | 
							
								#include <windows.h>
							 | 
						||
| 
								 | 
							
								#include <detours.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								LONG dwWrote = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
							 | 
						||
| 
								 | 
							
								static int (WINAPI * RawEntryPoint)(VOID) = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
							 | 
						||
| 
								 | 
							
								                                              const void *pv,
							 | 
						||
| 
								 | 
							
								                                              ULONG cb,
							 | 
						||
| 
								 | 
							
								                                              ULONG *pcbWritten) = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
							 | 
						||
| 
								 | 
							
								                                           const void *pv,
							 | 
						||
| 
								 | 
							
								                                           ULONG cb,
							 | 
						||
| 
								 | 
							
								                                           ULONG *pcbWritten)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HRESULT hr;
							 | 
						||
| 
								 | 
							
								    ULONG cbWritten = 0;
							 | 
						||
| 
								 | 
							
								    if (pcbWritten == NULL) {
							 | 
						||
| 
								 | 
							
								        pcbWritten = &cbWritten;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    hr = RealIStreamWrite(This, pv, cb, pcbWritten);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (;;) {
							 | 
						||
| 
								 | 
							
								        LONG dwOld = dwWrote;
							 | 
						||
| 
								 | 
							
								        LONG dwNew = dwOld + *pcbWritten;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (InterlockedCompareExchange(&dwWrote, dwNew, dwOld) == dwOld) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return hr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								int WINAPI TimedEntryPoint(VOID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // We couldn't call CoInitializeEx in DllMain,
							 | 
						||
| 
								 | 
							
								    // so we detour the vtable entries here...
							 | 
						||
| 
								 | 
							
								    LONG error;
							 | 
						||
| 
								 | 
							
								    LPSTREAM pStream = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Create a temporary object so we can get a vtable.
							 | 
						||
| 
								 | 
							
								    CreateStreamOnHGlobal(NULL, TRUE, &pStream);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Apply the detour to the vtable.
							 | 
						||
| 
								 | 
							
								    DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								    DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								    if (pStream != NULL) {
							 | 
						||
| 
								 | 
							
								        RealIStreamWrite = pStream->lpVtbl->Write;
							 | 
						||
| 
								 | 
							
								        DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    error = DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pStream != NULL) {
							 | 
						||
| 
								 | 
							
								        pStream->lpVtbl->Release(pStream);
							 | 
						||
| 
								 | 
							
								        pStream = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (error == NO_ERROR) {
							 | 
						||
| 
								 | 
							
								        printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								               " Detoured IStream::Wrote() from OnHGlobal.\n");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								               " Error detouring IStram::Wrote(): %ld\n", error);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								           " Calling EntryPoint\n\n");
							 | 
						||
| 
								 | 
							
								    fflush(stdout);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return TrueEntryPoint();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								               " Starting.\n");
							 | 
						||
| 
								 | 
							
								        fflush(stdout);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // NB: DllMain can't call LoadLibrary, so we hook the app entry point.
							 | 
						||
| 
								 | 
							
								        TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
							 | 
						||
| 
								 | 
							
								        RawEntryPoint = TrueEntryPoint;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								        DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								        DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
							 | 
						||
| 
								 | 
							
								        error = DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (error == NO_ERROR) {
							 | 
						||
| 
								 | 
							
								            printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								                   " Detoured EntryPoint().\n");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								                   " Error detouring EntryPoint(): %ld\n", error);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (dwReason == DLL_PROCESS_DETACH) {
							 | 
						||
| 
								 | 
							
								        DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								        DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								        if (RealIStreamWrite != NULL) {
							 | 
						||
| 
								 | 
							
								            DetourDetach(&(PVOID&)RealIStreamWrite, (PVOID)MineIStreamWrite);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
							 | 
						||
| 
								 | 
							
								        error = DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
							 | 
						||
| 
								 | 
							
								               " Removed IStream::Wrote() detours (%ld), wrote %ld bytes.\n",
							 | 
						||
| 
								 | 
							
								               error, dwWrote);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        fflush(stdout);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////// End of File.
							 |