Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Java - Write And Read From memory Like CheatEngine ( Writing not working?)

Andre LopesJul 18 2013 — edited Sep 16 2013

Hello Oracle Forum

I came here some time ago to ask about javaFX , i solved all my issues and im right now waiting for javaFx tot ake over swing and hmm, im working on learning LIBGDX to create games in java.

However, im in need to create an app to change values of memory to fix a bug in an old program that i have, and the only way until now is using cheatEngine, So i decided to take a tutorial and learn how to do that in java.

Well, im able to read from the memory but the write isnt working somehow... Im posting the code here, if anyone can give me a hint, i would thank and a lot, because theres a community that really needs this app to automate the fix without using cheat engine.

package MainStart;

import com.br.HM.User32;

import com.br.kernel.Kernel32;

import com.sun.jna.Memory;

import com.sun.jna.Native;

import com.sun.jna.Pointer;

import com.sun.jna.ptr.IntByReference;

public class Cheater {

    static Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

    static User32 user32 = (User32) Native.loadLibrary("user32", User32.class);

    static int readRight = 0x0010;

    static int writeRight = 0x0020;

    //static int PROCESS_VM_OPERATION = 0x0008;

    public static void main(String[] args) {

        //Read Memory

        //MineSweeper = Campo Minado

        int pid = getProcessId("Campo Minado"); // get our process ID

        System.out.println("Pid = " + pid);

        Pointer readprocess = openProcess(readRight, pid); // open the process ID with read priviledges.

        Pointer writeprocess = openProcess(writeRight, pid);

        int size = 4; // we want to read 4 bytes

        int address = 0x004053C8;

        //Read Memory

        Memory read = readMemory(readprocess, address, size); // read 4 bytes of memory starting at the address 0x00AB0C62.

        System.out.println(read.getInt(0)); // print out the value!      

        //Write Memory

        int writeMemory = writeMemory(writeprocess, address, new short[0x22222222]);

        System.out.println("WriteMemory :" + writeMemory);

       

        Memory readM = readMemory(readprocess, address, size);

        System.out.println(readM.getInt(0));

    }

    public static int writeMemory(Pointer process, int address, short[] data) {

        IntByReference written = new IntByReference(0);

        Memory toWrite = new Memory(data.length);

        for (long i = 0; i < data.length; i++) {

            toWrite.setShort(0, data[new Integer(Long.toString(i))]);

        }

        boolean b = kernel32.WriteProcessMemory(process, address, toWrite, data.length, written);

        System.out.println("kernel32.WriteProcessMemory : " + b); // Retorna false

        return written.getValue();

    }

    public static Pointer openProcess(int permissions, int pid) {

        Pointer process = kernel32.OpenProcess(permissions, true, pid);

        return process;

    }

    public static int getProcessId(String window) {

        IntByReference pid = new IntByReference(0);

        user32.GetWindowThreadProcessId(user32.FindWindowA(null, window), pid);

        return pid.getValue();

    }

    public static Memory readMemory(Pointer process, int address, int bytesToRead) {

        IntByReference read = new IntByReference(0);

        Memory output = new Memory(bytesToRead);

        kernel32.ReadProcessMemory(process, address, output, bytesToRead, read);

        return output;

    }

}

package com.br.HM;

import com.sun.jna.Native;

import com.sun.jna.Pointer;

import com.sun.jna.Structure;

import com.sun.jna.platform.win32.WinDef.RECT;

import com.sun.jna.ptr.ByteByReference;

import com.sun.jna.ptr.IntByReference;

import com.sun.jna.win32.StdCallLibrary.StdCallCallback;

import com.sun.jna.win32.W32APIOptions;

/**

* Provides access to the w32 user32 library. Incomplete implementation to

* support demos.

*

* @author Todd Fast, todd.fast@sun.com

* @author twall@users.sf.net

*/

