JNA实现远程线程注入

宁可枝头抱香死,何曾吹落北风中。这篇文章主要讲述JNA实现远程线程注入相关的知识,希望能为你提供帮助。


首先准备一个dll,为了能看到效果最好是dllMain返回一个对话框或者窗口,可以很明显的看出注入是否成功。
下面的??WxDemoDll.dll?? 一个64位的dll
主界面如下,如果注入成功会在目标进程起一个线程跑这个对话框,然后在这个dll里面写代码就是代码注入。相当于自己调自己

JNA实现注入:

package top.yumbo.demo.inter.x64;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;

import static com.sun.jna.Pointer.NULL;
import static com.sun.jna.platform.win32.Tlhelp32.TH32CS_SNAPPROCESS;
import static com.sun.jna.platform.win32.WinNT.*;


public class JNADllx64InjectDemo

private static final User32 user32 = User32.INSTANCE;
private static final Kernel32 kernel32 = Kernel32.INSTANCE;

public static void main(String[] args)
//System.load("D:\\\\Jetbrains\\\\ClionProject\\\\WxDemoDll\\\\WxDemoDll\\\\x64\\\\Debug\\\\WxDemoDll.dll");
// 注入的进程
String processName = "XMind.exe"; // x64
// dll的路径,最好是将dll路径所在目录放到环境变量Path中,这样可以用LoadLibrary名称即可加载dll
String dllPath = "WxDemoDll.dll";
// 1.使用最高权限打开进程
int pid = getPidByProcessName(processName);
System.out.println(pid);
WinNT.HANDLE process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (process == null)
System.out.println("打开" + processName + "进程失败");
return;

Pointer virtualAllocEx = kernel32.VirtualAllocEx(process, NULL, new SIZE_T(dllPath.length()), MEM_COMMIT, PAGE_READWRITE);
if (virtualAllocEx == null)
System.out.println("向目标进程" + processName + "分配虚拟内存失败");
return;

// 字符串转Pointer
Pointer bufferPointer = new Memory(dllPath.length() + 1); // WARNING: assumes ascii-only string
bufferPointer.setString(0, dllPath);
boolean writeFlag = kernel32.WriteProcessMemory(process, virtualAllocEx, bufferPointer, dllPath.length(), null);
if (!writeFlag)
//为true表示写入成功,所以需要非一下表示写入失败
System.out.println("写入内存失败");
return;

HMODULE k32module = kernel32.GetModuleHandle("Kernel32.dll");
/**ordinal序号
* 969LoadLibraryA
* 970LoadLibraryExA
* 971LoadLibraryExW
* 972LoadLibraryW
*/
Pointer loadLibraryAddress = kernel32.GetProcAddress(k32module, 969);
HANDLE handle = kernel32.CreateRemoteThread(process, null, 0, loadLibraryAddress, virtualAllocEx, 0, null);
if (handle == null)
System.out.println("注入失败");
return;






/**
* 获取进程id
*
* @param processName 进程名
* @return 进程id
*/
public static int getPidByProcessName(String processName)
// 1、得到系统进程快照
WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, null);
// 2、遍历快照找到进程名为processName的进程id
Tlhelp32.PROCESSENTRY32 processentry32 = new Tlhelp32.PROCESSENTRY32();
do
if (new String(processentry32.szExeFile).contains(processName))
return processentry32.th32ProcessID.intValue();

while (kernel32.Process32Next(snapshot, processentry32));
return -1;


注入成功截图



【JNA实现远程线程注入】


    推荐阅读