diff --git a/ShellcodeObfuscator/Obfuscator.cpp b/ShellcodeObfuscator/Obfuscator.cpp index b00faab..d96de79 100644 --- a/ShellcodeObfuscator/Obfuscator.cpp +++ b/ShellcodeObfuscator/Obfuscator.cpp @@ -71,25 +71,89 @@ bool obf_init_from_buffer(pobfuscator_t obf, void* buffer, int buffer_size) } } -void obf_create_groups(pobfuscator_t obf, int group_size) +bool obf_create_groups(pobfuscator_t obf, int group_size) { - int group_id = 0, size_in_bytes = 0; + + obf->groups.clear(); + + if (group_size < 24) + return false; + + int cur_group_id = 0, cur_size_in_bytes = 0; pcode_link_t start = obf->code_start->next; for (pcode_link_t t = obf->code_start->next; t; t = t->next) { - if (size_in_bytes + t->instruction._decoded_length > group_size) + if (!(t->flags & CLFLAG_IS_GAGET)) { - size_in_bytes = 0; - obf->groups.emplace_back(); - obf->groups.back().size_in_bytes = size_in_bytes; - obf->groups.back().start = start; - start = t; - ++group_id; + if (cur_size_in_bytes + t->raw_data_size + 16 > group_size) + { + + pcode_link_t push_rax = new code_link_t; + push_rax->flags = 0; + push_rax->label_name = ""; + push_rax->raw_data = new unsigned char[1]; + push_rax->raw_data_size = 1; + push_rax->group = cur_group_id; + *(unsigned char*)push_rax->raw_data = 0x50; + push_rax->label_name = ""; + + pcode_link_t mov_address = new code_link_t; + mov_address->flags = CLFLAG_IS_GROUP_JMP; + mov_address->label_name = t->label_name; + mov_address->raw_data = new unsigned char[10]; + mov_address->raw_data_size = 10; + mov_address->group = cur_group_id; + unsigned char mov_address_data[] = { 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F }; + memcpy(mov_address->raw_data, mov_address_data, 10); + + pcode_link_t xchg_rax_rsp = new code_link_t; + xchg_rax_rsp->flags = 0; + xchg_rax_rsp->label_name = ""; + xchg_rax_rsp->raw_data = new unsigned char[4]; + xchg_rax_rsp->raw_data_size = 4; + xchg_rax_rsp->group = cur_group_id; + unsigned char xchg_rax_rsp_data[] = { 0x48, 0x87, 0x04, 0x24 }; + memcpy(xchg_rax_rsp->raw_data, xchg_rax_rsp_data, 4); + + pcode_link_t ret = new code_link_t; + ret->flags = 0; + ret->label_name = ""; + ret->raw_data = new unsigned char[1]; + ret->raw_data_size = 1; + ret->group = cur_group_id; + *(unsigned char*)ret->raw_data = 0xC3; + + t->prev->next = push_rax; + push_rax->next = mov_address; + mov_address->next = xchg_rax_rsp; + xchg_rax_rsp->next = ret; + ret->next = t; + + ret->prev = xchg_rax_rsp; + xchg_rax_rsp->prev = mov_address; + mov_address->prev = push_rax; + push_rax->prev = t->prev; + t->prev = ret; + + printf("creating group %d\n", cur_group_id); + obf->groups.emplace_back(); + obf->groups.back().size_in_bytes = cur_size_in_bytes + 16; + obf->groups.back().start = start; + cur_size_in_bytes = 0; + cur_group_id++; + start = t; + } } - t->group = group_id; - size_in_bytes += t->instruction._decoded_length; + cur_size_in_bytes += t->raw_data_size; + t->group = cur_group_id; } + + obf->groups.emplace_back(); + obf->groups.back().size_in_bytes = cur_size_in_bytes + 16; + obf->groups.back().start = start; + + return true; } void obf_replace_rel_jmps(pobfuscator_t obf) @@ -119,10 +183,10 @@ void obf_replace_rel_jmps(pobfuscator_t obf) case 4: *(int*)((unsigned char*)t->raw_data + opcode_size) = (int)2; break; } - t->flags = 0; + t->flags = CLFLAG_IS_GAGET; pcode_link_t jmp_around_gagt = new code_link_t; - jmp_around_gagt->flags = 0; + jmp_around_gagt->flags = CLFLAG_IS_GAGET; jmp_around_gagt->label_name = ""; jmp_around_gagt->raw_data = new unsigned char[2]; jmp_around_gagt->raw_data_size = 2; @@ -131,7 +195,7 @@ void obf_replace_rel_jmps(pobfuscator_t obf) pcode_link_t push_rax = new code_link_t; - push_rax->flags = 0; + push_rax->flags = CLFLAG_IS_GAGET; push_rax->label_name = ""; push_rax->raw_data = new unsigned char[1]; push_rax->raw_data_size = 1; @@ -140,7 +204,7 @@ void obf_replace_rel_jmps(pobfuscator_t obf) pcode_link_t mov_address = new code_link_t; - mov_address->flags = CLFLAG_IS_ABS_ADDR; + mov_address->flags = (CLFLAG_IS_ABS_ADDR | CLFLAG_IS_GAGET); mov_address->label_name = t->label_name; mov_address->raw_data = new unsigned char[10]; mov_address->raw_data_size = 10; @@ -148,7 +212,7 @@ void obf_replace_rel_jmps(pobfuscator_t obf) memcpy(mov_address->raw_data, mov_address_data, 10); pcode_link_t xchg_rax_rsp = new code_link_t; - xchg_rax_rsp->flags = 0; + xchg_rax_rsp->flags = CLFLAG_IS_GAGET; xchg_rax_rsp->label_name = ""; xchg_rax_rsp->raw_data = new unsigned char[4]; xchg_rax_rsp->raw_data_size = 4; @@ -156,7 +220,7 @@ void obf_replace_rel_jmps(pobfuscator_t obf) memcpy(xchg_rax_rsp->raw_data, xchg_rax_rsp_data, 4); pcode_link_t ret = new code_link_t; - ret->flags = 0; + ret->flags = CLFLAG_IS_GAGET; ret->label_name = ""; ret->raw_data = new unsigned char[1]; ret->raw_data_size = 1; @@ -184,35 +248,8 @@ void obf_replace_rel_jmps(pobfuscator_t obf) } } -void obf_replace_abs_jmps(pobfuscator_t obf) +bool obf_replace_abs_jmps(pobfuscator_t obf) { - //FIRST ITERATE AND CHECK BEHIND THE JMP - //pcode_link_t Temp; - //for (Temp = Jmp; Temp && Temp->Prev; Temp = Temp->Prev) - //{ - // if (Temp->Prev->IsLabel && Temp->Prev->Name == Jmp->Name) - // { - // Jmp->Data = (PVOID)Delta; - // return TRUE; - // } - // Delta -= Assembler->Instructions[Temp->Prev->InstructionId].LengthInBytes; - //} - - ////NOW LOOK IN FRONT - //Delta = Assembler->Instructions[Jmp->InstructionId].LengthInBytes; //9 - //for (Temp = Jmp; Temp && Temp->Next; Temp = Temp->Next) - //{ - // if (Temp->Next->IsLabel && Temp->Next->Name == Jmp->Name) - // { - // Jmp->Data = (PVOID)Delta; - // return TRUE; - // } - // Delta += Assembler->Instructions[Temp->Next->InstructionId].LengthInBytes; - //} - - //return FALSE; - - for (pcode_link_t t = obf->code_start->next; t;) { if (t->flags & CLFLAG_IS_ABS_ADDR) @@ -222,21 +259,33 @@ void obf_replace_abs_jmps(pobfuscator_t obf) { if (temp->flags & CLFLAG_IS_LABEL && temp->label_name == t->label_name) { - uint64_t addr = obf->groups[t->group].base_address; - pcode_link_t temp2 = obf->groups[t->group].start; - for (; temp2 && temp2->group == temp->group; temp2 = temp2->next) - { - if (temp2 == temp) - { - break; - } - addr += temp->raw_data_size; - } + goto have_label_found; + } + } + for (temp = t; temp && temp->next; temp = temp->next) + { + if (temp->flags & CLFLAG_IS_LABEL && temp->label_name == t->label_name) + { + goto have_label_found; + } + } + return false; + continue; + have_label_found: + uint64_t addr = obf->groups[temp->group].base_address; + for (pcode_link_t temp2 = obf->groups[temp->group].start; temp2 && temp2->group == temp->group; temp2 = temp2->next) + { + if (temp2 == temp) + { + break; } + addr += temp->raw_data_size; } + *(uint64_t*)((unsigned char*)t->raw_data + 2) = addr; } } + return true; } size_t obf_get_group_size(pobfuscator_t obf, int group_id) @@ -344,6 +393,19 @@ void obf_dbg_print_code(pobfuscator_t obf) } } +void obf_dbg_print_group(pobfuscator_t obf, int group_id) +{ + if (group_id >= obf->groups.size()) + return; + + for (pcode_link_t t = obf->groups[group_id].start; t && t->group == group_id; t = t->next) + { + if (!(t->flags & CLFLAG_IS_LABEL)) + { + obf_print_byte_array(t->raw_data, t->raw_data_size); + } + } +} #include #include diff --git a/ShellcodeObfuscator/Obfuscator.h b/ShellcodeObfuscator/Obfuscator.h index eaf45a3..1632dea 100644 --- a/ShellcodeObfuscator/Obfuscator.h +++ b/ShellcodeObfuscator/Obfuscator.h @@ -12,6 +12,8 @@ extern "C" #define CLFLAG_IS_LABEL (1<<0) #define CLFLAG_IS_REL_JUMP (1<<1) #define CLFLAG_IS_ABS_ADDR (1<<2) +#define CLFLAG_IS_GAGET (1<<3) +#define CLFLAG_IS_GROUP_JMP (1<<4) typedef struct _code_link_t { @@ -52,13 +54,13 @@ void obf_one_time_please(); bool obf_init_from_buffer(pobfuscator_t obf, void* buffer, int buffer_size); //creates the groups of instructions based on number of bytes -void obf_create_groups(pobfuscator_t obf, int group_size); +bool obf_create_groups(pobfuscator_t obf, int group_size); //replaces all relative jumps with the abs jump gadget void obf_replace_rel_jmps(pobfuscator_t obf); //replaces address in the abs jmp stub with the right address of the given label. -void obf_replace_abs_jmps(pobfuscator_t obf); +bool obf_replace_abs_jmps(pobfuscator_t obf); //return number of bytes needed to store given group size_t obf_get_group_size(pobfuscator_t obf, int group_id); @@ -75,6 +77,8 @@ bool obf_gen_label(pobfuscator_t obf, pcode_link_t start, int32_t delta); void obf_dbg_print_code(pobfuscator_t obf); +void obf_dbg_print_group(pobfuscator_t obf, int group_id); + void obf_print_byte_array(void* arr, unsigned int size); diff --git a/ShellcodeObfuscator/main.cpp b/ShellcodeObfuscator/main.cpp index 1558faa..2633377 100644 --- a/ShellcodeObfuscator/main.cpp +++ b/ShellcodeObfuscator/main.cpp @@ -17,6 +17,7 @@ int main(int argc, char** argv) { + unsigned char buffer[] = { 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, 0xEB, 0x08, 0x48, 0x33, 0xC0, 0x7E, 0x03, 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0 };//{ 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, 0xEB, 0xFB, 0x48, 0x33, 0xC0, 0x7E, 0xF6, 0xC3 }; unsigned int buffer_size = sizeof(buffer); @@ -24,7 +25,13 @@ int main(int argc, char** argv) obf_one_time_please(); obf_init_from_buffer(&obf, buffer, buffer_size); obf_gen_all_labels(&obf); - obf_replace_rel_jmps(&obf); + //obf_replace_rel_jmps(&obf); obf_dbg_print_code(&obf); + obf_create_groups(&obf, 28); + for (int i = 0; i < obf.groups.size(); i++) + { + printf("printing group %d \n", i); + obf_dbg_print_group(&obf, i); + } system("pause"); } diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.command.1.tlog b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.command.1.tlog index 9eaff67..8e49b8a 100644 Binary files a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.command.1.tlog and b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.command.1.tlog differ diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.read.1.tlog b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.read.1.tlog index 76dcc75..b4066f5 100644 Binary files a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.read.1.tlog and b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.read.1.tlog differ diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.write.1.tlog b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.write.1.tlog index 11f0789..9212edc 100644 Binary files a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.write.1.tlog and b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/CL.write.1.tlog differ diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/ShellcodeObfuscator.write.1u.tlog b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/ShellcodeObfuscator.write.1u.tlog index 620e80f..be57009 100644 Binary files a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/ShellcodeObfuscator.write.1u.tlog and b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/ShellcodeObfuscator.write.1u.tlog differ diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/link.read.1.tlog b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/link.read.1.tlog index 95b01bf..0830750 100644 Binary files a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/link.read.1.tlog and b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/link.read.1.tlog differ diff --git a/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/unsuccessfulbuild b/ShellcodeObfuscator/x64/Release/Shellcod.ad60371b.tlog/unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/ShellcodeObfuscator/x64/Release/ShellcodeObfuscator.log b/ShellcodeObfuscator/x64/Release/ShellcodeObfuscator.log index de9e71d..3e3e23f 100644 --- a/ShellcodeObfuscator/x64/Release/ShellcodeObfuscator.log +++ b/ShellcodeObfuscator/x64/Release/ShellcodeObfuscator.log @@ -1,9 +1,3 @@ - Obfuscator.cpp -C:\$Fanta\ShellcodeObfuscator\ShellcodeObfuscator\Obfuscator.cpp(353,20): warning C4018: '<': signed/unsigned mismatch -LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library - Generating code - 2 of 134 functions ( 1.5%) were compiled, the rest were copied from previous compilation. - 0 functions were new in current compilation - 0 functions had inline decision re-evaluated but remain unchanged - Finished generating code - ShellcodeObfuscator.vcxproj -> C:\$Fanta\ShellcodeObfuscator\x64\Release\ShellcodeObfuscator.exe + main.cpp +C:\$Fanta\ShellcodeObfuscator\ShellcodeObfuscator\main.cpp(33,35): error C2228: left of '.i' must have class/struct/union +C:\$Fanta\ShellcodeObfuscator\ShellcodeObfuscator\main.cpp(33,35): message : type is 'const char [20]' diff --git a/x64/Release/ShellcodeObfuscator.iobj b/x64/Release/ShellcodeObfuscator.iobj index af49c9e..99150af 100644 Binary files a/x64/Release/ShellcodeObfuscator.iobj and b/x64/Release/ShellcodeObfuscator.iobj differ diff --git a/x64/Release/ShellcodeObfuscator.ipdb b/x64/Release/ShellcodeObfuscator.ipdb index 1f996df..41e43d2 100644 Binary files a/x64/Release/ShellcodeObfuscator.ipdb and b/x64/Release/ShellcodeObfuscator.ipdb differ