Results 1 to 8 of 8

Thread: [RESOLVED] Crashing when reading UNICODE_STRING

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    3,456

    Resolved [RESOLVED] Crashing when reading UNICODE_STRING

    I'm trying to get a process commandline. Everything goes fine, including getting the proper string length in UNICODE_STRING.uLength, and a non-null .pBuffer, but then actually retrieving the string crashes, with both methods below;

    Code:
    Public Function GetProcessCommandLine(pid As Long, sProc As String) As String
    If (pid <= 0&) Or (pid = 4&) Then Exit Function 'Invalid, system idle, and system process. Command line n/a.
    Dim tPEB As PEB
    Dim tUPP As RTL_USER_PROCESS_PARAMETERS
    Dim tPBI As PROCESS_BASIC_INFORMATION
    Dim hProc As Long
    Dim status As Long
    Dim dwSizeNeeded As Long
    Dim cbRead As Long
    Dim sOut As String
    
    hProc = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0&, pid)
    If hProc <> INVALID_HANDLE_VALUE Then
    	status = NtQueryInformationProcess(hProc, ProcessBasicInformation, tPBI, LenB(tPBI), dwSizeNeeded)
        If tPBI.PebBaseAddress Then
            PostLog "ReadPEB"
            If ReadProcessMemory(hProc, tPBI.PebBaseAddress, tPEB, LenB(tPEB), cbRead) Then
            	cbRead = 0&
                PostLog "ReadUPP"
                If ReadProcessMemory(hProc, tPEB.ProcessParameters, tUPP, LenB(tUPP), cbRead) Then
                    If tUPP.CommandLine.uLength Then
                        PostLog "StrLen " & tUPP.CommandLine.uLength
                        Dim bstr() As Byte
                        ReDim bstr(tUPP.CommandLine.uLength - 1)
                        If ReadProcessMemory(hProc, tUPP.CommandLine.pBuffer, bstr(0), tUPP.CommandLine.uLength, cbRead) Then
                            sOut = bstr
                            PostLog "sOut=" & sOut
                        End If
                    Else
                    	PostLog "CmdLineLen=0 for " & sProc
                    End If
                Else
                    PostLog "Failed to read process params for " & sProc
                End If
            Else
                PostLog "Failed to read PEB for " & sProc
            End If
        Else
            PostLog "Failed to obtain PebBaseAddress for " & hProc & ", status=0x" & Hex(status)
        End If
        CloseHandle hProc
    Else
        PostLog "Failed to open process " & sProc & ", err=0x" & Hex$(Err.LastDllError)
    End If
    
    End Function
    Program is running elevated and has enabled SeDebugPrivilege.

    I've gone VB string->UNICODE_STRING many times, but this is the first needing to go the other way; am I missing anything obvious?

  2. #2

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    3,456

    Re: Crashing when reading UNICODE_STRING

    Why would it read everything fine right up until then?

    But anyway, nevermind. It crashed 8 times in a row but now it's working. I don't know what was going on but it seems to work now.

  4. #4

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    3,456

    Re: [RESOLVED] Crashing when reading UNICODE_STRING

    Yeah I've been playing around with those functions ever since I found your modX64Call.bas, fun stuff.

    I wrote out the full structures for 32bit... I see why you'd just get the pointers from their raw offset though, it took a good half hour.

    Code:
    Private Type RTL_DRIVE_LETTER_CURDIR
        Flags As Integer
        Length As Integer
        TimeStamp As Long
        DosPath As UNICODE_STRING
    End Type
    Private Type CURDIR
    	DosPath As UNICODE_STRING
        Handle As Long
    End Type
    Private Type LIST_ENTRY
        Flink As Long
        Blink As Long
    End Type
    
    Private Type RTL_USER_PROCESS_PARAMETERS
        MaximumLength As Long
        Length As Long
        Flags As Long
        DebugFlags As Long
        ConsoleHandle As Long
        ConsoleFlags As Long
        StdInputHandle As Long
        StdOutputHandle As Long
        StdErrorHandle As Long
        CurrentDirectory As CURDIR
        DllPath As UNICODE_STRING
        ImagePathName As UNICODE_STRING
        CommandLine As UNICODE_STRING
        Environment As Long
        StartingPositionLeft As Long
        StartingPositionTop As Long
        Width As Long
        Height As Long
        CharWidth As Long
        CharHeight As Long
        ConsoleTextAttributes As Long
        WindowFlags As Long
        ShowWindowFlags As Long
        WindowTitle As UNICODE_STRING
        DesktopName As UNICODE_STRING
        ShellInfo As UNICODE_STRING
        RuntimeData As UNICODE_STRING
        DLCurrentDirectory(31) As RTL_DRIVE_LETTER_CURDIR
        EnvironmentSize As Currency
        'Windows Vista stops here, so we will as well as that's our compatibility target.
    End Type
    Private Type PEB
        InheritedAddressSpace As Byte
        ReadImageFileExecOptions As Byte
        BeingDebugged As Byte
        BitField As Byte
        Mutant As Long
        ImageBaseAddress As Long
        Ldr As Long
        ProcessParameters As Long 'RTL_USER_PROCESS_PARAMETERS, what we're primarily interested in.
        SubSystemData As Long
        ProcessHeap As Long
        FastPebLock As Long
        AtlThinkSListPtr As Long
        IFEOKey As Long
        CrossProcessFlags As Long
        CBTableOrInfoPtr As Long
        SystemReserved(0) As Long
        AtlThinkSListPtr32 As Long
        ApiSetMap As Long
        TlsExpansionCounter As Long
        TlsBitmap As Long
        TlsBitmaps(1) As Long
        ReadOnlySharedMemoryBase As Long
        HotpatchInformation As Long
        ReadOnlyStaticServerData As Long
        AnsiCodePageData As Long
        OemCodePageData As Long
        UnicodeCaseTableData As Long
        NumberOfProcessors As Long
        NtGlobalFlag As Long
        CriticalSectionTimeout As LARGE_INTEGER
        HeapSegmentReserve As Currency
        HeapSegmentCommit As Currency
        HeapDeCommitTotalFreeThreshold As Currency
        HeapDeCommitFreeBlockThreshold As Currency
        NumberOfHeaps As Long
        MaximumNumberOfHeaps As Long
        ProcessHeaps As Long
        GdiSharedHandleTable As Long
        ProcessStarterHelper As Long
        GdiDCAttributeList As Long
        LoaderLock As Long
        OSMajorVersion As Long
        OSMinorVersion As Long
        OSBuildNumber As Integer
        OSCSDVersion As Integer
        OSPlatformId As Long
        ImageSubsystem As Long
        ImageSubsystemMajorVersion As Long
        ImageSubsystemMinorVersion As Long
        ImageProcessAffinityMask As Currency
        GdiHandleBuffer(59) As Long
        PostProcessInitRoutine As Long
        TlsExpansionBitmap As Long
        TlsExpansionBitmapBits(31) As Long
        SessionId As Long
        AppCompatFlags As LARGE_INTEGER
        AppCompatFlagUser As LARGE_INTEGER
        pShimData As Long
        AppCompatInfo As Long
        CSDVersion As UNICODE_STRING
        ActivationContextData As Long
        ProcessAssemblyStorageMap As Long
        SystemDefaultActivationContextData As Long
        SystemAssemblyStorageMap As Long
        MinimumStackCommit As Long
        FlsCallback As Long
        FlsListHead As LIST_ENTRY
        FlsBitmap As Long
        FlsBitmapBits(3) As Long
        FlsHighIndex As Long
        WerRegistrationData As Long
        WerShipAssertPtr As Long
        'Believe it or not, future OS' have *even more* members. But Vista stops here, so we will too. 
    End Type
    Need to define separate structures PEB64 for x86 crossover work... I haven't done all that yet, since I'll have to carefully review alignment issues. But I did x64 for VBA and twinBASIC:

    Code:
    Private Type RTL_DRIVE_LETTER_CURDIR
        Flags As Integer
        Length As Integer
        TimeStamp As Long
        DosPath As UNICODE_STRING
    End Type
    Private Type CURDIR
    	DosPath As UNICODE_STRING
        Handle As LongPtr
    End Type
    Private Type LIST_ENTRY
        Flink As LongPtr
        Blink As LongPtr
    End Type
    
    Private Type RTL_USER_PROCESS_PARAMETERS
        MaximumLength As Long
        Length As Long
        Flags As Long
        DebugFlags As Long
        ConsoleHandle As LongPtr
        ConsoleFlags As Long
        StdInputHandle As LongPtr
        StdOutputHandle As LongPtr
        StdErrorHandle As LongPtr
        CurrentDirectory As CURDIR
        DllPath As UNICODE_STRING
        ImagePathName As UNICODE_STRING
        CommandLine As UNICODE_STRING
        Environment As LongPtr
        StartingPositionLeft As Long
        StartingPositionTop As Long
        Width As Long
        Height As Long
        CharWidth As Long
        CharHeight As Long
        ConsoleTextAttributes As Long
        WindowFlags As Long
        ShowWindowFlags As Long
        WindowTitle As UNICODE_STRING
        DesktopName As UNICODE_STRING
        ShellInfo As UNICODE_STRING
        RuntimeData As UNICODE_STRING
        DLCurrentDirectory(31) As RTL_DRIVE_LETTER_CURDIR
        EnvironmentSize As LongLong
        'Windows Vista stops here, so we will as well as that's our compatibility target.
    End Type
    Private Type PEB
        InheritedAddressSpace As Byte
        ReadImageFileExecOptions As Byte
        BeingDebugged As Byte
        BitField As Byte
        Mutant As LongPtr
        ImageBaseAddress As LongPtr
        Ldr As LongPtr
        ProcessParameters As LongPtr 'RTL_USER_PROCESS_PARAMETERS, what we're primarily interested in.
        SubSystemData As LongPtr
        ProcessHeap As LongPtr
        FastPebLock As LongPtr
        AtlThinkSListPtr As LongPtr
        IFEOKey As LongPtr
        CrossProcessFlags As Long
        CBTableOrInfoPtr As LongPtr
        SystemReserved(0) As Long
        AtlThinkSListPtr32 As Long
        ApiSetMap As LongPtr
        TlsExpansionCounter As Long
        TlsBitmap As LongPtr
        TlsBitmaps(1) As Long
        ReadOnlySharedMemoryBase As LongPtr
        HotpatchInformation As LongPtr
        ReadOnlyStaticServerData As LongPtr
        AnsiCodePageData As LongPtr
        OemCodePageData As LongPtr
        UnicodeCaseTableData As LongPtr
        NumberOfProcessors As Long
        NtGlobalFlag As Long
        CriticalSectionTimeout As LARGE_INTEGER
        HeapSegmentReserve As LongLong
        HeapSegmentCommit As LongLong
        HeapDeCommitTotalFreeThreshold As LongLong
        HeapDeCommitFreeBlockThreshold As LongLong
        NumberOfHeaps As Long
        MaximumNumberOfHeaps As Long
        ProcessHeaps As LongPtr
        GdiSharedHandleTable As LongPtr
        ProcessStarterHelper As LongPtr
        GdiDCAttributeList As Long
        LoaderLock As LongPtr
        OSMajorVersion As Long
        OSMinorVersion As Long
        OSBuildNumber As Integer
        OSCSDVersion As Integer
        OSPlatformId As Long
        ImageSubsystem As Long
        ImageSubsystemMajorVersion As Long
        ImageSubsystemMinorVersion As Long
        ImageProcessAffinityMask As LongLong
        GdiHandleBuffer(59) As Long
        PostProcessInitRoutine As LongPtr
        TlsExpansionBitmap As LongPtr
        TlsExpansionBitmapBits(31) As Long
        SessionId As Long
        AppCompatFlags As LARGE_INTEGER
        AppCompatFlagUser As LARGE_INTEGER
        pShimData As LongPtr
        AppCompatInfo As LongPtr
        CSDVersion As UNICODE_STRING
        ActivationContextData As LongPtr
        ProcessAssemblyStorageMap As LongPtr
        SystemDefaultActivationContextData As LongPtr
        SystemAssemblyStorageMap As LongPtr
        MinimumStackCommit As Long
        FlsCallback As LongPtr
        FlsListHead As LIST_ENTRY
        FlsBitmap As LongPtr
        FlsBitmapBits(3) As Long
        FlsHighIndex As Long
        WerRegistrationData As LongPtr
        WerShipAssertPtr As LongPtr
        'Believe it or not, future OS' have *even more* members. But Vista stops here, so we will too. 
    End Type
    For CommandLine x64 can read both 32bit and 64bit with the same structures/calls. If you wanted to list loaded modules you'd have to declare PEB32 et al with the 32bit defs

  6. #6
    Banned
    Join Date
    Nov 2011
    Posts
    7,803

    Re: [RESOLVED] Crashing when reading UNICODE_STRING

    I'm curious. Why do you guys do it this way? This seems like a lot of unnecessary work when you could just use WMI. For example I use this in VB.Net to get the command line of a process:-
    Code:
        Public Shared Function GetProcessCommandLineArguments(ByVal p As Process) As String
    
            Dim searcher As New ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + p.Id.ToString)
    
            Dim col = searcher.Get
    
            For Each obj As ManagementObject In col
                Dim wholeCmdLine As String = obj("CommandLine")
    
                Dim args As String = GetCommandLineArgsOnly(wholeCmdLine)
    
                Return args
            Next
    
            Return ""
        End Function
    I'm pretty sure I've seen a lot of posts here where people have used WMI in VB6. Why not use that?

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    3,456

    Re: [RESOLVED] Crashing when reading UNICODE_STRING

    A lot of people disable WMI these days.

    Plus this is a hobby, I do what interests me the most. If my job wanted something done, sure I'd use whatever is simplest and easiest, so if I could assume WMI was running, I'd use that. And I have used it for various things in the past. But I'm interested in low level Windows programming right now, including Windows internals and kernel mode.

  8. #8
    Banned
    Join Date
    Nov 2011
    Posts
    7,803

    Re: [RESOLVED] Crashing when reading UNICODE_STRING

    Ah ok. Fair enough.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width