青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

Hooking a DirectX/COM Interface

Posted on 2010-01-13 00:33 S.l.e!ep.¢% 閱讀(769) 評論(0)  編輯 收藏 引用 所屬分類: RootKit
Hooking a DirectX/COM Interface

原文:http://www.codeproject.com/KB/system/Hooking_DirectX_COM.aspx

Introduction

After all the helpful articles I read here, I am glad that I can contribute a subject which has not yet been covered.

This article features a description on how to hook a DirectX/COM interface. I used the DirectInput interface as an example of how to hook an interfacefunction.

For the basic Windows hook, I refer to an article by Wade Brainerd, which describes the API hooking process.

Task

To intercept a method of a COM interfacerequires an extended approach compared to hooking an API call. If the desired DLL is examined, only the create interfacefunction is actually exported by the DLL. So, how can you hook your desired function?

Screenshot - dinputdll.jpg
DInput.dll

A COM interfaceis basically a list of virtual function pointers, which are linked together. You merely have to follow the links and modify every node till you finally reach the pointer of the function, which you would like to replace.

Step 1

As you can see, only the create interfaceCOM functions are visible, so you have to start your hooking chain at the DirectInputCreate function which returns a COM interface.

Here, you have to inject your DLL into the import address table (IAT) of the calling program.

Step 2

If the calling program invokes a DirectInputCreate, your function is called, you receive a pointer to a pointer of a pointer to a virtual function table, which is the interfaceof direct input:

Collapse Copy Code
DECLARE_INTERFACE_(IDirectInputW, IUnknown)
{
    /*** IUnknown methods ***/
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    /*** IDirectInputW methods ***/
    STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE;
    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE;
    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;
};

Step 3

Now you can create your device with CreateDevice. You will again receive an address to a different virtual function pointer table, which represents the Device.

Screenshot - dinputh.jpg

Pick the method you would like to replace and change the virtual function pointer table in the desired place to inject your function.

Step 4

Do the actual data manipulation.

Implementation

Step 1

To hook yourself into an API function, you can simply use the Windows API call SetWindowsHookEx. Here you create a system hook to monitor starting processes and match it to your desired program. After you identified your program, you have to compare the import module names with the DLL you wish to replace. Since this hook is written for direct input, the entry we are looking for is DINPUT8.DLL. To find this entry you have to loop through the descriptors till you find your DLL.

Collapse Copy Code
// Iterate through each import descriptor, and redirect if appropriatewhile ( pImportDesc->FirstThunk )
  {
    PSTR pszImportModuleName = MakePtr( PSTR, hModEXE, pImportDesc->Name);

    if ( lstrcmpi( pszImportModuleName, Hook->Name ) == 0 )
    {
      sprintf(dbBuffer,"Dll Found in module  %s replace it\n", Hook->Name );
      WriteToLog(dbBuffer);
      RedirectIAT( Hook, pImportDesc, (PVOID)hModEXE );
    }

    pImportDesc++;  // Advance to next import descriptor
  }

After you found your entry, you have to remove the write protection from the IAT with...

Collapse Copy Code
VirtualQuery( pIAT, &mbi, sizeof(mbi) );

... to be able to write into the memory. After the memory is open, you have to find your entry by iterating through the IAT.

Collapse Copy Code
while ( pIteratingIAT->u1.Function )
  {
    void* HookFn = 0;  // Set to either the SFunctionHook or pStubs.if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) )  // import by name
    {
      PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME,
          pBaseLoadAddr, pINT->u1.AddressOfData );

      // Iterate through the hook functions, searching for this import.
      SFunctionHook* FHook = DLLHook->Functions;
      while ( FHook->Name )
      {
        if ( lstrcmpi( FHook->Name, (char*)pImportName->Name ) == 0 )
        {
          sprintf(dbBuffer,"Hooked function: %s\n",(char*)pImportName->Name );
          WriteToLog(dbBuffer);
          // Save the old function in the SFunctionHook structure and get the new one.
          FHook->OrigFn = (unsignedlong*)pIteratingIAT->u1.Function;
          HookFn = FHook->HookFn;
          break;
         }

          FHook++;
        }
      }

Now, you can replace it with your own one.

