diff --git a/Crypter/Crypter.vcxproj b/Crypter/Crypter.vcxproj
index 281c31a..5513f6b 100644
--- a/Crypter/Crypter.vcxproj
+++ b/Crypter/Crypter.vcxproj
@@ -78,9 +78,20 @@
true
+ $(IncludePath)
+ false
+ $(LibraryPath)
false
+ $(IncludePath)
+ false
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);
+
+
+ true
+ true
+ true
@@ -121,6 +132,7 @@
Console
true
+ %(AdditionalDependencies)
diff --git a/Crypter/Crypter.vcxproj.filters b/Crypter/Crypter.vcxproj.filters
index 682958d..d62534f 100644
--- a/Crypter/Crypter.vcxproj.filters
+++ b/Crypter/Crypter.vcxproj.filters
@@ -14,9 +14,6 @@
{47733102-deb7-437d-ada8-bca851a43356}
-
- {ecae1be1-6edb-45a9-bf23-273b5e5bf6f3}
-
diff --git a/Crypter/main.cpp b/Crypter/main.cpp
index 8366d3b..97048e2 100644
--- a/Crypter/main.cpp
+++ b/Crypter/main.cpp
@@ -8,14 +8,13 @@
#include
#include
-#include
-#include
+#include
+#include
#include "random.hpp"
#include "utils.hpp"
#include "config.hpp"
-
extern g_random random;
unsigned __int64 origSeed;
@@ -165,10 +164,11 @@ int main(int argc, char* argv[]) {
}
printf("\n");
+ printf(" Enumerating .text instructions and finding the stuff to change...\n");
// Initialize decoder context
ZydisDecoder decoder;
- ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
+ ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_STACK_WIDTH_32);
// Initialize formatter. Only required when you actually plan to do instruction
// formatting ("disassembling"), like we do here
@@ -182,18 +182,58 @@ int main(int argc, char* argv[]) {
ZyanUSize offset = text_addr;
const ZyanUSize length = sizeof((char*)mapped_file);
ZydisDecodedInstruction instruction;
+ ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, (char*)mapped_file + offset, length - offset,
- &instruction)) && offset < text_size + text_addr)
+ while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(&decoder, (char*)mapped_file + offset, length - offset,
+ &instruction, operands)) && offset < text_size + text_addr)
{
// Print current instruction pointer.
printf(" %016" PRIX64 " ", runtime_address);
// Format & print the binary instruction structure to human-readable format
char buffer[256];
- ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer), runtime_address);
+ ZydisFormatterFormatInstruction(&formatter, &instruction, operands, instruction.operand_count_visible, buffer, sizeof(buffer), runtime_address, ZYAN_NULL);
puts(buffer);
+ // Create an encoder request from the previously decoded instruction.
+ ZydisEncoderRequest enc_req;
+ ZydisEncoderDecodedInstructionToEncoderRequest(&instruction, operands,
+ instruction.operand_count_visible, &enc_req);
+
+ // Now, change some things about the instruction!
+
+ // Change `jz` -> `jnz` and `add` -> `sub`.
+ bool changed = true;
+ switch (enc_req.mnemonic)
+ {
+ case ZYDIS_MNEMONIC_ADD:
+ enc_req.mnemonic = ZYDIS_MNEMONIC_SUB;
+ break;
+ case ZYDIS_MNEMONIC_JZ:
+ enc_req.mnemonic = ZYDIS_MNEMONIC_JNZ;
+ break;
+ default:
+ // Don't change other instructions.
+ changed = false;
+ break;
+ }
+
+ if (changed) {
+ printf(" Instruction %s changed\n", buffer);
+ }
+
+ // Encode the instruction back to raw bytes.
+ uint8_t new_bytes[ZYDIS_MAX_INSTRUCTION_LENGTH];
+ ZyanUSize new_instr_length = sizeof(new_bytes);
+ ZydisEncoderEncodeInstruction(&enc_req, new_bytes, &new_instr_length);
+
+ // Decode and print the new instruction. We re-use the old buffers.
+ ZydisDecoderDecodeFull(&decoder, new_bytes, new_instr_length, &instruction,
+ operands);
+ ZydisFormatterFormatInstruction(&formatter, &instruction, operands,
+ instruction.operand_count_visible, buffer, sizeof(buffer), 0, NULL);
+ printf(" New instruction: %s\n", buffer);
+
offset += instruction.length;
runtime_address += instruction.length;
}