Mit JNI finale Variablen überschreiben

T

Tomate_Salat

Gast
Hi, ich habe gerade etwas nettes entdeckt:

Java:
public class SoundLib
{
	private final String[] tracks;
	
	static 
	{
		System.loadLibrary("sounds");		
	}
	
	public native void play(int track);	
	public native void loadTracks();
	
	public SoundLib()
	{
		tracks	= null;
	}
	
	public String[] getTrackList()
	{
		return tracks;
	}
	
	public int getTrackCount()
	{		
		return tracks == null ? -1 : tracks.length;
	}
}

und die loadMethode in c++:
Code:
JNIEXPORT void JNICALL Java_jni_SoundLib_loadTracks(JNIEnv *env, jobject obj)
{			
	jstring track1	= env->NewStringUTF("TrackA");
	jstring track2	= env->NewStringUTF("TrackB");

	jobjectArray a	= env->NewObjectArray(2,env->FindClass("java/lang/String"),env->NewStringUTF(""));

	env->SetObjectArrayElement(a,0,track1);
	env->SetObjectArrayElement(a,1,track2);

	jclass clazz	= env->GetObjectClass(obj);
	jfieldID fid	= env->GetFieldID(clazz,"tracks", "[Ljava/lang/String;");
	env->SetObjectField(obj,fid,a);
}

Ist euch schonmal aufgefallen, dass man mit JNI finale Variablen überschreiben kann. Ich nehme mal, das funktioniert, weil er einfach auf den Speicherplatz zugreift.

MFG

Tomate_Salat
 
T

Tomate_Salat

Gast
auf Methoden (java) habe ich jetzt noch nicht zugegriffen, aber das mit den privaten Attributen wusste ich. Habe es mal abgehandelt, weil die dll aus der Klasse ja auch aufgerufen wird :p
 

Marco13

Top Contributor
Jo, mit JNI geht so einiges. Bei finalen Variablen muss man aber trotzdem vorsichtig sein, weil es sein kann, dass der Compiler jedes Auftreten dieser Variablen durch ihren Wert ersetzt, sinngemäß
Code:
class A { final int value = 123; }

class B
{
    private A a = new A();

    void print()
    {
         System.out.println(a.value);
    }
}


// Main:
B b = new B();
b.print(); // Gibt 123 aus
ändereVariableMitJNI();
b.print(); // KÖNNTE immernoch 123 ausgeben...
 
T

Tomate_Salat

Gast
Nun ja, ich habe zwar erst wenig mit jni gemacht, aber bisher hielt ich es immer so: Variablen die von der DLL aus verändert werden sollen, werden in Java nur lesend angesprochen. Aber ich glaube zu wissen was du meinst. Aktuell ist mir eh nicht ganz klar wie ich z.B. von B aus die variable in der Referenz a verändern sollte, von daher bin ich auch erstmal außer Gefahr ^^
 
G

Guest2

Gast
Moin,

das geht leider nicht nur per JNI sondern auch schon mit Java Bordmitteln:

Java:
public class Foo {

    private final int bar;

    public Foo(){

        bar = 7;

    }

    @Override
    public String toString(){

        return Integer.toString(bar);

    }

}


public class Test {


    public static void main(final String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {

        final Foo foo = new Foo();

        final Field field = Foo.class.getDeclaredField("bar");
        field.setAccessible(true);
        field.setInt(foo, 42);

        System.out.println(foo);

    }

}

(wenn jemand zufällig weis, wie man sowas verhindern kann, wäre das schnuckelig! ;)
(würde gerne C-Pointer unter Java als long zwischenspeichern, aber ohne das jemand mit reinem Java den C-Pointer verbiegen kann))

Gruß,
Fancy
 
T

Tomate_Salat

Gast
Oo ich mein: ich wusste das man finale nicht als konstanten bezeichnen kann....jz ist auch definitiv klar wieso -.-. Vllt könnte man das mit dem SecurityManager unterbinden (es wirft ja eine securityexception)

Edit habs mal getestet: wird die das ganze als private definiert, findet er das Feld nicht und eine [c]NoSuchFieldException[/c]:

Java:
public class Main
{
	private final int test = 5;
	
	public static void main(String[] args)
	{
		Main main	= new Main();
		try
		{
			java.lang.reflect.Field field	= Main.class.getField("test");
			field.setAccessible(true);
			field.setInt(main, 6);
			
			System.out.println(main.test);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}	
}
 
Zuletzt bearbeitet von einem Moderator:
G

Guest2

Gast
Leider nicht ganz. ;)

Java:
private final int test = 5;

