2016-04-11 13 views
0

Ich habe versucht, dieses Problem seit mindestens einem Tag herauszufinden, alle Variablentypen recherchierend, sie umwandernd, 24 andere Beispiele ansehend, die ich online fand (sogar eine von ihnen, die auf JNA zur Verfügung gestellt wurde) github für Kernel32). Ich versuche, die VirtualAllocEx-Funktion in Java mithilfe von JNA abzubilden. Ich habe eine allgemeine Idee auf, wie dies zu tun, und das ist meine Klasse ist so weit:VirtualAllocEx-Funktion in Java JNA-Mapping

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 können Sie die Druckzeilen (Debug-Informationen für mich) ignorieren und alle zufällig nicht verwendete oder unnötige Variablen, die ich die Schaffung bin . Also meine erste Frage: Konstruiere ich meine Kernel32-Schnittstelle richtig? (Es funktioniert ganz gut, aber; ich habe viele andere Beispiele gesehen, erweitern einfach andere Bibliotheken und so ...). Zweite Frage: Der Grund, warum ich dies poste ... Ich kann VirtualAllocEx nicht zur Arbeit bringen. Ich habe die Methodendefinition von MSDN nachgeschlagen und die Typen selbst konvertiert und 23 andere Beispiele betrachtet, die ich online gefunden habe: Example directly from JNA repo [Links gelöscht].

Wie Sie sehen Ich habe auch ein paar andere Funktion Header kommentiert heraus, dass ich versucht habe (hatte ich viel mehr, aber ich löschte die anderen, die ich versucht habe, zu kartieren, um ein wenig aufzuräumen.)

Im Grunde, was ich hier erreichen will, ist print all running process (funktioniert gut ...), dann schnappen Sie sich die pid für Firefox (als Test ...) [ich hardcodiere die pid sofort] und öffnen Sie den Prozess , dann injiziere cmd.exe in (oder einen anderen verwandten Shellcode), um diesen Code auszuführen. (Ich habe auch Code, der das CreateRemoteThread tut und sollte zum Erstellen der cmd.exe funktionieren.) Aber für die Zwecke dieses Beispiels habe ich es kurz gehalten, weil das VirtualAllocEx nicht funktioniert ... (Muss ich sogar Alloc Speicher innerhalb des laufenden Prozesses, um es zur Arbeit zu bringen?).

Auch etwas zu diesem Beispiel zu beachten: Es ist wirklich spät in der Nacht und ich weiß, dass ich noch einige fehlerhafte Logik innerhalb des Programms habe (wie die Elemente, die ich an WriteProcessMemory bekomme ich eine 487 für "Versuch, auf ungültige Adresse zuzugreifen . "aber das liegt daran, dass ich VirtualAllocEx nicht dazu bringen kann, mir eine Adresse zurückzugeben, die ich dort eintragen konnte.

Ich bin offen für irgendwelche Vorschläge an dieser Stelle, wie man weiter vorgeht Links, die ich vielleicht noch nicht besucht habe, um mir ein besseres Verständnis dafür zu geben, was ich falsch mache.

Edit: vergessen zu erwähnen, die Ausgabe des Programms:

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

Das ist was es ausgibt. Fehlercode 87 für den Funktionsaufruf VirtualAllocEx, weil ich es nicht richtig verstanden habe, dann 487 nach Schreibaufruf, weil ich noch keine gültige Adresse von VirtualAllocEx habe. Vielen Dank!

+0

Versuchen Sie zuerst den gleichen Code in C, um zu sehen, ob das funktioniert. – Voo

+0

@Voo Es tat, aber aus irgendeinem Grund wird VirtualAllocEx immer noch nicht zuordnen. – user2494817

+0

Das Problem kann sein, dass Sie den Rückgabetyp von 'VirtualAllocEx' zu 'int' deklariert haben, was 32 Bit ist, wohingegen der tatsächliche Rückgabetyp (unter der Annahme einer 64-Bit-JRE) ein 64-Bit-Zeiger ist. –

Antwort

4

Wahrscheinlich die Antwort: Sie sind nicht berechtigt, in diesen Speicher zu schreiben, also müssen Sie die Rechte irgendwie erhöhen. Hast du das als Admin ausgeführt?

Zum Erweitern einer Bibliothek vs. Schreiben von eigenen von Grund auf, ist nicht wirklich wichtig, aber beziehen Sie sich darauf, wie JNA Bibliothek Initialisierung für W32-API-Bibliotheken durchführt (Nämlich mit StdCallLibrary und Initialisierung mit W32APIOptions.DEFAULT_OPTIONS).

EDIT

Sie auch Native.getLastError() statt GetLastError() nennen sollte; normalerweise wird JNA das für Sie tun, aber es gibt einen neuen Bug, bei dem das Abfangen unter bestimmten Umständen fehlschlägt. Sehen Sie nach, ob nach dieser Änderung ein anderer Fehler auftritt.

EDIT

VirtualAllocEx sollte eine Pointer, kein int zurückkehren. Das wird wahrscheinlich nicht den Fehlercode 87 (INVALID_PARAMETER) beeinflussen.

EDIT

Ihre PAGE_EXECUTE_READWRITE hat einen Wert von Null, wo es 0x40 sein sollte.

+0

Ich führe dieses Programm als Administrator aus und führe Firefox mit einem privilegierten Benutzerkonto aus. Außerdem weiß ich, wie es die Bibliotheksinitialisierung durchführt, und es gibt einen Grund, warum ich es W32APIOptions.UNICODE_Options übergebe. [Beantwortet auch nicht die Fehler 87 Frage der falschen Parameter]. Danke für die Antwort tho! – user2494817

+0

nach dem Bearbeiten: Nope hat den gleichen Fehlercode von 87 mit Native.getLastError() – user2494817

+1

Wahrscheinlich keine Berechtigungen, es sei denn, es ist ein Systemprozess oder ein Prozess, der zu einem anderen Benutzer gehört. Außerdem würde ein Berechtigungsproblem dazu führen, dass OpenProcess fehlschlägt, nicht VirtualAllocEx. –