Need to work with 32 and 64 bit files using 32 bit VB6

I wrote a program in VB6 that enumerates auto-run values in the registry such as HKLM/Run, Services, Drivers, etc. It takes the returned values and checks if file exists and then gathers file info such as size, version, etc. It works fine with 32 bit operating systems, but when it runs on a 64 bit operating system, it gets a little weird. I read up on the problem and realize that when you use a 32 bit app, it will only see 32 bit processes and when you look in a system32 folder, it will redirect to syswow64 folder instead. I did figure out  that if you use WMI in VBScript, it can see both 32 and 64 bit processes and paths, but if you put the same code in VB6, it redirects to the 32 bit path. I know it is possible for a 32 bit app to handle 64 bit files, because the program Autoruns will run as 32 bit, but can show correct paths for 32 and 64 bit files. So my question is, how does Autoruns do this? You can download Autoruns for yourself and run in on a 64 bit operating system and Task Manager will show *32 and yet it will display 32 and 64 bit paths correctly.
advcomAsked:
Who is Participating?
 
connectexConnect With a Mentor Commented:
While I don't use VB myself. I do most stuff in C++ or VBScript. I do know you can get the information via Win32 call. Here's the information on how a 32-bit program can read the 64-bit registry or a 64-bit program can read the 32-bit registry: http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx. It is done by adding a rights flag to some calls like RegOpenKeyEx: http://msdn.microsoft.com/en-us/library/ms724878(v=VS.85).aspx. And I also found this posting on how to do Win32 calls from VB: http://www.vb6.us/tutorials/using-win32-api

-Matt-
0
 
advcomAuthor Commented:
Ok, well the link you posted did not give me any code examples, but it did point me in the right direction and I came up with this which works well. It grabs the 64 bit values instead of redirecting me to the 32 bit values.

I do have a another question? Anybody know how to make this open a key when the program does not have permission to access that key? Maybe SEBackupPrivelege? Not really sure


Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
    Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

    Const HKEY_CLASSES_ROOT = &H80000000
    Const HKEY_CURRENT_USER = &H80000001
    Const HKEY_LOCAL_MACHINE = &H80000002
    Const HKEY_USERS = &H80000003
    Const ERROR_SUCCESS = 0&
    Const KEY_WOW64_64KEY As Long = &H100& '32 bit app to access 64 bit hive
    Const KEY_WOW64_32KEY As Long = &H200& '64 bit app to access 32 bit hive
    Const SYNCHRONIZE = &H100000
    Const STANDARD_RIGHTS_READ = &H20000
    Const STANDARD_RIGHTS_WRITE = &H20000
    Const STANDARD_RIGHTS_EXECUTE = &H20000
    Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Const STANDARD_RIGHTS_ALL = &H1F0000
    Const KEY_QUERY_VALUE = &H1
    Const KEY_SET_VALUE = &H2
    Const KEY_CREATE_SUB_KEY = &H4
    Const KEY_ENUMERATE_SUB_KEYS = &H8
    Const KEY_NOTIFY = &H10
    Const KEY_CREATE_LINK = &H20
    Const KEY_READ32 = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
    Const KEY_READ64 = ((KEY_WOW64_64KEY Or STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
    Const REG_DWORD = 4
    Const REG_BINARY = 3
    Const REG_SZ = 1
    Const BACKUPRESTORE = &H4
    Const KEY_OPTIONS = (BACKUPRESTORE)
Function enumerateValues32(strKeyPath)
    Dim lngKeyHandle As Long
    Dim lngResult As Long
    Dim lngCurIdx As Long
    Dim strValue As String
    Dim lngValueLen As Long
    Dim lngData As Long
    Dim lngDataLen As Long
    Dim strResult As String
    Dim lResult As Long
    Dim lValueType As Long
    Dim strBuf As String
    Dim lDataBufSize As Long
    Dim arrValueList() As String
    
    'ENUMERATE 32 BIT REGISTRY KEYS ON 64 BIT OS
    lngResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0&, KEY_READ32, lngKeyHandle)
    If lngResult <> ERROR_SUCCESS Then
        MsgBox "Cannot open key"
        Exit Function
    End If
    
    lngCurIdx = 0
    Do
       lngValueLen = 2000
       strValue = String(lngValueLen, 0)
       lngDataLen = 2000
    
       lngResult = RegEnumValue(lngKeyHandle, lngCurIdx, ByVal strValue, lngValueLen, 0&, REG_DWORD, ByVal lngData, lngDataLen)
       lngCurIdx = lngCurIdx + 1
    
        If lngResult = ERROR_SUCCESS Then
           strResult = Left(strValue, lngValueLen)
           
            'retrieve nformation about the key
            lResult = RegQueryValueEx(lngKeyHandle, strResult, 0, lValueType, ByVal 0, lDataBufSize)
            'Create a buffer
            strBuf = String(lDataBufSize, Chr$(0))
            'retrieve the key's content
            lResult = RegQueryValueEx(lngKeyHandle, strResult, 0, 0, ByVal strBuf, lDataBufSize)
            ReDim Preserve arrValueList(lngCurIdx - 1)
            arrValueList(lngCurIdx - 1) = Left$(strBuf, InStr(1, strBuf, Chr$(0)) - 1) & " *32"
            enumerateValues32 = arrValueList
        End If
    
    Loop While lngResult = ERROR_SUCCESS
    Call RegCloseKey(lngKeyHandle)
    
End Function
Function enumerateValues64(strKeyPath)
    Dim lngKeyHandle As Long
    Dim lngResult As Long
    Dim lngCurIdx As Long
    Dim strValue As String
    Dim lngValueLen As Long
    Dim lngData As Long
    Dim lngDataLen As Long
    Dim strResult As String
    Dim lResult As Long
    Dim lValueType As Long
    Dim strBuf As String
    Dim lDataBufSize As Long
    Dim arrValueList() As String

    'ENUMERATE 64 BIT REGISTRY KEYS ON 64 BIT OS
    lngResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0&, KEY_READ64, lngKeyHandle)
    If lngResult <> ERROR_SUCCESS Then
        MsgBox "Cannot open key"
        Exit Function
    End If
    
    lngCurIdx = 0
    Do
       lngValueLen = 2000
       strValue = String(lngValueLen, 0)
       lngDataLen = 2000
    
       lngResult = RegEnumValue(lngKeyHandle, lngCurIdx, ByVal strValue, lngValueLen, 0&, REG_DWORD, ByVal lngData, lngDataLen)
       lngCurIdx = lngCurIdx + 1
    
        If lngResult = ERROR_SUCCESS Then
           strResult = Left(strValue, lngValueLen)
           
            'retrieve nformation about the key
            lResult = RegQueryValueEx(lngKeyHandle, strResult, 0, lValueType, ByVal 0, lDataBufSize)
            'Create a buffer
            strBuf = String(lDataBufSize, Chr$(0))
            'retrieve the key's content
            lResult = RegQueryValueEx(lngKeyHandle, strResult, 0, 0, ByVal strBuf, lDataBufSize)
            ReDim Preserve arrValueList(lngCurIdx - 1)
            arrValueList(lngCurIdx - 1) = Left$(strBuf, InStr(1, strBuf, Chr$(0)) - 1) & " *64"
            enumerateValues64 = arrValueList
        End If
    
    Loop While lngResult = ERROR_SUCCESS
    Call RegCloseKey(lngKeyHandle)
End Function

Open in new window

0
 
connectexCommented:
So basically you want to override registry security?
0
 
advcomAuthor Commented:
Yes, for example I just removed a virus that got missed by Autoruns. It was a driver entry in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. It's key had all the permissions removed from it so that you could not read the image path. Other programs such as TDSS Killer can read it fine and show the path, even with permissions removed, so obviously it is possible. I would like to add that feature to my code.
0
 
advcomAuthor Commented:
nm on the registry access, I figured it out
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.