Skip to content
This repository was archived by the owner on Jun 6, 2022. It is now read-only.

Commit 39e6dc1

Browse files
author
adaei
committed
Renamed packages. Updated maven repository to include jna dependencies.
Added exceptions for writeprocessmemory and openprocess. Fixed bugs with finding class/window names
1 parent 411993b commit 39e6dc1

File tree

10 files changed

+247
-217
lines changed

10 files changed

+247
-217
lines changed

java-win-memory-trainer/.classpath

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
33
<classpathentry kind="src" path="src/main/java"/>
4-
<classpathentry kind="lib" path="lib/jna.jar"/>
5-
<classpathentry kind="lib" path="lib/platform.jar"/>
64
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
75
<attributes>
86
<attribute name="maven.pomderived" value="true"/>

java-win-memory-trainer/pom.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.sprogcoder</groupId>
5-
<artifactId>memoryeditor</artifactId>
5+
<artifactId>memory-trainer</artifactId>
66
<version>0.0.1-SNAPSHOT</version>
77
<build>
88
<sourceDirectory>src/main/java</sourceDirectory>
@@ -24,5 +24,17 @@
2424
<artifactId>guava</artifactId>
2525
<version>13.0.1</version>
2626
</dependency>
27+
<dependency>
28+
<groupId>net.java.dev.jna</groupId>
29+
<artifactId>jna</artifactId>
30+
<version>3.4.0</version>
31+
</dependency>
32+
<dependency>
33+
<groupId>net.java.dev.jna</groupId>
34+
<artifactId>jna</artifactId>
35+
<version>3.3.0</version>
36+
<classifier>platform</classifier>
37+
</dependency>
2738
</dependencies>
39+
2840
</project>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.sprogcoder.memory;
2+
3+
import com.sun.jna.Memory;
4+
import com.sun.jna.Native;
5+
import com.sun.jna.Pointer;
6+
import com.sun.jna.ptr.IntByReference;
7+
import com.sun.jna.win32.StdCallLibrary;
8+
9+
public class JKernel32
10+
{
11+
12+
public interface Kernel32 extends StdCallLibrary
13+
{
14+
public static final int ACCESS_FLAGS = 0x0439;
15+
public static final int PROCESS_QUERY_INFORMATION = 0x0400;
16+
public static final int PROCESS_VM_READ = 0x0010;
17+
public static final int PROCESS_VM_WRITE = 0x0020;
18+
public static final int PROCESS_VM_OPERATION = 0x0008;
19+
public static final int PROCESS_ALL_ACCESS = 0x001F0FFF;
20+
public static final int FORMAT_MESSAGE_FROM_SYSTEM = 4096;
21+
public static final int FORMAT_MESSAGE_IGNORE_INSERTS = 512;
22+
23+
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
24+
Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);
25+
26+
int GetLastError();
27+
28+
int FormatMessageW(int dwFlags, Pointer lpSource, int dwMessageId, int dwLanguageId, char[] lpBuffer, int nSize, Pointer Arguments);
29+
30+
int OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
31+
32+
boolean CloseHandle(int hObject);
33+
34+
int WriteProcessMemory(int hProcess, int lpBaseAddress, int[] lpBuffer, int nSize, int[] lpNumberOfBytesWritten);
35+
36+
boolean ReadProcessMemory(int hProcess, int baseAddress, Pointer outputBuffer, int nSize, IntByReference outNumberOfBytesRead);
37+
38+
}
39+
40+
public static int openProcess(int dwProcessId) throws MemoryException
41+
{
42+
int hProcess = Kernel32.SYNC_INSTANCE.OpenProcess(Kernel32.PROCESS_VM_OPERATION | Kernel32.PROCESS_VM_WRITE | Kernel32.PROCESS_VM_READ, 0,
43+
dwProcessId);
44+
if (hProcess <= 0)
45+
{
46+
throw new MemoryException("OpenProcess", getLastError());
47+
}
48+
return hProcess;
49+
}
50+
51+
public static boolean closeHandle(int hObject)
52+
{
53+
return Kernel32.SYNC_INSTANCE.CloseHandle(hObject);
54+
}
55+
56+
public static void writeProcessMemory(int hProcess, int lpBaseAddress, int lpBuffer[]) throws MemoryException
57+
{
58+
for (int i = 0; i < lpBuffer.length; i++)
59+
{
60+
int[] singleValue = new int[] { lpBuffer[i] };
61+
int valueLength = Integer.toHexString(singleValue[0]).length();
62+
int result = Kernel32.SYNC_INSTANCE.WriteProcessMemory(hProcess, lpBaseAddress + (i * 0x00000001), singleValue, valueLength, null);
63+
if (result <= 0)
64+
{
65+
throw new MemoryException("WriteProcessMemory", getLastError());
66+
}
67+
}
68+
}
69+
70+
public static byte[] readProcessMemory(int hProcess, int lpBaseAddress, int nSize) throws MemoryException
71+
{
72+
IntByReference baseAddress = new IntByReference();
73+
baseAddress.setValue(lpBaseAddress);
74+
Memory lpBuffer = new Memory(nSize);
75+
76+
boolean success = Kernel32.SYNC_INSTANCE.ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, null);
77+
78+
if (success)
79+
{
80+
return lpBuffer.getByteArray(0, nSize);
81+
}
82+
else
83+
{
84+
throw new MemoryException("ReadProcessMemory", getLastError());
85+
}
86+
}
87+
88+
public static String getLastError()
89+
{
90+
int dwMessageId = Kernel32.SYNC_INSTANCE.GetLastError();
91+
char[] lpBuffer = new char[1024];
92+
int lenW = Kernel32.SYNC_INSTANCE.FormatMessageW(Kernel32.FORMAT_MESSAGE_FROM_SYSTEM | Kernel32.FORMAT_MESSAGE_IGNORE_INSERTS, null,
93+
dwMessageId, 0, lpBuffer, lpBuffer.length, null);
94+
String message = new String(lpBuffer, 0, lenW);
95+
return message;
96+
}
97+
98+
@SuppressWarnings("serial")
99+
public static class MemoryException extends Exception
100+
{
101+
public MemoryException(String functionName, String message)
102+
{
103+
super(String.format("Kernel32 Function %s failed:\n\t%s", functionName, message));
104+
}
105+
}
106+
107+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.sprogcoder.memory;
2+
3+
import com.sprogcoder.memory.JKernel32.MemoryException;
4+
import com.sprogcoder.memory.JUser32.WindowNotFoundException;
5+
6+
public class JTrainer
7+
{
8+
9+
private int pid = -1;
10+
private String windowClass = "";
11+
private String windowText = "";
12+
13+
public JTrainer(int pid)
14+
{
15+
this.pid = pid;
16+
}
17+
18+
public JTrainer(String windowClass, String windowText) throws WindowNotFoundException
19+
{
20+
this.windowClass = windowClass;
21+
this.windowText = windowText;
22+
this.pid = JUser32.getWindowThreadProcessId(JUser32.findWindow(windowClass, windowText));
23+
}
24+
25+
public void writeProcessMemory(int lpBaseAddress, int lpBuffer[]) throws MemoryException
26+
{
27+
int hProcess = JKernel32.openProcess(pid);
28+
JKernel32.writeProcessMemory(hProcess, lpBaseAddress, lpBuffer);
29+
JKernel32.closeHandle(hProcess);
30+
}
31+
32+
public byte[] readProcessMemory(int lpBaseAddress, int nSize) throws MemoryException
33+
{
34+
int hProcess = JKernel32.openProcess(pid);
35+
byte[] result = JKernel32.readProcessMemory(hProcess, lpBaseAddress, nSize);
36+
JKernel32.closeHandle(hProcess);
37+
return result;
38+
}
39+
40+
public String getLastError()
41+
{
42+
return JKernel32.getLastError();
43+
}
44+
45+
public void retryProcess() throws WindowNotFoundException
46+
{
47+
if (!isProcessAvailable())
48+
{
49+
this.pid = JUser32.getWindowThreadProcessId(JUser32.findWindow(windowClass, windowText));
50+
}
51+
}
52+
53+
public boolean isProcessAvailable()
54+
{
55+
try
56+
{
57+
JKernel32.openProcess(this.pid);
58+
return true;
59+
}
60+
catch (MemoryException e)
61+
{
62+
//
63+
}
64+
return false;
65+
}
66+
67+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.sprogcoder.memory;
2+
3+
import com.sun.jna.Native;
4+
import com.sun.jna.platform.win32.WinDef.HWND;
5+
import com.sun.jna.win32.StdCallLibrary;
6+
7+
public class JUser32
8+
{
9+
10+
public interface User32 extends StdCallLibrary
11+
{
12+
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
13+
User32 SYNC_INSTANCE = (User32) Native.synchronizedLibrary(INSTANCE);
14+
15+
HWND FindWindowA(String lpClassName, String lpWindowName);
16+
17+
int GetWindowThreadProcessId(HWND hWnd, int[] lpdwProcessId);
18+
}
19+
20+
public static HWND findWindow(String lpClassName, String lpWindowName) throws WindowNotFoundException
21+
{
22+
lpClassName = (lpClassName == null || lpClassName.equals("")) ? null : lpClassName;
23+
lpWindowName = (lpWindowName == null || lpWindowName.equals("")) ? null : lpWindowName;
24+
25+
HWND hWnd = User32.SYNC_INSTANCE.FindWindowA(lpClassName, lpWindowName);
26+
if (hWnd == null)
27+
{
28+
throw new WindowNotFoundException(lpClassName, lpWindowName);
29+
}
30+
return hWnd;
31+
}
32+
33+
public static int getWindowThreadProcessId(HWND hWnd)
34+
{
35+
int[] lpdwProcessId = new int[1];
36+
User32.SYNC_INSTANCE.GetWindowThreadProcessId(hWnd, lpdwProcessId);
37+
return lpdwProcessId[0];
38+
}
39+
40+
@SuppressWarnings("serial")
41+
public static class WindowNotFoundException extends Exception
42+
{
43+
public WindowNotFoundException(String className, String windowName)
44+
{
45+
super(String.format("Window Handle null for className: %s; windowName: %s", className, windowName));
46+
}
47+
}
48+
49+
}

java-win-memory-trainer/src/main/java/com/sprogcoder/memory/editor/MemoryUtils.java renamed to java-win-memory-trainer/src/main/java/com/sprogcoder/memory/MemoryUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.sprogcoder.memory.editor;
1+
package com.sprogcoder.memory;
22

33
import java.util.Arrays;
44
import java.util.Collections;

java-win-memory-trainer/src/main/java/com/sprogcoder/memory/editor/JKernel32.java

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)