...führt dazu das der Compiler das Wegoptimiert (das ist der Punkt den Marco schon ansprach).

Java:
java.lang.reflect.Field field   = Main.class.getField("test");

...getDeclaredField("test").

Und so gehts dann leider wieder:

Java:
public class Main
{
    private final int test = Integer.parseInt("5");

    public static void main(final String[] args)
    {
        final Main main   = new Main();
        try
        {
            final java.lang.reflect.Field field   = Main.class.getDeclaredField("test");
            field.setAccessible(true);
            field.setInt(main, 6);

            System.out.println(main.test);
        }
        catch(final Exception e)
        {
            e.printStackTrace();
        }
    }
}

Gruß,
Fancy
 
G

Guest2

Gast
So geht’s dann wieder nicht mehr:

Java:
public class Main {
    private final int test = Integer.parseInt("5");


    public static void main(final String[] args) {

        System.setSecurityManager(new RMISecurityManager());

        final Main main = new Main();
        try {
            final java.lang.reflect.Field field = Main.class.getDeclaredField("test");
            field.setAccessible(true);
            field.setInt(main, 6);

            System.out.println(main.test);
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}

Also vielleicht lässt sich wirklich was mit dem SecurityManager drehen, aber ob das wirklich wasserdicht zu kriegen ist? Werd mich mal Einlesen. ;)

Thanx für den Tip! ;)

Gruß,
Fancy
 
G

Guest2

Gast
Heißt das "zB." das Du evtl. noch einen weiteren Weg wüsstest?

Wie ich inzwischen gelernt habe, bezieht sich der SecurityManager wohl immer auf die gesamte VM. Wenn ich aber jetzt eine (open source) Library (nutzt intern JNI) als signiertes JAR veröffentlichen würde (für die, die kein eigenes code sign Zertifikat haben) und würde intern den SecurityManager setzen, hätte das Seiteneffekte auf die gesamte Anwendung (z.B. Inkompatibilität mit RMI).
Wenn ich jedoch keinen SecurityManager setze, könnte jemand per Reflection meine signierte Lib nutzen, um selbst ohne signiertes JAR auf einem fremden Rechner rum zu fuhrwerken (unter meinem Namen!).

Also eigentlich suche ich etwas um sicherzustellen, dass von genau meinem JAR mindestens keine final Variabeln verändert werden können.
(Oder noch besser auf nichts, das nicht public ist, zugegriffen werden kann.)

Gruß,
Fancy

(@Tomate Salat: Sorry, hab gerade ein wenig ein schlechtes Gewissen weil das Thema etwas von Deinem Ursprungspost abweicht (auch wenns immer noch ums nicht so ganz finale final und JNI geht ;)))
 
M

maki

Gast
JNI hat so einige tücken, da war auch mal etwas mit Vererbung dass dann nicht mehr funktioniert....

Den SecurityManager kannst du nur sinnvoll in der VM Konfig setzen (gibt eine eigene Datei für), wichtig bei Servern (Tomcat zB.) die mehrere WebApps ausführt.

Ein weiterer Weg?
Denke mit OSGi, dann würden die Nutzer niemals auf die Implemenetierung der Klasse zugreifen können, nur auf ein Interface .
 
G

Guest2

Gast
Ja, OSGi währe vielleicht eine Lösung. Aber die Nische, die ich mit meiner Lib füllen will, benötig vor allem das die Lib "schlank, schnell und einfach" ist. Da will ich den Nutzer nicht unbedingt zu einem OSGi Framework drängen. ;)

Gruß,
Fancy
 
G

Guest2

Gast
Für "mein" Problem habe ich inzwischen eine Lösung gefunden:

Einfach den zu schützenden Code in ein JAR packen, in das Manifest "Trusted-Library: true" eintragen und das JAR normal signieren.

Das führt dann zu:

All trusted library jars are loaded into a separate dedicated class loader which is unique to the application or applet. The trusted library code components cannot be replaced and trusted library classes and resources are isolated from all untrusted components.

Quelle: Mixing Signed and Unsigned Code

Beim einem kurzen Versuch von einer nicht signierten Webstartanwendung, die meine signierte Lib nutzt, per Reflection auf die privaten Teile der Lib zuzugreifen, hat das auch hervorragend funktioniert.

Per JNI geht das vermutlich immer noch, aber da JNI Code nur von trusted Code aus geladen werden kann, ist das in "meinem" Fall ok.


Vielleicht hilft es ja dem einen oder anderen, dafür zu sorgen, dass seine JNI Lib nicht missbraucht werden kann. ;)

Gruß,
Fancy
 
T

Tomate_Salat

