parent
4abff96fa3
commit
1708e8575e
@ -1,194 +1,194 @@ |
|||||||
package de.marenthyu.memedit.bunny; |
package de.marenthyu.memedit.bunny; |
||||||
|
|
||||||
import com.sun.jna.Memory; |
import com.sun.jna.Memory; |
||||||
import com.sun.jna.Pointer; |
import com.sun.jna.Pointer; |
||||||
import de.marenthyu.twitch.pubsub.PubSubClient; |
import de.marenthyu.twitch.pubsub.PubSubClient; |
||||||
import de.marenthyu.twitch.pubsub.channelpoints.ChannelPointsRedemptionHandler; |
import de.marenthyu.twitch.pubsub.channelpoints.ChannelPointsRedemptionHandler; |
||||||
|
|
||||||
import javax.swing.*; |
import javax.swing.*; |
||||||
import java.io.IOException; |
import java.io.IOException; |
||||||
|
|
||||||
import static de.marenthyu.memedit.bunny.BunnyConstants.*; |
import static de.marenthyu.memedit.bunny.BunnyConstants.*; |
||||||
import static de.marenthyu.memedit.util.Shared.*; |
import static de.marenthyu.memedit.util.Shared.*; |
||||||
|
|
||||||
public class BunnyMemoryManager { |
public class BunnyMemoryManager { |
||||||
|
|
||||||
|
|
||||||
static int RABI_BASE_SIZE; |
static int RABI_BASE_SIZE; |
||||||
public static Pointer bunnyProcess; |
public static Pointer bunnyProcess; |
||||||
public static int bunnyPID; |
public static int bunnyPID; |
||||||
|
|
||||||
|
|
||||||
public static void init() { |
public static void init() { |
||||||
bunnyPID = getProcessId(RABI_TITLE); |
bunnyPID = getProcessIdByWindowTitle(RABI_TITLE); |
||||||
System.out.println("[BUNNY] Bunny PID: " + bunnyPID); |
System.out.println("[BUNNY] Bunny PID: " + bunnyPID); |
||||||
bunnyProcess = openProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, bunnyPID); |
bunnyProcess = openProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, bunnyPID); |
||||||
try { |
try { |
||||||
RABI_BASE_SIZE = getBaseAddress("rabiribi.exe"); |
RABI_BASE_SIZE = getBaseAddress("rabiribi.exe"); |
||||||
if (RABI_BASE_SIZE == 0) { |
if (RABI_BASE_SIZE == 0) { |
||||||
throw new IOException("Invalid Size Returned from Powershell"); |
throw new IOException("Invalid Size Returned from Base Address Detection"); |
||||||
} |
} |
||||||
} catch (NumberFormatException | IOException e) { |
} catch (NumberFormatException | IOException e) { |
||||||
// e.printStackTrace();
|
// e.printStackTrace();
|
||||||
System.out.println(); |
System.out.println(); |
||||||
System.out.println("[BUNNY] Error getting the Module base address automatically, asking user."); |
System.out.println("[BUNNY] Error getting the Module base address automatically, asking user."); |
||||||
String userInput = JOptionPane.showInputDialog("Please Enter the base address of rabiribi.exe\n If you dare, please help me automate this. I am at the end of my knowledge. If you don't know how to do this, ask whoever linked you this software."); |
String userInput = JOptionPane.showInputDialog("Please Enter the base address of rabiribi.exe\n Too bad this failed. Thanks sig for the actual implementation that works most of the time. If you don't know how to do this, ask whoever linked you this software."); |
||||||
try { |
try { |
||||||
RABI_BASE_SIZE = Integer.decode(userInput); |
RABI_BASE_SIZE = Integer.decode(userInput); |
||||||
} catch (Exception y) { |
} catch (Exception y) { |
||||||
try { |
try { |
||||||
RABI_BASE_SIZE = Integer.decode("0x" + userInput); |
RABI_BASE_SIZE = Integer.decode("0x" + userInput); |
||||||
} catch (Exception ex) { |
} catch (Exception ex) { |
||||||
System.out.println("[BUNNY] You're stupid. I think. something went wrong."); |
System.out.println("[BUNNY] You're stupid. I think. something went wrong."); |
||||||
e.printStackTrace(); |
e.printStackTrace(); |
||||||
ex.printStackTrace(); |
ex.printStackTrace(); |
||||||
System.exit(2); |
System.exit(2); |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
if (bunnyPID == 0) { |
if (bunnyPID == 0) { |
||||||
System.err.println("[BUNNY] COULD NOT LOCATE PID FOR " + RABI_TITLE + " - PLEASE MAKE SURE THE GAME IS RUNNING AND ON THE SPECIFIED VERSION!"); |
System.err.println("[BUNNY] COULD NOT LOCATE PID FOR " + RABI_TITLE + " - PLEASE MAKE SURE THE GAME IS RUNNING AND ON THE SPECIFIED VERSION!"); |
||||||
System.exit(1); |
System.exit(1); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
public static void addSetHPHandler(PubSubClient pubSub) { |
public static void addSetHPHandler(PubSubClient pubSub) { |
||||||
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][HP]") { |
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][HP]") { |
||||||
@Override |
@Override |
||||||
public void matched(String input) { |
public void matched(String input) { |
||||||
try { |
try { |
||||||
int newHeahlth = Integer.parseInt(input); |
int newHeahlth = Integer.parseInt(input); |
||||||
setHP(newHeahlth); |
setHP(newHeahlth); |
||||||
System.out.println("[BUNNY][HP] HP set to " + newHeahlth); |
System.out.println("[BUNNY][HP] HP set to " + newHeahlth); |
||||||
} catch (NumberFormatException e) { |
} catch (NumberFormatException e) { |
||||||
System.err.println("[BUNNY][HP] Invalid Number."); |
System.err.println("[BUNNY][HP] Invalid Number."); |
||||||
} |
} |
||||||
} |
} |
||||||
}); |
}); |
||||||
} |
} |
||||||
|
|
||||||
public static void addFullHealHandler(PubSubClient pubSub) { |
public static void addFullHealHandler(PubSubClient pubSub) { |
||||||
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][FULLHEAL]") { |
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][FULLHEAL]") { |
||||||
@Override |
@Override |
||||||
public void matched(String input) { |
public void matched(String input) { |
||||||
fullHeal(); |
fullHeal(); |
||||||
System.out.println("[BUNNY][FULLHEAL] Healed fully!"); |
System.out.println("[BUNNY][FULLHEAL] Healed fully!"); |
||||||
} |
} |
||||||
}); |
}); |
||||||
} |
} |
||||||
|
|
||||||
public static void addHealHandler(PubSubClient pubSub) { |
public static void addHealHandler(PubSubClient pubSub) { |
||||||
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][HEAL]") { |
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][HEAL]") { |
||||||
@Override |
@Override |
||||||
public void matched(String input) { |
public void matched(String input) { |
||||||
try { |
try { |
||||||
int amount = Integer.parseInt(input); |
int amount = Integer.parseInt(input); |
||||||
heal(amount); |
heal(amount); |
||||||
System.out.println("[BUNNY][HEAL] Healed by " + amount); |
System.out.println("[BUNNY][HEAL] Healed by " + amount); |
||||||
} catch (NumberFormatException e) { |
} catch (NumberFormatException e) { |
||||||
System.err.println("[BUNNY][HEAL] Invalid Number."); |
System.err.println("[BUNNY][HEAL] Invalid Number."); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
}); |
}); |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
public static void addBadgeHandlers(PubSubClient pubSub) { |
public static void addBadgeHandlers(PubSubClient pubSub) { |
||||||
for (int i = 0;i < RABI_BADGES.length;i++) { |
for (int i = 0;i < RABI_BADGES.length;i++) { |
||||||
for (int j = 0;j<=2;j++) { |
for (int j = 0;j<=2;j++) { |
||||||
String type; |
String type; |
||||||
switch (j) { |
switch (j) { |
||||||
case 0: |
case 0: |
||||||
{ |
{ |
||||||
type = "DELETE"; |
type = "DELETE"; |
||||||
break; |
break; |
||||||
} |
} |
||||||
case 1: { |
case 1: { |
||||||
type = "UNLOCK"; |
type = "UNLOCK"; |
||||||
break; |
break; |
||||||
} |
} |
||||||
case 2: { |
case 2: { |
||||||
type = "EQUIP"; |
type = "EQUIP"; |
||||||
break; |
break; |
||||||
} |
} |
||||||
default: |
default: |
||||||
throw new IllegalStateException("Unexpected value: " + j); |
throw new IllegalStateException("Unexpected value: " + j); |
||||||
} |
} |
||||||
final int finalJ = j; |
final int finalJ = j; |
||||||
final int finalI = i; |
final int finalI = i; |
||||||
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][BADGE][" + type + "][" + RABI_BADGES[finalI] + "]") { |
pubSub.addChannelPointsRedemptionHandler(new ChannelPointsRedemptionHandler("[BUNNY][BADGE][" + type + "][" + RABI_BADGES[finalI] + "]") { |
||||||
@Override |
@Override |
||||||
public void matched(String input) { |
public void matched(String input) { |
||||||
switch (finalJ) { |
switch (finalJ) { |
||||||
case 0: |
case 0: |
||||||
{ |
{ |
||||||
removeBadge(finalI); |
removeBadge(finalI); |
||||||
break; |
break; |
||||||
} |
} |
||||||
case 1: { |
case 1: { |
||||||
unluckAndUnequipBadge(finalI); |
unluckAndUnequipBadge(finalI); |
||||||
break; |
break; |
||||||
} |
} |
||||||
case 2: { |
case 2: { |
||||||
equipBadge(finalI); |
equipBadge(finalI); |
||||||
break; |
break; |
||||||
} |
} |
||||||
default: |
default: |
||||||
throw new IllegalStateException("Unexpected value: " + finalJ); |
throw new IllegalStateException("Unexpected value: " + finalJ); |
||||||
} |
} |
||||||
System.out.println("[BUNNY][BADGE][" + type + "][" + RABI_BADGES[finalI] + "] Badges changed!"); |
System.out.println("[BUNNY][BADGE][" + type + "][" + RABI_BADGES[finalI] + "] Badges changed!"); |
||||||
} |
} |
||||||
|
|
||||||
}); |
}); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
public static void setHP(int newHeahlth) { |
public static void setHP(int newHeahlth) { |
||||||
System.out.println("[BUNNY] Got request to change HP - setting it to " + newHeahlth); |
System.out.println("[BUNNY] Got request to change HP - setting it to " + newHeahlth); |
||||||
long dynAddress = findDynAddress(bunnyProcess, RABI_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, RABI_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
||||||
int curHealth = getCurHP(); |
int curHealth = getCurHP(); |
||||||
System.out.println(String.format("[BUNNY] Old health read from memory was: %d, setting it to %d", curHealth, newHeahlth)); |
System.out.println(String.format("[BUNNY] Old health read from memory was: %d, setting it to %d", curHealth, newHeahlth)); |
||||||
writeMemory(bunnyProcess, dynAddress, intToBytes(newHeahlth)); |
writeMemory(bunnyProcess, dynAddress, intToBytes(newHeahlth)); |
||||||
} |
} |
||||||
|
|
||||||
public static int getCurHP() { |
public static int getCurHP() { |
||||||
long dynAddress = findDynAddress(bunnyProcess, RABI_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, RABI_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
||||||
Memory healthCurrentMem = readMemory(bunnyProcess, dynAddress, 4); |
Memory healthCurrentMem = readMemory(bunnyProcess, dynAddress, 4); |
||||||
return healthCurrentMem.getInt(0); |
return healthCurrentMem.getInt(0); |
||||||
} |
} |
||||||
|
|
||||||
public static int getMaxHP() { |
public static int getMaxHP() { |
||||||
long dynAddress = findDynAddress(bunnyProcess, RABI_MAX_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, RABI_MAX_HEALTH_OFFSETS_IN_SAVBLOCK, RABI_BASE_SIZE + RABI_SAVBLOCK_OFFSET); |
||||||
Memory healthCurrentMem = readMemory(bunnyProcess, dynAddress, 4); |
Memory healthCurrentMem = readMemory(bunnyProcess, dynAddress, 4); |
||||||
return healthCurrentMem.getInt(0); |
return healthCurrentMem.getInt(0); |
||||||
} |
} |
||||||
|
|
||||||
public static void heal(int amount) { |
public static void heal(int amount) { |
||||||
setHP(getCurHP() + amount); |
setHP(getCurHP() + amount); |
||||||
} |
} |
||||||
|
|
||||||
public static void fullHeal() { |
public static void fullHeal() { |
||||||
setHP(getMaxHP()); |
setHP(getMaxHP()); |
||||||
} |
} |
||||||
|
|
||||||
public static void equipBadge(int badgeID) { |
public static void equipBadge(int badgeID) { |
||||||
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
||||||
writeMemory(bunnyProcess, dynAddress, new byte[]{0x02}); |
writeMemory(bunnyProcess, dynAddress, new byte[]{0x02}); |
||||||
} |
} |
||||||
|
|
||||||
public static void unluckAndUnequipBadge(int badgeID) { |
public static void unluckAndUnequipBadge(int badgeID) { |
||||||
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
||||||
writeMemory(bunnyProcess, dynAddress, new byte[]{0x01}); |
writeMemory(bunnyProcess, dynAddress, new byte[]{0x01}); |
||||||
} |
} |
||||||
|
|
||||||
public static void removeBadge(int badgeID) { |
public static void removeBadge(int badgeID) { |
||||||
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
long dynAddress = findDynAddress(bunnyProcess, new int[]{badgeID * 4}, RABI_BASE_SIZE + RABI_BADGE_ARRAY_BASE_POINTER_OFFSET); |
||||||
writeMemory(bunnyProcess, dynAddress, new byte[]{0x00}); |
writeMemory(bunnyProcess, dynAddress, new byte[]{0x00}); |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,103 +1,139 @@ |
|||||||
package de.marenthyu.memedit.util; |
package de.marenthyu.memedit.util; |
||||||
|
|
||||||
import com.sun.jna.Memory; |
import com.sun.jna.Memory; |
||||||
import com.sun.jna.Native; |
import com.sun.jna.Native; |
||||||
import com.sun.jna.Pointer; |
import com.sun.jna.Pointer; |
||||||
import com.sun.jna.ptr.IntByReference; |
import com.sun.jna.platform.win32.WinNT; |
||||||
|
import com.sun.jna.ptr.IntByReference; |
||||||
import java.io.BufferedReader; |
import de.marenthyu.memedit.util.sig.Module; |
||||||
import java.io.IOException; |
import de.marenthyu.memedit.util.sig.PsapiTools; |
||||||
import java.io.InputStreamReader; |
|
||||||
|
import java.io.BufferedReader; |
||||||
public class Shared { |
import java.io.IOException; |
||||||
static Kernel32 kernel32 = Native.load("kernel32", Kernel32.class); |
import java.io.InputStreamReader; |
||||||
static User32 user32 = Native.load("user32", User32.class); |
import java.util.List; |
||||||
|
|
||||||
public static int PROCESS_VM_READ = 0x0010; |
public class Shared { |
||||||
public static int PROCESS_VM_WRITE = 0x0020; |
static Kernel32 kernel32 = Native.load("kernel32", Kernel32.class); |
||||||
public static int PROCESS_VM_OPERATION = 0x0008; |
static User32 user32 = Native.load("user32", User32.class); |
||||||
|
|
||||||
public static int getProcessId(String window) { |
final static int PROCESS_PERMISSIONS = WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ; |
||||||
IntByReference pid = new IntByReference(0); |
|
||||||
user32.GetWindowThreadProcessId(user32.FindWindowA(null, window), pid); |
public static int PROCESS_VM_READ = 0x0010; |
||||||
|
public static int PROCESS_VM_WRITE = 0x0020; |
||||||
return pid.getValue(); |
public static int PROCESS_VM_OPERATION = 0x0008; |
||||||
} |
|
||||||
|
public static int getProcessIdByWindowTitle(String window) { |
||||||
public static Pointer openProcess(int permissions, int pid) { |
IntByReference pid = new IntByReference(0); |
||||||
Pointer process = kernel32.OpenProcess(permissions, true, pid); |
user32.GetWindowThreadProcessId(user32.FindWindowA(null, window), pid); |
||||||
return process; |
|
||||||
} |
return pid.getValue(); |
||||||
|
} |
||||||
public static long findDynAddress(Pointer process, int[] offsets, long baseAddress) { |
|
||||||
|
|
||||||
long pointer = baseAddress; |
public static Pointer openProcess(int permissions, int pid) { |
||||||
|
Pointer process = kernel32.OpenProcess(permissions, true, pid); |
||||||
int size = 4; |
return process; |
||||||
Memory pTemp = new Memory(size); |
} |
||||||
long pointerAddress = 0; |
|
||||||
// System.out.println("initial pointerAddress: " + String.format("0x%X", pointer));
|
public static long findDynAddress(Pointer process, int[] offsets, long baseAddress) { |
||||||
for (int i = 0; i < offsets.length; i++) { |
|
||||||
if (i == 0) { |
long pointer = baseAddress; |
||||||
kernel32.ReadProcessMemory(process, pointer, pTemp, size, null); |
|
||||||
} |
int size = 4; |
||||||
|
Memory pTemp = new Memory(size); |
||||||
pointerAddress = ((pTemp.getInt(0) + offsets[i])); |
long pointerAddress = 0; |
||||||
|
// System.out.println("initial pointerAddress: " + String.format("0x%X", pointer));
|
||||||
// System.out.println("Current pointerAddress: " + String.format("0x%X", pointerAddress));
|
for (int i = 0; i < offsets.length; i++) { |
||||||
|
if (i == 0) { |
||||||
if (i != offsets.length - 1) |
kernel32.ReadProcessMemory(process, pointer, pTemp, size, null); |
||||||
kernel32.ReadProcessMemory(process, pointerAddress, pTemp, size, null); |
} |
||||||
|
|
||||||
|
pointerAddress = ((pTemp.getInt(0) + offsets[i])); |
||||||
} |
|
||||||
|
// System.out.println("Current pointerAddress: " + String.format("0x%X", pointerAddress));
|
||||||
return pointerAddress; |
|
||||||
} |
if (i != offsets.length - 1) |
||||||
|
kernel32.ReadProcessMemory(process, pointerAddress, pTemp, size, null); |
||||||
public static Memory readMemory(Pointer process, long address, int bytesToRead) { |
|
||||||
IntByReference read = new IntByReference(0); |
|
||||||
Memory output = new Memory(bytesToRead); |
} |
||||||
|
|
||||||
kernel32.ReadProcessMemory(process, address, output, bytesToRead, read); |
return pointerAddress; |
||||||
return output; |
} |
||||||
} |
|
||||||
|
public static Memory readMemory(Pointer process, long address, int bytesToRead) { |
||||||
public static void writeMemory(Pointer process, long address, byte[] data) { |
IntByReference read = new IntByReference(0); |
||||||
int size = data.length; |
Memory output = new Memory(bytesToRead); |
||||||
Memory toWrite = new Memory(size); |
|
||||||
|
kernel32.ReadProcessMemory(process, address, output, bytesToRead, read); |
||||||
for (int i = 0; i < size; i++) { |
return output; |
||||||
toWrite.setByte(i, data[i]); |
} |
||||||
} |
|
||||||
|
public static void writeMemory(Pointer process, long address, byte[] data) { |
||||||
boolean b = kernel32.WriteProcessMemory(process, address, toWrite, size, null); |
int size = data.length; |
||||||
} |
Memory toWrite = new Memory(size); |
||||||
|
|
||||||
public static byte[] intToBytes(final int data) { |
for (int i = 0; i < size; i++) { |
||||||
return new byte[]{ |
toWrite.setByte(i, data[i]); |
||||||
(byte) ((data >> 0) & 0xff), |
} |
||||||
(byte) ((data >> 8) & 0xff), |
|
||||||
(byte) ((data >> 16) & 0xff), |
boolean b = kernel32.WriteProcessMemory(process, address, toWrite, size, null); |
||||||
(byte) ((data >> 24) & 0xff) |
} |
||||||
}; |
|
||||||
} |
public static byte[] intToBytes(final int data) { |
||||||
|
return new byte[]{ |
||||||
public static int getBaseAddress(String executableName) throws IOException { |
(byte) ((data >> 0) & 0xff), |
||||||
String command = "powershell.exe \"$modules = Get-Process " + executableName.split("\\.")[0] + " -Module; $modules[0].BaseAddress;\""; |
(byte) ((data >> 8) & 0xff), |
||||||
// Executing the command
|
(byte) ((data >> 16) & 0xff), |
||||||
Process powerShellProcess = Runtime.getRuntime().exec(command); |
(byte) ((data >> 24) & 0xff) |
||||||
// Getting the results
|
}; |
||||||
powerShellProcess.getOutputStream().close(); |
} |
||||||
String line; |
|
||||||
BufferedReader stdout = new BufferedReader(new InputStreamReader( |
public static int getBaseAddress(String executableName) { |
||||||
powerShellProcess.getInputStream())); |
List<Integer> pids = null; |
||||||
StringBuilder output = new StringBuilder(); |
try { |
||||||
while ((line = stdout.readLine()) != null) { |
pids = PsapiTools.getInstance().enumProcesses(); |
||||||
output.append(line); |
} catch (Exception e) { |
||||||
} |
e.printStackTrace(); |
||||||
stdout.close(); |
return 0; |
||||||
return Integer.parseInt(output.toString()); |
} |
||||||
} |
for (Integer pid : pids) { |
||||||
|
WinNT.HANDLE process = com.sun.jna.platform.win32.Kernel32.INSTANCE.OpenProcess(PROCESS_PERMISSIONS, true, pid); |
||||||
} |
List<Module> hModules; |
||||||
|
try { |
||||||
|
hModules = PsapiTools.getInstance().EnumProcessModules(process); |
||||||
|
for (Module m : hModules) { |
||||||
|
//System.out.println(m.getFileName()+":"+m.getEntryPoint());
|
||||||
|
if (m.getFileName().contains(executableName)) { |
||||||
|
return (int) Pointer.nativeValue(m.getLpBaseOfDll().getPointer()); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Deprecated |
||||||
|
// Kept for historical reasons. Thanks sig.
|
||||||
|
public static int getBaseAddressPowerShell(String executableName) throws IOException { |
||||||
|
String command = "powershell.exe \"$modules = Get-Process " + executableName.split("\\.")[0] + " -Module; $modules[0].BaseAddress;\""; |
||||||
|
// Executing the command
|
||||||
|
Process powerShellProcess = Runtime.getRuntime().exec(command); |
||||||
|
// Getting the results
|
||||||
|
powerShellProcess.getOutputStream().close(); |
||||||
|
String line; |
||||||
|
BufferedReader stdout = new BufferedReader(new InputStreamReader( |
||||||
|
powerShellProcess.getInputStream())); |
||||||
|
StringBuilder output = new StringBuilder(); |
||||||
|
while ((line = stdout.readLine()) != null) { |
||||||
|
output.append(line); |
||||||
|
} |
||||||
|
stdout.close(); |
||||||
|
return Integer.parseInt(output.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
@ -0,0 +1,64 @@ |
|||||||
|
package de.marenthyu.memedit.util.sig; |
||||||
|
|
||||||
|
import com.sun.jna.platform.win32.WinDef.HMODULE; |
||||||
|
import com.sun.jna.platform.win32.WinNT.HANDLE; |
||||||
|
import de.marenthyu.memedit.util.sig.Psapi.LPMODULEINFO; |
||||||
|
|
||||||
|
public class Module { |
||||||
|
private HANDLE hProcess; |
||||||
|
private HMODULE hModule; |
||||||
|
private HANDLE lpBaseOfDll = null; |
||||||
|
private int SizeOfImage = 0; |
||||||
|
private HANDLE EntryPoint = null; |
||||||
|
|
||||||
|
private PsapiTools psapi = PsapiTools.getInstance(); |
||||||
|
|
||||||
|
protected Module() { |
||||||
|
} |
||||||
|
|
||||||
|
public Module(HANDLE hProcess, HMODULE hModule) { |
||||||
|
this.hProcess = hProcess; |
||||||
|
this.hModule = hModule; |
||||||
|
} |
||||||
|
|
||||||
|
public HMODULE getPointer() { |
||||||
|
return hModule; |
||||||
|
} |
||||||
|
|
||||||
|
public String getFileName() { |
||||||
|
return psapi.GetModuleFileNameExA(hProcess, hModule); |
||||||
|
} |
||||||
|
|
||||||
|
public String getBaseName() { |
||||||
|
return psapi.GetModuleBaseNameA(hProcess, hModule); |
||||||
|
} |
||||||
|
|
||||||
|
private void GetModuleInformation() { |
||||||
|
if (lpBaseOfDll == null) { |
||||||
|
try { |
||||||
|
LPMODULEINFO x = psapi.GetModuleInformation(hProcess, hModule); |
||||||
|
lpBaseOfDll = x.lpBaseOfDll; |
||||||
|
SizeOfImage = x.SizeOfImage; |
||||||
|
EntryPoint = x.EntryPoint; |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public HANDLE getLpBaseOfDll() { |
||||||
|
GetModuleInformation(); |
||||||
|
return lpBaseOfDll; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSizeOfImage() { |
||||||
|
GetModuleInformation(); |
||||||
|
return SizeOfImage; |
||||||
|
} |
||||||
|
|
||||||
|
public HANDLE getEntryPoint() { |
||||||
|
GetModuleInformation(); |
||||||
|
return EntryPoint; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
package de.marenthyu.memedit.util.sig; |
||||||
|
|
||||||
|
import com.sun.jna.Native; |
||||||
|
import com.sun.jna.Structure; |
||||||
|
import com.sun.jna.platform.win32.WinDef.HMODULE; |
||||||
|
import com.sun.jna.platform.win32.WinNT.HANDLE; |
||||||
|
import com.sun.jna.ptr.IntByReference; |
||||||
|
import com.sun.jna.win32.StdCallLibrary; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface Psapi extends StdCallLibrary { |
||||||
|
Psapi INSTANCE = Native.load("Psapi", Psapi.class); |
||||||
|
|
||||||
|
/* |
||||||
|
* http://msdn.microsoft.com/en-us/library/ms682629(VS.85).aspx
|
||||||
|
*/ |
||||||
|
boolean EnumProcesses(int[] pProcessIds, int cb, IntByReference pBytesReturned); |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* http://msdn.microsoft.com/en-us/library/ms682631(VS.85).aspx
|
||||||
|
*/ |
||||||
|
boolean EnumProcessModules(HANDLE hProcess, HMODULE[] lphModule, int cb, IntByReference lpcbNeededs); |
||||||
|
|
||||||
|
boolean EnumProcessModulesEx(HANDLE hProcess, HMODULE[] lphModule, int cb, IntByReference lpcbNeededs, int flags); |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* http://msdn.microsoft.com/en-us/library/ms683198(VS.85).aspx
|
||||||
|
*/ |
||||||
|
int GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, byte[] lpImageFileName, int nSize); |
||||||
|
|
||||||
|
int GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule, byte[] lpImageFileName, int nSize); |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* http://msdn.microsoft.com/en-us/library/ms684229(VS.85).aspx
|
||||||
|
*/ |
||||||
|
public static class LPMODULEINFO extends Structure { |
||||||
|
public HANDLE lpBaseOfDll; |
||||||
|
public int SizeOfImage; |
||||||
|
public HANDLE EntryPoint; |
||||||
|
@Override |
||||||
|
protected List getFieldOrder() { |
||||||
|
return Arrays.asList(new String[] { "lpBaseOfDll", "SizeOfImage", "EntryPoint"}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* http://msdn.microsoft.com/en-us/library/ms683201(VS.85).aspx
|
||||||
|
*/ |
||||||
|
boolean GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, int cb); |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package de.marenthyu.memedit.util.sig; |
||||||
|
|
||||||
|
import com.sun.jna.Native; |
||||||
|
import com.sun.jna.platform.win32.Kernel32; |
||||||
|
import com.sun.jna.platform.win32.WinDef.HMODULE; |
||||||
|
import com.sun.jna.platform.win32.WinNT.HANDLE; |
||||||
|
import com.sun.jna.ptr.IntByReference; |
||||||
|
import de.marenthyu.memedit.util.sig.Psapi.LPMODULEINFO; |
||||||
|
|
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class PsapiTools { |
||||||
|
private static PsapiTools INSTANCE=null; |
||||||
|
private static Psapi psapi = Psapi.INSTANCE; |
||||||
|
private static Kernel32 k32 = Kernel32.INSTANCE; |
||||||
|
|
||||||
|
private PsapiTools(){} |
||||||
|
|
||||||
|
public static PsapiTools getInstance(){ |
||||||
|
if (INSTANCE==null) |
||||||
|
INSTANCE=new PsapiTools(); |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<Integer> enumProcesses() throws Exception{ |
||||||
|
List<Integer> list = new LinkedList<Integer>(); |
||||||
|
|
||||||
|
int[] pProcessIds = new int[1024]; |
||||||
|
IntByReference pBytesReturned = new IntByReference(); |
||||||
|
boolean success = psapi.EnumProcesses(pProcessIds, pProcessIds.length*Integer.SIZE/8, pBytesReturned); |
||||||
|
if (!success){ |
||||||
|
int err=k32.GetLastError(); |
||||||
|
throw new Exception("EnumProcesses failed. Error: "+err); |
||||||
|
} |
||||||
|
|
||||||
|
int size = (pBytesReturned.getValue()/(Integer.SIZE/8)); |
||||||
|
for (int i=0;i<size;i++) |
||||||
|
list.add(pProcessIds[i]); |
||||||
|
|
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
public List<Module> EnumProcessModules(HANDLE hProcess) throws Exception{ |
||||||
|
List<Module> list = new LinkedList<Module>(); |
||||||
|
|
||||||
|
HMODULE[] lphModule = new HMODULE[1024]; |
||||||
|
IntByReference lpcbNeededs= new IntByReference(); |
||||||
|
boolean success = psapi.EnumProcessModules(hProcess, lphModule, lphModule.length, lpcbNeededs); |
||||||
|
if (!success){ |
||||||
|
int err=k32.GetLastError(); |
||||||
|
if (err!=6 && err!=299) { |
||||||
|
throw new Exception("EnumProcessModules failed. Error: "+err); |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i = 0; i < lpcbNeededs.getValue()/4; i++) { |
||||||
|
list.add(new Module(hProcess, lphModule[i])); |
||||||
|
} |
||||||
|
|
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
public List<Module> EnumProcessModulesEx(HANDLE hProcess, int flags) throws Exception{ |
||||||
|
List<Module> list = new LinkedList<Module>(); |
||||||
|
|
||||||
|
HMODULE[] lphModule = new HMODULE[1024]; |
||||||
|
IntByReference lpcbNeededs= new IntByReference(); |
||||||
|
boolean success = psapi.EnumProcessModulesEx(hProcess, lphModule, lphModule.length, lpcbNeededs, flags); |
||||||
|
if (!success){ |
||||||
|
int err=k32.GetLastError(); |
||||||
|
throw new Exception("EnumProcessModules failed. Error: "+err); |
||||||
|
} |
||||||
|
for (int i = 0; i < lpcbNeededs.getValue()/4; i++) { |
||||||
|
list.add(new Module(hProcess, lphModule[i])); |
||||||
|
} |
||||||
|
|
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
public String GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule){ |
||||||
|
byte[] lpImageFileName= new byte[256]; |
||||||
|
psapi.GetModuleFileNameExA(hProcess, hModule, lpImageFileName, 256); |
||||||
|
return Native.toString(lpImageFileName); |
||||||
|
} |
||||||
|
|
||||||
|
public String GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule){ |
||||||
|
byte[] lpImageFileName= new byte[256]; |
||||||
|
psapi.GetModuleBaseNameA(hProcess, hModule, lpImageFileName, 256); |
||||||
|
return Native.toString(lpImageFileName); |
||||||
|
} |
||||||
|
|
||||||
|
public LPMODULEINFO GetModuleInformation(HANDLE hProcess, HMODULE hModule) throws Exception{ |
||||||
|
LPMODULEINFO lpmodinfo = new LPMODULEINFO(); |
||||||
|
|
||||||
|
boolean success = psapi.GetModuleInformation(hProcess, hModule, lpmodinfo, lpmodinfo.size()); |
||||||
|
if (!success){ |
||||||
|
int err=k32.GetLastError(); |
||||||
|
throw new Exception("GetModuleInformation failed. Error: "+err); |
||||||
|
} |
||||||
|
return lpmodinfo; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
Thank you to https://github.com/sigonasr2/sigIRCv2 for providing the classes in this package. |
||||||
|
|
||||||
|
No LICENSE was attached to the project at the time of writing. Credit to the original author. |
Loading…
Reference in new issue