public interface User32 extends W32APIOptions {

    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, DEFAULT_OPTIONS);

    Pointer GetDC(Pointer hWnd);

    int ReleaseDC(Pointer hWnd, Pointer hDC);

    int FLASHW_STOP = 0;

    int FLASHW_CAPTION = 1;

    int FLASHW_TRAY = 2;

    int FLASHW_ALL = (FLASHW_CAPTION | FLASHW_TRAY);

    int FLASHW_TIMER = 4;

    int FLASHW_TIMERNOFG = 12;

    public static class FLASHWINFO extends Structure {

        public int cbSize;

        public Pointer hWnd;

        public int dwFlags;

        public int uCount;

        public int dwTimeout;

    }

    int IMAGE_BITMAP = 0;

    int IMAGE_ICON = 1;

    int IMAGE_CURSOR = 2;

    int IMAGE_ENHMETAFILE = 3;

    int LR_DEFAULTCOLOR = 0x0000;

    int LR_MONOCHROME = 0x0001;

    int LR_COLOR = 0x0002;

    int LR_COPYRETURNORG = 0x0004;

    int LR_COPYDELETEORG = 0x0008;

    int LR_LOADFROMFILE = 0x0010;

    int LR_LOADTRANSPARENT = 0x0020;

    int LR_DEFAULTSIZE = 0x0040;

    int LR_VGACOLOR = 0x0080;

    int LR_LOADMAP3DCOLORS = 0x1000;

    int LR_CREATEDIBSECTION = 0x2000;

    int LR_COPYFROMRESOURCE = 0x4000;

    int LR_SHARED = 0x8000;

    Pointer FindWindowA(String winClass, String title);

    int GetClassName(Pointer hWnd, byte[] lpClassName, int nMaxCount);

    public static class GUITHREADINFO extends Structure {

        public int cbSize = size();

        public int flags;

        Pointer hwndActive;

        Pointer hwndFocus;

        Pointer hwndCapture;

        Pointer hwndMenuOwner;

        Pointer hwndMoveSize;

        Pointer hwndCaret;

        RECT rcCaret;

    }

    boolean GetGUIThreadInfo(int idThread, GUITHREADINFO lpgui);

    public static class WINDOWINFO extends Structure {

        public int cbSize = size();

        public RECT rcWindow;

        public RECT rcClient;

        public int dwStyle;

        public int dwExStyle;

        public int dwWindowStatus;

        public int cxWindowBorders;

        public int cyWindowBorders;

        public short atomWindowType;

        public short wCreatorVersion;

    }

    boolean GetWindowInfo(Pointer hWnd, WINDOWINFO pwi);

    boolean GetWindowRect(Pointer hWnd, RECT rect);

    int GetWindowText(Pointer hWnd, byte[] lpString, int nMaxCount);

    int GetWindowTextLength(Pointer hWnd);

    int GetWindowModuleFileName(Pointer hWnd, byte[] lpszFileName, int cchFileNameMax);

    int GetWindowThreadProcessId(Pointer hWnd, IntByReference lpdwProcessId);

    interface WNDENUMPROC extends StdCallCallback {

        /**

         * Return whether to continue enumeration.

         */

        boolean callback(Pointer hWnd, Pointer data);

    }

    boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer data);

    boolean EnumThreadWindows(int dwThreadId, WNDENUMPROC lpEnumFunc, Pointer data);

    boolean FlashWindowEx(FLASHWINFO info);

    Pointer LoadIcon(Pointer hInstance, String iconName);

    Pointer LoadImage(Pointer hinst, // handle to instance

            String name, // image to load

            int type, // image type

            int xDesired, // desired width

            int yDesired, // desired height

            int load // load options

            );

    boolean DestroyIcon(Pointer hicon);

    int GWL_EXSTYLE = -20;

    int GWL_STYLE = -16;

    int GWL_WNDPROC = -4;

    int GWL_HINSTANCE = -6;

    int GWL_ID = -12;

    int GWL_USERDATA = -21;

    int DWL_DLGPROC = 4;

    int DWL_MSGRESULT = 0;

    int DWL_USER = 8;

    int WS_EX_COMPOSITED = 0x20000000;

    int WS_EX_LAYERED = 0x80000;

    int WS_EX_TRANSPARENT = 32;

    int GetWindowLong(Pointer hWnd, int nIndex);

    int SetWindowLong(Pointer hWnd, int nIndex, int dwNewLong);

    int LWA_COLORKEY = 1;

    int LWA_ALPHA = 2;

    int ULW_COLORKEY = 1;

    int ULW_ALPHA = 2;

    int ULW_OPAQUE = 4;

    boolean SetLayeredWindowAttributes(Pointer hwnd, int crKey,

            byte bAlpha, int dwFlags);

    boolean GetLayeredWindowAttributes(Pointer hwnd,

            IntByReference pcrKey,

            ByteByReference pbAlpha,

            IntByReference pdwFlags);

    /**

     * Defines the x- and y-coordinates of a point.

     */

    public static class POINT extends Structure {

        public int x, y;

    }

    /**

     * Specifies the width and height of a rectangle.

     */

    public static class SIZE extends Structure {

        public int cx, cy;

    }

    int AC_SRC_OVER = 0x00;

    int AC_SRC_ALPHA = 0x01;

    int AC_SRC_NO_PREMULT_ALPHA = 0x01;

    int AC_SRC_NO_ALPHA = 0x02;

    public static class BLENDFUNCTION extends Structure {

        public byte BlendOp = AC_SRC_OVER; // only valid value

        public byte BlendFlags = 0; // only valid value

        public byte SourceConstantAlpha;

        public byte AlphaFormat;

    }

    boolean UpdateLayeredWindow(Pointer hwnd, Pointer hdcDst,

            POINT pptDst, SIZE psize,

            Pointer hdcSrc, POINT pptSrc, int crKey,

            BLENDFUNCTION pblend, int dwFlags);

    int SetWindowRgn(Pointer hWnd, Pointer hRgn, boolean bRedraw);

    int VK_SHIFT = 16;

    int VK_LSHIFT = 0xA0;

    int VK_RSHIFT = 0xA1;

    int VK_CONTROL = 17;

    int VK_LCONTROL = 0xA2;

    int VK_RCONTROL = 0xA3;

    int VK_MENU = 18;

    int VK_LMENU = 0xA4;

    int VK_RMENU = 0xA5;

    boolean GetKeyboardState(byte[] state);

    short GetAsyncKeyState(int vKey);

}

