Skip to content

Commit

Permalink
Added the injector package
Browse files Browse the repository at this point in the history
+[ADD] Added Injector.java which allows injecting code into hooked
processes
+[ADD] SpaceInvaders as example for jar to jar injection
-[ADD] Custom exceptions for common errors
  • Loading branch information
Zabuzard committed Jun 24, 2016
1 parent 280b4b5 commit ad601b8
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 1 deletion.
Binary file added lib/attach.dll
Binary file not shown.
Binary file added lib/tools.jar
Binary file not shown.
Binary file added releases/memEaterBug-1.0.zip
Binary file not shown.
Binary file added res/examples/SpaceInvaders.jar
Binary file not shown.
Binary file added res/examples/SpaceInvadersInjection.jar
Binary file not shown.
25 changes: 24 additions & 1 deletion src/de/zabuza/memeaterbug/MemEaterBug.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.sun.jna.platform.win32.WinNT.HANDLE;

import de.zabuza.memeaterbug.exceptions.NotHookedException;
import de.zabuza.memeaterbug.injection.Injector;
import de.zabuza.memeaterbug.locale.ErrorMessages;
import de.zabuza.memeaterbug.memory.MemManipulator;
import de.zabuza.memeaterbug.util.Masks;
Expand All @@ -26,6 +28,10 @@
*/
public final class MemEaterBug {

/**
* Injector for the current process handle, if hooked, <tt>null</tt> else.
*/
private Injector mInjector;
/**
* If the current process runs in an 64 bit environment or not. Can only be
* accessed after the the Mem-Eater-Bug was hooked to a process using
Expand Down Expand Up @@ -73,6 +79,7 @@ public MemEaterBug(final int processId) {
mIsHooked = false;
mProcessHandle = null;
mMemManipulator = null;
mInjector = null;

if (processId == 0) {
throw new IllegalArgumentException(ErrorMessages.PROCESS_NOT_FOUND);
Expand Down Expand Up @@ -115,6 +122,21 @@ public MemEaterBug(final String processClassName, final String windowTitle) {
this(User32Util.getWindowThreadProcessIdByClassAndTitle(processClassName, windowTitle).getValue());
}

/**
* Gets an object for injecting code into the hooked process.
*
* @return An object for injecting code into the hooked process.
* @throws IllegalStateException
* If the Mem-Eater-Bug is not hooked to a process
*/
public Injector getInjector() throws IllegalStateException {
ensureIsHooked();
if (mInjector == null) {
mInjector = new Injector(mProcessId, mProcessHandle);
}
return mInjector;
}

/**
* Gets an object for memory manipulation of the hooked process.
*
Expand Down Expand Up @@ -224,6 +246,7 @@ public void unhookProcess() {
}
mProcessHandle = null;
mMemManipulator = null;
mInjector = null;
mIsHooked = false;
}

Expand All @@ -236,7 +259,7 @@ public void unhookProcess() {
*/
private void ensureIsHooked() throws IllegalStateException {
if (!mIsHooked) {
throw new IllegalStateException(ErrorMessages.UNABLE_SINCE_NOT_HOOKED);
throw new NotHookedException(ErrorMessages.UNABLE_SINCE_NOT_HOOKED);
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/de/zabuza/memeaterbug/examples/SoliScorer.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,11 @@ public static void main(final String[] args) {
// Unhook from the game
memEaterBug.unhookProcess();
}

/**
* Utility class. No implementation.
*/
private SoliScorer() {

}
}
41 changes: 41 additions & 0 deletions src/de/zabuza/memeaterbug/examples/SpaceInvadersInjection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package de.zabuza.memeaterbug.examples;

import java.lang.instrument.Instrumentation;

/**
* Hack for the popular game Space Invaders that displays various information on
* the game screen by jar-injection.<br/>
* <br/>
* This is the agent as jar that gets injected inside the Space Invaders
* jar-file.
*
* @author Zabuza
*
*/
public final class SpaceInvadersInjection {

/**
* JVM hook to dynamically load this agent at runtime.
*
* @param args
* Passed arguments, not supported
* @param inst
* Object used for ByteCode manipulation
*/
public static void agentmain(final String args, final Instrumentation inst) {
try {
System.out.println("Injected the agent.");
} catch (Exception e) {
// Catch and print every exception as they would otherwise be
// ignored in an agentmain method
e.printStackTrace();
}
}

/**
* Utility class. No implementation.
*/
private SpaceInvadersInjection() {

}
}
48 changes: 48 additions & 0 deletions src/de/zabuza/memeaterbug/examples/SpaceInvadersInjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.zabuza.memeaterbug.examples;

import de.zabuza.memeaterbug.MemEaterBug;
import de.zabuza.memeaterbug.injection.Injector;

/**
* Hack for the popular game Space Invaders that displays various information on
* the game screen by jar-injection.
*
* @author Zabuza
*
*/
public final class SpaceInvadersInjector {
/**
* Demonstrates the usage of the Mem-Eater-Bug for jar-injection by
* displaying various information on the game screen of the game Space
* Invaders.<br/>
* <br/>
* The program was tested on a Windows 10 64-bit system using the provided
* SpaceInvaders.jar file.
*
* @param args
* Not supported
*/
public static void main(final String[] args) {
// Constants
String windowTitle = "Space Invaders 101";
String pathToInjectionAgent = "C:\\Users\\Zabuza\\Desktop\\SpaceInvadersInjection.jar";

// Hook to the game
MemEaterBug memEaterBug = new MemEaterBug(null, windowTitle);
memEaterBug.hookProcess();
Injector injector = memEaterBug.getInjector();

// Inject the agent jar into the target jar
injector.injectJarIntoJar(pathToInjectionAgent);

// Unhook from the game
memEaterBug.unhookProcess();
}

/**
* Utility class. No implementation.
*/
private SpaceInvadersInjector() {

}
}
35 changes: 35 additions & 0 deletions src/de/zabuza/memeaterbug/exceptions/NotHookedException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package de.zabuza.memeaterbug.exceptions;

/**
* Thrown when a method could not be executed since the
* {@link de.zabuza.memeaterbug.MemEaterBug MemEaterBug} was not hooked to a
* process.
*
* @author Zabuza
*
*/
public final class NotHookedException extends RuntimeException {

/**
* Serial UID.
*/
private static final long serialVersionUID = 1L;

/**
* Creates a new exception without a detailed description.
*/
public NotHookedException() {
super();
}

/**
* Creates a new exception with a given description.
*
* @param description
* Description of the exception
*/
public NotHookedException(final String description) {
super(description);
}

}
34 changes: 34 additions & 0 deletions src/de/zabuza/memeaterbug/exceptions/UnableToInjectException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.zabuza.memeaterbug.exceptions;

/**
* Thrown when an {@link de.zabuza.memeaterbug.injection.Injector Injector}
* method could not inject code into the given process.
*
* @author Zabuza
*
*/
public final class UnableToInjectException extends RuntimeException {

/**
* Serial UID.
*/
private static final long serialVersionUID = 1L;

/**
* Creates a new exception without a detailed description.
*/
public UnableToInjectException() {
super();
}

/**
* Creates a new exception with a given description.
*
* @param description
* Description of the exception
*/
public UnableToInjectException(final String description) {
super(description);
}

}
4 changes: 4 additions & 0 deletions src/de/zabuza/memeaterbug/exceptions/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* This is the core package for exceptions and error handling for Mem-Eater-Bug.
*/
package de.zabuza.memeaterbug.exceptions;
115 changes: 115 additions & 0 deletions src/de/zabuza/memeaterbug/injection/Injector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package de.zabuza.memeaterbug.injection;

import java.io.IOException;

import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

import de.zabuza.memeaterbug.exceptions.UnableToInjectException;
import de.zabuza.memeaterbug.locale.ErrorMessages;
import de.zabuza.memeaterbug.winapi.Process;
import de.zabuza.memeaterbug.winapi.jna.util.PsapiUtil;

/**
* Provides various methods for injecting code into a given process.
*
* @author Zabuza
*
*/
public final class Injector {

/**
* Name of the attach library that is used for attaching to a virtual
* machine.
*/
private static final String ATTACH_LIBRARY_NAME = "attach";

/**
* The process this object belongs to.
*/
private final Process mProcess;

/**
* Creates a new object that is able to inject code into the given process.
*
* @param processId
* Id of the process to inject into
*/
public Injector(final int processId) {
this(processId, null);
}

/**
* Creates a new object that is able to inject code into the given process.
*
* @param processId
* Id of the process to inject into
* @param processHandle
* An optional previously created handle object that must
* correspond to the same process that is specified by processId.
* Using <tt>null</tt> results in the creation of a default
* handle, that has all access rights.
*/
public Injector(final int processId, final HANDLE processHandle) {
mProcess = PsapiUtil.getProcessById(processId);
if (processHandle != null) {
mProcess.setHandle(processHandle);
}
loadAttachLibrary();
}

/**
* Loads the native attach library into the built path. It is used for
* attaching to a virtual machine.
*/
private void loadAttachLibrary() {
System.loadLibrary(ATTACH_LIBRARY_NAME);
}

/**
* Injects a given agent jar-file into the hooked process. The hooked
* process also needs to be a jar-file.
*
* @param pathToAgentJar
* Path to the agent jar-file to inject. The agent jar-file needs
* to specify an agentmain-method and must have the Agent-Class
* key accordingly.
* @throws UnableToInjectException
* If the operation was unable to inject the agent jar-file into
* the target jar-file
*/
public void injectJarIntoJar(final String pathToAgentJar) throws UnableToInjectException {
try {
VirtualMachine vm = VirtualMachine.attach("" + mProcess.getPid());
vm.loadAgent(pathToAgentJar);
vm.detach();
} catch (AttachNotSupportedException | AgentLoadException | AgentInitializationException | IOException e) {
throw new UnableToInjectException(ErrorMessages.UNABLE_TO_INJECT_JAR_INTO_JAR);
}
}

/**
* Injects a given agent library into the hooked process. The hooked process
* needs to be a jar-file.
*
* @param pathToAgentLibrary
* Path to the agent library to inject. The agent library needs
* to specify all needed agent-methods via the native agent
* interface.
* @throws UnableToInjectException
* If the operation was unable to inject the agent library into
* the target jar-file
*/
public void injectLibraryIntoJar(final String pathToAgentLibrary) throws UnableToInjectException {
try {
VirtualMachine vm = VirtualMachine.attach("" + mProcess.getPid());
vm.loadAgentLibrary(pathToAgentLibrary);
vm.detach();
} catch (AttachNotSupportedException | AgentLoadException | AgentInitializationException | IOException e) {
throw new UnableToInjectException(ErrorMessages.UNABLE_TO_INJECT_LIBRARY_INTO_JAR);
}
}
}
4 changes: 4 additions & 0 deletions src/de/zabuza/memeaterbug/injection/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* This is the core package for injecting code into processes.
*/
package de.zabuza.memeaterbug.injection;
10 changes: 10 additions & 0 deletions src/de/zabuza/memeaterbug/locale/ErrorMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ public final class ErrorMessages {
* process.
*/
public static final String UNABLE_SINCE_NOT_HOOKED = "Unable to execute since not hooked to a process. First hook, then try again.";
/**
* Thrown when an {@link de.zabuza.memeaterbug.injection.Injector Injector}
* method could not inject an agent jar file into a target jar file.
*/
public static final String UNABLE_TO_INJECT_JAR_INTO_JAR = "Unable to inject the agent jar into the target jar. Ensure the target process is a jar-file and you have all needed permissions. Also make sure the agent jar specifies an agentmain-method and has set the Agent-Class key accordingly.";
/**
* Thrown when an {@link de.zabuza.memeaterbug.injection.Injector Injector}
* method could not inject an agent jar file into a target jar file.
*/
public static final String UNABLE_TO_INJECT_LIBRARY_INTO_JAR = "Unable to inject the agent library into the target jar. Ensure the target process is a jar-file and you have all needed permissions. Also make sure the agent library specifies all needed agent-methods via the native agent interface.";

/**
* Utility class. No implementation.
Expand Down

0 comments on commit ad601b8

Please sign in to comment.