понедельник, 18 апреля 2011 г.

shim handlers

а вот например гражданин TSS просветил меня вчера насчет всяких малопонятных хуков в отдельных процессах - оказывается это был shim engine
Соотв-но моя злобная паранойя потребовала предпринять какие-нть действия и например найти в недрах ntdll.dll следы деятельности shim модуля

Следы впрочем находятся не очень сложно - берем экспортируемую (начиная с xp) ф-цию LdrInitShimEngineDynamic, проходим по всему ее пути исполнения, выкидывая вызовы LdrLockLoaderLock & LdrUnlockLoaderLock (в checked builds также RtlAssert). Единственный оставшимся неидентифицированным вызов ф-ции будет LdrpGetShimEngineInterface

В самой же LdrpGetShimEngineInterface все достаточно просто - через пару ф-ций RtlInitString (экспортируемую) и LdrpGetProcedureAddress (неэкспортируемую) находятся различные callbacks из модуля shim и через RtlEncodeSystemPointer сохраняются в глобальных переменных в секции .data
HMODULE на сам модуль shim сохраняется в глобальной же переменной g_pShimEngineModule
Единственная сложность во всей этой процедуре - что число callbacks отличается на разных версиях windows

windows xp

  • g_pfnSE_InstallBeforeInit - в модуле shim имеет имя SE_InstallBeforeInit
  • g_pfnSE_InstallAfterInit - в модуле shim имеет имя SE_InstallAfterInit
  • g_pfnSE_DllLoaded - в модуле shim имеет имя SE_DllLoaded
  • g_pfnSE_DllUnloaded - в модуле shim имеет имя SE_DllUnloaded
  • g_pfnSE_GetProcAddress - в модуле shim имеет имя SE_GetProcAddress
  • g_pfnSE_ProcessDying - в модуле shim имеет имя SE_ProcessDying

vista & w2k3

  • g_pfnSE_InstallBeforeInit
  • g_pfnSE_InstallAfterInit
  • g_pfnSE_DllLoaded
  • g_pfnSE_DllUnloaded
  • g_pfnSE_ProcessDying

windows 7

  • g_pfnSE_InstallBeforeInit
  • g_pfnSE_InstallAfterInit
  • g_pfnSE_DllLoaded
  • g_pfnSE_DllUnloaded
  • g_pfnSE_LdrEntryRemoved - в модуле shim имеет имя SE_LdrEntryRemoved
  • g_pfnSE_GetProcAddressLoad
  • g_pfnSE_ProcessDying
Из этих таблиц очевиден интерфейс общения с shim модулем:
  • SE_InstallBeforeInit зовется при его загрузке в LdrpLoadShimEngine
  • SE_InstallAfterInit вызывается в конце LdrpInitializeProcess
  • SE_DllLoaded вызывается в LdrpLoadDll, причем только если _g_ShimsEnabled имеет ненулевое значение
  • SE_DllUnloaded вызывается в LdrUnloadDll, также если _g_ShimsEnabled != NULL
  • SE_ProcessDying вызывается в LdrShutdownProcess
  • SE_LdrEntryRemoved под windows 7 также вызывается в LdrpUnloadDll
  • SE_GetProcAddress вызывается в LdrGetProcedureAddressEx/LdrpGetProcedureAddress

    1 комментарий: