Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Enumerate modules via the Process Environment Block (PEB)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBCC Enumerate modules via the Process Environment Block (PEB)

    For more info see ...
    http://undocumented.ntinternals.net/...ocess/PEB.html
    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

    Each process has a Process Environment Block so this method can be used to read the loaded modules in other processes (the only trick required is that you need to determine the PEB address in the remote process, but there are ways to do this), but for this sample i've just got it enumerating within its own process.

    It also shows how to access other members of the PEB, for example the BeingDebugged byte which the Windows API function IsDebuggerPresent directly references, as you can see in a disassembly of its code:
    ! mov eax, dword ptr fs:[18]
    ! mov eax, dword ptr [eax+30]
    ! movzx eax, byte ptr [eax+2] <-- PEB.BeingDebugged
    ! retn


    Code updated - José Roca was correct in quickly spotting that array members in my PB translation of the PEB were 1 extra, i've since corrected the code, cheers José!

    Code:
    #COMPILE EXE
    #INCLUDE "win32api.inc"
    
    TYPE UNICODE_STRING
      Length AS WORD
      MaximumLength AS WORD
      ptrBuffer AS DWORD
    END TYPE
    
    FUNCTION UniStrToAnsi (UNI_STR AS UNICODE_STRING) AS STRING  'Convert Unicode to ANSI
    ON ERROR RESUME NEXT
      DIM Buffer AS STRING
      Buffer = SPACE$(UNI_STR.Length / 2)
      WideCharToMultiByte %CP_ACP, _                 ' code page
                          %NULL, _                   ' performance and mapping flags
                          BYVAL UNI_STR.ptrBuffer, _ ' Unicode string to convert
                          UNI_STR.Length, _          ' len of Unicode string
                          BYVAL STRPTR(Buffer), _    ' buffer for ANSI string
                          UNI_STR.Length / 2, _      ' len of ANSI buffer
                          BYVAL %NULL, _             ' default for unmappable chars
                          BYVAL %NULL                ' default flag
      FUNCTION = LEFT$(Buffer, UNI_STR.Length / 2)
    END FUNCTION
    
    TYPE LARGE_INTEGER
        dwLo AS DWORD
        dwHi AS DWORD
    END TYPE
    
    TYPE RTL_DRIVE_LETTER_CURDIR
        Flags AS DWORD
        Length AS DWORD
        TimeStamp AS DWORD
        DosPath AS UNICODE_STRING
    END TYPE
    
    TYPE RTL_USER_PROCESS_PARAMETERS
     MaximumLength AS DWORD
     Length AS DWORD
     Flags AS DWORD
     DebugFlags AS DWORD
     ConsoleHandle AS DWORD
     ConsoleFlags AS DWORD
     StdInputHandle AS DWORD
     StdOutputHandle AS DWORD
     StdErrorHandle AS DWORD
     CurrentDirectoryPath AS UNICODE_STRING
     CurrentDirectoryHandle AS DWORD
     DllPath AS UNICODE_STRING
     ImagePathName AS UNICODE_STRING
     CommandLine AS UNICODE_STRING
     Environment AS DWORD
     StartingPositionLeft AS DWORD
     StartingPositionTop AS DWORD
     dwWidth AS DWORD
     dwHeight AS DWORD
     CharWidth AS DWORD
     CharHeight AS DWORD
     ConsoleTextAttributes AS DWORD
     WindowFlags AS DWORD
     ShowWindowFlags AS DWORD
     WindowTitle AS UNICODE_STRING
     DesktopName AS UNICODE_STRING
     ShellInfo AS UNICODE_STRING
     RuntimeData AS UNICODE_STRING
     DLCurrentDirectory(31) AS RTL_DRIVE_LETTER_CURDIR
    END TYPE
    
    TYPE PEB_LDR_DATA
     dwLength AS DWORD
     Initialized AS DWORD
     SsHandle AS DWORD
     InLoadOrderModuleList AS LIST_ENTRY
     InMemoryOrderModuleList AS LIST_ENTRY
     InInitializationOrderModule AS LIST_ENTRY
    END TYPE
    
    TYPE LDR_MODULE
     InLoadOrderModuleList AS LIST_ENTRY
     InMemoryOrderModuleList AS LIST_ENTRY
     InInitializationOrderModule AS LIST_ENTRY
     BaseAddress AS DWORD
     EntryPoint AS DWORD
     SizeOfImage AS DWORD
     FullDllName AS UNICODE_STRING
     BaseDllName AS UNICODE_STRING
     Flags AS DWORD
     LoadCount AS WORD
     TlsIndex AS WORD
     HashTableEntry AS LIST_ENTRY
     TimeDateStamp AS DWORD
    END TYPE
    
    TYPE PEB
     InheritedAddressSpace AS BYTE
     ReadImageFileExecOptions AS BYTE
     BeingDebugged AS BYTE
     Spare AS BYTE
     Mutant AS DWORD
     ImageBaseAddress AS DWORD
     LoaderData AS PEB_LDR_DATA PTR
     ProcessParameters AS RTL_USER_PROCESS_PARAMETERS PTR
     SubSystemData AS DWORD
     ProcessHeap AS DWORD
     FastPebLock AS DWORD
     FastPebLockRoutine AS DWORD '//PPEBLOCKROUTINE
     FastPebUnlockRoutine AS DWORD '//PPEBLOCKROUTINE
     EnvironmentUpdateCount AS DWORD
     KernelCallbackTable AS DWORD
     EventLogSection AS DWORD
     EventLog AS DWORD
     FreeList AS DWORD '//PPEB_FREE_BLOCK
     TlsExpansionCounter AS DWORD
     TlsBitmap AS DWORD
     TlsBitmapBits(1) AS DWORD
     ReadOnlySharedMemoryBase AS DWORD
     ReadOnlySharedMemoryHeap AS DWORD
     ReadOnlyStaticServerData AS DWORD
     AnsiCodePageData AS DWORD
     OemCodePageData AS DWORD
     UnicodeCaseTableData AS DWORD
     NumberOfProcessors AS DWORD
     NtGlobalFlag AS DWORD
     Spare2(3) AS BYTE
     CriticalSectionTimeout AS LARGE_INTEGER
     HeapSegmentReserve AS DWORD
     HeapSegmentCommit AS DWORD
     HeapDeCommitTotalFreeThreshold AS DWORD
     HeapDeCommitFreeBlockThreshold AS DWORD
     NumberOfHeaps AS DWORD
     MaximumNumberOfHeaps AS DWORD
     ProcessHeaps AS DWORD
     GdiSharedHandleTable AS DWORD
     ProcessStarterHelper AS DWORD
     GdiDCAttributeList AS DWORD
     LoaderLock AS DWORD
     OSMajorVersion AS DWORD
     OSMinorVersion AS DWORD
     OSBuildNumber AS DWORD
     OSPlatformId AS DWORD
     ImageSubSystem AS DWORD
     ImageSubSystemMajorVersion AS DWORD
     ImageSubSystemMinorVersion AS DWORD
     GdiHandleBuffer(33) AS DWORD
     PostProcessInitRoutine AS DWORD
     TlsExpansionBitmap AS DWORD
     TlsExpansionBitmapBits(127) AS BYTE
     SessionId AS DWORD
    END TYPE
    
    
    FUNCTION PBMAIN() AS LONG
    LOCAL pPEB AS PEB PTR, pModule AS LDR_MODULE PTR, dwPEB AS DWORD, FirstModule AS DWORD
    
    ! mov dwPEB, fs:[&h30]  ;Get PEB
    pPEB = dwPEB
    
    STDOUT "ImageBaseAddress=0x" & HEX$(@pPEB.ImageBaseAddress,8)
    STDOUT "BeingDebugged=" & HEX$(@pPEB.BeingDebugged)
    STDOUT "CurrentDirectoryPath=" & UniStrToAnsi(@[email protected])
    STDOUT "ImagePathName=" & UniStrToAnsi(@[email protected])
    
    '// Enum modules
    pModule = @[email protected]
    DO
      IF @pModule.BaseAddress = 0 THEN EXIT DO
      STDOUT "Module: " & HEX$(@pModule.BaseAddress,8) & " " & UniStrToAnsi(@pModule.FullDllName)
      pModule = @pModule.InLoadOrderModuleList.FLink
    LOOP
    
    WAITKEY$
    END FUNCTION
    Last edited by Wayne Diamond; 1 Aug 2009, 07:27 AM.
    -

  • #2
    The array members of the types, such TlsExpansionBitmapBits(128), must be one less, i.e. TlsExpansionBitmapBits(127), because PB arrays are zero based unless otherwise stated.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment

    Working...
    X