NTDLL 関数のみでレジストリにアクセスしてみる実験

sample

NtOpenKey、NtClose、NtEnumerateKey、NtQueryValueKey の4つの関数を使って、レジストリにアクセスして、マウスデバイスを取得してみるプログラムを作ってみました。

typedef struct UNICODE_STRING{
short size1;
short size2;
wchar_t *str;
}*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
  ULONG           Length;
  HANDLE          RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG           Attributes;
  PVOID           SecurityDescriptor;
  PVOID           SecurityQualityOfService;
}  OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

__declspec(dllimport) int WINAPI NtOpenKey (HKEY*,int,OBJECT_ATTRIBUTES*);
__declspec(dllimport) int WINAPI NtClose (HKEY);
__declspec(dllimport) int WINAPI RtlInitUnicodeString(UNICODE_STRING*,wchar_t*);
__declspec(dllimport) int WINAPI NtEnumerateKey(HANDLE KeyHandle,ULONG Index,KEY_INFORMATION_CLASS KeyInformationClass,PVOID KeyInformation,ULONG Length,PULONG ResultLength);
__declspec(dllimport) int WINAPI NtQueryValueKey(HANDLE KeyHandle,PUNICODE_STRING ValueName,KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,PVOID KeyValueInformation,ULONG Length,PULONG ResultLength);

typedef enum _KEY_VALUE_INFORMATION_CLASS {
  KeyValueBasicInformation           = 0,
  KeyValueFullInformation            = 1,
  KeyValuePartialInformation         = 2,
  KeyValueFullInformationAlign64     = 3,
  KeyValuePartialInformationAlign64  = 4,
  MaxKeyValueInfoClass               = 5
} KEY_VALUE_INFORMATION_CLASS;

typedef enum _KEY_INFORMATION_CLASS {
  KeyBasicInformation           = 0,
  KeyNodeInformation            = 1,
  KeyFullInformation            = 2,
  KeyNameInformation            = 3,
  KeyCachedInformation          = 4,
  KeyFlagsInformation           = 5,
  KeyVirtualizationInformation  = 6,
  KeyHandleTagsInformation      = 7,
  MaxKeyInfoClass               = 8
} KEY_INFORMATION_CLASS;

typedef struct _KEY_BASIC_INFORMATION {
  LARGE_INTEGER LastWriteTime;
  ULONG         TitleIndex;
  ULONG         NameLength;
  WCHAR         Name[260];
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
  ULONG TitleIndex;
  ULONG Type;
  ULONG DataLength;
  UCHAR Data[260];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;

void main(){
    HKEY hKey;
    int cnt,i,j,k;
    OBJECT_ATTRIBUTES oj;
    wchar_t nm[360]=L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{378de44c-56ef-11d1-bc8c-00a0c91405dd}";
    wchar_t sl[260];
    wchar_t l1[]=L"linked",l2[]=L"SymbolicLink";
    UNICODE_STRING linked;
    KEY_BASIC_INFORMATION ifx;
    KEY_VALUE_PARTIAL_INFORMATION ifx2;
    UNICODE_STRING rtl;
    DWORD sz;
    cnt=0;
    oj.Length=0x18;
    oj.RootDirectory=0;
    oj.ObjectName=&rtl;
    oj.Attributes=0x40;
    oj.SecurityDescriptor=0;
    oj.SecurityQualityOfService=0;
    do{
        nm[103]=0;
        RtlInitUnicodeString(&rtl,nm);
        i=NtOpenKey(&hKey,KEY_ENUMERATE_SUB_KEYS,&oj);
        if(i==ERROR_SUCCESS){
            sz=260;
            nm[103]=L'\\';
            i=NtEnumerateKey(hKey,cnt,KeyBasicInformation,&ifx,sizeof(ifx),&sz);
            ifx.Name[ifx.NameLength/2]=0;
            lstrcpyW(nm+104,ifx.Name);
            NtClose(hKey);        
            if(i==ERROR_SUCCESS){
                printf("DEVICE %d:%ws\n",cnt,ifx.Name);
                j=lstrlenW(nm);
                lstrcatW(nm,L"\\#\\Control");
                RtlInitUnicodeString(&rtl,nm);
                i=NtOpenKey(&hKey,KEY_READ,&oj);
                if(i==ERROR_SUCCESS){
                    RtlInitUnicodeString(&linked,l1);
                    k=NtQueryValueKey(hKey,&linked,KeyValuePartialInformation,&ifx2,sizeof(ifx2),&sz);
                     NtClose(hKey);        
                    if(k==ERROR_SUCCESS){
                        printf("LINKED:%d\n",*(DWORD*)ifx2.Data);
                        {
                            nm[j+2]=0;
                            RtlInitUnicodeString(&rtl,nm);
                            i=NtOpenKey(&hKey,KEY_READ,&oj);
                            if(i==ERROR_SUCCESS){
                                RtlInitUnicodeString(&linked,l2);
                                k=NtQueryValueKey(hKey,&linked,KeyValuePartialInformation,&ifx2,sizeof(ifx2),&sz);
                                if(k==ERROR_SUCCESS){    
                                    if(ifx2.DataLength)
                                    {
                                        ifx2.Data[ifx2.DataLength*2]=0;
                                            printf("%ws\n",ifx2.Data);
                                    }
                                }
                                NtClose(hKey);        
                            }
                        }
                    }
                }
                cnt++;
            }
            else break;
        }
    }while(1);
}

資料がなかったので結構苦労しましたが、接続中のマウスデバイスを列挙します。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{378de44c-56ef-11d1-bc8c-00a0c91405dd}
がマウスクラスなのでそれを列挙し、 linked が 0の場合はドライバー未ロード(未接続)でLink=0となっています。

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です