zigzi package¶
Submodules¶
zigzi.CodeManager module¶
Disassembler engine for disassemble and instrumentation base on Capstone disassemble engine.
zigzi.DataObject module¶
DataObject Helper class for data instrument to file.
-
class
zigzi.DataObject.
DataObject
(base_address)[source]¶ Bases:
object
-
append_dword
(dword, variable_name=None)[source]¶ append_dword size value to data list.
Parameters: - dword – value.
- variable_name – name of this space.
Returns: base position point before appending.
Return type: int
-
base_address
¶
-
declare_dword
(init_value=None, variable_name=None)[source]¶ declare and set up dword type variable.
Parameters: - init_value – value of this variable
- variable_name – name of this variable
Returns: current base position.
Return type: int
-
size
¶
-
zigzi.DataSegment module¶
zigzi.Disassembler module¶
Disassembler engine for disassemble and instrumentation base on Capstone disassemble engine.
-
class
zigzi.Disassembler.
Disassembler
(_code_manager)[source]¶ Bases:
object
-
disassemble
()[source]¶ Disassemble.
Returns: - Dict containing:
- int : address of instruction.
instruction
: instruction.
Return type: dict
-
get_disassemble_list
()[source]¶ get instructions sorted by address.
Returns: - list containing:
instruction
: instruction.
Return type: list
-
static
get_opcode_length
(instruction)[source]¶ calculate opcode length from instruction.
Parameters: instruction (instruction) – target instruction. Returns: length of opcode. Return type: int
-
static
is_branch
(instruction)[source]¶ Check whether it is a indirect branch instruction.
Parameters: instruction (instruction) – instruction for check. Returns: True if instruction is indirect branch, False otherwise. Return type: bool
-
static
is_call
(instruction)[source]¶ Check whether it is a call instruction.
Parameters: instruction (instruction) – instruction for check. Returns: True if instruction is call, False otherwise. Return type: bool
-
static
is_indirect_branch
(instruction)[source]¶ Check whether it is a indirect branch instruction.
Parameters: instruction (instruction) – instruction for check. Returns: True if instruction is indirect branch, False otherwise. Return type: bool
-
static
is_relative_branch
(instruction)[source]¶ Check whether it is a relative branch instruction.
Parameters: instruction (instruction) – instruction for check. Returns: True if instruction is direct branch, False otherwise. Return type: bool
-
zigzi.Heap module¶
Heap, helper class for heap space.
-
class
zigzi.Heap.
Heap
(base_address)[source]¶ Bases:
zigzi.DataObject.DataObject
zigzi.Log module¶
Logger, Utility for logging.
-
class
zigzi.Log.
LoggerFactory
[source]¶ Bases:
zigzi.Log.Singleton
,object
zigzi.PEAnalyzeTool module¶
PEAnalyzeTool, Analyze tool for PE that Windows Portable Executable Format
-
class
zigzi.PEAnalyzeTool.
PEAnalyzer
(execute_section, execute_section_data, entry_point_va)[source]¶ Bases:
object
-
OPERAND_ABSOLUTE_ADDRESS
= 'AbsoluteMemoryAddress'¶
-
OPERAND_FAR_MEMORY
= 'FarMemory'¶
-
OPERAND_IMMEDIATE
= 'Immediate'¶
-
OPERAND_MEMORY
= 'AbsoluteMemory'¶
-
OPERAND_NONE
= ''¶
-
OPERAND_REGISTER
= 'Register'¶
-
handle_FC_CALL
(basic_block_size, inst)[source]¶ handle kinds of CALL instruction. ex) CALL, CALL FAR. :param BasicBlock: @type BasicBlock :return:
-
handle_FC_CND_BRANCH
(basic_block_size, inst)[source]¶ handle kinds of Contional Branch instructions ex) JCXZ, JO, JNO, JB, JAE, JZ, JNZ, JBE, JA, JS, JNS, JP, JNP, JL, JGE, JLE, JG, LOOP, LOOPZ, LOOPNZ. :param basic_block: @type BasicBlock :return:
-
handle_FC_RET
(basic_block_size, inst)[source]¶ handle kinds of RET instruction. ex) RET, IRET, RETF. :param BasicBlock: @type BasicBlock :return: always return True cause RET is notice that end of decoding.
-
handle_FC_SYS
(basic_block_size, inst)[source]¶ handle kinds of SYS instruction. ex) SYSCALL, SYSRET, SYSENTER, SYSEXIT. :param basic_block: @type BasicBlock :return:
-
zigzi.PEInstrument module¶
PEInstrument support instrumentation feature for window executable binary format(PE).
-
class
zigzi.PEInstrument.
PEInstrument
(pe_manager)[source]¶ Bases:
future.types.newobject.newobject
-
adjust_direct_branches
(instruction)[source]¶ adjust instruction’s operand value. Because the instructions calculate the address to branch relatively from the current position, it is necessary to apply the offset value changed by the instrument.
Parameters: instruction (instruction) – branch instruction that has relatively operand value
-
adjust_instruction_layout
()[source]¶ Adjusts the binary layout that has changed due to the address and the relatively operand of the instruction being changed during the instrumenting.
-
adjust_registers_instruction_operand
(instruction)[source]¶ adjust instruction operand that register before.
Parameters: instruction (instruction) – instruction to be adjusting. Returns: adjusted operand value. Return type: int
-
append_code
(code)[source]¶ append code to last of code section.
Parameters: code (str) – assembly code that append to last of code section. Returns: relative address of code that appended Return type: int
-
do_instrument
()[source]¶ instrument instruction when reached instruction that has control flow as redirect.
-
falloc
(size)[source]¶ get allocated memory space from data segment.
Parameters: size (int) – size of space that allocate. Returns: DataSegment that represent for allocation. Return type: DataSegment
-
get_instructions
()[source]¶ get disassembled instructions. Instructions excluding data that exist in the text section.
Returns: - list containing :
tuple
- int : instruction address.
instruction
: instruction.
Return type: list
-
get_instrumented_size
(instruction)[source]¶ Calculate the instrumented size from the current address to the branch target. use this when instrumented thing is applied to disassembled one. but if not applied instrumented thing, then use method the get_instrumented_size_with_vector.
Parameters: instruction (instruction) – branch instruction that has relatively operand value Returns: size of instrumented until instruction’s address. Return type: int
-
get_instrumented_total_size
()[source]¶ Total size of instrument.
Returns: Total size of instrumentation. Return type: int
-
get_instrumented_vector_size
(rva, instrument_pos_dict=None)[source]¶ Calculate the instrumented size until virtual address that argumented. if not applied instrumented thing, to disssembled one, use this.
Parameters: - rva (int) – virtual address for calculate on.
- instrument_pos_dict (dict) – dict contains instruments position.
Returns: instrumented size until argument virtual address with increasing of instrumented size.
Return type: int
-
handle_overflowed_instrument
()[source]¶ extend the size of the operand if exceed the range of operand values while instrument.
Note
The formula for determining the operand value of a branch instruction in x86: [Destination.Address - Instruction.Address - Instruction.size]
in this case, the operand value overflowed while we adjust direct branches operands. that mean, 1 byte of operand size is too small for adjusted operand value. cause we expand operand size to 4byte.
instruction size increase to 5byte or 6byte. according in formula of determining operand value, The keystone adjusts the operand value when it compiled.
the keystone is based on the address at which the instruction ends,
like this, ks.asm(‘jmp 140’) = [233, 135, 0, 0, 0]
but since the value we pass is based on the start address of the instruction, it corrects the value of operand in the case of a positive branch.
In the case of a negative branch, the base address is the starting address of the instruction, so do not change it.
Returns: True if occurred overflow while instrumentation, False otherwise. Return type: bool
-
instrument
(fn, instruction, total_count=0, position=4096)[source]¶ The instrument passes the instruction to the user function. When the user function is finished and the instruction to be instrumented is returned, the instruction is inserted at the position of the current instruction. As a result, the position of the current instruction is pushed backward by the size of the inserted instruction.
Parameters: - fn (function) – User function to return instruction to be instrumented
- instruction (instruction) – Instruction to be passed to the user function.
- total_count (int) – total count of instrumented.
- position (int) – position where be instrumented.
Returns: size of instrumented instructions.
Return type: int
-
zigzi.PEManager module¶
PEManager, Utility for parsing and modifying PE.
-
class
zigzi.PEManager.
PEManager
(filename)[source]¶ Bases:
future.types.newobject.newobject
-
adjust_TLS
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_TLS - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_bound_imports
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_data_in_range
(start, end, increase_size)[source]¶ Adjust the values of data belonging to a specific range.
Parameters: - start (int) – start of range.
- end (int) – end of range.
- increase_size (int) – the size to be adjust.
-
adjust_debug
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_DEBUG - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_delay_import
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_directories
(data_directories, origin_section_start, adjust_section_start, origin_section_end, adjust_section_end)[source]¶ adjust directories Virtual address.
Parameters: - data_directories (
list
) – data directories in PE file. - origin_section_start (Int) – start virtual address of section.
- adjust_section_start (int) – start virtual address of adjust section.
- origin_section_end (int) – last virtual address of section.
- adjust_section_end (int) – last virtual address of adjust section.
- data_directories (
-
adjust_export
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_EXPORT - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_import
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_IMPORT - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_load_config
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_relocation
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_BASERELOC - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
adjust_relocation_directories
(increase_size)[source]¶ adjust relocation directories and its elements.
-
adjust_relocation_offset
()[source]¶ structures has owned offset. so, if modify position or order of structures element then must fix offset of structures element.
-
adjust_resource
(directory, rva, size, increase_size)[source]¶ adjust relocation directory’s elements.
Parameters: - directory (
Structure
) – IMAGE_DIRECTORY_ENTRY_RESOURCE - rva (int) – current directory’s relative virtual address.
- size (int) – current directory’s size.
- increase_size (int) – increased size of section that directory included.
- directory (
-
append_data_to_file
(data)[source]¶ append data to file.
Parameters: data (bytearray) – data for append that bytearray type. Returns: - tuple containing:
- aligned_orig_data_len(int) : file data length that aligned.
aligned_data_len(int) : argument data length that aligned.
Return type: tuple
-
append_relocation_entry_to_block
(entry, block_index)[source]¶ append relocation entry to appropriate relocation block.
Parameters: - entry (Structure) – entry to be append.
- block_index (int) – index of block.
-
append_section_to_file
(section)[source]¶ append section to file structure.
Parameters: section ( Section
) – section that append to file
-
create_new_data_section
(data, name)[source]¶ Create a new data section and add it to the last section.
Parameters: - data (bytearray) – data for append to section.
- name (str) – name of section.
Returns: new section that created.
Return type: Section
-
create_new_executable_section
(data)[source]¶ Create new executable section with given data.
Parameters: data (bytearray) – Raw point of new section
-
gen_new_empty_import_descriptor
()[source]¶ generate new import descriptor that has empty.
Returns: IMPORT_DESCRIPTOR Return type: Structure
-
gen_new_empty_import_thunk
()[source]¶ generate new import descriptor that has empty.
Returns: IMPORT_THUNK Return type: Structure
-
gen_new_relocation_block
(block_rva)[source]¶ generate new relocation block that cover rva. :param block_rva: relative address that has covered by new block.
Returns: index of generated block. Return type: int
-
gen_new_relocation_entry
(rva)[source]¶ Create a relocation entry for rva.
Parameters: rva (int) – relative address. Returns: IMAGE_BASE_RELOCATION_ENTRY Return type: Structure
-
get_abs_va_from_offset
(offset)[source]¶ calculate absolute virtual address from offset.
Parameters: offset (int) – offset of file. Returns: absolute address to match offset. Return type: int
-
get_abs_va_from_rva
(rva)[source]¶ get absolute virtual address from rva that argument.
Parameters: rva (int) – relative address to be calculate. Returns: absolute address from rva. Return type: int
-
get_aligned_offset
(offset)[source]¶ Align offset with file alignment
Parameters: offset (int) – offset of file Returns: aligned offset Return type: int
-
get_aligned_rva
(va)[source]¶ get aligned virtual address from argument.
Parameters: va (int) – virtual address for align Returns: aligned virtual address Return type: int
-
static
get_cloned_section_header
(section)[source]¶ make clone section from argument and return it.
Parameters: section ( Section
) – section that need cloneReturns: cloned section from argument Return type: Section
-
get_data_directory_address_range
(entry_name)[source]¶ Gets the scope of the data directory with the given name as an argument.
Parameters: entry_name (str) – name of data directory to find. Returns: - tuple containing :
- int : Virtual address of data directory.
- int : Size of data directory.
Return type: tuple
-
get_entry_point_rva
()[source]¶ get Entry point virtual address of file
Returns: entry point virtual address Return type: int
-
get_image_base
()[source]¶ get address of image base.
Returns: virtual address of image base. Return type: int
-
get_image_size
()[source]¶ last section’s end represent that Image size.
Returns: Image size. Return type: int
-
get_import_address_table_address_range
()[source]¶ Gets the scope of the import address table.
Returns: - int : Virtual address of import address table.
- int : Size of import data address table.
Return type: tuple
-
get_import_descriptor_address_range
()[source]¶ Gets the scope of the import descriptor.
Returns: - int : Virtual address of import descriptor.
- int : Size of import data descriptor.
Return type: tuple
-
get_import_structures
()[source]¶ get import lists of pe file.
Returns: - containing structures of import :
Structure
: IMAGE_IMPORT_DESCRIPTOR or IMAGE_THUNK_DATA
Return type: list
-
get_imports_range_in_structures
()[source]¶ start and end index of import at structures.
Returns: - tuple containing:
- int : start index of import at structures.
- int : last index of import at structures.
Return type: tuple
-
get_instrument
()[source]¶ get instrument of current file
Returns: instrument of current file util Return type: PEInstrument
-
get_relocation
()[source]¶ get relocation elements.
Returns: - Dict containing:
- int : address of relocation block
list
: relocation block info. list containing:- int : relative address of relocation element.
- int : address of relocation element.
- int : type that represented by int.
Return type: dict
-
get_relocation_directories
()[source]¶ get relocation directories with its include elements.
Returns: - tuple containing:
dict
: relocation blocks- block address(int) : address of block
- block entry(
Structure
) : IMAGE_BASE_RELOCATION
dict
: relocation entry- block address(int) : The block address to which the entry belongs
- relocation entry(
Structure
) : IMAGE_BASE_RELOCATION_ENTRY
Return type: tuple
-
get_relocation_from_structures
()[source]¶ get relocation elements from file structures that not parsed yet.
Returns: - Dict containing:
- int : relative address of relocation block.
list
: list of relocation entry.list
containing:Structure
: IMAGE_BASE_RELOCATION_ENTRY
Return type: dict
Examples
{ Relocation block address : [Relocation Entry]}
-
get_section_belong_rva
(rva)[source]¶ Find the section containing rva.
Parameters: rva (int) – rva for find section. Returns: the Section to which the given relative address as argument belongs. Return type: Section
-
get_section_raw_data
(section)[source]¶ get raw data from section header
Parameters: section (Section) – section header that Returns: data that section contain. Return type: bytearray
-
get_structure_from_rva
(rva)[source]¶ Find the structure located in rva.
Parameters: rva (int) – relative address. Returns: structure that has located in rva. Return type: Structure
-
get_text_section_virtual_address_range
()[source]¶ get Virtual address range of text section
Returns: - tuple containing :
- int : the start address of section.
- int : the end address of section.
Return type: tuple
-
static
is_executable_section
(section)[source]¶ Whether the section is an executable.
Parameters: section (Section) – Section to check Returns: true if executable, false otherwise Return type: bool
-
is_possible_relocation
()[source]¶ Verify that the file can be relocated.
Returns: True if relocation possible, False otherwise. Return type: bool
-
register_rva_to_relocation
(rva)[source]¶ append rva to relocation list. if appropriate block is not exist, then append it after make new block.
Parameters: rva (int) – relative address for relocating.
-
relocation_entry_move_to_appropriate_block
(entry, block, increase_size)[source]¶ move relocation entry to appropriate relocation block.
Parameters: - entry (Structure) – IMAGE_BASE_RELOCATION_ENTRY
- block (Structure) – IMAGE_BASE_RELOCATION
- increase_size (int) – size to move the entry
-
set_dword_at_rva
(rva, dword)[source]¶ set dword at rva.
Parameters: - rva (int) – relative address.
- dword (bytes) – 4-bytes type value.
-
set_entry_point
(entry_va)[source]¶ Set up entry point of file
Parameters: entry_va (int) – virtual address of entry point
-
set_instrument
(instrumentor)[source]¶ set up instrument
Parameters: instrumentor ( PEInstrument
) – instrument of this file
-
zigzi.SampleReturnVerifier module¶
This is sample of security migration that implement by instrumenting. called Return Address Verifier(RAV), the part of CFI(Control Flow Integrity).
-
zigzi.SampleReturnVerifier.
simple_instrument_error_handler
(pe_instrument, pe_manager, fn_rva)[source]¶ add error handler, in this case it is a message box.
Parameters: - pe_instrument (
PEInstrument
) – instrumentation for PE. - pe_manager (
PEManager
) – file manager for PE. - fn_rva (int) – relative address of function at import address table.
- pe_instrument (
zigzi.Stack module¶
Stack, helper class for stack.
zigzi.WindowAPIHelper module¶
-
class
zigzi.WindowAPIHelper.
WindowAPIHelper
(pe_manager)[source]¶ Bases:
future.types.newobject.newobject
-
add_dll_to_import_descriptor
(first_thunk_rva, dll_name_rva, iat_rva)[source]¶ create import descriptor with given argument and append it to structure.
Parameters: - first_thunk_rva (int) – relative address of first thunk.
- dll_name_rva (int) – relative address of dll name string.
- iat_rva (int) – the relative address of import thunk located at
- address table. (import) –
Returns: a new import descriptor.
Return type: Structure
-
add_function_to_import
(dll_import_descriptor, dll_name, fn_name)[source]¶ create import thunk by given argument dll and function name. and append it to structures.
Parameters: - dll_import_descriptor (Structure) – The generated import thunk is
- to the following index of this descriptor in structures. (appended) –
- dll_name (str) – dll name.
- fn_name (str) – function name.
-
add_message_box
()[source]¶ add MessageBoxA window API to PE File.
Returns: relative address of message box Api located in iat. Return type: int
-
adjust_data_directory_size
()[source]¶ Increase the size of the import directory and import address table by the number of import descriptors and import thunks added.
-
adjust_references_of_iat
(start, end, gap_size)[source]¶ adjust a relocation element that references the import address table.
Parameters: - start (int) – start of range.
- end (int) – end of range.
- gap_size (int) – size to adjust.
-
append_import_thunk_to_descriptor
(descriptor, thunk)[source]¶ add import thunk at the following index of the descriptor in structures.
Parameters: - descriptor (Structure) – descriptor
- thunk (Structure) – import thunk to append.
-
append_import_thunk_to_next_of_descriptor
(import_thunk, descriptor)[source]¶ append import thunk to the next index of given descriptor as an argument.
Parameters: - import_thunk (Structure) – import thunk
- descriptor (Structure) – import descriptor
-
gen_new_import_lookup_table
(fn_name, dll_name)[source]¶ create import lookup table.
Parameters: - fn_name (str) – name of function.
- dll_name (str) – name of dll.
Returns: - tuple containing:
- int : relative address of generated ilt table.
- int : relative address of name.
Return type: tuple
-
gen_new_import_thunk
(ordinal)[source]¶ create the new import thunk with given ordinal as argument. and append it to structure.
Parameters: ordinal (int) – Ordinal to be assigned to a new import thunk. Returns: - tuple containing:
Structure
: created import thunk.- int : relative address of ordinal located in import address table.
Return type: tuple
-
gen_new_thunk
(attr_data)[source]¶ Creates a new thunk filled with the attribute value given as an argument.
Parameters: attr_data (int) – attribute value that to be filled. Returns: import thunk structure. Return type: Structure
-
gen_separator_thunk
()[source]¶ Creates a new thunk filled with zero that mean separator.
Returns: import thunk structure that has filled zero. Return type: Structure
-
get_iat_rva_with_size
()[source]¶ get import address relative address and its size.
Returns: - tuple containing :
- int : relative address of import address table.
- int : size of import address table.
Return type: tuple
-
get_last_import_address_thunk
()[source]¶ get the import address thunk that located last offset.
Returns: import thunk Return type: Structure
-
get_last_import_descriptor
()[source]¶ get the import descriptor that located last offset.
Returns: the last import descriptor. Return type: Structure
-
get_last_import_descriptor_offset
()[source]¶ get offset of the import descriptor that located last offset.
Returns: offset of the last import descriptor. Return type: int
-
get_last_import_lookup_thunk
()[source]¶ get the import lookup thunk that located last offset.
Returns: import lookup thunk Return type: Structure
-
get_last_import_thunk_offset
()[source]¶ get the import thunk offset that located last offset.
Returns: the offset of the import thunk at the last offset. Return type: int
-
get_ordinal_from_common_library
(dll_name, fn_name)[source]¶ get the ordinal from common libraries with given dll and function name as argument.
Parameters: - dll_name (str) – dll name.
- fn_name (str) – function name.
Returns: ordinal of matched.
Return type: int
-
is_already_import_dll
(dll_name)[source]¶ Checks whether an import descriptor with the given dll name exists.
Parameters: dll_name (str) – dll name. Returns: True if dll name exist in import descriptor, False otherwise. Return type: bool
-
is_already_import_function
(fn)[source]¶ check whether an import thunk with the given function name.
Parameters: fn (str) – function name. Returns: True if function name exist in import thunk, False otherwise. Return type: bool
-
Module contents¶
zigzi, Platform independent binary instrumentation module.
Copyright (c) 2016-2017 hanbum park <kese111@gmail.com>
All rights reserved.
For detailed copyright information see the file COPYING in the root of the distribution archive.