I am trying to port the following code in C ++:
BOOL SyskeyGetClassBytes(HKEY hKeyReg,LPSTR keyName,LPSTR valueName,LPBYTE classBytes) { HKEY hKey,hSubKey; DWORD dwDisposition=0,classSize; BYTE classStr[16]; LONG ret; BOOL isSuccess = FALSE; ret = RegCreateKeyEx(hKeyReg,keyName,0,NULL,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE,NULL,&hKey,&dwDisposition); if(ret!=ERROR_SUCCESS) return FALSE; else if(dwDisposition!=REG_OPENED_EXISTING_KEY) { RegCloseKey(hKey); return FALSE; } else { if(RegOpenKeyEx(hKey,valueName,0,KEY_READ,&hSubKey)==ERROR_SUCCESS) { classSize = 8+1; ret = RegQueryInfoKey(hSubKey,(LPTSTR)classStr,&classSize,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); if((ret==ERROR_SUCCESS)&&(classSize==8)) { classBytes[0]= (HexDigitToByte(classStr[0]) << 4) | HexDigitToByte(classStr[1]); classBytes[1]= (HexDigitToByte(classStr[2]) << 4) | HexDigitToByte(classStr[3]); classBytes[2]= (HexDigitToByte(classStr[4]) << 4) | HexDigitToByte(classStr[5]); classBytes[3]= (HexDigitToByte(classStr[6]) << 4) | HexDigitToByte(classStr[7]); isSuccess = TRUE; } RegCloseKey(hSubKey); } RegCloseKey(hKey); } return isSuccess;
}
I spent like 5 hours trying to figure out my problem, without success. I know that I correctly call this method. My c # code
unsafe static bool SyskeyGetClassBytes(RegistryHive hKeyReg, string keyName, string valueName, byte* classBytes) { UIntPtr hSubKey; UIntPtr hKey; RegResult tmp; ; uint classSize; StringBuilder classStr = new StringBuilder(); int ret; bool isSuccess = false; ret = RegCreateKeyEx(hKeyReg, keyName, 0, null, RegOption.NonVolatile, RegSAM.QueryValue, UIntPtr.Zero, out hKey, out tmp); if (ret != 0) { return false; } else if (tmp != RegResult.OpenedExistingKey) { return false; } else { int res = RegOpenKeyEx(hKey, valueName, 0, (int)RegSAM.Read, out hSubKey); if (res == 0) { classSize = 8 + 1; ret = RegQueryInfoKey(hSubKey, out classStr, ref classSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if ((classSize == 8)) { classBytes[0] = (byte)((byte)(HexDigitToByte(classStr[0]) << (byte)4) | HexDigitToByte(classStr[1])); classBytes[1] = (byte)((byte)(HexDigitToByte(classStr[2]) << (byte)4) | HexDigitToByte(classStr[3])); classBytes[2] = (byte)((byte)(HexDigitToByte(classStr[4]) << (byte)4) | HexDigitToByte(classStr[5])); classBytes[3] = (byte)((byte)(HexDigitToByte(classStr[6]) << (byte)4) | HexDigitToByte(classStr[7])); isSuccess = true; } RegCloseKey(hSubKey); } else { return false; } RegCloseKey(hKey); } return isSuccess; }
Itβs a little difficult for me to debug, but in the end I decided that the problem was arising on this line. Execution seems to stop afterwards.
ret = RegQueryInfoKey(hSubKey, out classStr, ref classSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
I know that this is not a permissions problem, since this C # program works with admin perms and as a local system account. The method I need to prevent .Net APIs from offering is RegQueryInfoKey. Signatures used and P / Invoke types:
[StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public unsafe byte* lpSecurityDescriptor; public int bInheritHandle; } [Flags] public enum RegOption { NonVolatile = 0x0, Volatile = 0x1, CreateLink = 0x2, BackupRestore = 0x4, OpenLink = 0x8 } [Flags] public enum RegSAM { QueryValue = 0x0001, SetValue = 0x0002, CreateSubKey = 0x0004, EnumerateSubKeys = 0x0008, Notify = 0x0010, CreateLink = 0x0020, WOW64_32Key = 0x0200, WOW64_64Key = 0x0100, WOW64_Res = 0x0300, Read = 0x00020019, Write = 0x00020006, Execute = 0x00020019, AllAccess = 0x000f003f } public enum RegResult { CreatedNewKey = 0x00000001, OpenedExistingKey = 0x00000002 } [DllImport("advapi32.dll", CharSet = CharSet.Auto)] public static extern int RegOpenKeyEx( UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); [DllImport("advapi32.dll", SetLastError = true)] public static extern int RegCloseKey( UIntPtr hKey); [DllImport("advapi32.dll", SetLastError = true)] static extern int RegCreateKeyEx( RegistryHive hKey, string lpSubKey, int Reserved, string lpClass, RegOption dwOptions, RegSAM samDesired, UIntPtr lpSecurityAttributes, out UIntPtr phkResult, out RegResult lpdwDisposition); [DllImport("advapi32.dll", EntryPoint = "RegQueryInfoKey", CallingConvention = CallingConvention.Winapi, SetLastError = true)] extern private static int RegQueryInfoKey( UIntPtr hkey, out StringBuilder lpClass, ref uint lpcbClass, IntPtr lpReserved, IntPtr lpcSubKeys, IntPtr lpcbMaxSubKeyLen, IntPtr lpcbMaxClassLen, IntPtr lpcValues, IntPtr lpcbMaxValueNameLen, IntPtr lpcbMaxValueLen, IntPtr lpcbSecurityDescriptor, IntPtr lpftLastWriteTime);