Skip to content

Commit

Permalink
Merge pull request #10 from seeker89/jvm
Browse files Browse the repository at this point in the history
Chapter 8: JVM
  • Loading branch information
seeker89 authored Jun 13, 2020
2 parents b0a336b + 06536c1 commit f99a1e2
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 1 deletion.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
all: killer-whiles who-you-gonna-call
all: killer-whiles who-you-gonna-call jvm

killer-whiles:
(cd examples/killer-whiles && make)
Expand All @@ -7,6 +7,9 @@ who-you-gonna-call:
(cd examples/who-you-gonna-call && make)
(cd examples/who-you-gonna-call/src && make gen && make)

jvm:
(cd examples/jvm && make)

clean:
rm -rf vm/vm.zip vm/parts.sha256 vm/chaos-engineering-VM*

Expand Down
75 changes: 75 additions & 0 deletions examples/jvm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
CFLAGS=-O0

all: FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition byteman-download-4.0.11 byte-monkey.jar

src:
git clone https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition.git src

byteman-download-4.0.11:
wget https://downloads.jboss.org/byteman/4.0.11/byteman-download-4.0.11-bin.zip
unzip byteman-download-4.0.11-bin.zip
rm byteman-download-4.0.11-bin.zip

byte-monkey.jar:
wget https://github.com/mrwilson/byte-monkey/releases/download/1.0.0/byte-monkey.jar

FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition: src
(cd src && ./gradlew assemble && ./gradlew build)
unzip src/build/distributions/FizzBuzzEnterpriseEdition.zip

run:
./FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition

run2:
java -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main

run3:
javap -classpath "./FizzBuzzEnterpriseEdition/lib/*" -c com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main

run4:
java -javaagent:./agent1.jar -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main

run5:
java -javaagent:./agent2.jar -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main

run6:
java \
-javaagent:./byteman-download-4.0.11/lib/byteman.jar=script:throw.btm \
-classpath "./FizzBuzzEnterpriseEdition/lib/*" \
com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main

run7:
java \
-javaagent:byte-monkey.jar=mode:fault,rate:0.5,filter:com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/strategies/SystemOutFizzBuzzOutputStrategy/output \
-classpath "./FizzBuzzEnterpriseEdition/lib/*" \
com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main



example1-compile:
javac ./org/my/example1.java
example1-run:
java org.my.Example1
example1-bytecode:
javap -c org.my.Example1
example1-agent:
java -javaagent:./agent1.jar org.my.Example1

example2-compile:
javac ./org/my/example2.java
example2-run:
java org.my.Example2
example2-bytecode:
javap -c org.my.Example2

.PHONY: run run2 run3 example1-compile example1-run example1-bytecode example2-compile example2-run example2-bytecode

agent1.jar: org/agent/Agent.java org/agent/ClassPrinter.java org/agent/manifest.mf
javac org/agent/Agent.java
javac org/agent/ClassPrinter.java
jar vcmf org/agent/manifest.mf agent1.jar org/agent

agent2.jar: org/agent2/Agent.java org/agent2/ClassInjector.java org/agent2/manifest.mf
javac -XDignore.symbol.file org/agent2/Agent.java
javac -XDignore.symbol.file org/agent2/ClassInjector.java
jar vcmf org/agent2/manifest.mf agent2.jar org/agent2
10 changes: 10 additions & 0 deletions examples/jvm/org/agent/Agent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.agent;

import java.lang.instrument.Instrumentation;

class Agent {
public static void premain(String args, Instrumentation instrumentation){
ClassPrinter transformer = new ClassPrinter();
instrumentation.addTransformer(transformer);
}
}
17 changes: 17 additions & 0 deletions examples/jvm/org/agent/ClassPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.agent;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;


class ClassPrinter implements ClassFileTransformer {
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
System.out.println("Found class: " + className + " (" + classfileBuffer.length + " bytes)");
return classfileBuffer;
}
}
2 changes: 2 additions & 0 deletions examples/jvm/org/agent/manifest.mf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
Premain-Class: org.agent.Agent
10 changes: 10 additions & 0 deletions examples/jvm/org/agent2/Agent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.agent2;

import java.lang.instrument.Instrumentation;

class Agent {
public static void premain(String args, Instrumentation instrumentation){
ClassInjector transformer = new ClassInjector();
instrumentation.addTransformer(transformer);
}
}
59 changes: 59 additions & 0 deletions examples/jvm/org/agent2/ClassInjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.agent2;

import java.io.IOException;
import java.util.List;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.tree.*;
import jdk.internal.org.objectweb.asm.Opcodes;


public class ClassInjector implements ClassFileTransformer {

public String targetClassName = "com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/strategies/SystemOutFizzBuzzOutputStrategy";

public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
if (className.equals(this.targetClassName)){
System.err.println("[CHAOS] TARGET ACQUIRED: " + className + " (" + classfileBuffer.length + " bytes)");

ClassNode classNode = new ClassNode();
new ClassReader(classfileBuffer).accept(classNode, 0);
classNode.methods.stream()
.filter(method -> method.name.equals("output"))
.forEach(method -> {
InsnList instructions = new InsnList();
instructions.add(new MethodInsnNode(
Opcodes.INVOKESTATIC,
"org/agent2/ClassInjector",
"throwIOException",
"()V",
false // not a method
));
method.maxStack += 1;
method.instructions.insertBefore(method.instructions.getFirst(), instructions);
System.err.println("[CHAOS] Method " + method.name + " modified");
});
final ClassWriter classWriter = new ClassWriter(0);
classNode.accept(classWriter);
byte[] bytes = classWriter.toByteArray();
System.err.println("[CHAOS] Rewrote: " + className + " (" + bytes.length + " bytes)");
return bytes;
}
return classfileBuffer;
}

public static void throwIOException() throws IOException
{
System.err.println("[CHAOS] BOOM! Throwing");
throw new IOException("CHAOS");
}
}
4 changes: 4 additions & 0 deletions examples/jvm/org/agent2/manifest.mf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Manifest-Version: 1.0
Premain-Class: org.agent2.Agent
Can-Redefine-Classes: true
Can-Retransform-Classes: true
9 changes: 9 additions & 0 deletions examples/jvm/org/my/example1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.my;

class Example1
{
public static void main(String[] args)
{
System.out.println("Hello chaos!");
}
}
15 changes: 15 additions & 0 deletions examples/jvm/org/my/example2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.my;
import java.io.IOException;

class Example2
{
public static void main(String[] args) throws IOException
{
Example2.throwIOException();
}

public static void throwIOException() throws IOException
{
throw new IOException("Oops");
}
}
9 changes: 9 additions & 0 deletions examples/jvm/throw.btm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
RULE throw an exception at output
CLASS SystemOutFizzBuzzOutputStrategy
METHOD output
AT ENTRY
IF true
DO
traceln("entering the method output");
throw new java.io.IOException("BOOM");
ENDRULE
2 changes: 2 additions & 0 deletions vm/ansible/prerequisites/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ packages_to_install:
- manpages-posix-dev
# seccomp
- libseccomp-dev
# java
- openjdk-8-jdk

packages_to_remove:
- libreoffice-core
Expand Down
9 changes: 9 additions & 0 deletions vm/ansible/prerequisites/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,12 @@
become: false
shell: |
gsettings set org.gnome.desktop.session idle-delay 0
- name: Add auto-login
become: true
lineinfile:
path: /etc/gdm3/custom.conf
line: "{{ item }}"
loop:
- "AutomaticLoginEnable = true"
- "AutomaticLogin = chaos"

0 comments on commit f99a1e2

Please sign in to comment.