Collapse Copy Code
// Replace the IAT function pointer if we have a hook.if ( HookFn )
  {
    // Cheez-o hack to see if what we're importing is code or data.// If it's code, we shouldn't be able to write to itif ( IsBadWritePtr( (PVOID)pIteratingIAT->u1.Function, 1 ) )
    {
      pIteratingIAT->u1.Function = (DWORD)HookFn;
    }
    elseif ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
    {
      // Special hack for Win9X, which builds stubs for imported// functions in system DLLs (Loaded above 2GB).  These stubs are// writeable, so we have to explicitly check for this caseif ( pIteratingIAT->u1.Function > (DWORD)0x80000000 )
          pIteratingIAT->u1.Function = (DWORD)HookFn;
    }
  }

The only thing remaining is to restore the memory attributes, as nothing ever happened.

Collapse Copy Code
VirtualProtect( pIAT, sizeof(PVOID) * cFuncs, flOldProtect, &flDontCare);

Step 2

Inside of the CreateInterface method, we start hooking into the COM interfaceby injecting our own CreateDevice function pointer into the Virtual function table (Vtbl), which is returned in the ppvOut pointer of the original call.

Collapse Copy Code
  DirectInput8Create_Type OldFn =
     (DirectInput8Create_Type)D3DHook.Functions[D3DFN_DirectInput8Create].OrigFn;
    HRESULT hr = OldFn( hinst, dwVersion, riidltf, ppvOut, punkOuter );

Resolve the pointer until you get the pointer to the Vtbl of the interface.

With this address, you have to again remove the memory protection before you can inject your function into the table and save the old function pointer for later use.

Inject your function pointer into the offset of the CreateDevice function pointer inside of the interfaceVtbl and restore the memory protection.

As you can see, the CreateDevice is the fourth method of the DirectInput interface, which means the offset inside of the Vtbl is 0x0C (pointer(DWORD)*index 3).

Collapse Copy Code
typedefstruct IDirectInput *LPDIRECTINPUT;

#if !defined(__cplusplus) || defined(CINTERFACE)
#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDirectInput_Release(p) (p)->lpVtbl->Release(p)
#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
#else#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
#define IDirectInput_AddRef(p) (p)->AddRef()
#define IDirectInput_Release(p) (p)->Release()
#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b)
#endif

After we know where to inject it, we can start thinking about the implementation. When you look at the declaration of CreateDevice in the dinput.h, it does not match up with the declaration you see in the DirectX Help.

Collapse Copy Code
HRESULT CreateDevice(

    REFGUID rguid,
    LPDIRECTINPUTDEVICE *lplpDirectInputDevice,
    LPUNKNOWN pUnkOuter
);

As you can see in the definition inside the dinput.h, you have to add a fourth parameter, which is the interfacepointer. This ends up in the following function declaration:

Collapse Copy Code
HRESULT __stdcall   PASCAL MyCreateDevice(LPVOID *ppvOut,REFGUID rguid,
    LPDIRECTINPUTDEVICE *lplpDirectInputDevice,
    LPUNKNOWN pUnkOuter

This is important. You have to make sure, to use the __stdcallcalling convention in your declaration. Refer to the MSDN.

The __stdcallcalling convention is used to call Win32 API functions. The callee cleans the stack. __cdeclis the default calling convention for C and C++ programs. The stack has to be cleaned up by the caller, which is not the case with our function.

When you look at the disassembly of this call, you can see the stack pointer verification function _RTC_CheckEsp is called after the call to the interfacefunction.

Collapse Copy Code
if (lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey, NULL)!=DI_OK)
00401365  mov         esi,esp
00401367  push        000401369  push        offset lpdikey (4552C8h)
0040136E  push        offset _GUID_SysKeyboard (44643Ch)
00401373  mov         eax,dword ptr [lpdi (4552C4h)]
00401378  mov         ecx,dword ptr [eax]
0040137A  mov         edx,dword ptr [lpdi (4552C4h)]
00401380  push        edx
00401381  mov         eax,dword ptr [ecx+0Ch]
00401384  call        eax
00401386  cmp         esi,esp
00401388  call        _RTC_CheckEsp (4026A0h)
0040138D  test        eax,eax
0040138F  je          Game_Init+78h (401398h)
   return(0);