Gast
@Tomate Salat: Sorry, hab gerade ein wenig ein schlechtes Gewissen weil das Thema etwas von Deinem Ursprungspost abweicht (auch wenns immer noch ums nicht so ganz finale final und JNI geht ;))

Sehe ich jz erst^^ war in dem Post lange nicht mehr. Aber ne, ich finde das ganze recht Interessant. Vor allem weil ich gerade auch damit wieder rumspiele (mit der NON-JNI-VERSION =] ). Insofern war dein kleines OT brauchbar für mich :p
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Vererbung finale Methoden überschreiben Allgemeine Java-Themen 24
E Finale Attribute und Konstruktor Allgemeine Java-Themen 3
C Erste Schritte Variablen in abhängigkeit von Git branch Allgemeine Java-Themen 7
Fabiator Variablen Variablen Zählen Allgemeine Java-Themen 3
S Mit Methoden kann man definieren für was <T> steht. Geht das auch irgendwie für Variablen? Allgemeine Java-Themen 12
berserkerdq2 Labels in IJVM sind keine lokalen Variablen oder? Allgemeine Java-Themen 2
O Fehler bei Variablen Allgemeine Java-Themen 2
N File Path mit Variablen angeben Allgemeine Java-Themen 1
nonickatall Methoden Kann man Klassen/Methoden aus Variablen heraus aufrufen? Allgemeine Java-Themen 6
R Geometry erstellen die abhängig von Variablen ist Allgemeine Java-Themen 6
O Formatierte String ausgabe bei vier Variablen in einer Zeile Allgemeine Java-Themen 1
P static Blocks und variablen Allgemeine Java-Themen 41
S Klassen Einfügen von unbekannter menge an Variablen in eine Klasse mithilfe von ASM Allgemeine Java-Themen 5
V Datentypen Graphikrechner 2/Strings und Variablen in Doubles umwandeln Allgemeine Java-Themen 6
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
B Übernommene Variablen(werte) aus der Main-Klasse ändern? Allgemeine Java-Themen 9
D BlueJ, Variablen die mehrfach vorkommen gleichzeitig umbenennen Allgemeine Java-Themen 3
C Variablen Variablen mit unendlichem Wert Allgemeine Java-Themen 22
J Variablen Mehrere int-variablen in txt abspeichern und danach wieder auslesen Allgemeine Java-Themen 1
T Maximale Felder maximale Variablen Allgemeine Java-Themen 2
W Lebendige Variablen herauslesen Allgemeine Java-Themen 1
K Summierung einer Variablen Allgemeine Java-Themen 5
B Gibt es eine Funktion die den Datentyp einer Variablen ermittelt? Allgemeine Java-Themen 8
X Threads Externe Variablen in Run Methoden verändern Allgemeine Java-Themen 4
Messoras Klassen Sämtliche Variablen einer Klasse übernehmen Allgemeine Java-Themen 6
K Static Variablen verbieten Allgemeine Java-Themen 10
I Problem beim Aufrufen, von Objektmethoden/ -variablen Allgemeine Java-Themen 6
J Text lesen und in Variablen speichern Allgemeine Java-Themen 3
A Best Practice Variablen vertauschen - Performance Allgemeine Java-Themen 1
F Variablen Variablen schachteln Allgemeine Java-Themen 6
7 6 int variablen vergleichen Allgemeine Java-Themen 34
C Threads Variablen in einem Thread Aktualisieren Allgemeine Java-Themen 17
M Variablen Variablen in Text einbinden Allgemeine Java-Themen 5
K Überschreiben von Variablen bei rekursivem Funktionsaufruf Allgemeine Java-Themen 2
R Übergreifende Variablen? Allgemeine Java-Themen 10
OnDemand Input/Output Variablen in Datei Speichern um sie wieder auszulesen Allgemeine Java-Themen 4
D Variablen zur Laufzeit global speichern (Registry Pattern?) Allgemeine Java-Themen 6
iB0T "goto" Befehl aus Batch in Java und Variablen wert immer wieder neu setzen Allgemeine Java-Themen 4
D ClassLoader für Variablen einer Klasse setzen Allgemeine Java-Themen 24
B Methoden Alle Methoden und Variablen aus Java-Dateien auslesen. Allgemeine Java-Themen 7
D Alle Variablen final setzen ? Allgemeine Java-Themen 26
C Kapselung Warum graift man auf Variablen nur über Methoden und nich direkt zu? Allgemeine Java-Themen 10
C Classloading und statische Variablen Allgemeine Java-Themen 2
K Variablen speichern Allgemeine Java-Themen 2
S Variablen bei Aufruf zurücksetzen Allgemeine Java-Themen 4
faetzminator statische Variablen in Interface - Vererbung? Allgemeine Java-Themen 9
V Gibt es einen Variablen Cast? Allgemeine Java-Themen 8
K Mehrere JVMs die auf eine Klasse mit statischen Variablen zugreift Allgemeine Java-Themen 19
D Wann sollte ich statische Methoden und Variablen benutzen? Allgemeine Java-Themen 44
M Generische Methoden mit Java und globale Variablen Allgemeine Java-Themen 9
J Statische Variablen, Threadübergreifend. Allgemeine Java-Themen 4
E Variablen anderer Klassen auslesen (nur Name bekannt) Allgemeine Java-Themen 4
P Variablen in einer anderen Klasse auf Änderungen überwachen Allgemeine Java-Themen 12
V Typargument einer Variablen erfragen Allgemeine Java-Themen 4
B Rechnen mit mehreren Variablen Allgemeine Java-Themen 2
G Thread variablen Sichtbarkeit Allgemeine Java-Themen 15
J Java Pfad nicht mehr in Path Variablen??? Allgemeine Java-Themen 2
T JNI -> auf Java-Variablen etc zugreifen Allgemeine Java-Themen 6
M Bezeichnung für Component-Variablen Allgemeine Java-Themen 6
M Variablen an Java-Programm übergeben Allgemeine Java-Themen 3
Airwolf89 dynamischer Zugriff auf Variablen/ Objekte Allgemeine Java-Themen 4
A Überschreibung von Variablen Allgemeine Java-Themen 3
A JavaCC: Variablen zaehlen Allgemeine Java-Themen 12
B globale und lokale Variablen Allgemeine Java-Themen 17
G referenz von variablen Allgemeine Java-Themen 9
O getRuntime().Exec() - Environment - Variablen setzen? Allgemeine Java-Themen 2
S XML-Parsing / public-Member-Variablen / Design-Frage Allgemeine Java-Themen 8
M Variablen Speicher wieder freigeben ? Allgemeine Java-Themen 9
N Variablen eines Objektes (instanz) in einen Array lesen Allgemeine Java-Themen 7
S In Subklasse auf private Variablen zugreifen Allgemeine Java-Themen 4
S Variablen und ihre Tücken. Allgemeine Java-Themen 7
C Binärbereich einer Variablen abfragen Allgemeine Java-Themen 8
J Zugriff auf den Namen einer Variablen Allgemeine Java-Themen 7
J Überschreiben von Variablen Allgemeine Java-Themen 3
C dynamische variablen Namen! Allgemeine Java-Themen 4
M Int und String Variablen verändern Allgemeine Java-Themen 10
H zwei Date Variablen überschreiben sich Allgemeine Java-Themen 2
G Taushen der Input variablen einer method Allgemeine Java-Themen 14
P Objekt- Variablen Allgemeine Java-Themen 16
K Environment Variablen per java -D weitergeben Allgemeine Java-Themen 9
D in class-Dateien nach variablen suchen! Allgemeine Java-Themen 5
F Werte von Member-Variablen erst im Konstruktor setzen? Allgemeine Java-Themen 7
T Größe eine Variablen in Bytes? Allgemeine Java-Themen 22
B Reguläre ausdrücke mit variablen? Allgemeine Java-Themen 12
MQue JButton an verschiedenen Variablen Allgemeine Java-Themen 2
T Unabhängigkeit von Variablen/ Objekten. Allgemeine Java-Themen 6
G Frage zu statischen Variablen bei Vererbung Allgemeine Java-Themen 15
L Sichtbarkeit von Variablen / getMethode Allgemeine Java-Themen 4
H Variablen (A1, A2, A3 mit A_irgendetwas aufrufen) ohne Array Allgemeine Java-Themen 5
M Variablen in einer .doc Vorlage ersetzen Allgemeine Java-Themen 4
A Reflection - Variablen innerhalb einer Methode ermitteln Allgemeine Java-Themen 9
E Zugriff auf Variablen äusserer Klassen Allgemeine Java-Themen 2
M Variablen in Klasse verpacken? Allgemeine Java-Themen 10
F Allegemeiner Datentyp für Objekte und Primitive Variablen Allgemeine Java-Themen 6
W Array mit Variablen aus Vararg füllen Allgemeine Java-Themen 4
S Problem mit Boolean Variablen Allgemeine Java-Themen 8
A [SOLVED] Classpath und statische Variablen Allgemeine Java-Themen 6
J variablen wert ändernung mit einer art actionlistener? Allgemeine Java-Themen 4
C klassenübergreifende variablen Allgemeine Java-Themen 3

Ähnliche Java Themen


Oben