Find Modules That Have Been Rebased

Rebasing of DLLs is an issue that can add to the overall load time of an application.  If a DLL can’t be loaded at it’s preferred base address (image base address) then the OS loader has to go in and patch up addresses in the code (like in jmp statements) to account for a different base address. 
 
You can find out what the preferred base address of a DLL is by using the Visual Studio command line tool dumpbin.  From PowerShell just execute the following on a DLL but make sure you have put the Visual C++ Bin dir your path first – "${env:VS80COMNTOOLS}..\..\VC\Bin"):  
 
PS> dumpbin /headers c:\windows\system32\ntdll.dll | 
      match-string "image base"
 
Or since the base address can be found in an executable’s PE header, you can use this MSH function (thanks to Lionel Fourquaux for supplying this to me):
 
function Get-ImageBase($path) {
    $dosh = gc $path -enc Byte -total 64
    $pehb = $dosh[60] + 0x100 * $dosh[61] + 0x10000 * $dosh[62] +
            0x1000000 * $dosh[63]
    $peh = gc $path -enc Byte -total $($pehb + 248)
    $peh[$pehb + 52] + 0x100 * $peh[$pehb + 53] + 0x10000 * $peh[$pehb + 54] +
        0x1000000 * $peh[$pehb + 55]
}
 
You can also find the actual image load address using get-process like so:
 
PS> get-process | select -uniq |
       select ProcessName -expand Modules -ea silentlycontinue |
       sort {$_.BaseAddress.ToInt32()} |
       ft @{l="BaseAddress";e={$_.BaseAddress.ToInt32()};f="0x{0:X8}"},
          @{l="Name";e={parse-path -leaf $_.filename}} -auto
 
Now wouldn’t it be cool to have a way to quickly determine which DLLs have been rebased?  With what we have above it is very easy to put together a PowerShell srcript to do just that.  Here it is:
 
FindRebasedModules.ps1 contents below:
—————————–
param([int]$processId = $(throw "A process id must be provided."))
function Get-ImageBase($path) {
    $dosh = gc $path -enc Byte -total 64
    $pehb = $dosh[60] + 0x100 * $dosh[61] + 0x10000 * $dosh[62] +
            0x1000000 * $dosh[63]
    $peh = gc $path -enc Byte -total $($pehb + 248)
    $peh[$pehb + 52] + 0x100 * $peh[$pehb + 53] + 0x10000 * $peh[$pehb + 54] + 
        0x1000000 * $peh[$pehb + 55]
}
$printHdr = $true
$modules = get-process -id $processId | select -expand Modules -ea silentlycontinue
foreach ($module in $modules) {
    $imageBase = Get-ImageBase($module.Filename)
    $actualBase = $module.BaseAddress.ToInt32()
    if ($actualBase -ne $imageBase) {
        if ($printHdr) {
            "`nModule Relocations in Process Id: $processId"
            "——————————————–"
            $printHdr = $false
        }
        "{0}`n    Image base: 0x{1:X8}`n    Loaded at:  0x{2:X8}" -f
          $module.Filename, $imageBase, $actualBase
    }
}
Module Relocations in Process Id: 928
——————————————–
C:\Program Files\Symantec AntiVirus\Dec2TAR.dll
    Image base: 0x51B70000
    Loaded at:  0x01130000
C:\Program Files\Symantec AntiVirus\Dec2RTF.dll
    Image base: 0x51B50000
    Loaded at:  0x04960000
C:\Program Files\Symantec\LiveUpdate\LuComServerPS.DLL
    Image base: 0x10000000
    Loaded at:  0x043E0000
 
Enjoy.
 
Advertisements
This entry was posted in PowerShell. Bookmark the permalink.

One Response to Find Modules That Have Been Rebased

  1. Marek says:

    Great tip :)One warning: Int32 is too small for 64 bit machines out there, so for a quick fix consider changing cast in "$module.BaseAddress.ToInt32()" to "$module.BaseAddress.ToInt64()".

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s