首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

遠端執行緒執行組合語言代碼:RunRemoteASMCode 基類實作詳解

     編輯:關於.NET

背景

VB6 時代遠端執行緒注入代碼在 XP 正常,移植至 VB.NET 2008 在 Vista 多核心環境失效。重寫基類解決相容性與記憶體對齊問題。

核心流程四步驟

  1. 取得進程控制代碼,申請 4KB 執行頁面:
    RemoteProcess = Process.GetProcessById(PID)
    AllocBaseAddress = VirtualAllocEx(RemoteProcess.Handle, 0, &H1000,
        MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
  2. 構建機器碼與資料區 (前 512 位元組代碼,後段資料):
    ' 代碼區寫入輔助方法
    Protected Sub AddInt2Code(val As Integer)
        Dim bytes = BitConverter.GetBytes(val)
        Add2Memory(bytes, PtrAddressOffset)
        PtrAddressOffset += 4
    End Sub
    Protected Sub AddByte2Code(val As Byte) ... 
    Protected Sub AddBytes2Code(bytes As Byte()) ...
    
    ' 資料區寫入並記錄位址/長度 (4 位元組對齊)
    Protected Function AddData(bytes As Byte()) As Integer
        Add2Memory(bytes, ObjAddressOffset)
        Dim odata As New mData With {.prt = ObjAddressOffset + AllocBaseAddress, .len = bytes.Length}
        DataArraylist.Add(odata)
        ObjAddressOffset += bytes.Length + (ObjAddressOffset Mod 4)
        Return ObjAddressOffset
    End Function
  3. 建立遠端執行緒執行並等待:
    Function Run() As Integer
        Dim hThread = CreateRemoteThread(RemoteProcess.Handle, 0, 0, AllocBaseAddress, 0, 0, 0)
        WaitForSingleObject(hThread, INFINITE)
        GetExitCodeThread(hThread, lngRet)
        Return lngRet
    End Function
  4. 物件終結時釋放遠端記憶體:
    Protected Overrides Sub Finalize()
        VirtualFreeEx(RemoteProcess.Handle, AllocBaseAddress, MEM_AUTOFREE, MEM_RELEASE)
        MyBase.Finalize()
    End Sub

完整類別代碼

Imports System.Runtime.InteropServices
Public Class RunRemoteASMCode
    Private Const MEM_SIZE = &H1000
    Private Const INFINITE = -1
    Private Const MEM_COMMIT = &H1000, MEM_RESERVE = &H2000, MEM_RELEASE = &H8000
    Private Const PAGE_EXECUTE_READWRITE = &H40

    Protected AllocBaseAddress As Integer
    Protected RemoteProcess As Process
    Protected PtrAddressOffset As Integer = 0
    Protected ObjAddressOffset As Integer = 512
    Protected DataArraylist As New ArrayList

    Sub New(PID As Integer)
        RemoteProcess = Process.GetProcessById(PID)
        AllocBaseAddress = VirtualAllocEx(RemoteProcess.Handle, 0, MEM_SIZE,
            MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
        ClearCodeAndData()
    End Sub

    Protected Sub Add2Memory(bytes As Byte(), offset As Integer)
        WriteProcessMemory(RemoteProcess.Handle, AllocBaseAddress + offset, bytes, bytes.Length, 0)
    End Sub

    ' ... AddInt2Code, AddByte2Code, AddBytes2Code, AddData, Run, ClearCodeAndData, Finalize

    Protected Class mData
        Public prt As Integer
        Public len As Integer
    End Class
End Class

測試驗證

表單按鈕點擊:

api = New RunRemoteAPI(PID)
TextBox3.Text = Hex(api.CallRemoteAPIByName("kernel32", "LoadLibraryA", _
    New mFuncParam(Encoding.ASCII.GetBytes("c:\test.dll"))))
TextBox2.Text = Hex(api.BaseAddress)
' 列舉模組驗證 DLL 已注入
api.CallRemoteAPIByName("kernel32", "FreeLibrary", New mFuncParam(CInt("&H" & TextBox3.Text)))
' 再次列舉確認已卸載

測試執行截圖

模組列表變化截圖

已知問題與後續優化

  • 代碼/資料區固定 512/3.5KB,大型 Shellcode 可能溢位 → 動態計算所需大小。
  • 未處理 DEP (Data Execution Prevention) 相容性,Vista+ 需確保 `PAGE_EXECUTE_READWRITE` 生效。
  • 多執行緒並發注入需同步機制。
  • 後續將整合 Hook 框架,消除 `WriteProcessMemory` 來回切換,實現「一條龍」注入服務。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved