memory address search

I'm wondering whether it's possible to somehow search for a specific object instance by checking every possible (used, if that's checkable) memory address. The object wouldn't be accessible otherwise but this way (or it's stored in some unknown instance or class). Would some Unsafe magic work for that?
16 Replies
JavaBot
JavaBot5mo ago
This post has been reserved for your question.
Hey @ShadowOfHeaven! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Peter Rader
Peter Rader5mo ago
I am pretty sure that you can not do this in plain java. A object that wouldn't be accessible by normal java logic is an Object that usually is garbage-collected and about to be removed. Thats why I think that even JNI will not help here.
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
What if I'm sure that this object isn't garbage-collected For example because it's handling incoming connections Wouldn't that prevent it from being garbage-collected as it's method's bytecode is used? Or if you just once started a new thread And it always does something but the reference to it is lost Wouldn't it still be stored as an object in memory somewhere?
Peter Rader
Peter Rader5mo ago
A object without references is garbage-collected. Every thread (even virtual Threads) are in a Threadgroup, that's a fact and you can not do anything about it. All threadgroups have a root-threadgroup, thats also a fact. That means starting with public static void main you will have a root Threadgroup and every single Thread is referenced to this Root-Threadgroup. That means no thread s able to have the reference lost to the Root-Threadgroup. TLDR; That means no running thread is garbage-collected! See the code of Thread:
@SuppressWarnings("removal")
private Thread(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}

this.name = name;

Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */

/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}

/* If the security manager doesn't have a strong opinion
on the matter, use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}

/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
@SuppressWarnings("removal")
private Thread(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}

this.name = name;

Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */

/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}

/* If the security manager doesn't have a strong opinion
on the matter, use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}

/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
If there is g == null g is set to the parent's threadgroup. If g remains null it will throw a nullpointerexception (NPE) in the code g.checkAccess();. Lets think out of the box for a moment. The JDK sources are opensource. So you could modify and compile the java-code of the class java.lang.Object. You could try to add a WeakReferenceList to every instance of Object-pendend superclasses as a static variable in the class java.lang.Object. This way you MIGHT be able to collect every Object in a list of WeakReference. Unfortunaltey, since WeakReference depend of Object, every WeakReference will generate a WeakReference, and the WeakReference of a WeakReference will create a WeakReference. You will run in to a memory-deadlock. @dan1st | Daniel correct me if I am wrong.
dan1st
dan1st5mo ago
I'd say that running threads are GC roots and therefore not GCed
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
So I COULD perform a search by like Unsafe#getObject(long address) and check every address to get for example a thread? That makes me wonder If I were to replace that memory address with another object Could I somehow update the thread-cached values And therefore completly override any object I want? Even if it's not stored anywhere as a variable
Peter Rader
Peter Rader5mo ago
Oh, I did not know there is a class Unsafe. I do not know about that.
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
It does wonders for fast modifying of basically anything I just don't know about this
dan1st
dan1st5mo ago
what? you cannot rely on objects being stored at a specific address, objects may be moved at any time It is a JDK internal class giving you somewhat low level access to more or less raw memory. The memory access methods are deprecated for removal in favor of the Foreign Function and Memory API and VarHandles
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
So it isn't likely that I can find any object by searching through all addresses? It's deprecated since java 23 But I honestly don't see the reason behind that
dan1st
dan1st5mo ago
ig it would probably work
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
Unsafe can offer better performance to VarHandles
dan1st
dan1st5mo ago
depends how you are using it
ShadowOfHeaven
ShadowOfHeavenOP5mo ago
And even if that's not the main concern or the difference isn't significant VarHandles' main features were added in java 9 So they pretty much are saying "more work if you wanna support all java versions"
dan1st
dan1st5mo ago
Well Unsafe stuff is probably gonna get removed at some point
JavaBot
JavaBot5mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server