Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNA映射中的VirtualAllocEx函数_Java_C++_Windows_Native_Jna - Fatal编程技术网

Java JNA映射中的VirtualAllocEx函数

Java JNA映射中的VirtualAllocEx函数,java,c++,windows,native,jna,Java,C++,Windows,Native,Jna,至少一天来,我一直在努力解决这个问题,研究所有转换它们的变量类型,查看在线找到的24个其他示例(甚至其中一个示例是在JNA github for Kernel32上提供的)。我试图使用JNA在java中映射VirtualAllocEx函数。我对如何做到这一点有一个大致的想法,到目前为止,这是我的课程: import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import ja

至少一天来,我一直在努力解决这个问题,研究所有转换它们的变量类型,查看在线找到的24个其他示例(甚至其中一个示例是在JNA github for Kernel32上提供的)。我试图使用JNA在java中映射VirtualAllocEx函数。我对如何做到这一点有一个大致的想法,到目前为止,这是我的课程:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.WinDef;
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.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public class HelloWorld 
{

    public interface Kernel32 extends StdCallLibrary 
    {
        public static final Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.UNICODE_OPTIONS);


        public static final int PROCESS_CREATE_THREAD = 0x0002;
        public static final int PAGE_EXECUTE_READWRITE = 0;
        public static int PROCESS_QUERY_INFORMATION = 0x0400;
        public static int PROCESS_VM_OPERATION = 0x0008;
        public static int PROCESS_VM_WRITE = 0x0020;
        public static int PROCESS_VM_READ = 0x0010;
        public static int PAGE_READWRITE = 0x04;
        public static int MEM_RESERVE = 0x2000;
        public static int MEM_COMMIT = 0x1000;

        //public Pointer VirtualAllocEx(int ProcessToAllocateRamIn, int AddresToStartAt, int DesiredSizeToAllocate, int AllocationType, int  ProtectType);
        int VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, int flAllocationType, int flProtect); 
        //public int VirtualAllocEx(HANDLE hProcess,IntByReference lpAddress,int dwSize,int flAllocationType,int flProtect);
        //public IntByReference VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, int flAllocationType, int flProtect);
        public WinNT.HANDLE CreateToolhelp32Snapshot(WinDef.DWORD var1, WinDef.DWORD var2);
        public boolean Process32First(WinNT.HANDLE var1, Tlhelp32.PROCESSENTRY32 var2);
        public boolean Process32Next(WinNT.HANDLE var1, Tlhelp32.PROCESSENTRY32 var2);
        public WinNT.HANDLE OpenProcess(int var1, boolean var2, int var3);
        public boolean CloseHandle(WinNT.HANDLE var1);
        public boolean WriteProcessMemory(WinNT.HANDLE var1, Pointer var2, Pointer var3, int var4, IntByReference var5);
        public int GetLastError();
    }

    public static void main(String[] args) throws Exception 
    {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("C:\\WINDOWS\\system32\\cmd.exe")));
        byte[] buffer = new byte[1000000];
        int read = bis.read(buffer);
        bis.close();
        byte[] nwBuff = Arrays.copyOfRange(buffer, 0, read);

        Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();  

        WinNT.HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
        try  {
            while (Kernel32.INSTANCE.Process32Next(snapshot, processEntry)) {
                System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile));
            }
        }
        finally {
            Kernel32.INSTANCE.CloseHandle(snapshot);
        }
        HANDLE process = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_VM_OPERATION|Kernel32.PROCESS_VM_WRITE|Kernel32.PROCESS_VM_READ|Kernel32.PROCESS_CREATE_THREAD|Kernel32.PROCESS_QUERY_INFORMATION, false, 3756);
        System.out.println((process != null));
        writeMemory(process, nwBuff);
    }

    public static void writeMemory(HANDLE process, byte[] data)
    {
        int size = data.length;
        Memory toWrite = new Memory(size);

        for(int i = 0; i < size; i++)
            toWrite.setByte(i, data[i]);

        System.out.println("Memory size: "+size+"\t"+toWrite.size());

        SIZE_T a = new SIZE_T();
        a.setValue(toWrite.size());
        int x = Kernel32.INSTANCE.VirtualAllocEx(process, Pointer.NULL, a, Kernel32.MEM_RESERVE|Kernel32.MEM_COMMIT, Kernel32.PAGE_EXECUTE_READWRITE);
        int c = Kernel32.INSTANCE.GetLastError();
        System.out.println(x+"\t"+c);
        Pointer pros = process.getPointer();
        Pointer buffer = toWrite.getPointer(0);
        IntByReference z = new IntByReference();
        boolean b = Kernel32.INSTANCE.WriteProcessMemory(process, pros, buffer, size, z);
        c = Kernel32.INSTANCE.GetLastError();
        System.out.println(b+"\t"+c+"\t"+z.getValue());
    }
}

