Saturday 9 March 2013

Detours

(Original post at: http://www.mpgh.net)
Here's a short tutorial on using Detours 2.1 with Visual Studio 2008 via the IDE.

1. Download and install "DetoursExpress.msi" from their page. The default folder is: "C:\Program Files\Microsoft Research\Detours Express 2.1".

2. Open Visual Studio and go to "Tools->Options". In the new dialog go to "Projects and Solutions->VC++ Directories". Change the "Show directories for:" combobox in the top right corner to "Include files". Add the path to the 'src' folder of the default detours install directory. In the default case, this will be "C:\Program Files\Microsoft Research\Detours Express 2.1\src". Hit Ok to close the dialog.

3. Create a new project for testing. I just made a simple empty Win32 project named DetoursTest. Add a new source file as well.
Code:
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 return 0;
}
4. Go to "Project->Add Existing Item". Paste in the path to the 'src' folder of the Detours directory. Once again, by default this is"C:\Program Files\Microsoft Research\Detours Express 2.1\src". Highlight all the CPP and H files except for "detoured.cpp" and hit Add. You can just delete "detoured.cpp" if you wish or move it into another directory.

5. Now if you try to compile, you will see a few errors:
1>c:\program files\microsoft research\detours express 2.1\src\detours.cpp(22) : fatal error C1189: #error : Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
1>c:\program files\microsoft research\detours express 2.1\src\disasm.cpp(19) : fatal error C1189: #error : Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
Go back to "Project->Properties". Choose "Configuration Properties->C/C++->Preprocessor" and add "DETOURS_X86" to the end of the list, making sure to separate the entry with a ';'. The final result should look like: "WIN32;_DEBUG;_WINDOWS;DETOURS_X86". Click Apply and then change the current Configuration via the top left combobox to Release and repeat the step. The final result should look like: "WIN32;NDEBUG;_WINDOWS;DETOURS_X86".

6. Now you should be able to compile and link successfully. Time for the actual detour code. The "Character Set" of the project is set to "Use Unicode Character Set" by default, so keep that in mind if you use API functions without specifying the A/W version manually. You will be hooking only the W versions or if you change the Character Set to "Use Multi-Byte Character Set" you will be hooking the A versions. You can change the setting via the "General" section in the project properties, 3rd to last setting.
Code:
#include <windows.h>
#include <stdio.h>
#include <detours.h>

// We must track this modules instance handle for detours
HINSTANCE gInstance;

// Wrapping detour functions in a namespace to keep things neat
namespace nsDetours
{
 // We must always make sure to use the correct calling convention for the
 // API functions we are wishing to hook.
 extern "C" int (WINAPI * Real_MessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) = MessageBoxA;
 int WINAPI Fake_MessageBoxA(HWND hWnd, LPSTR lpText, LPSTR lpCaption, UINT uType)
 {
  // For this detour, we want to modify the title of any MessageBoxA
  // call that has a MB_OK uType specified (0).
  if(uType == 0)
  {
   return Real_MessageBoxA(hWnd, lpText, "Detoured MessageBoxA!", uType);
  }
  // Otherwise, returned the original call with no modifications
  return Real_MessageBoxA(hWnd, lpText, lpCaption, uType);
 }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 gInstance = hInstance;

 // Detour our API functions, no error checking
 DetourRestoreAfterWith();
 DetourTransactionBegin();
 DetourUpdateThread(GetCurrentThread());
 // DetourAttach all functions to hook
 DetourAttach(&(PVOID&)nsDetours::Real_MessageBoxA, nsDetours::Fake_MessageBoxA);
 DetourTransactionCommit();

 MessageBoxW(0, L"Hello World", L"MessageBoxW from WinMain", 0);
 MessageBoxA(0, "Hello World", "MessageBoxA from WinMain", 0);
 MessageBoxA(0, "Hello World", "MessageBoxA from WinMain", MB_ICONINFORMATION);

 // Undetour our API functions, no error checking shown
 DetourTransactionBegin();
 DetourUpdateThread(GetCurrentThread());
 // DetourDetach all DetourAttach'ed functions
 DetourDetach(&(PVOID&)nsDetours::Real_MessageBoxA, nsDetours::Fake_MessageBoxA);
 DetourTransactionCommit();

 return 0;
}

// We must always have this function linked for detours. In a DLL, we
// return the HINSTANCE from DLLMain. In EXEs we use the HINSTANCE
// of WinMain.
HMODULE WINAPI Detoured()
{
 return gInstance;
}
Now you have the ability to detour functions as you need. I prefer using the source files in my project each time than building the lib as it makes it easier for people to look through the code in redistributed projects. Others might prefer the LIB, your call.

I showed an example using an EXE to control the detours, most people will instead use an injected DLL. The steps are pretty much the same, except the code for the DLL has to be mindful of the Best Practices for Creating DLLs!

Lastly for reference, I used this blog post way back when I started using detours 2.1 to help get a jump start after having troubles with it when migrating from 1.5.
//-------------------------------------------------------------------------------------------
http://www.experts-exchange.com/Programming/System/Windows__Programming/A_848-Create-a-Standard-DLL-with-VC.html
http://stackoverflow.com/questions/13532007/simple-packet-logger-with-detours-3-0-express
http://mzf2008.blog.163.com/blog/static/35599786201092743214268/

//------------------------------------------------------------------------------------------------------
1 . File /New Project / Visual C++/win 32 console Application /...Next/ select DLL../Finish

Add detours library











































Add new file   (hook.cpp)  /build to create DLL file
  1.   #include <windows.h>
    #include <stdio.h> 
    #include <stdlib.h>
    #include "detours.h"

    //#define BUILDING_DLL
    //-----------------------------------------------------------

     _declspec (dllexport)  void exportfunc() ;

    int (WINAPI * SysMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)  = MessageBox;
    int WINAPI HookMessageBox (HWND hWnd, LPCTSTR lpText,  LPCTSTR lpCaption, UINT uType) 
    return SysMessageBox (hWnd,  L"Hello vietnam " ,lpCaption, uType); 
    }
    //-------------------------------------------------------------
    BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason ,LPVOID reserved)
    {
    LONG Error;
        switch (reason)
        {
        case DLL_PROCESS_ATTACH:
           DetourTransactionBegin();
      DetourUpdateThread(GetCurrentThread());
       DetourAttach(&(PVOID&)SysMessageBox, HookMessageBox);
       DetourTransactionCommit();
            break;
        case DLL_PROCESS_DETACH:
            DetourTransactionBegin();
       DetourUpdateThread(GetCurrentThread());
      DetourDetach(&(PVOID&)SysMessageBox, HookMessageBox);
       DetourTransactionCommit();
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
        }  
        return TRUE;
    }





File New project .  and  copy dll file into new project

#include <windows.h> 
#include <stdio.h> 
#include <iostream>

int main( void ) 
{ 
    HINSTANCE h = LoadLibrary(TEXT("HOOK.dll"));
 if(h == NULL)
 {
  printf("error ");
  return 0;
 }
 MessageBox(NULL,L"Test",L"Test", MB_OK);

 while(1);
 
    return 0;

}


download : Click Here
http://www.cmlab.csie.ntu.edu.tw/~cathyp/eBooks/WindowsNT/Undocumented%20Windows%20NT.pdf

http://www.codeproject.com/Articles/2018/Detecting-Windows-NT-2K-process-execution
http://www.codeproject.com/Articles/2082/API-hooking-revealed
Codeproject.com

No comments:

Post a Comment