usr/lib/Get-ApiSet.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using namespace System.Runtime.InteropServices

function Get-ApiSet {
  [CmdletBinding()]param()

  begin {
    New-Structure API_SET_NAMESPACE {
      UInt32 Version
      UInt32 Size
      UInt32 Flags
      UInt32 Count
      UInt32 EntryOffset
      UInt32 HashOffset
      UInt32 HashFactor
    }

    New-Structure API_SET_NAMESPACE_ENTRY {
      UInt32 Flags
      UInt32 NameOffset
      UInt32 NameLength
      UInt32 HashedLength
      UInt32 ValueOffset
      UInt32 ValueCount
    }

    New-Structure API_SET_VALUE_ENTRY {
      UInt32 Flags
      UInt32 NameOffset
      UInt32 NameLength
      UInt32 ValueOffset
      UInt32 ValueLength
    }

    New-Delegate ntdll {
      ptr RtlGetCurrentPeb
    }

    $to_i = "ToInt$(($sz = [IntPtr]::Size) * 8)"
  }
  process {}
  end {
    $ptr = [Marshal]::ReadIntPtr([IntPtr]( # ApiSetMap offset
      $ntdll.RtlGetCurrentPeb.Invoke().$to_i() + ($sz -eq 8 ? 0x68 : 0x38)
    ))
    $asn, $mov = ($ptr -as [API_SET_NAMESPACE]), $ptr.$to_i()

    $pasne = [IntPtr]($asn.EntryOffset + $mov) # first entry pointer
    for ($i = 0; $i -lt $asn.Count; $i++) {
      $asne = $pasne -as [API_SET_NAMESPACE_ENTRY]
      $dll = [Marshal]::PtrToStringUni([IntPtr]($asne.NameOffset + $mov), $asne.NameLength / 2)
      $ses = [Boolean]$asne.Flags

      $pasve = [IntPtr]($asne.ValueOffset + $mov)
      $mod = for ($j = 0; $j -lt $asne.ValueCount; $j++) {
        $asve = $pasve -as [API_SET_VALUE_ENTRY]
        [Marshal]::PtrToStringUni([IntPtr]($asve.ValueOffset + $mov), $asve.ValueLength / 2)
        # move to the next value
        $pasve = [IntPtr]($pasve.$to_i() + $asve::GetSize())
      }

      [PSCustomObject]@{
        Module = "$dll.dll"
        Sealed = $ses
        Linked = $mod
      }
      # move to the next entry
      $pasne = [IntPtr]($pasne.$to_i() + $asne::GetSize())
    }
  }
}

Export-ModuleMember -Function Get-ApiSet