我有一个用Visual Basic 6编译的DLL注入器,我试图在x64 notepad.exe上注入我的DLL(x64),但没有任何作用。
我在网上搜索过这个并看到了这个:
[重要:32位/ 64位]
这是一个可移植性表:
- 32位程序在32位目标中注入32位dll
- 32位程序在64位目标中注入64位dll
- 64位程序在32位目标中注入32位dll
- 64位程序在64位目标中注入64位dll
如果这是真的,那么我的注射器应该正常工作。
有人能帮助我吗?
使用的代码:
Module1.bas
Option Explicit
Private Const INFINITE As Long = &HFFFF
Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20
Private Const TOKEN_QUERY As Long = &H8
Private Const SE_PRIVILEGE_ENABLED As Long = &H2
Private Const ANYSIZE_ARRAY As Long = 1
Private Const SE_DEBUG_NAME As String = "SeDebugPrivilege"
Private Const PAGE_READWRITE As Long = &H4
Private Const MEM_RELEASE As Long = &H8000
Private Const MEM_COMMIT As Long = &H1000
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const SYNCHRONIZE As Long = &H100000
Private Const PROCESS_VM_OPERATION As Long = (&H8)
Private Const PROCESS_VM_WRITE As Long = (&H20)
Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const PROCESS_ALL_ACCESS As Long = _
(STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION Or &HFFF)
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * 260
End Type
Private Type Luid
lowpart As Long
highpart As Long
End Type
Private Type LUID_AND_ATTRIBUTES
pLuid As Luid
Attributes As Long
End Type
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
End Type
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) 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 WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject 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
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef 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 OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As Luid) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As Any, ReturnLength As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" (ByVal lFlags As Long, lProcessID As Long) As Long
Private Declare Function ProcessFirst Lib "kernel32.dll" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32.dll" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Public Function InjectByPID(ByVal sDllPath As String, ByVal lProcessID As Long) As Boolean
Dim lProc As Long
Dim lLibAdd As Long
Dim lMem As Long
Dim lRet As Long
Dim lThread As Long
On Local Error GoTo InjectByPID_Error
'//Adjust token privileges to open system processes
Call AdjustPrivileges(GetCurrentProcess)
'// Open the process with all access
lProc = OpenProcess(PROCESS_ALL_ACCESS, False, lProcessID)
If lProc = 0 Then GoTo InjectByPID_Error
'// Get the address of LoadLibrary
lLibAdd = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA")
If lLibAdd = 0 Then GoTo InjectByPID_Error
'// Allocate memory to hold the path to the Dll File in the process's memory
lMem = VirtualAllocEx(lProc, 0, Len(sDllPath), MEM_COMMIT, PAGE_READWRITE)
If lMem = 0 Then GoTo InjectByPID_Error
'// Write the path to the Dll File in the location just created
Call WriteProcessMemory(lProc, ByVal lMem, ByVal sDllPath, Len(sDllPath), lRet)
If lRet = 0 Then GoTo InjectByPID_Error
'// Create a remote thread that starts begins at the LoadLibrary function and _
is passed are memory pointer
lThread = CreateRemoteThread(lProc, ByVal 0, 0, ByVal lLibAdd, ByVal lMem, 0, 0&)
If lThread = 0 Then GoTo InjectByPID_Error
'// Wait for the thread to finish
Call WaitForSingleObject(lThread, INFINITE)
'// Free the memory created on the other process
Call VirtualFreeEx(lProc, lMem, Len(sDllPath), MEM_RELEASE)
'//Release the handle to the other process
Call CloseHandle(lProc)
InjectByPID = True
On Error GoTo 0
Exit Function
InjectByPID_Error:
'// Free the memory created on the other process
Call VirtualFreeEx(lProc, lMem, Len(sDllPath), MEM_RELEASE)
'//Release the handle to the other process
Call CloseHandle(lProc)
End Function
Public Function AdjustPrivileges(ByVal lProcessID As Long) As Boolean
Dim lToken As Long
Dim tTOKEN_PRIVILEGES As TOKEN_PRIVILEGES
On Local Error GoTo AdjustPrivileges_Error
If Not OpenProcessToken(lProcessID, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, lToken) = 0 Then
With tTOKEN_PRIVILEGES
If LookupPrivilegeValue(vbNullString, SE_DEBUG_NAME, .Privileges(0).pLuid) = 0 Then
Exit Function
End If
.PrivilegeCount = 1
.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
End With
If Not AdjustTokenPrivileges(lToken, 0, tTOKEN_PRIVILEGES, Len(tTOKEN_PRIVILEGES), 0&, 0&) = 0 Then
AdjustPrivileges = True
End If
End If
On Error GoTo 0
Exit Function
AdjustPrivileges_Error:
End Function
'Get PID
Public Function whereISmyFUFUprocess(ByVal ProcessName As String) As Long
Dim procSnapshot As Long
Dim uProcess As PROCESSENTRY32
Dim success As Long
Dim ProcessId As Long
Dim ProcessId_found As Boolean
ProcessId_found = False
procSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
If procSnapshot = -1 Then Exit Function
uProcess.dwSize = Len(uProcess)
success = ProcessFirst(procSnapshot, uProcess)
If success = 1 Then
Do
If LCase(VBA.Left$(uProcess.szexeFile, InStr(1, uProcess.szexeFile, Chr(0)) - 1)) = LCase(ProcessName) Then
ProcessId = uProcess.th32ProcessID
Debug.Print "First process found with PID: " & ProcessId
If ProcessId_found = True Then
Debug.Print "Second process found with PID: " & ProcessId
whereISmyFUFUprocess = ProcessId
Exit Do
End If
ProcessId_found = True
End If
Loop While ProcessNext(procSnapshot, uProcess)
End If
If whereISmyFUFUprocess = 0 Then
whereISmyFUFUprocess = ProcessId
End If
Call CloseHandle(procSnapshot)
End Function
表单1
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Sub Command1_Click()
Dim PID As Long
' // Run Notepad
Shell "notepad.exe", vbNormalFocus
Sleep 1000
PID = whereISmyFUFUprocess("notepad.exe")
Sleep 1000
InjectByPID "Project1.dll", PID
End Sub
答案 0 :(得分:0)
检查您是否正在获取进程ID。
如果我没记错的话(我之前已经尝试过这种方法),你就无法从只使用API的32位进程中获取64位进程列表。所以你的VB6应用程序只能看到32位进程。您需要(另一个)64位帮助程序来为您提供64位和32位进程ID的列表,然后您就可以使用它们了。
编辑#1: CreateToolhelp32Snapshot()
的文档提及:
如果指定的进程是64位进程且调用者是a 32位进程,此函数失败,最后一个错误代码是 ERROR_PARTIAL_COPY(299)。
更正:无关紧要,因为您在没有指定进程的情况下调用CreateToolhelp32Snapshot()
以包含在快照中(即第二个参数为null)
通过获取64位记事本过程的PID并手动输入,您仍然可以在调试时检查程序的注入部分是否正常工作。直接到InjectByPID()。
编辑#2:您可能会通过WMI获得包含64位进程的进程列表。请参阅this Super User question。
CORRECTION: CreateToolhelp32Snapshot()
列出了64位和32位进程。我可能与EnumProcesses()
混淆了。
答案 1 :(得分:0)
行。这可能不是一个完整/直接的答案,因为它只提供解决问题的方向;另外,我不熟悉amd64汇编代码,所以我无法帮助你。
根据this article,CreateRemoteThread()
处理64位进程需要从另一个64位进程调用(注意:这个答案是基于那个我没有测试过的假设。
知道这一点,你有三(3)个选择:
使用x64代理代表x86 / VB6注入器调用CreateRemoteThread()
。其他一切都是在VB6中完成的,包括注入引导代码。
CreateRemoteThread()
,包含引导代码的进程句柄和入口点地址; (6)引导代码获取" kernel32.dll",proc的模块地址。地址LoadLibraryW()
并从提供的路径加载DLL;远程线程从那里继续; (7)同时,x64代理返回CreateRemoteThread()
调用的x86注入结果。好吧,如果我们为注入添加x64代理的依赖关系,为什么不让它执行整个DLL加载而不是一些引导代码。然后,x64代理也负责(至少)解析LoadLibraryW()
的地址,并调用LoadLibraryW()
将DLL加载到目标进程中。
最简单的路径是让x86注入器找到目标的进程ID,当目标进程是64位时,传递该进程ID&注入的DLL到x64代理的路径,所以它会进行注入。
CreateRemoteThread()
调用CreateRemoteThread()
以及指向我们注入远程进程的DLL路径的地址;远程线程从那里继续; GetModuleHandle()
调用之后(4)(或者如果某些内容失败之前),x64代理会将调用结果或遇到的任何错误返回给x86注入器。利用天堂之门(概念here;使用here的例子)从x86,VB6构建的注入器中运行amd64代码。
LoadLibraryW()
,CreateRemoteThread()
和LdrLoadDll()
( easy part ...); RtlEqualUnicodeString()
ntdll.dll [[]通过挂钩和修补{{1}}的ntdll.dll来加载kernel32.dll的amd64版本,这样我们就可以加载了" KERNEL32.DLL"第二次但是在另一个地址,*或*通过释放加载的32位kernel32.dll并在我们运行amd64代码]的情况下将其替换为64位 ,切换到64位模式,然后清理并撤消所有内容以安全返回到x86模式。希望在阅读完之后你应该知道下一步该尝试什么。