JNA 中 String 转 Pointer

网友投稿 1146 2022-09-14

JNA 中 String 转 Pointer

JNA 中 String 转 Pointer

最近在写JNA的过程中需要将字符串转Pointer对象,原因是jna的api要求传一个Pointer,直接的字符串则不能处理,但发现并不能通过new 得到Pointer对象。

但是通过内部的方法可以得知有一些方法似乎就是我们想要的,例如​​setString​​方法

​​com.sun.jna.Pointer​​对象是有​​setString​​方法的,但是你会发现我们没法通过new创建一个Pointer对象,也就没法直接用。

可以通过​​import com.sun.jna.Memory;​​直接在内存中申请一块空间,然后给这块内存空间放入我们的java字符串

具体代码如下:需要注意的是注意申请的内存空间长度,如果有中文长度可能不是字符数

String dllPath = "WxDemoDll.dll";// java的字符串// 字符串转PointerPointer bufferPointer = new Memory(dllPath.length() + 1); // WARNING: assumes ascii-only stringbufferPointer.setString(0, dllPath);

完整的注入dll代码

import com.sun.jna.Memory;import com.sun.jna.Pointer;import com.sun.jna.platform.win32.*;import top.yumbo.demo.util.Kernel32MissingFunctions;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 JNADllInjectDemo { private static final User32 user32 = User32.INSTANCE; private static final Kernel32 kernel32 = Kernel32.INSTANCE; private static final Kernel32MissingFunctions kernel32MissingFunctions = Kernel32MissingFunctions.INSTANCE; public static void main(String[] args) { // 注入的进程 String processName = "XMind.exe"; // dll的路径,最好是将dll路径所在目录放到环境变量Path中,这样可以用LoadLibrary名称即可加载dll String dllPath = "DemoDll.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); kernel32.WriteProcessMemory(process, virtualAllocEx, bufferPointer, dllPath.length(), null);// if () {// System.out.println("写入内存失败");// return;// } HMODULE k32module = kernel32.GetModuleHandle("Kernel32.dll"); * 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; }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何计算磁盘IOPS
下一篇:springboot web - 启动(4) tomcat(springboot starter工作原理)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~