JNA实现远程线程注入
Posted 诗水人间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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序号
* 969 LoadLibraryA
* 970 LoadLibraryExA
* 971 LoadLibraryExW
* 972 LoadLibraryW
*/
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实现远程线程注入的主要内容,如果未能解决你的问题,请参考以下文章