【问题标题】:JNA: Missing some specifics methodsJNA:缺少一些具体的方法
【发布时间】:2016-07-21 01:21:26
【问题描述】:

我想在 Java 中(并且仅在 Java 中)创建一个 dll 注入器,用于我自己的教育用途,并在 website especialized in online game 中找到了一个基本示例。

作者只说是使用JNA接口制作的。

所以,我正在研究这段代码并尝试使用 NetBeans IDE 和 JNA 成功编译,但似乎我在这里拥有的 JNA 接口( 4.2.2 )没有留下一段代码上使用的所有方法和函数作者。

他们是:

  1. GetProcAddress
  2. VirtualAllocEx
  3. VirtualFreeEx

所以,如果可能的话,我在这里需要一些帮助,以尝试解决 JNA 中缺少方法的问题。

我已经修复了大部分这些错误,但仍然缺少 JNA 中的一些方法,例如我将使用 cmets 显示以下点对点。

package inject;

//////////////////// JNA-4.2.2 /////////////////////

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;
import java.io.File;

//////////////////////////////////////////////////

// Extracted from: https://github.com/warmuuh/AndroidCtx/tree/master/HotContext/src/luz/winapi

import inject.luz.winapi.constants.DwDesiredAccess;
import inject.luz.winapi.tools.Advapi32Tools;
import inject.luz.winapi.tools.Kernel32Tools;
import luz.winapi.api.exception.Kernel32Exception;

//////////////////////////////////////////////////////////////////////////////////////////////

public class Inject {

    private static int GetPid(String proc){

         int id = 0;

         Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
         Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();          

        WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
        try  {
            while (kernel32.Process32Next(snapshot, processEntry)) {   

                if (Native.toString(processEntry.szExeFile).equalsIgnoreCase(proc)) {

                    id = processEntry.th32ProcessID.intValue();

                }
             }
          }
    finally {
             kernel32.CloseHandle(snapshot);
        }

     return id;
   }

  private static String findProcessByPID(int pid){

         String name = "";

         Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
         Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();          

        WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
        try  {
            while (kernel32.Process32Next(snapshot, processEntry)) {   

                if (pid == processEntry.th32ProcessID.intValue()) {

                    name = processEntry.szExeFile.toString();
                }
             }
          }
    finally {
             kernel32.CloseHandle(snapshot);
        }

     return name;
   }

   public static void inject(File dll, Integer pId) throws Kernel32Exception {

     if(null == dll || !dll.exists() || !dll.isFile() || !dll.getName().endsWith(".dll"))
            return;

    String p = findProcessByPID(pId);

    if(null == p) return;

    Kernel32 kernel  = Kernel32.INSTANCE;

    HMODULE kernel32Pointer  = kernel.GetModuleHandle("Kernel32");

                                      // Cannot find "GetProcAddress"
        Pointer loadLibraryAddress  = kernel.GetProcAddress(kernel32Pointer, "LoadLibraryA");

    HANDLE process  = null;

    DwDesiredAccess access  = new DwDesiredAccess();
        access.setPROCESS_ALL_ACCESS();

        try {
            Advapi32Tools.getInstance().enableDebugPrivilege(Kernel32Tools.getInstance().GetCurrentProcess());
        } catch (Exception e) {
        }

                            // Incompatible types "Pointer" and "HANDLE"  
        process = Kernel32Tools.getInstance().OpenProcess(access, false, pId);

        String path  = dll.getPath() + '\0';
        byte[] bytes  = path.getBytes();

        int pathLength  = bytes.length;

                                    // Cannot find "VirtualAllocEx"
        Pointer memoryDllPath  = kernel.VirtualAllocEx(process, null, pathLength, Kernel32Tools.MEM_COMMIT, Kernel32Tools.PAGE_READWRITE);

        Memory dllPathContent   = new Memory(pathLength);

        for(int i=0;i<pathLength;i++)
            dllPathContent.setByte(i, bytes[i]);

        IntByReference writeResult  = new IntByReference();

        boolean successWritting = kernel.WriteProcessMemory(process, memoryDllPath, dllPathContent, pathLength, writeResult);

        if(!successWritting) {

                kernel.CloseHandle(process);

            return;
        }

        IntByReference threadId   = new IntByReference();     

                // Pointer cannot be converted to "FOREIGN_THREAD_START_ROUTINE"
        Pointer thread   = kernel.CreateRemoteThread(process, null, 0, loadLibraryAddress, memoryDllPath, 0, threadId);

        boolean res   = false;

                        // Incompatible types "Pointer" and "HANDLE"             //Cannot find "WAIT_TIMEOUT"
            res = kernel.WaitForSingleObject(thread, Integer.MAX_VALUE) != Kernel32Tools.WAIT_TIMEOUT;

                // Cannot find "VirtualFreeEx" method                   // Cannot find "MEM_RELEASE" 
        kernel.VirtualFreeEx(process, memoryDllPath, pathLength, Kernel32Tools.MEM_RELEASE);

        kernel.CloseHandle(process);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

             System.out.println(GetPid("notepad.exe"));


  }
}

提前感谢任何建议或帮助:-)

【问题讨论】:

  • 如果您列出了缺少的或给您带来问题的方法,这可能是一个合理的问题。请明确点。期望每个人都编译您的代码以找出您的意思在 SO 上并不受欢迎。
  • @Erwin Bolwidt,我在上面编辑过。

标签: java jna


【解决方案1】:

JNA 缺少方法? It ain't so!

您只需要扩展库并添加您自己的(理想情况下,还将“缺失”的方法贡献回 JNA 库,以便其他人受益。

Here is an example 有人如何映射 GetProcAddress。

Someone has mapped VirtualAllocEx here(尽管他们应该正确扩展 Kernel32 而不是完全复制它并编辑部分)

我在找到其他的 15 秒内找不到 VirtualFreeEx 的示例......并不意味着它不存在,但在写完其他的之后,您也应该不会遇到太多麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多