trustme Posted November 25, 2007 Share Posted November 25, 2007 Heres some background for as to what I want to do, I originally posted this on the sun forums, but they told me Java wouldn't do it. If I have a class (main) thats making an instance of my class, and I pass information to that class in the form of an array, is there any way to search through the computers memory to find my values? Say another class passed in the same data, with values within a reasonable distance of my own. So if I feed in through the class: Positions {99, 55, 66, 77} and the other class fed in similar data, say Positions (76, 48, 68, 24}, can I find out the values based on their proximity in memory to my values? I'm assuming that when the main class asks for my data, it will create a block of memory that stores my values, and immediately afterwards or soon afterwards would create a second block of memory with the other values. So say I knew that the data being input would be between 1 and 100, could I search for 4 values +-50 memory positions (of the memory positions that matched my input) that are all within a certain tolerance (1-100)? Apparently Java won't do this (or at least those on the Sun forum said it wouldn't) and I had a feeling it wouldn't work anyway. So my extension of that idea is to have a program be called from my java program which then searches through the memory after which I read in that programs output from a text file. Framework(Main Java class) -> My class -> Search proggie -> Text file -> My class I've searched the nets and can't find a program in another language that I can modify to do this (I only know Java and hava a friend who knows C++) My friend who knows C++ tried, but we ran into two problems, he doesn't know how to set the memory address pointer to the first memory address, and we get some weird crash error from windows. Any suggestions? I'll post the code as soon as i can, prolly monday. Quote Link to comment Share on other sites More sharing options...
Sparda Posted November 25, 2007 Share Posted November 25, 2007 That 'won't' be possible in Java due to it's VM'ness (a VM escape vulnarability would get around this however). If you plan on doing this in windows (or Linux for that matter) you would (most likly) need a kernel module (a system driver for windows users) that allows you access memory directly. kernel modules tend to be writen in C. If you did use a Java VM escape, this would not detract from the need of the kernel module. Quote Link to comment Share on other sites More sharing options...
trustme Posted November 25, 2007 Author Share Posted November 25, 2007 OK, well assuming I wanted to do it in C++, why would I need a kernel module? What we found we could do was to create a new variable, then increment and decrement the pointer value, printing out what was stored in memory at each point. I'm surprised C++ doesn't have some defined starting point where the memory is able to be read. If we have to we could just run through it incrementing and decrementing each time until we started hitting the values that I input into an array. I'd rather start at the beginning and just increment through though. Or is there some limitation related to the error we were getting or something like that? I don't really have that deep an understanding of the memory and what limitations there are on accessing it. Quote Link to comment Share on other sites More sharing options...
Sparda Posted November 25, 2007 Share Posted November 25, 2007 OK, well assuming I wanted to do it in C++, why would I need a kernel module? What we found we could do was to create a new variable, then increment and decrement the pointer value, printing out what was stored in memory at each point. I'm surprised C++ doesn't have some defined starting point where the memory is able to be read. That would only be the VM's memory, with out a VM escape of some nature you would never be able to read memory out side of Java (or perhaps the current program). Quote Link to comment Share on other sites More sharing options...
trustme Posted November 25, 2007 Author Share Posted November 25, 2007 For some reason I thought C++ wasn't in a VM (this is for windows btw). Or is C++ not going to be able to read the memory thats inside the java vm? Doesn't it all have to go to the ram at some point? Quote Link to comment Share on other sites More sharing options...
cooper Posted November 25, 2007 Share Posted November 25, 2007 Doesn't it all have to go to the ram at some point? It does. Your previous respondents have been thinking too much from inside the box. Java is run from within a VM, and your program only has access to that VM. There are ways to venture off into the host OS with stuff like JINI or Jacob, but you'd need signed binaries and a whole host of configuration issues that need to be dealt with. Simply put, you can, but it's difficult, and designed to be so. So if you want to do this, you'd need something like C/C++ or an even lower-level language. But I wonder why you'd want to write this yourself... You can just get one of those Windows debuggers. Try Microsoft's own for starters, as it appears to be free. Alternatively WinICE/SoftICE Pro used to be the shit, but googling for it now yields precious little information. Good luck. Quote Link to comment Share on other sites More sharing options...
trustme Posted November 25, 2007 Author Share Posted November 25, 2007 Doesn't it all have to go to the ram at some point? It does. Your previous respondents have been thinking too much from inside the box. Java is run from within a VM, and your program only has access to that VM. There are ways to venture off into the host OS with stuff like JINI or Jacob, but you'd need signed binaries and a whole host of configuration issues that need to be dealt with. Simply put, you can, but it's difficult, and designed to be so. Figures.... I'll go with another program then So if you want to do this, you'd need something like C/C++ or an even lower-level language. But I wonder why you'd want to write this yourself... You can just get one of those Windows debuggers. Try Microsoft's own for starters, as it appears to be free. Alternatively WinICE/SoftICE Pro used to be the shit, but googling for it now yields precious little information. Good luck. In short: What I want to do this for is to demonstrate how data stored in private classes and the like can be read without breaking encapsulation by an instanced object of the main class without being specifically passed the information. In Long: My AP Comp Sci teacher gave us a bonus assignment (make a battleship AI that plugs into a framework) and said that it was impossible to cheat when he gave it to us, even after I asked about reading stuff out of the memory. (For those who will cry about me cheating, I will write my own AI, he's not that stupid.) The without breaking encapsulation is because I don't know how to properly do reflection and introspection, its prolly over my head, (the page about it http://java.sun.com/docs/books/tutorial/reflect/index.html even says not to use it unless you know whats going on), and I'm not sure if its even possible to do it with the way the framework is set up. Quote Link to comment Share on other sites More sharing options...
trustme Posted November 25, 2007 Author Share Posted November 25, 2007 Would the following work to set a pointer address to zero? int *pnPtr = NULL; Or this? int *pnPtr = 0; or do i need to use a void as my type? OR Can I do this in VB, tons of people seem to have some understanding of it around here? Quote Link to comment Share on other sites More sharing options...
cooper Posted November 25, 2007 Share Posted November 25, 2007 I don't know how to properly do reflection and introspection, its prolly over my head, (the page about it even says not to use it unless you know whats going on), and I'm not sure if its even possible to do it with the way the framework is set up. Dude, for real, go with Reflection. They've scare-mongered you into thinking alternative ways are easier, when in fact they're not. Reflection basically means that if you can get your hands on an object reference, you can pretty much take it apart in ways you weren't specifically intended to. Start out by examining the Class class. You can get at fields of an object by doing Object.getClass().getDeclaredField(name).get<fieldtype>(Object); That was easy wasn't it? Well, that's reflection for ya. You basically take an object instance, dig through the underlying class structure (fields, methods, that sort of stuff) and once you found the little gold nugget you were looking for, you access it. The setAccessible(true) method of each AccessibleObject is your friend. It can be countered by using a SecurityManager, but I've mostly only encountered those when writing Applets. Quote Link to comment Share on other sites More sharing options...
cooper Posted November 25, 2007 Share Posted November 25, 2007 Would the following work to set a pointer address to zero? Both will work. The first is the cleaner way. or do i need to use a void as my type? Void is better when you don't know what you're digging into. Making it int basically means you'll be accessing the memory in units of sizeof(int). If alignment is off, you're screwed. The char type seems more appropriate, but it's your call. Can I do this in VB, tons of people seem to have some understanding of it around here? Yech! Quote Link to comment Share on other sites More sharing options...
trustme Posted November 26, 2007 Author Share Posted November 26, 2007 If i was to use reflection, can I call directly from their class? Say I have AI1, which has the methods for one AI. Can I call AI2s placeShips method? The interface says that placeships must be in the following format: public ArrayList placeShips() { ArrayList placeShips = new ArrayList(); placeShips.add(new Location(0, 0)); placeShips.add(new Direction("East")); - Snip - return placeShips; } I want to retrieve the ArrayList placeShips. So can I call it from that class? Would it be AI2.getClass().getDeclaredField(placeShips).getArrayList(Object); Or? ArrayList enemy = new ArrayList(); enemy = Object.getClass(AISEJ).getDeclaredFields(placeShips).getArrayList(); Jbuilder won't shut up/ make/ compile, what am I doing wrong? Should I be calling getMethods instead? Or does it not matter since they made a field of Arraylists inside the method named the exact same thing? Quote Link to comment Share on other sites More sharing options...
trustme Posted November 26, 2007 Author Share Posted November 26, 2007 I'm still not sure on the code to use, but I just realized you can't do it that way if a player decided to randomly generate their ship placement... (wow, how did i miss that) So inside one of the classes spawned by main is the following code, I've stripped out superfluous stuff like some of the error handling. public boolean placeShipsOnGrid(Player p) { System.out.println("Inside place ships = "); outputGrid(p.grid); //ships is the ArrayList of Locations and Directions ArrayList ships = null; //get the ships from player //handle any exceptions they might create outFile("--------------------------------n"); outFile("Placing " + p.getName() + " shipsn"); outFile("--------------------------------n"); try { ships = p.placeShipsWrapper(); } catch (Exception e) { outFile("EXCEPTIONnn"); outFile(e.toString()); return false; //indicate failure in place ships } //Place player's ships for (int i = 0, j = 0 /*the ship*/; i < 10; i += 2, j++) { //get the Location Location l = (Location) ships.get(i); //get the directioi Direction d = (Direction) ships.get(i + 1); outFile("pppppppppppppppppppppppppppppppppppppppppppppn"); outFile("Ship " + j); outFile(l + " DIR " + d + "n"); //loop through the ArrayList for (int k = 0 /*k = ship placing*/, x = l.col(), y = l.row(); k < Globals.sizes[j]; k++) { Location newSpot = new Location(y, x); //place the ship p.grid[y][x] = Globals.SHIPCODES[j]; //SHIPCODES 5 CAR, etc //Are we heading East /*if (d.toString().equals(d.EAST.toString())) { x++; } else { y++; }*/ switch (d.inDegrees()) { case 0: y--; break; case 90: //East x++; break; case 180: //South y++; break; case 270: //West x--; break; } //switch } // for loop for for this ship } //System.out.println("Done placing ships, HERE is the Placement_____"); //outputGrid(p.grid); return true; } Ships seems to be the arraylist containing the input from the placeships method in the players AI. But I'm pretty sure ships will die after this method is called, so I need to try and read stuff in from grid. Grid hangs around, so i would need to get p2 and p1.grid, correct? Quote Link to comment Share on other sites More sharing options...
cooper Posted November 26, 2007 Share Posted November 26, 2007 Can't you just put the full source up someplace so I can take a decent look? Quote Link to comment Share on other sites More sharing options...
trustme Posted November 26, 2007 Author Share Posted November 26, 2007 Yeah sorry about that, at the sun forums I had given a link, forgot I hadn't here. Personally I think the source is a bit messy, but I think my teacher actually had to rewrite part of someone else's stuff, which is commented out. http://www.shenet.org/high/hsacaddept/tech...h%202%20ais.exe The code is set up as a self extracting archive. It includes two AIs, but when I tried to run it, for some reason it couldn't find them. I decompiled the class files. Heres one, I called it AIBIM, just duplicate it if the system requires a second one and the included class files don't work. import java.awt.Image; import java.util.ArrayList; import java.util.Random; import java.lang.reflect.Array; import java.lang.reflect.Field; public class AIBIM implements Bai2 { public ArrayList placeShips() { ArrayList placeShips = new ArrayList(); placeShips.add(new Location(0, 0)); placeShips.add(new Direction("East")); placeShips.add(new Location(0, 6)); placeShips.add(new Direction("east")); placeShips.add(new Location(2, 9)); placeShips.add(new Direction("South")); placeShips.add(new Location(6, 9)); placeShips.add(new Direction("South")); placeShips.add(new Location(5, 4)); placeShips.add(new Direction("South")); return placeShips; } public Location guess() { if(x == 10) { x = 0; y++; } if(x == 11) { x = 0; y++; } if(y == 10) { y = 0; x = 1; } Location guess = new Location(y, x); x++; int xCounter = x; int yCounter = y; guessed.add(guess); Field f = null; try { f = System.class.getField("myShips"); } catch (SecurityException ex) { } catch (NoSuchFieldException ex) { } Class c = f.getDeclaringClass(); System.out.println(c); // ArrayList enemy = new ArrayList(); return guess; } public boolean didIGuess(Location guess) { int i = 0; if(i < guessed.size()) return guessed.get(i).equals(guess); else return true; } public void didIHit(boolean flag, boolean sunk, int size) { didIHit = flag; didISink = sunk; } public void enemyGuess(Location loc) { Location enemyGuess = new Location(0, 0); enemyGuess = loc; } public Image represent() { return null; } public void who(String s) { } public AIBIM() { r = new Random(); hitStatus = new int[10][10]; shipPresent = new boolean[10][10]; hasGuessed = new boolean[10][10]; hasHit = new boolean[10][10]; lastHit = false; lastSunk = false; lastDir = true; dir = true; lastHitLoc = null; x = 0; y = 0; nextGuess = new Location(0, 0); guessed = new ArrayList(); } Random r; int hitStatus[][]; final int lengths[] = { 5, 4, 3, 3, 2 }; boolean shipPresent[][]; boolean hasGuessed[][]; boolean hasHit[][]; boolean lastHit; boolean lastSunk; boolean lastDir; boolean dir; Location lastHitLoc; Location lastLoc; int x; int y; Location nextGuess; ArrayList guessed; boolean didIHit; boolean didISink; } Quote Link to comment Share on other sites More sharing options...
trustme Posted November 28, 2007 Author Share Posted November 28, 2007 Any luck? Quote Link to comment Share on other sites More sharing options...
cooper Posted November 30, 2007 Share Posted November 30, 2007 Okay, I did some serious digging, and the answer is that not only can it be done, it's not really that hard except for the last bit. Now, assuming you're using a 1.5 or up JVM, what you do: First, make sure your AI class has a private member to which you assign a good random number. Next, run the jps.exe program and read its output. It will tell you the process IDs of the active JVMs, and which programs those JVMs are running. Now that you know your process id run the jmap.exe program against this process to get a heap dumpfile. And finally, spawn a new thread, and from there, run the jhat.exe program, feeding it the dumpfile. It will read the file, and start an HTTP server on a port of your choosing via which you can access _EVERYTHING_ about that JVM. Just click through there manually at first to see where you need to go. The memory address (which is part of the URL) you need to dig up someplace, but other than that you should be golden. You need to check the Player's obj property to see if the player you're looking at is either you or your opponent. Test both, as you might've just made a dumpfile of another game running alongside yours. The hard part really is navigating the webserver. It would be easier if you could easily dig into the heap dumpfile, but I haven't found any decent description of the file format just yet. Quote Link to comment Share on other sites More sharing options...
trustme Posted December 1, 2007 Author Share Posted December 1, 2007 I knew reflection would be too simple. Thanks a lot, I'll start working on getting it all together. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.