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

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>
            欧美大片专区| 亚洲精品三级| 欧美激情五月| 久久久久**毛片大全| 亚洲欧美在线一区二区| 亚洲精品资源| 一区二区精品在线观看| 亚洲精品乱码久久久久久| 久久久精品动漫| 欧美一区1区三区3区公司| 久久久人成影片一区二区三区| 欧美一区激情视频在线观看| 久久精品成人一区二区三区 | 久久女同互慰一区二区三区| 欧美一区二区网站| 免费一级欧美在线大片| 欧美日韩成人免费| 国产精品久久久久一区| 黑丝一区二区三区| 在线亚洲自拍| 欧美极品aⅴ影院| 欧美天堂在线观看| 黄色成人片子| 性做久久久久久| 亚洲第一主播视频| 亚洲综合首页| 欧美国产一区二区三区激情无套| 国产精品老牛| 一本久道久久久| 欧美激情精品久久久| 亚洲欧美日韩一区在线观看| 欧美激情视频一区二区三区免费 | 亚洲欧美乱综合| 欧美三级午夜理伦三级中文幕| 在线国产精品播放| 久久综合久久综合久久| 亚洲欧美日韩一区二区在线| 国产精品久久77777| 一区二区三区免费网站| 亚洲国产一区二区三区在线播| 久久精品亚洲一区二区| 韩曰欧美视频免费观看| 久久久久久高潮国产精品视| 久久精品国产免费| 在线播放日韩欧美| 免费亚洲电影| 欧美三级中文字幕在线观看| 亚洲欧美一区二区原创| 亚洲欧美日本另类| 国产一区二区三区黄视频| 久久一区亚洲| 欧美日韩美女一区二区| 亚洲免费视频中文字幕| 亚洲在线一区| 久久精品一区| 日韩视频不卡| 性欧美暴力猛交另类hd| 亚洲精品欧洲| 欧美专区一区二区三区| 亚洲精品乱码久久久久久久久| 亚洲午夜电影| 亚洲精品乱码久久久久久久久| 亚洲一区二区精品在线| 最近中文字幕日韩精品| 欧美一级视频| 亚洲一区二区免费| 麻豆精品一区二区综合av | 欧美国产精品| 久久婷婷丁香| 国产精品久久久对白| 亚洲国产mv| 亚洲欧洲在线看| 老司机凹凸av亚洲导航| 久久婷婷国产综合国色天香| 国产日韩欧美在线视频观看| 亚洲视频一区二区| 中文在线一区| 国产精品www| 亚洲尤物视频在线| 欧美一区免费| 一区二区亚洲精品| 久久久精品五月天| 欧美成人午夜视频| 亚洲精品国产精品乱码不99按摩| 欧美综合国产| 欧美黄免费看| 亚洲一卡二卡三卡四卡五卡| 欧美午夜在线| 久久精品在线观看| 亚洲国产成人tv| 欧美gay视频激情| 日韩午夜免费视频| 欧美一区二区私人影院日本| 极品av少妇一区二区| 欧美激情一区在线观看| 亚洲欧美国产三级| 最近中文字幕日韩精品| 亚洲欧美日韩国产综合| 伊人精品久久久久7777| 欧美亚男人的天堂| 久久夜色精品国产| 亚洲在线成人精品| 亚洲伦理在线| 亚洲成在人线av| 美女精品国产| 久久精品国产一区二区三 | 久久综合婷婷| 亚洲砖区区免费| 亚洲欧洲美洲综合色网| 久久婷婷av| 久久青草欧美一区二区三区| 亚洲永久字幕| 亚洲欧美日韩精品久久久| 亚洲另类春色国产| 亚洲日韩第九十九页| 亚洲高清毛片| 在线精品观看| 亚洲国产裸拍裸体视频在线观看乱了 | 在线一区二区三区四区五区| 在线欧美福利| 亚洲三级免费观看| 亚洲精品视频一区二区三区| 亚洲伦理在线| 亚洲一区二区在线免费观看| 夜夜躁日日躁狠狠久久88av| 国产精品美女久久久久av超清| 久久亚洲精品中文字幕冲田杏梨| 久久综合一区二区| 欧美在线日韩| 亚洲欧美国产视频| 久久久国产一区二区| 久久天天躁狠狠躁夜夜爽蜜月 | 欧美性色视频在线| 国产日韩精品在线| 亚洲国产乱码最新视频| 亚洲一二三区精品| 久久伊人亚洲| 日韩视频在线一区| 欧美淫片网站| 欧美午夜片在线免费观看| 好看不卡的中文字幕| 99国内精品久久| 欧美综合激情网| 日韩亚洲一区二区| 欧美sm视频| 永久域名在线精品| 性做久久久久久| 亚洲美女在线观看| 欧美韩国一区| 亚洲欧洲一区二区在线观看| 久久另类ts人妖一区二区| 99精品福利视频| 欧美精品免费看| 一本色道久久综合亚洲91| 亚洲福利视频在线| 欧美专区在线| 国内精品伊人久久久久av一坑| 亚久久调教视频| 香港久久久电影| 国产亚洲综合精品| 久久夜色精品国产噜噜av| 欧美一级专区免费大片| 在线看成人片| 亚洲大片免费看| 欧美日韩另类丝袜其他| 亚洲影院色无极综合| 一区二区三区免费在线观看| 免费日韩视频| 欧美激情一区二区三区不卡| 一区二区免费在线视频| 亚洲欧美综合精品久久成人| 狠狠综合久久av一区二区小说| 欧美gay视频| 欧美体内谢she精2性欧美| 久久国产加勒比精品无码| 欧美成人精品不卡视频在线观看| 亚洲性线免费观看视频成熟| 欧美一区二区三区视频| 99在线精品视频| 久久久久久尹人网香蕉| a4yy欧美一区二区三区| 欧美一级欧美一级在线播放| 一本色道久久综合狠狠躁的推荐| 午夜精品一区二区三区电影天堂| 亚洲韩国日本中文字幕| 性色av一区二区三区红粉影视| 亚洲激情av| 久久久噜久噜久久综合| 久久成人免费日本黄色| 欧美日韩高清不卡| 亚洲国产欧美不卡在线观看 | 9久re热视频在线精品| 在线观看欧美日韩国产| 久久疯狂做爰流白浆xx| 久久狠狠久久综合桃花| 国产伦精品一区二区三区免费迷| 亚洲日韩中文字幕在线播放| 91久久亚洲| 欧美人成在线| 在线亚洲欧美专区二区|