воскресенье, 30 января 2011 г.

Shim Engine и режим совместимости

Shim Engine это технология для обеспечения совместимости, реализованная в различных DLL'ках, а также через некоторые колбеки и хаки в PE Loader'е, который находится в ntdll.dll.

Shim Engine в основном реализован в shimeng.dll и apphelp.dll — которые суть есть Application Compatibility Interface,

Shim также содержит различные записи в реестре для своего конфигурирования, а также system database files(*.sdb).

Основы описаны у Ионеску, а в данной заметке будет немного описана реализация и возможности шимов для режима совместимости.

Итак, для исполняемых файлов в их свойствах, в разделе совместимость, можно указать, с какими ОС должно быть совместимо данное приложение.

Конфигурация хранится в ветке HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers.
Для режима совместимости с вин95, например, ключ будет выглядеть так: "C:\\Test\\TEST.EXE"="WIN95".

Далее при запуске ехе в режиме совместимости будет запущен shim engine. Последовательность вызовов выглядит примерно следующим образом:

KiUserApcDispatcher => LdrInitializeThunk => LdrpInitialize => LdrpInitializeProcess => LdrpLoadShimEngine.

LdrpLoadShimEngine грузит shimeng.dll (LdrpLoadShimEngine), получает адреса ф-ций из нее (LdrpGetShimEngineInterface), загружает базы шимов (SdbInitDatabase), распаковывает их (SdbUnpackAppCompatData) и применяет.

Данные шима процесс может получить через Peb->pShimData.

В режиме совместимости грузяться дополнительные длл: Aclayers.dll и AcGenral.dll, в которых находятся реализации шимов оформленные в виде классов, список шимов для Aclayers.dll:

"ChangeAuthenticationLevel"
"CorrectBitmapHeader"
"CorrectCreateEventName"
"CorrectFilePaths"
"CorrectSoundDeviceId"
"DirectPlayEnumOrder"
"DuplicateHandleFix"
"EmulateBitmapStride"
"EmulateCDFS"
"EmulateClipboardDIBFormat"
"EmulateCreateFileMapping"
"EmulateCreateProcess"
"EmulateDeleteObject"
"EmulateDirectDrawSync"
"EmulateDrawText"
"EmulateEnvironmentBlock"
"EmulateFindHandles"
"EmulateGetCommandLine"
"EmulateGetDeviceCaps"
"EmulateGetDiskFreeSpace"
"EmulateGetProfileString"
"EmulateJoystick"
"EmulateHeap"
"EmulateMissingEXE"
"EmulatePlaySound"
"EmulatePrinter"
"EmulateSlowCPU"
"EmulateTextColor"
"EmulateToolHelp32"
"EmulateUSER"
"EmulateVerQueryValue"
"EmulateWriteFile"
"EnableRestarts"
"FeedbackReport"
"FileVersionInfoLie"
"Force640x480"
"Force8BitColor"
"ForceAnsiGetDisplayNameOf"
"ForceCDStop"
"ForceCoInitialize"
"ForceDXSetupSuccess"
"ForceKeepFocus"
"ForceMessageBoxFocus"
"ForceShellLinkResolveNoUI"
"HandleAPIExceptions"
"HandleRegExpandSzRegistryKeys"
"HandleWvsprintfExceptions"
"HideDisplayModes"
"IgnoreException"
"IgnoreLoadLibrary"
"IgnoreOleUninitialize"
"IgnoreScheduler"
"MapMemoryB0000"
"ProfilesEnvStrings"
"ProfilesGetFolderPath"
"ProfilesRegQueryValueEx"
"Shrinker"
"SingleProcAffinity"
"SyncSystemAndSystem32"
"VirtualRegistry"
"WinXPVersionLie"
"WinXPSP1VersionLie"
"WinXPSP2VersionLie"
"Win2000VersionLie"
"Win2000SP1VersionLie"
"Win2000SP2VersionLie"
"Win2000SP3VersionLie"
"Win95VersionLie"
"Win98VersionLie"
"WinExecRaceConditionFix"
"WinNT4SP5VersionLie"
"Win2kPropagateLayer"


Каждый шим реализован ввиде класса, с префиксом "NS_"(например class NS_IgnoreLoadLibrary) и предназначен для изменения стандартного поведения системы ( как раз для обеспечения той самой обратной совместимости ).

Данная технология позволяет очень многое, от простых вещей вроде добавления флагов в PEB, до виртуализации реестра и полного изменения поведения Heap Manager'a.

К примеру шим, виртуализирующий реестр перехватывает практически все ф-ции работы с реестром в "ADVAPI32.DLL":

"RegConnectRegistryA";
"RegConnectRegistryW";
"RegOpenKeyExA";
"RegOpenKeyExW";
"RegQueryValueExA";
"RegQueryValueExW";
"RegCloseKey";
"RegOpenKeyA";
"RegOpenKeyW";
"RegQueryValueA";
"RegQueryValueW";     
"RegCreateKeyA";     
"RegCreateKeyW";     
"RegCreateKeyExA";     
"RegCreateKeyExW";     
"RegEnumValueA";     
"RegEnumValueW";     
"RegEnumKeyA";     
"RegEnumKeyW";     
"RegEnumKeyExA";     
"RegEnumKeyExW";
"RegQueryInfoKeyA";     
"RegQueryInfoKeyW";     
"RegSetValueExA";     
"RegSetValueExW";     
"RegDeleteKeyA";     
"RegDeleteKeyW";


Подменяются они соответствующими ф-циями из класса данного шима( NS_VirtualRegistry::APIHook_RegOpenKeyExA и т.д. ).
Или например шим Shrinker фиксит проблемы приложений с Shrinker resource compression library, подменяя ф-ции "LdrAccessResource" в "NTDLL.DLL" и "ExitProcess" в "KERNEL32.DLL" на свои.

Таким образом, shim engine предоставляет легальный путь изменения поведения приложений на уровне Win API.

2 комментария:

  1. Скоро (Win 8) это нас ждёт в KM: http://twitter.com/#!/aionescu/status/63070801825497088

    ОтветитьУдалить
  2. Хм, интересно, спасибо за коментарий =]

    ОтветитьУдалить