Opravené verze projektů ObInit, ObjView a Vad

Nedávno jsem dokončil jednu malou utilitu, kterou bylo nutné otestovat na co nejvíce různých verzích Windows, včetně těch verzí, které se liší pouze číslem Service Packu. Z tohoto důvodu jsem byl nucen kompletně předělat své portfolio virtuálních strojů, které obsahovalo pouze instalace plně aktualizovaných systémů od každé verze (tedy byly například zastoupeny Windows Vista SP2, ale nikoliv SP1 či SP0). Nová sada virtuálních počítačů již obsahuje i verze se Service Packy, které v dnešní době již nejsou aktuální.

Při testování oné utility jsem zjistil, že Windows Vista SP0 představují problém. Ovladač (který byl součástí testovaného programu) způsoboval modré obrazovky smrti. Po prozkoumání pozadí jejich vzniku jsem zjistil, že problém tkví v mém frameworku pro práci s interními datovými strukturami správce objektů (Object Manager), který také používají ukázkové aplikace ObInit a ObjView. Můj framework, který předtím nebyl testován na Windows Vista SP0, nepočítal s tím, že by v takovém prostředí mohly být jinak definované datové struktury než na Windows Vista SP1. A opravdu tomu tak je.

Service Pack 1 pro Windows Vista mimo jiné přináší i rozhraní OB Filtering Model, které dovoluje ovladačům třetích stran monitorovat přístup (získávání handle) aplikací k procesům a vláknům. Do jisté míry se jedná o náhradu za technologii DKOH (Direct Kernel Object Hooking), kterou nelze provozovat na 64bitových platformách. Aby toto nové rozhraní mohlo fungovat, vývojáři změnili datové struktury OBJECT_TYPE a OBJECT_TYPE_INITIALIZER. Na Windows Vista SP0 jejich definice vypadají následovně:

typedef struct 
{
  USHORT  Length;    
  union 
  { 
    UCHAR ObjectTypeFlags;
    struct {
      UCHAR CaseInsensitive : 1;                  
      UCHAR UnnamedObjectsOnly : 1; 
      UCHAR UseDefaultObject : 1;
      UCHAR SecurityRequired : 1;               
      UCHAR MaintainHandleCount : 1;                  
      UCHAR MaintainTypeList : 1;               
      UCHAR SupportsObjectCallbacks : 1;                 
    } ObjectFlags;
  }; 
 
  ULONG32 ObjectTypeCode;
  ULONG32 InvalidAttributes;
  ULONG32 GenericMapping [4];                          
  ULONG32 ValidAccessMask;
  POOL_TYPE PoolType;
  ULONG32 DefaultPagedPoolCharge;
  ULONG32 DefaultNonPagedPoolCharge;
  DUMP_METHOD DumpProcedure;
  OPEN_METHOD OpenProcedure;
  CLOSE_METHOD CloseProcedure;
  DELETE_METHOD DeleteProcedure;                            
  PARSE_METHOD ParseProcedure;
  SECURITY_METHOD SecurityProcedure;
  QUERYNAME_METHOD QueryNameProcedure;
  OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
 
typedef struct {
  ERESOURCE Mutex;
  LIST_ENTRY TypeList;
  UNICODE_STRING Name;
  PVOID DefaultObject;
  UCHAR Index;                                                      
  ULONG32 TotalNumberOfObjects;                
  ULONG32 TotalNumberOfHandles;                                             
  ULONG32 HighWaterNumberOfObjects;                                         
  ULONG32 HighWaterNumberOfHandles;                                         
  OBJECT_TYPE_INITIALIZER TypeInfo;
  ULONG32  Key;
  PVOID ObjectLocks[32];
} OBJECT_TYPE_VISTA, *POBJECT_TYPE_VISTA;

Service Pack 1 je změnil do následující podoby:

typedef struct 
{
  USHORT  Length;    
  union 
  { 
    UCHAR ObjectTypeFlags;
    struct {
      UINT8 CaseInsensitive : 1;                  
      UCHAR UnnamedObjectsOnly : 1; 
      UCHAR UseDefaultObject : 1;
      UCHAR SecurityRequired : 1;               
      UCHAR MaintainHandleCount : 1;                  
      UCHAR MaintainTypeList : 1;               
      UCHAR SupportsObjectCallbacks : 1;                 
    } ObjectFlags;
  }; 
 
  ULONG32 ObjectTypeCode;
  ULONG32 InvalidAttributes;
  ULONG32 GenericMapping [4];                          
  ULONG32 ValidAccessMask;
  ULONG32 RetainAccess;
  POOL_TYPE PoolType;
  ULONG32 DefaultPagedPoolCharge;
  ULONG32 DefaultNonPagedPoolCharge;
  DUMP_METHOD DumpProcedure;
  OPEN_METHOD OpenProcedure;
  CLOSE_METHOD CloseProcedure;
  DELETE_METHOD DeleteProcedure;                            
  PARSE_METHOD ParseProcedure;
  SECURITY_METHOD SecurityProcedure;
  QUERYNAME_METHOD QueryNameProcedure;
  OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
 
typedef struct {
  LIST_ENTRY TypeList;
  UNICODE_STRING Name;
  PVOID DefaultObject;
  UCHAR Index;                                                      
  ULONG32 TotalNumberOfObjects;                
  ULONG32 TotalNumberOfHandles;                                             
  ULONG32 HighWaterNumberOfObjects;                                         
  ULONG32 HighWaterNumberOfHandles;                                         
  OBJECT_TYPE_INITIALIZER TypeInfo;
  ERESOURCE Mutex;
  PVOID TypeLock;
  ULONG32  Key;
  PVOID ObjectLocks[32];
  LIST_ENTRY CallbackList;   
} OBJECT_TYPE, *POBJECT_TYPE;

Bylo tedy nutné do souborů starajících se o rozlišování verze OS (version.c a version.h) přidat rutinu GetServicePackNumber a rozvětvit některé části frameworku tak, aby se vykonal odlišný (a správný) kód pro Windows Vista SP0 a Windows Vista SP1.

Po otestování nové verze jsem framework hned zabudoval do projektů ObInit a ObjView, které by nyní měly na Windows Vista SP0 běžet bez problémů (zatím jsem neupravoval tabulku podporovaných verzí kernelu).

Jelikož jsem v téže době začal připravovat rozsáhlejší článek o deskriptorech virtuálních adres, se kterými je úzce spojena utilita Vad, objevil jsem a opravil další chyby. V případě utlility Vad se jednalo pouze o překlepy v kódu aplikace, Přidal jsem možnost uložení virtuálních deskriptorů adres procesu do textového souboru, která velmi pomohla při psaní (zatím ještě nedokončeného) článku.

Nové verze všech tří projektů si můžete stáhnout na jejich stránkách (viz levé menu, sekce Projekty). Nyní za link Stáhnout přibylo do závorky datum uvolnění dané verze. Pro výukové účely nechávám na webu ke stažení i starší verze všech tří projektů.

Leave a Reply

Your email address will not be published. Required fields are marked *