package com.br.kernel;

import com.sun.jna.*;

import com.sun.jna.win32.StdCallLibrary;

import com.sun.jna.ptr.IntByReference;

// by deject3d

public interface Kernel32 extends StdCallLibrary

{

    // description from msdn

    //BOOL WINAPI WriteProcessMemory(

    //__in   HANDLE hProcess,

    //__in   LPVOID lpBaseAddress,

    //__in   LPCVOID lpBuffer,

    //__in   SIZE_T nSize,

    //__out  SIZE_T *lpNumberOfBytesWritten

    //);

    boolean WriteProcessMemory(Pointer p, int address, Pointer buffer, int size, IntByReference written);

  

  

    //BOOL WINAPI ReadProcessMemory(

    //          __in   HANDLE hProcess,

    //          __in   LPCVOID lpBaseAddress,

    //          __out  LPVOID lpBuffer,

    //          __in   SIZE_T nSize,

    //          __out  SIZE_T *lpNumberOfBytesRead

    //        );

    boolean ReadProcessMemory(Pointer hProcess, int inBaseAddress, Pointer outputBuffer, int nSize, IntByReference outNumberOfBytesRead);

  

  

    //HANDLE WINAPI OpenProcess(

    //  __in  DWORD dwDesiredAccess,

    //  __in  BOOL bInheritHandle,

    //  __in  DWORD dwProcessId

    //);

    Pointer OpenProcess(int desired, boolean inherit, int pid);

  

    /* derp */

    int GetLastError();

}

http://pastebin.com/Vq8wfy39

Comments

800387
The redirect looks ok to me. However, what does AGSenderServlet (specifically line 43) look like? If you are sending yourself a redirect, then you should handle it. :^)

- Saish
843842
The AGSenderServlet is sending a file to the AGReceiverServlet using multipart and Postmethod object. Here is the code.
public class AGSenderServlet extends HttpServlet {
	public void doGet(HttpServletRequest request,
            HttpServletResponse response)
	throws ServletException, IOException {
		String filename = request.getParameter("filename");
		String ext = request.getParameter("ext");
		String serverName = request.getParameter("serverName");
		String port = request.getParameter("port");
		String path = null;
		String uri = "http://"+serverName+":"+port+"/AGReceiverServlet";
		
		File file = new File((this.getServletContext().getRealPath("/sync/out"))+"\\"+filename+'.'+ext);
		System.out.println("Test = "+file.getAbsolutePath());
		PostMethod post = new PostMethod(uri);
        Part[] parts = new Part[] {
            new FilePart(file.getName(), file) // File you want to upload
        };
        post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
 
        // Now perform the POST and check for errors
        HttpClient http = new HttpClient();
        int status = http.executeMethod(post);
        if (status != HttpStatus.SC_OK) {
            throw new IOException("Received HTTP status code " + status);
        }		
	}
	
	public void doPost(HttpServletRequest request,
            HttpServletResponse response)
	throws ServletException, IOException {
			doGet(request, response);
	}
}
Line 43 is just
throw new IOException("Received HTTP status code " + status);
What do you mean by " then you should handle it." ? I think I handle it. It redirects to the JSP filereceived.jsp which is hosted and available on the server (tried to access it directly by entering the url and it works).

Edited by: Foobrother on Sep 13, 2010 7:38 AM
843842
I'm just thinking. Is it possible that at the end (just after doing the redirect) of the second servlet (AGReceiverServlet) it returns a response to the 1st one which is not HttpStatus.SC_OK (but still not an error status) and this throws an exception and stops the whole process before beeing able to run the content of the JSP (as I'm doing the test on the same server)?!
800387
You are sending a HttpRequest to your own Servlet. That Servlet is responding with 302. Your sending Servlet is looking for 200, finding 302, and throwing your own exception. This error is 100% of your own making. See?

- Saish
843842
I see indeed. I assumed "HttpStatus.SC_OK" represented all "non-error" status.