00401391  xor         eax,eax
00401393  jmp         Game_Init+107h (401427h)

// set cooperation levelif (lpdikey->SetCooperativeLevel(main_window_handle,

If you forget to declare your function with __stdcallyour function will process fine, but you will fail the esp pointer test of this function which sets the eax and test it after the function call.

Step 3

When you now create the device, the call is re-routed to your CreateDevice function.

After you call the original function, you receive a new pointer in lplpDirectInputDevice, which will direct you to the Vtbl of the device.

Collapse Copy Code
HRESULT hr = OldCreateDev(ppvOut,rguid,lplpDirectInputDevice,pUnkOuter);

In my sample, I replaced the GetDeviceState, since I can add additional input in the return data of the calling function. To get to the offset, you have to look at the definition inside the DInput.dll. You see that the GetDeviceState function is the tenth method inside of the device, which leads to an offset of 0x24.

After you know the offset, we can proceed with the instructions in step 2 to remove the protection, store the old pointer, inject your own function, and restore the memory protection.

Step 4

When the GetDeviceState function is called by the target program, the injected function is called and you can manipulate the data as you wish.

History

  • 8th May, 2006: Article posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Martin Mueller


Member
My first PC program was written on MS DOS in Assembler, after I got
Peter Norton's Assembler book where the Edlin and DOS Debugger supported
me in exploring my and code of others. I went from there over
IDE/Debugger like Borland Turbo Debugger over several microcontroller
H8, ST16, 8051, SLE66, SLE88 to my favorite MS Visual Studio 6. Now I
mainly program in C++ and Java, where I prefer C++ since your abilities
to interfere with the system are an easier task, which is still my
favorite, than implementing some natives in Java to enhance the
functionality. I am working since 18 years as a programmer and still
love every day of it. My experience include ever level of programming
from Hardware programming, where you have to take care of nano seconds
in your assembler program over real time operating system programming,
to VM programming, system services, applications, game programming, web
server to high level web script programming.
Occupation: Web Developer
Location: Germany Germany

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线日韩精品视频| 欧美中文字幕精品| 欧美一区二区视频在线观看| 在线视频欧美日韩| 亚洲一区二区三区精品在线| 一区二区欧美在线| 亚洲欧美色一区| 久久免费精品视频| 亚洲第一福利社区| 亚洲日本视频| 亚洲永久免费| 老鸭窝亚洲一区二区三区| 欧美福利专区| 国产精品视频xxxx| 91久久黄色| 亚洲欧美一区二区三区在线 | 伊人精品视频| 亚洲欧洲精品一区二区三区不卡 | 亚洲国产成人av好男人在线观看| 欧美激情精品| 亚洲图片欧美午夜| 久久一区二区三区四区| 欧美女主播在线| 国产欧美一区二区视频| 亚洲人成77777在线观看网| 亚洲自拍三区| 亚洲福利视频一区二区| 亚洲综合首页| 欧美人与性动交a欧美精品| 国产免费观看久久| 一区二区高清视频| 免费欧美在线| 亚洲嫩草精品久久| 欧美日韩国产成人高清视频| 好吊一区二区三区| 日韩午夜在线电影| 一本不卡影院| 久久久久**毛片大全| 欧美日韩精品一区二区在线播放| 国产自产女人91一区在线观看| 亚洲美女精品久久| 久久亚洲影院| 亚洲直播在线一区| 欧美日韩一区二区三区免费| 亚洲高清在线精品| 久久久综合精品| 亚洲中午字幕| 欧美午夜精品伦理| 亚洲作爱视频| 亚洲国产精品悠悠久久琪琪| 久久精品亚洲精品国产欧美kt∨| 国产精品亚洲成人| 亚洲一区二区三区视频播放| 亚洲激情在线| 欧美成人精品在线播放| 极品少妇一区二区| 久久久伊人欧美| 欧美亚洲专区| 国产亚洲一级高清| 久久久www成人免费精品| 亚洲一区二区在线观看视频| 欧美日韩国产区| 日韩系列欧美系列| 亚洲精品中文字幕在线观看| 欧美精品日韩一本| 99在线热播精品免费99热| 亚洲国产一区二区视频| 欧美国产日韩a欧美在线观看| 在线成人av网站| 欧美电影免费观看网站| 欧美电影在线播放| 一本色道久久综合亚洲91| 亚洲伦伦在线| 国产精品午夜在线| 久久久久天天天天| 美女视频黄a大片欧美| 91久久精品久久国产性色也91| 欧美激情一区二区三区| 欧美精品午夜| 欧美亚洲三级| 久久免费视频网站| 9l国产精品久久久久麻豆| 中文国产成人精品| 黄色一区二区三区| 亚洲精品之草原avav久久| 欧美午夜女人视频在线| 久久久国际精品| 欧美sm视频| 欧美一区二区免费观在线| 欧美在线视频免费| 99re成人精品视频| 欧美一区二区视频在线| 最近中文字幕日韩精品| 亚洲一区二区在线视频| 亚洲成色777777在线观看影院| 欧美精品色综合| 久久蜜桃av一区精品变态类天堂| 午夜精品久久久久久久久| 亚洲国产成人精品女人久久久| 亚洲精品免费看| 国模套图日韩精品一区二区| 亚洲精品国久久99热| 国产亚洲综合性久久久影院| 欧美激情久久久久久| 国产精品系列在线播放| 亚洲国产欧美一区二区三区丁香婷| 国产精品美女午夜av| 亚洲国产日韩欧美在线99| 国产一区二区精品久久91| 99精品欧美一区二区三区| 亚洲国产欧美日韩| 久久se精品一区精品二区| 亚洲一区日本| 欧美精品一区二区三区高清aⅴ| 欧美在线亚洲在线| 欧美片第一页| 亚洲福利精品| 在线看一区二区| 欧美在线视频一区二区| 亚洲一区二区三区四区中文| 欧美激情一区二区在线| 美国三级日本三级久久99| 国产精品久久久一本精品| 亚洲欧洲一区| 日韩视频在线观看国产| 久久综合中文字幕| 老司机免费视频一区二区| 国产欧美日韩视频一区二区三区| 99精品国产在热久久下载| 亚洲日本欧美| 牛牛影视久久网| 欧美激情一区二区三区高清视频| 在线观看欧美精品| 麻豆视频一区二区| 亚洲电影免费观看高清完整版| 亚洲大片在线观看| 久久婷婷国产麻豆91天堂| 久久久久一区二区| 在线观看成人av电影| 久久躁狠狠躁夜夜爽| 亚洲第一精品在线| 在线视频一区观看| 国产精品美女www爽爽爽| 午夜一区二区三区在线观看| 久久黄色网页| 在线观看亚洲一区| 欧美国产日韩二区| 99re成人精品视频| 午夜亚洲性色福利视频| 国产美女精品免费电影| 午夜视频在线观看一区| 久久av资源网站| 尹人成人综合网| 欧美国产三区| 亚洲尤物影院| 免费h精品视频在线播放| 亚洲黄色免费电影| 欧美午夜在线一二页| 亚洲欧美日韩国产| 欧美jizzhd精品欧美喷水| 日韩午夜高潮| 国产精品一页| 欧美成人一区二区三区在线观看| 亚洲美女福利视频网站| 久久视频一区二区| 久久久国产精彩视频美女艺术照福利| 欧美在线视频日韩| 老司机午夜精品视频| 影视先锋久久| 欧美国产日韩亚洲一区| 亚洲无线视频| 欧美亚洲免费电影| 狠狠色丁香久久综合频道| 美女91精品| 宅男精品视频| 免费在线观看成人av| 中文在线资源观看视频网站免费不卡| 欧美午夜宅男影院| 老司机精品导航| 亚洲一区二区在线视频| 亚洲第一网站| 西西人体一区二区| 91久久线看在观草草青青| 国产精品一区二区三区久久| 久热精品视频在线观看| 亚洲一区欧美一区| 欧美韩国日本综合| 欧美一区二区三区免费视| 亚洲国产精品一区在线观看不卡| 欧美精品一区二区三区视频| 欧美一区二区三区四区视频| 亚洲精品乱码久久久久| 美女999久久久精品视频| 亚洲欧美日韩一区二区在线 | 99视频一区二区三区| 久久一区欧美| 久久精品亚洲热| 午夜精品一区二区三区电影天堂| 亚洲欧洲一区二区在线播放| 国产日韩欧美在线视频观看|