1

我目前正在尝试将带有线程注入的代码洞穴注入到在我的 win7 (x64) 系统上运行的远程 win32 EXE。为此,我使用 Microsoft VB6,通过它我执行以下操作:

  • OpenProcess,获取远程进程的句柄 [OK]
  • VirtualAllocEx,在进程内部分配一些空间(以 PAGE_EXECUTE 保护和 MEM_COMMIT 作为参数。lpAddress 设置为 NULL 以便函数确定分配区域的位置)[OK,返回一个有效的偏移量]
  • WriteProcessMemory,编写我的 shellcode [好的,实际上正确写入了字节,我已经检查过 CheatEngine/MemoryView]
  • CreateRemoteThread,线程注入执行我的代码洞穴
  • 我的目标 EXE(刚刚创建的远程线程的主机)此时崩溃(“exename”停止工作)
  • WaitForSingleObject / CloseHandle / VirtualFreeEx

为了测试成功的代码注入,我试图注入一个什么都不做的shellcode。我对shellcoding和asm了解不多,但我才刚刚开始学习。

我尝试注入不同的代码,例如: - 只有 NOP(崩溃,但我假设它是正常的):\x90\x90\x90.. - 只有 NULL(与上面相同):\x00\x00\x00.. 但是我不明白的是,RETN 之后的 NOP 也会使我的目标 EXE 崩溃 \x90\x90\x90\xCB。我尝试注入的每个字节序列后跟一个 NULL 字节。

为什么我的目标进程崩溃?我必须注入什么字节序列才能执行不会使我的目标 EXE 崩溃的成功注入(但它什么也没做,只是为了测试注入方案)?

我最终想要做的是向游戏注入一个 PUSH x, CALL 目标函数。但是,如果我的虚拟 shellcode 使我的目标进程崩溃,我假设后一个字节序列也会崩溃。谢谢你的时间。

编辑:我得到的异常是 0xC0000005 [写入时访问冲突]

VB6 代码:只需使用目标 Exe 的 pid 作为参数调用 sub

Private Const PAGE_READWRITE As Long = &H4
Private Const PAGE_EXECUTE As Long = &H10

Private Const MEM_RELEASE As Long = &H8000
Private Const MEM_COMMIT As Long = &H1000
Private Const INFINITE As Long = &HFFFFFF

Public Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CreateRemoteThread Lib "kernel32" (ByVal hProcess As Long, lpThreadAttributes As Long, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long

'Function that performs the shellcode injection to a remote process. Takes the target's PID as argument
Public Sub injectCode(ByVal lngPid As Long)
    Dim RemThread As Long, LngModule As Long, LngProcess As Long
    Dim i As Long

    'The byte sequence we'll inject in the remote process (
    Dim shellcode(4) As Byte
    shellcode(0) = &H90 'NOP : just to pretend that it's actual code
    shellcode(1) = &H90 'NOP : same
    shellcode(2) = &HC2 'Near return to calling procedure and pop 4 bytes from stack.
    shellcode(3) = &H4
    shellcode(4) = 0    'NULL terminator

    'OpenProcess, to get a handle to the remote process
    LngProcess = OpenProcess(PROCESS_ALL_ACCESS, False, lngPid)
    'to allocate some space inside of process (with PAGE_EXECUTE protection and MEM_COMMIT as parameter.
    'lpAddress set to NULL so that the function determines where to allocate the region)
    LngModule = VirtualAllocEx(LngProcess, 0, UBound(shellcode), MEM_COMMIT, PAGE_EXECUTE)

    Debug.Print "VirtualAllocEx: " & Hex(LngModule) 'debug info

    'writing our shellcode to the target's memory
    For i = 0 To UBound(shellcode)
        Call WriteProcessMemory(LngProcess, LngModule + i, shellcode(i), 1, 0&)
    Next i
    'thread injection to execute my code cave
    RemThread = CreateRemoteThread(LngProcess, 0&, 0&, ByVal LngModule, 0&, 0&, ByVal 0&)

    Debug.Print "CreateRemoteThread: " & Hex(RemThread) 'debug info

    'wait for the thread to run
    Call WaitForSingleObject(RemThread, INFINITE)
    CloseHandle (RemThread)
    Call VirtualFreeEx(LngProcess, LngModule, UBound(shellcode), MEM_RELEASE)

    Debug.Print "DONE" 'debug info
End Sub

不过有些奇怪的事情发生了。当我在调用 CreateRemoteThread 之前出于调试目的放置 MsgBox(暂停执行)时,该函数返回一个非 NULL 句柄(但目标 EXE 崩溃)。如果我在调用 CreateRemoteThread 之前没有放置 Msgbox,则会返回一个 NULL 句柄。

4

1 回答 1

3

ThreadProc传递给的回调CreateRemoteThread接受一个LPVOID参数并且ThreadProc__stdcall.

LPVOID参数 for是从'sThreadProc转发的。CreateRemoteThreadLPVOID lpParameter

在 x86 上,这意味着您需要放置RET指令以便从堆栈中释放四个字节。

(也ThreadProc返回 DWORD,这意味着你应该EAX在返回之前返回值,但如果你不关心返回值,你可以跳过它)

另外,CB 是远回报,你需要使用近回报。

寻找RETN imm opcode,看起来你需要C2 04 00

于 2019-03-03T10:01:41.623 回答