So in fact when it throws the exception it stops the process (the JSP is not processed). Because at the moment it doesn't run the code in the JSP.
I'll remove this status test to see what happens.
843842
After removing the status test it doesn't throw any error now but it still doesn't run the JSP file.
I have also tried to change the redirect with response.sendRedirect("http://www.google.com"); but it didn't change anything.
However I do a println just after the response.sendRedirect() and it's printed.
800387
I suggest you read the documentation on redirects for HttpClient found here. The API handles redirects within the same domain, but requires additional steps if the domain changes.

- Saish
843842
Indeed, I didn't know it didn't handle different domains. It explains maybe why it doesn't work with Google. But it should work with my JSP which is hosted on exactly the same server?!
843842
I've looked at your link. But I don't understand. It's speaking about the redirect in HttpClient. But I'm using the redirect of HttpServletResponse and I have found few code examples using sendRedirect with other domains (Google, etc...).
800387
Take it apart step by step. You yourself wrote code that checks for HTTP status 200. You yourself wrote code that is redirecting and resulting in a status 302. You are throwing the IOException you posted earlier in the thread.

The docs for HttpClient indicate that if it receives a 302 response (remember, at this point it is the sender and not the responder that is at issue), it will seamlessly handle the redirect if in the same domain. If not in the same domain, you have to write additional code as demonstrated in the link I sent you.

After removing the check for status code 200, what happens?

- Saish
843842
Ok so if I have well understood the response.sendRedirect() from the receiver is just sending a redirect request to the sender?!
So if a client calls Sender on ServerA, it will call Receiver on ServerB. Then Sender gets the redirect response from Receiver and calls the JSP file on ServerB. Am I right?!

But if it works like that, I don't understand how you get the location/URL to redirect from Sender servlet to JSP file.
Basically:

- Sender (ServerA) ==> Receiver (ServerB) done via PostMethod object (post) and HttpClient object (http) and this line "int status = http.executeMethod(post);"
- Receiver (ServerB ==> Sender (ServerA) done via response.sendRedirect(redirectURL); which makes a request on the Sender servlet to redirect to redirectURL ?!
- Sender (ServerA) ==> JSP file (ServerB) done via ???

If I apply the code of your link, it will get the location from the PostMethod object which is a URL to Receiver?!
And then to redirect to the location found in the header I need to do a reponse.sendRedirect() ?!

I'm totally confused.

Anyway, after removing the check for status code 200 nothing happens. No error, no exception but also not redirection to my JSP file (not code from the page run)

Here is my current code:
- AGSenderServlet » [http://pastebin.com/vW0YxGcE]
- AGReceiverServlet » [http://pastebin.com/nV39JKS1]
843842
I have just tried to change my reponse.sendRedirect() with a dispatcher.forward(), but it didn't change the result :(
String redirectURL = "http://"+request.getServerName()+':'+request.getServerPort()+"/upTool/filereceived.jsp?filename="+fileName;
//response.sendRedirect(redirectURL);
RequestDispatcher dispatcher = request.getRequestDispatcher(redirectURL);
dispatcher.forward(request, response);
800387
Ok. Let's make it simpler: client and server. Your client is initiating a HTTP post request. The server is responding with a HTTP 302 (found, redirect), that is returned the the client. The client should then issue another HTTP post request to the new redirected URL. The server then receives the second request which is handled, presumably by a JSP.

You should be able to see this exact behavior in a browser. What happens when you do so? Meaning, rather than using your client, use a browser. Does the redirect occur properly?

- Saish
843842
Actually I never used my client to test it but only my browser. I use this URL to start testing: [http://localhost:8080/AGSenderServlet?filename=defacto&ext=zip&serverName=localhost&port=8080]
(parameter serverName should be different I was using 2 different servers)

When I load that servlet, my printouts from the 1st and 2nd servlet are displayed in my Tomcat (not the ones of the JSP) console but nothing changes on the browser. No redirection to another servlet or the JSP page. I just have a blank page.

Edited by: Foobrother on Sep 14, 2010 5:54 AM
800387
AGSenderServlet has no code to send a response back to the browser.

- Saish
843842
What do you mean by "send a response back to the browser"?

An HTML reponse? Like
PrintWriter out = response.getWriter();
response.println("Result");
800387
Correct, with a call to close() in a finally block. (Or a JSP).

- Saish
843842
Actually I managed to make the request.getRequestDispatcher() work.
In fact I just needed to put an absolut path from the webapps root instead of an absolute path from my drive root.
No it works fine.


Cheers.
800387
Glad things are working. Best of luck.

- Saish
EJP
I just needed to put an absolutepath from the webapps root
A relative path from the webapp's root.
1 - 20
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Oct 14 2013
Added on Jul 18 2013
1 comment
22,923 views