这就是它的输出。after VirtualAllocEx函数调用的错误代码87,因为我无法正确获取它,然后是487 after Write调用,因为我还没有来自VirtualAllocEx的有效地址。谢谢

最可能的答案是:您没有写入该内存的权限,因此您需要以某种方式提升权限。你作为管理员运行过这个吗

至于扩展库与从头开始编写自己的库,这并不重要,但请参阅JNA如何为W32 API库执行库初始化(即,使用StdCallLibrary并使用W32 API选项进行初始化。默认值为\u选项)

编辑

您还应该调用
Native.getLastError()
,而不是
getLastError()
;通常JNA会为您这样做,但最近有一个bug,在某些情况下拦截失败。查看更改后是否出现其他错误

编辑

VirtualAllocEx应该返回一个
指针,而不是
int
。不过,这可能不会影响错误代码87(
无效的\u参数

编辑


您的
页面\u EXECUTE\u READWRITE
的值为零,应该是0x40。

最有可能的答案是:您没有写入该内存的权限,因此需要以某种方式提升权限。你作为管理员运行过这个吗

至于扩展库与从头开始编写自己的库,这并不重要,但请参阅JNA如何为W32 API库执行库初始化(即,使用StdCallLibrary并使用W32 API选项进行初始化。默认值为\u选项)

编辑

您还应该调用
Native.getLastError()
,而不是
getLastError()
;通常JNA会为您这样做,但最近有一个bug,在某些情况下拦截失败。查看更改后是否出现其他错误

编辑

VirtualAllocEx应该返回一个
指针,而不是
int
。不过,这可能不会影响错误代码87(
无效的\u参数

编辑


您的
PAGE\u EXECUTE\u READWRITE
的值为零,其中应为0x40。

首先尝试用C语言编写相同的代码,看看是否有效。@Voo确实有效,但无论出于何种原因,VirtualAllocEx仍然无法映射。问题可能是您已将
VirtualAllocEx
的返回类型声明为
int
,即32位,而(假设为64位JRE)实际的返回类型是一个64位指针。@HarryJohnston这就是我的想法,但我也尝试了指针的返回类型,它只是指针还是有一些特殊的类?请先尝试使用C中的相同代码,看看它是否有效。@Voo确实有效,但无论出于何种原因,VirtualAllocEx仍然无法映射。问题可能是您已经声明了将
VirtualAllocEx
的类型改为
int
,为32位,而(假设为64位JRE)实际的返回类型是64位指针。@HarryJohnston我是这么想的,但我也尝试了指针的返回类型,是指针还是有特殊类?不太可能是权限,除非是系统进程或属于其他用户的进程。此外,权限问题会导致OpenProcess failing,不是VirtualAllocEx。您的页面“执行”和“读写”的值为零-是的,就是这样。很好!Franciscocamilo JNA是一个开源库,用于在Java中调用windows api。用谷歌搜索链接。@Franciscocamilo while
int
可以工作(但仅在32位windows上),
Pointer
是首选的返回值。
LPVOID
只是一个指针。@technomage,所以,
Pointer
键入一个返回值,上面的代码将在32位和64位窗口中工作?不太可能是权限,除非它是系统进程或属于不同用户的进程。此外,权限问题将导致OpenProcess失败,不是VirtualAllocEx。您的页面“执行”和“读写”的值为零-是的,就是这样。很好!Franciscocamilo JNA是一个开源库,用于在Java中调用windows api。用谷歌搜索链接。@Franciscocamilo while
int
可以工作(但仅在32位windows上),首选
指针
作为返回值。
LPVOID
只是一个指针。@technomage,那么,
指针
作为返回值键入,上面的代码在32位和64位窗口中可以工作吗?
[All processes [cut out for space]]
true
Memory size: 232448 232448
0   87
false   487 0