简体   繁体   中英

VirtualAllocEx function in Java JNA mapping

I have been trying to figure this problem out for at least a day now, researching all the variable types converting them over, looking at 24 other examples i found online (even one of them provided on JNA github for Kernel32). I am trying to map out the VirtualAllocEx function in java using JNA. I have a general idea on how to do this and this is my class so far:

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());
    }
}

So you can ignore the print lines (debug info for me) and all the random unused or unnecessary variables that I am creating. So my first question: Am i constructing my Kernel32 interface correctly? (It works just fine, but; I have seen a lot of other examples just extend other libraries and such...). Second question: The reason why i am posting this... I can't get VirtualAllocEx to work. I looked up the method definition from MSDN and converted the types myself and looked at 23 other examples i have found online: Example directly from JNA repo [links deleted].

As you can see I have also commented out a few other function headers I have tried (I had a lot more but I deleted the others i have tried to map to in order to clean up a little bit.)

Basically what i am trying to accomplish here is print all running process (works just fine...), then grab the pid for firefox (as a test...) [i hardcode the pid right now] and open the process, then inject cmd.exe into (or other related shellcode) in order to run that code. (I also have code that will does the CreateRemoteThread and should work for spawning the cmd.exe.) But for the sakes of this example i just kept it short because the VirtualAllocEx won't work... (Do i even need to Alloc memory inside the running process to get it to work?).

Also to note something about this example: It is really late at night and I know i still have some flawed logic inside the program (like the items i pass to WriteProcessMemory i am getting a 487 for "Attempt to access invalid address." but that is because i can't get VirtualAllocEx to return me an address to put in there, so i just passed it whatever was available.

I am open to any suggestions at this point on how to proceed or any links that I may have not visited yet to give me a better understanding on what i am doing wrong.

Edit: forgot to mention the output of the program:

[All processes [cut out for space]]
true
Memory size: 232448 232448
0   87
false   487 0

That is what it outputs. Error code 87 for after VirtualAllocEx function call because i can't get it right then 487 after Write call because I don't have a valid address from VirtualAllocEx yet. Thanks!

Most likely answer: you don't have permissions to write to that memory, so you'll need to somehow elevate privileges. Have you run this as admin?

As for extending a library vs writing your own from scratch, doesn't really matter, but refer to how JNA performs library initialization for W32 API libraries (namely, using StdCallLibrary and initializing with W32APIOptions.DEFAULT_OPTIONS).

EDIT

You should also call Native.getLastError() rather than GetLastError() ; normally JNA will do that for you but there's a recent bug where that interception fails to happen in some circumstances. See if you get a different error after that change.

EDIT

VirtualAllocEx should be returning a Pointer , not an int . That's probably not going to affect the error code 87 ( INVALID_PARAMETER ), though.

EDIT

Your PAGE_EXECUTE_READWRITE has a value of zero, where it should be 0x40.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM