Skip to content

Commit a028d7a

Browse files
committed
Improved logic and design pattern
1 parent 32d14ec commit a028d7a

10 files changed

Lines changed: 213 additions & 241 deletions

File tree

src/main/java/com/beaudoin/jmm/Main.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,21 @@
2525
package com.beaudoin.jmm;
2626

2727
import com.beaudoin.jmm.process.Module;
28-
import com.beaudoin.jmm.process.NativeProcess;
28+
import com.beaudoin.jmm.process.Process;
2929

3030
import java.io.IOException;
3131

32-
import static com.beaudoin.jmm.process.NativeProcess.byName;
32+
import static com.beaudoin.jmm.process.Processes.byName;
3333

3434
/**
3535
* Created by Jonathan on 12/22/2015.
3636
*/
3737
public final class Main {
3838

3939
public static void main(String[] args) throws IOException {
40-
NativeProcess proc = byName("csgo.exe");
41-
42-
Module client = proc.findModule("client.dll");
40+
Process proc = byName("csgo.exe");
41+
Module client = proc.findModule("client.dll");
4342
System.out.println(client);
44-
//System.out.println(proc.readInt(0x61ff1c));
4543
}
4644

4745
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.beaudoin.jmm.process;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* Created by Jonathan on 7/19/2016.
8+
*/
9+
public abstract class AbstractProcess implements Process {
10+
11+
protected Map<String, Module> modules = new HashMap<>();
12+
13+
private final int id;
14+
15+
public AbstractProcess(int id) {
16+
this.id = id;
17+
}
18+
19+
@Override
20+
public int id() {
21+
return id;
22+
}
23+
24+
@Override
25+
public Module findModule(String moduleName) {
26+
Module module = modules.get(moduleName);
27+
if (module == null) {
28+
initModules();
29+
}
30+
return module;
31+
}
32+
33+
}

src/main/java/com/beaudoin/jmm/process/ReadableRegion.java renamed to src/main/java/com/beaudoin/jmm/process/DataSource.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
/**
1111
* Created by Jonathan on 3/24/2016.
1212
*/
13-
public interface ReadableRegion {
13+
public interface DataSource {
1414

1515
MemoryBuffer read(Pointer address, int size);
1616

17-
NativeProcess write(Pointer address, MemoryBuffer buffer);
17+
Process write(Pointer address, MemoryBuffer buffer);
1818

1919
boolean canRead(Pointer address, int size);
2020

@@ -60,31 +60,31 @@ default MemoryBuffer read(long address, int size) {
6060
return read(Cacheable.pointer(address), size);
6161
}
6262

63-
default NativeProcess writeBoolean(long address, boolean value) {
63+
default Process writeBoolean(long address, boolean value) {
6464
return write(Cacheable.pointer(address), buffer(1).putBoolean(value));
6565
}
6666

67-
default NativeProcess writeByte(long address, int value) {
67+
default Process writeByte(long address, int value) {
6868
return write(Cacheable.pointer(address), buffer(1).putByte(value));
6969
}
7070

71-
default NativeProcess writeShort(long address, int value) {
71+
default Process writeShort(long address, int value) {
7272
return write(Cacheable.pointer(address), buffer(2).putShort(value));
7373
}
7474

75-
default NativeProcess writeInt(long address, int value) {
75+
default Process writeInt(long address, int value) {
7676
return write(Cacheable.pointer(address), buffer(4).putInt(value));
7777
}
7878

79-
default NativeProcess writeLong(long address, long value) {
79+
default Process writeLong(long address, long value) {
8080
return write(Cacheable.pointer(address), buffer(8).putLong(value));
8181
}
8282

83-
default NativeProcess writeFloat(long address, float value) {
83+
default Process writeFloat(long address, float value) {
8484
return write(Cacheable.pointer(address), buffer(4).putFloat(value));
8585
}
8686

87-
default NativeProcess writeDouble(long address, double value) {
87+
default Process writeDouble(long address, double value) {
8888
return write(Cacheable.pointer(address), buffer(8).putDouble(value));
8989
}
9090

src/main/java/com/beaudoin/jmm/process/Module.java

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,26 @@
2727

2828
import com.beaudoin.jmm.misc.Cacheable;
2929
import com.beaudoin.jmm.misc.MemoryBuffer;
30-
import com.beaudoin.jmm.natives.win32.Kernel32;
31-
import com.beaudoin.jmm.process.impl.win32.Win32Process;
32-
import com.sun.jna.Native;
3330
import com.sun.jna.Pointer;
34-
import com.sun.jna.platform.win32.Win32Exception;
3531

36-
public final class Module implements ReadableRegion {
32+
public final class Module implements DataSource {
3733

38-
private final NativeProcess process;
34+
private final Process process;
3935
private final String name;
4036
private final long address;
4137
private final int size;
4238
private final Pointer pointer;
4339
private MemoryBuffer data;
4440

45-
public Module(NativeProcess process, String name, Pointer pointer, long size) {
41+
public Module(Process process, String name, Pointer pointer, long size) {
4642
this.process = process;
4743
this.name = name;
4844
this.address = Pointer.nativeValue(pointer);
4945
this.size = (int) size;
5046
this.pointer = pointer;
5147
}
5248

53-
public NativeProcess process() {
49+
public Process process() {
5450
return process;
5551
}
5652

@@ -75,32 +71,22 @@ public MemoryBuffer data() {
7571
}
7672

7773
public MemoryBuffer data(boolean forceNew) {
78-
if (forceNew || data == null) {
79-
data = process().read(pointer(), size());
80-
}
81-
return data;
74+
return data == null || forceNew ? data = process().read(pointer(), size()) : data;
8275
}
8376

8477
@Override
8578
public MemoryBuffer read(Pointer offset, int size) {
86-
MemoryBuffer buffer = Cacheable.buffer(size);
87-
if (Kernel32.ReadProcessMemory(((Win32Process) process()).pointer(), Cacheable.pointer(address() + Pointer.nativeValue(offset)), buffer, size, 0) == 0) {
88-
throw new Win32Exception(Native.getLastError());
89-
}
90-
return buffer;
79+
return process().read(Cacheable.pointer(address() + Pointer.nativeValue(offset)), size);
9180
}
9281

9382
@Override
94-
public NativeProcess write(Pointer offset, MemoryBuffer buffer) {
95-
if (Kernel32.WriteProcessMemory(((Win32Process) process()).pointer(), Cacheable.pointer(address() + Pointer.nativeValue(offset)), buffer, buffer.size(), 0) == 0) {
96-
throw new Win32Exception(Native.getLastError());
97-
}
98-
return process();
83+
public Process write(Pointer offset, MemoryBuffer buffer) {
84+
return process().write(Cacheable.pointer(address() + Pointer.nativeValue(offset)), buffer);
9985
}
10086

10187
@Override
10288
public boolean canRead(Pointer offset, int size) {
103-
return Kernel32.ReadProcessMemory(((Win32Process) process()).pointer(), Cacheable.pointer(address() + Pointer.nativeValue(offset)), Cacheable.buffer(size), size, 0) != 0;
89+
return process().canRead(Cacheable.pointer(address() + Pointer.nativeValue(offset)), size);
10490
}
10591

10692
@Override

src/main/java/com/beaudoin/jmm/process/NativeProcess.java

Lines changed: 0 additions & 96 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Jonathan Beaudoin
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.beaudoin.jmm.process;
26+
27+
/**
28+
* Created by Jonathan on 12/12/15.
29+
*/
30+
public interface Process extends DataSource {
31+
32+
int id();
33+
34+
void initModules();
35+
36+
Module findModule(String moduleName);
37+
38+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.beaudoin.jmm.process;
2+
3+
import com.beaudoin.jmm.misc.Utils;
4+
import com.beaudoin.jmm.natives.mac.mac;
5+
import com.beaudoin.jmm.natives.unix.libc;
6+
import com.beaudoin.jmm.natives.win32.Kernel32;
7+
import com.beaudoin.jmm.process.impl.mac.MacProcess;
8+
import com.beaudoin.jmm.process.impl.unix.UnixProcess;
9+
import com.beaudoin.jmm.process.impl.win32.Win32Process;
10+
import com.sun.jna.Native;
11+
import com.sun.jna.Platform;
12+
import com.sun.jna.Pointer;
13+
import com.sun.jna.platform.win32.Tlhelp32;
14+
import com.sun.jna.ptr.IntByReference;
15+
16+
/**
17+
* Created by Jonathan on 7/19/2016.
18+
*/
19+
public final class Processes {
20+
21+
public static Process byName(String name) {
22+
if (Platform.isWindows()) {
23+
Tlhelp32.PROCESSENTRY32.ByReference entry = new Tlhelp32.PROCESSENTRY32.ByReference();
24+
Pointer snapshot = Kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPALL.intValue(), 0);
25+
try {
26+
while (Kernel32.Process32Next(snapshot, entry)) {
27+
String processName = Native.toString(entry.szExeFile);
28+
if (name.equals(processName)) {
29+
return byId(entry.th32ProcessID.intValue());
30+
}
31+
}
32+
} finally {
33+
Kernel32.CloseHandle(snapshot);
34+
}
35+
} else if (Platform.isMac() || Platform.isLinux()) {
36+
return byId(Utils.exec("bash", "-c", "ps -A | grep -m1 \"" + name + "\" | awk '{print $1}'"));
37+
} else {
38+
throw new UnsupportedOperationException("Unknown operating system! (" + System.getProperty("os.name") + ")");
39+
}
40+
return null;
41+
}
42+
43+
public static Process byId(int id) {
44+
if ((Platform.isMac() || Platform.isLinux()) && !isSudo()) {
45+
throw new RuntimeException("You need to run as root/sudo in order for functionality.");
46+
}
47+
if (Platform.isWindows()) {
48+
return new Win32Process(id, Kernel32.OpenProcess(0x438, true, id));
49+
} else if (Platform.isMac()) {
50+
IntByReference out = new IntByReference();
51+
if (mac.task_for_pid(mac.mach_task_self(), id, out) != 0) {
52+
throw new IllegalStateException("Failed to find mach task port for process, ensure you are running as sudo.");
53+
}
54+
return new MacProcess(id, out.getValue());
55+
} else if (Platform.isLinux()) {
56+
return new UnixProcess(id);
57+
} else {
58+
throw new IllegalStateException("Process " + id + " was not found. Are you sure its running?");
59+
}
60+
}
61+
62+
private static boolean isSudo() {
63+
return libc.getuid() == 0;
64+
}
65+
66+
}

0 commit comments

Comments
 (0)