© Cryptic Apps SARL

## Presentation

Hopper is a tool that will assist you in your static analysis of executable files.

This quick presentation will give you a good overview of what is Hopper, and how it works.

Hopper is a rich-featured application, and all cannot be discussed here, but don’t worry, you’ll quickly find your marks, and easily discover all its subtleties.

The interface is split into three main areas:

- The left pane contains a list of all the symbols defined in the file, and the list strings. The list can be filtered using tags and text.
- The right pane is called the inspector. It contains contextual information about the explored area.
- The center part is where the assembly language, and its various representations are displayed.

## The Concept

The idea behind Hopper is to transform a set of bytes (the binary you want to analyze) into something that could be read by a human.

To do so, Hopper will try to associate a type to each byte of the file. Because it would be much too expensive to do it manually, Hopper proceeds to an automatic analysis as soon as you loaded a file.

The various types that can be used in hopper are:

- Data: an area is set to the data type when Hopper thinks it is an area that represents a constant, like an array of int for instance.
- ASCII: a NULL-terminated C string.
- Code: an instruction
- Procedure: a byte receives this type once it has been determinate that it is part of a method that has been successfully reconstructed by Hopper.
- Undefined: this is an area that has not yet been explored by Hopper,

As soon as an executable is loaded, you can manually change the type, by using either the keyboard, or the toolbar on top of the window.

The toolbar contains one button by type you can set (D for data, A for ASCII, etc.). These letters are also the keyboard shortcut you can directly use.).

The data type has a little specific behavior: the first time you use this type, Hopper will transform the area into a byte. If you use it again, the byte will be transformed into a 16 bits integer, then a 32 bits integer, and so on…

Feel free to play with transformations to explore the executable: Hopper provides an undo / redo feature.

# Display Modes

Reading assembly language is a little bit difficult, and boring in some cases. In order to help you, Hopper can use different kinds of representations for the code.

Most of them require the construction of a procedure, because procedures contain additional information about the structure of the code, like basic blocks, or stack usage.

The current mode can be changed using the toolbar:

## Assembly

The first mode is the Assembly Mode. Hopper prints the lines of assembly code, one after the other. This is what most disassemblers provide.

The first column (blue numbers) represents the addresses of the instructions. In front of each of them, the instruction, and its operands (or arguments). As an option, in the preferences of the application, you can choose to print the instruction encoding between the address, and the instruction mnemonic.

In the margin, you'll see some colored arrows. These arrows represent the possible destination of a jump instruction. For instance, on the above screenshot, the blue arrow between addresses 0x100002d82, and 0x100002db4 represents the fact that the instruction je at 0x100002d82 may jump to the address 0x100002db4 if the conditions are met. When an instruction jumps to a greater address (a forward jump), the arrow is drawn in blue. If the jump goes forward, the arrow is drawn in red.

Note that, in this representation, if you click in the red column, you'll set a breakpoint at the corresponding address, and if you click in the blue column, you'll set a bookmark.

## Control Flow Graph

The CFG mode represent a procedure in a more structured way.

You can still edit things in this representation, like comments and labels. The cursor can be moved from one basic block to another; simply move the cursor to the bound of the current basic block, and use the arrow key of your keyboard to jump to the nearest basic block. If you press the up, or down key, the cursor will move to the nearest basic block, but keeping the same column. For instance, in the following case, the cursor will move like indicated:

The same behavior applies for the left, and right keys.

In the right panel (the inspector), you'll find a section dedicated to the mode. The Control Flow Graph component displays a smaller representation of the current procedure, called minimap. Each square represents a basic block, and lines are drawn to represents their connections. One of them is filled in blue: this is the basic block containing the cursor. A light gray square represents the current portion of the method drawn in the main part. You can move the viewport by clicking direcly in this map.

The nodes of the graph can be modified. For instance, it is possible to group some of them when you think that they are closely related. Select the nodes, and click on the Group Nodes button in the inspector.

You can also set a custom background color to a given node, or edit the printed text.

## Pseudo-Code

In this representation, Hopper will try to produce some pseudo-code, functionally equivalent to the original CPU instructions, but more or less like an Objective-C method.

This is clearly the easiest way of reading code you are analyzing, but you should remind that there is no magic: sometimes, it is not possible to construct a perfect pseudo-code representation of a procedure, and some parts may disappear, because Hopper wrongly thought that it was unreachable code (also called dead code). In order to mitigate this problem, you can try to toggle the corresponding checkbox at the top of the view.

## Hex Mode

This mode allows you to take a look directly at the bytes of the file.

The first column represents the offset in the file, and the other columns, each of the bytes. When you put the cursor on a byte, you'll notice that the selection automatically extends to the left, and to the right. Indeed, Hopper knows more about the file than any regular hexadecimal editor, and for instance, on the previous screenshot, Hopper knows that the cursor is inside an instruction, and selects all of its bytes.

If you double-click on a byte, you can change its value. In some case, it may destroy the underneath structure. For instance, if your cursor was in an instruction, the instruction is automatically destroyed, and the associated Hopper's type falls back to the undefined state. Also, if the instruction was part of a procedure, the procedure is destroyed. Anyway, keep in mind that you can always roll back your changes, as Hopper provides an undo / redo feature.

The number of columns in this representation depends on the width of the window; this is the default behavior, but this can be changed in the application preferences. For instance, you can force Hopper to always display 16 columns, whatever is the width of the window.

# Navigating Through the File

## Segments and Sections

An executable file is split into smaller pieces of data, called segments, and sections.

When the operating system loads an executable, some parts of its bytes are mapped into memory. Each contiguous piece of the file mapped into memory is called segments. These segments are split into smaller parts, called sections, which will receive various access properties.

You can navigate through these objects by using the Navigate > Show Segment List and Navigate > Show Section List menu items.

## Symbols, Tags and Strings

Because it would be too difficult to remember the address where each piece of code lies into the executable, you can affect names, or symbols to the addresses.

To name an address, you just need to put the cursor on the address, and press N. A dialog will pop up: simply type the name you want to set.

The symbol list is accessible in the left pane of the window.

Using the search field, you can filter the symbols listed below. Hopper uses a kind of regular expression to filter the list; first, it will present the items that completely contain the term you wrote. Then, right below, the list of symbols that contain one text insertion, then two insertions, and so on. This is what I called the fuzzy search, and this behavior can be disabled in the preferences of the application.

You can use the tags to filter even more efficiently the symbol list. Tags are textual information that can be put on an address, a basic-block of a procedure, or a whole procedure. You can open the Tag Scope element to see all tags that exists in the current document. If you select a tag, only procedures that contain this tag will be listed. Note that if you close the Tag Scope item, the filter is reset to all tags.

An interesting thing to note is that many tags are automatically generated during the loading process of an executable. For instance, every entry points will receive a specific entrypoint tag, and each implementation of each Objective-C class will be tagged with the name of the class (or category). It allows you to quickly navigate through code written in Objective-C!

You can choose to display the strings contained in the file. In this mode, only the ASCII strings are displayed, and the Tag Scope has no effect.

## The Navigation Stack

You can jump to an address, or a symbol by double-clicking on it. The address where the cursor was located, is pushed on a stack. You pop this stack, and navigate back by using the escape key or the backspace key on your keyboard. You can also use the navigation toolbar items.

The right arrow will jump to the address under the cursor, and the left arrow will come back.

## The Navigation Bar

Just above the assembly, you’ll find the navigation bar.

This bar is used to quickly navigate into the file. A color scheme is used to indicate the various types given to the bytes of the file.

- Blue parts represent code,
- Yellow parts represent procedures,
- Green parts represent ASCII strings,
- Purple parts represent data,
- Grey parts are undefined.

A little red arrow indicates where the cursor is currently located.

## Using the Inspector

The inspector is the rightmost part of the window. It contains various components that will show up, or hidden depending on the context where the cursor is currently located.

Here is a quick overview of the components that you can find in the inspector:

### Instruction Encoding

This component displays the bytes of the current instruction. If the current processor has multiple CPU modes (like the ARM and Thumb modes of the ARM processor family), you’ll see a popup menu that lets you change the CPU mode at the current address.

### Format

This component is used to change the display format of the operand of an instruction. You can choose between signed / unsigned hexadecimal, decimal, octal, address, etc.

### Comment

You can associate a textual comment at a given address. Use this component to edit this comment.

### Colors and Tags

This component lets you associate tags to addresses, basic-block of a procedure, or a procedure. Those tags are useful to navigate efficiently through the file.

You can even put some colors on addresses in order to quickly, and visually, distinguish parts of the executable.

### References

This is a very important component; it shows all the references that one instruction can have to another instruction, or piece of data. It contains the references in the other way too, i.e., the other instructions that references this one. You can even add your own references by hand if the analysis performed by Hopper didn’t find some references.

### Procedure

This component contains the information on the current procedure. For each basic-block, it displays the list of its predecessors and its successors.

At the bottom of the component, you’ll find a very useful button: Switch/case hint. This button is enabled on instructions like *jmp REGISTER. It allows you to help Hopper to find the statements of a switch/case construction.

# Modifying the File

## The Hexadecimal Editor

As previously seen, Hopper provides a hexadecimal editor. The editor is synchronized with the assembly language view, and automatically highlights bytes that are part of the current instruction.

Double-click on a byte to modify it. You can use the Undo/Redo feature if you made a mistake.

## The Assembler

An embedded assembler can be invoked from Hopper from the Modify > Assemble Instruction… menu.

You can also use the Modify > NOP Region menu to replace the currently selected instructions by NOP instructions.

# Hexadecimal Regular Expressions

Hopper can search for a given pattern in the bytes of a disassembled file. In order to proceed, Hopper uses a small language, very similar to regular expressions seen in tools like grep.

Regular expressions are made of words, using letters from the alphabet 0123456789abcdef, and special characters like *, +, ?, ., |, and parenthesis. From a regular expression, Hopper will build a deterministic finite automaton, and use it to search the pattern in the file. Each byte of the file is split into two 4-bits words, and given to the automaton.

- Letters from the 0123456789abcdef alphabet are used as is,
- The special character . matches any 4-bit word. If you want to match with any byte, you should use the .. sequence,
- The character * is used to indicate that the previous word can be repeated 0, or more times. Please note that this character applies to the whole word, not only the last character, or byte. For instance, the regular expression:

      123*abc*123

  matches the strings:
  - 123abc123
  - 123123123abcabc123
  - abc123
  - …
- You can restrict the effect of the star by using some parenthesis. For instance, in the regular expression:

      12345(ab*)678

  only the word ab is repeated.
- You can specify a subset of characters, using the square brackets:

      [168ab]

  Will match if the word is 1, 6, 8, a, or b. You can also provide ranges:

      [2-8cd]

  Will match if the word is 2, 3, 4, 5, 6, 7, 8, c, or d.
- As a shortcut, you can use the character + as a way to represent 1, or more occurences of the pattern.
- Another shortcut is the character ?, which mean 0, or 1 occurrence of the pattern.
- You can combine two regular expressions using a logical or with the character |. For instance:

      AB|CD

  Will match words AB, or CD.

## Some examples

- A sequence beginning with 12, and ending with ab:

      12(..*)ab

- A NULL-terminated string of decimal characters:

      3[0-9]+00

- Roughly match all the instructions xor al,al, xor ax,ax, xor eax,eax, and xor rax,rax

    (48|66)?(30|31)C0

Here are all the public classes, and methods that you can use to script Hopper using Python.

Before using the scripting capabilities of Hopper, you need to understand the nature of a Hopper document. The basic concept is that it is a document constructed from Segments, each containing Sections of typed bytes. Let's consider a standard Mach-O file. It contains at least one segment of code (usually named TEXT) containing many bytes. Hopper attaches information to each bytes of each segments. At load time, all bytes are set to the type TYPE_UNDEFINED. Then, starting from the entry point, as Hopper follows the program flow it will set instructions to the type TYPE_CODE; if an instruction needs more than one byte, the following are set to TYPE_NEXT.

Using Python, you'll can manipulate the segments of disassembled files, retrieve information on bytes types, read or write data, create or modify label names, etc... You'll usually start by retrieving the current document, using the static method Document.getCurrentDocument().

Class CallReference
An object representing a call inside from / to a procedure.
type()
Returns the type of call. This is one of the value CALL_NONE, CALL_UNKNOWN, CALL_DIRECT, or CALL_OBJC.
fromAddress()
Source of the reference
toAddress()
Referenced address
Class LocalVariable
A procedure's local variable.
name()
Name of the local variable
displacement()
Displacement on the stack
Class Tag
A Tag that could be applied to a specific address, a BasicBlock or a Procedure. Tags are built using the document.
getName()
Returns a string with the tag name.
Class Procedure
This class represents a procedure, which is a collection of BasicBlocks. Please note that modifying the document (creating new procedure, or deleting an existing one), will result in a possible inconsistancy of the Python's Procedure object representation.
Procedure class defines some constants:
REGCLS_GENERAL_PURPOSE_REGISTER = 2
REGCLS_X86_FPU = 3
REGCLS_X86_MMX = 4
REGCLS_X86_SSE = 5
REGCLS_X86_AVX = 6
REGCLS_X86_CR = 7
REGCLS_X86_DR = 8
REGCLS_X86_SPECIAL = 9
REGCLS_X86_MEMMGMT = 10
REGCLS_X86_SEG = 11
REGCLS_ARM_VFP_SINGLE = 3
REGCLS_ARM_VFP_DOUBLE = 4
REGCLS_ARM_VFP_QUAD = 5
REGCLS_ARM_MEDIA = 6
REGCLS_ARM_SPECIAL = 7
REGIDX_X86_RAX = 0
REGIDX_X86_RCX = 1
REGIDX_X86_RDX = 2
REGIDX_X86_RBX = 3
REGIDX_X86_RSP = 4
REGIDX_X86_RBP = 5
REGIDX_X86_RSI = 6
REGIDX_X86_RDI = 7
REGIDX_X86_R8 = 8
REGIDX_X86_R9 = 9
REGIDX_X86_R10 = 10
REGIDX_X86_R11 = 11
REGIDX_X86_R12 = 12
REGIDX_X86_R13 = 13
REGIDX_X86_R14 = 14
REGIDX_X86_R15 = 15
REGIDX_X86_RIP = 16
getSegment()
Returns the segment this procedure belongs to.
getSection()
Returns the section this procedure belongs to.
getEntryPoint()
Returns the address of the entry point.
getBasicBlockCount()
Returns the total number of basic blocks.
getBasicBlock(index)
Get a BasicBlock object by index.
getBasicBlockAtAddress(addr)
Returns the basic block which contains an instruction starting at the given address, or None.
basicBlockIterator()
Iterate over all basic blocks of the procedure
getHeapSize()
Returns the heap size of the procedure in bytes.
getLocalVariableList()
Returns the list of all local variables.
addTag(tag)
Add a tag to the procedure.
removeTag(tag)
Remove the tag from the procedure.
hasTag(tag)
Returns True if the procedure has this tag.
getTagCount()
Returns the number of tags for this procedure.
getTagAtIndex(index)
Returns the Nth tag of the procedure.
tagIterator()
Iterate over all tags of the procedure
getTagList()
Returns a list a all tags for this procedure.
getAllCallers()
Returns a list of CallReference objects representing callers of this procedure.
getAllCallees()
Returns a list of CallReference objects representing all the places called by this procedure.
getAllCallerProcedures()
Returns a list of Procedure objects representing callers of this procedure.
getAllCalleeProcedures()
Returns a list of CallReference objects representing all the procedures called by this procedure.
hasLocalLabelAtAddress(addr)
Return True if there is a local label at a given address.
localLabelAtAddress(addr)
Return the local label name at a given address, or None if there is no label at this address.
setLocalLabelAtAddress(label,addr)
Set the local label for a given address.
declareLocalLabelAt(addr)
Create a local label at a given address, and return its name.
removeLocalLabelAtAddress(addr)
Remove a local label.
addressOfLocalLabel(label)
Return the address of the local label.
decompile()
Returns a string containing the pseudo-code of the procedure, or None if the decompilation is not possible.
signatureString()
Returns a string containing the signature of the procedure.
renameRegister(reg_cls,reg_idx,name)
Rename the register reg_idx, of class reg_cls to the provided name. The reg_cls argument is one of the REGCLS_* constants.
registerNameOverride(reg_cls,reg_idx)
Returns the name given to the register, if it has been previously renamed. Otherwise, returns None. The reg_cls argument is one of the REGCLS_* constants.
clearRegisterNameOverride(reg_cls,reg_idx)
Clear register renaming. The reg_cls argument is one of the REGCLS_* constants.
Class BasicBlock
A BasicBlock is a set of instructions that is guaranteed to be executed in a whole, if the control flow reach the first instruction.
getProcedure()
Returns the Procedure object this BasicBlock belongs to.
getStartingAddress()
Returns the address of the first instruction of the BasicBlock.
getEndingAddress()
Returns the address following the last instruction of the BasicBlock.
getSuccessorCount()
Returns the number of successors for this BasicBlock.
getSuccessorIndexAtIndex(index)
Returns the BasicBlock index of the Nth successors.
getSuccessorAddressAtIndex(index)
Returns the BasicBlock address of the Nth successors.
addTag(tag)
Add a tag to the basic block.
removeTag(tag)
Remove the tag from the basic block.
hasTag(tag)
Returns True if the basic block has this tag.
getTagCount()
Return the number of tags for this basic block.
getTagAtIndex(index)
Return the Nth tag of the basic block.
tagIterator()
Iterate over all tags of the basic block
getTagList()
Return a list a all tags for this basic block.
Class Instruction
This class represents a disassembled instruction. The class defines some constants, like ARCHITECTURE_i386, and ARCHITECTURE_X86_64
stringForArchitecture(t)
[static]
Helper method which converts one of the architecture value (ARCHITECTURE_UNKNOWN, ARCHITECTURE_i386, ARCHITECTURE_X86_64, ARCHITECTURE_ARM, ARCHITECTURE_ARM_THUMB, or ARCHITECTURE_AARCH64) to a string value.
getArchitecture()
Returns the architecture.
getInstructionString()
Return a strings representing the instruction.
getArgumentCount()
Returns the number of argument.
getRawArgument(index)
Returns the instruction argument, identified by an index. The argument is not modified by Hopper, and represents the raw ASM argument.
getFormattedArgument(index)
Returns the instruction argument, identified by an index. The argument may have been modified according to the user, or by Hopper if a specific pattern has been detected.
isAnInconditionalJump()
Returns True if the instruction represents an inconditional jump.
isAConditionalJump()
Returns True if the instruction represents a conditional jump.
getInstructionLength()
Returns the instruction length in byte.
Class Section
This class represents a section of a segment.
getName()
Returns the name of the section.
getStartingAddress()
Returns the starting address of the section.
getLength()
Returns the length, in bytes, of the section.
getFlags()
Returns the flags of the section.
Class Segment
This class represents a segment of a disassembled file. The class defines some values that are used as the type of bytes of the disassembled file.
TYPE_UNDEFINED : an undefined byte
TYPE_OUTSIDE : the byte is not in a mapped section
TYPE_NEXT : a byte that is part of a larger data type (ex, the second byte of a 4 bytes integer...)
TYPE_INT8 : an integer of a single byte
TYPE_INT16 : an integer of 2 bytes
TYPE_INT32 : an integer of 4 bytes
TYPE_INT64 : an integer of 8 bytes
TYPE_ASCII : an ASCII string
TYPE_ALIGN : an alignment
TYPE_UNICODE : an UNICODE string
TYPE_CODE : an instruction
TYPE_PROCEDURE : a procedure
The class defines the constant BAD_ADDRESS which is returned by some methods when the requested information is incorrect.
stringForType(t)
[static]
Helper method that converts one of the type value (TYPE_UNDEFINED, TYPE_NEXT, ...) to a string value.
getName()
Returns the name of the segment.
getStartingAddress()
Returns the starting address of the segment.
getLength()
Returns the length, in bytes, of the segment.
getFileOffset()
Returns the file offset of the beginning of the segment.
getFileOffsetForAddress(addr)
Returns the file offset of a particular address.
getSectionCount()
Returns the number of section this segment contains.
getSection(index)
Returns a section by index. The returned object is an instance of the Section class. If the index of not in the range [0;count[, the function returns None.
getSectionsList()
Returns a list containing all the sections.
getSectionIndexAtAddress(addr)
Returns the section index for a particular address.
getSectionAtAddress(addr)
Returns the section for a particular address.
readBytes(addr,length)
Read bytes at a given address range. Returns False if the byte is read outside of the segment.
readByte(addr)
Read a byte (between 0..255), read at a given address. Returns False if the byte is read outside of the segment.
readUInt16LE(addr)
Read a 16 bits little endian integer.
readUInt32LE(addr)
Read a 32 bits little endian integer.
readUInt64LE(addr)
Read a 64 bits little endian integer.
readUInt16BE(addr)
Read a 16 bits big endian integer.
readUInt32BE(addr)
Read a 32 bits big endian integer.
readUInt64BE(addr)
Read a 64 bits big endian integer.
writeBytes(addr,bytesStr)
Write bytes at a given address. Bytes are given as 'bytes'. Returns True if the writting has succeed.
writeByte(addr,value)
Write a byte at a given address. Returns True if the writting has succeed.
writeUInt16LE(addr,value)
Write a 16 bits little endian integer. Returns True if succeeded.
writeUInt32LE(addr,value)
Write a 32 bits little endian integer. Returns True if succeeded.
writeUInt64LE(addr,value)
Write a 32 bits little endian integer. Returns True if succeeded.
writeUInt16BE(addr,value)
Write a 16 bits big endian integer. Returns True if succeeded.
writeUInt32BE(addr,value)
Write a 32 bits big endian integer. Returns True if succeeded.
writeUInt64BE(addr,value)
Write a 32 bits big endian integer. Returns True if succeeded.
markAsUndefined(addr)
Mark the address as being undefined.
markRangeAsUndefined(addr,length)
Mark the address range as being undefined.
markAsCode(addr)
Mark the address as being code.
markAsProcedure(addr)
Mark the address as being a procedure.
markAsDataByteArray(addr,count)
Mark the address as being byte array.
markAsDataShortArray(addr,count)
Mark the address as being a short array.
markAsDataIntArray(addr,count)
Mark the address as being an int array.
isThumbAtAddress(addr)
Returns True is instruction at address addr is ARM Thumb mode.
setThumbModeAtAddress(addr)
Set the Thumb mode at the given address.
setARMModeAtAddress(addr)
Set the ARM mode at the given address.
getTypeAtAddress(addr)
Returns the type of the byte at a given address. The type can be TYPE_UNDEFINED, TYPE_NEXT, TYPE_INT8, ... The method will returns None if the address is outside the segment.
setTypeAtAddress(addr,length,typeValue)
Set the type of a byte range. The type must be TYPE_UNDEFINED, TYPE_INT8, ... You cannot use this method for alignments. Please use makeAlignment instead.
makeAlignment(addr,size)
Create an alignment at a given address so that the next address is a multiple of size. Size can only be 2, 4, 8, 16, 32 or 64.
getNextAddressWithType(addr,typeValue)
Returns the next address of a given type. The search begins at the given address, so the returned value can be the given address itself. If no address are found, the returned value is BAD_ADDRESS.
disassembleWholeSegment()
Disassemble the whole segment.
setNameAtAddress(addr,name)
Set the label name at a given address.
getNameAtAddress(addr)
Get the label name at a given address.
getDemangledNameAtAddress(addr)
Get the demangled label name at a given address.
getCommentAtAddress(addr)
Get the prefix comment at a given address.
setCommentAtAddress(addr,comment)
Set the prefix comment at a given address.
getInlineCommentAtAddress(addr)
Get the inline comment at a given address.
setInlineCommentAtAddress(addr,comment)
Set the inline comment at a given address.
getInstructionAtAddress(addr)
Get the disassembled instruction at a given address.
getReferencesOfAddress(addr)
Get the list of addresses that reference a given address.
getReferencesFromAddress(addr)
Get the list of addresses referenced by a given address.
addReference(addr,referenced)
Add a cross reference to the 'referenced' address from 'addr' address.
removeReference(addr,referenced)
Remove the cross reference to the 'referenced' address from 'addr' address.
getLabelCount()
Get the number of named addresses.
getLabelName(index)
Get a label name by index.
labelIterator()
Iterate over all the labels of a segment.
getLabelsList()
Returns a list with all the label of a segment.
getNamedAddresses()
Returns a list of all addresses with a label name. The list has the same order as the list returned by getLabelsList.
getProcedureCount()
Returns the number of procedures that has been defined in this segment.
getProcedureAtIndex(index)
Returns the Nth Procedure object of the segment.
getProcedureIndexAtAddress(address)
Returns the index of the procedure at a given address of the segment, or -1 if there is no procedure defined there.
getProcedureAtAddress(address)
Returns the Procedure object at a given address of the segment, or None if there is no procedure defined at there.
getInstructionStart(address)
Returns the lowest address value of the instruction found at a particular address. If the given address is in the middle of an instruction, Hopper will look back to find the first byte of this instruction.
getObjectLength(address)
Returns the length in bytes of the object at this address. The object can be an instruction, a data, etc.
isPartOfAnArray(address)
Returns True if the address is part of an array.
getArrayStartAddress(address)
Returns the array start address, or BAD_ADDRESS if not inside an array.
getArrayElementCount(address)
Returns the number of element in the array, or 0 if not inside an array.
getArrayElementAddress(address,index)
Returns the address of the element at the given index, or BAD_ADDRESS if not inside an array.
getArrayElementSize(address)
Returns the size in bytes of a single element of the array, or 0 if not inside an array.
getStringCount()
Returns the number of strings in the segment.
getStringAtIndex(index)
Return the nth string of the segment.
getStringAddressAtIndex(index)
Return the address of the nth string of the segment.
getStringsList()
Returns a list containing all the strings and there address as a tuple.
Class Document
This class represents the disassembled document. A document is a set of segments.
newDocument()
[static]
Creates and returns a new empty document.
getCurrentDocument()
[static]
Returns the current document.
getAllDocuments()
[static]
Returns a list of all currently opened documents.
ask(msg)
[static]
Open a window containing a text field, and wait for the user to give a string value. Returns the string, or returns None if the Cancel button is hit.
askFile(msg,path,save)
[static]
Open a file dialog with a specified title, in order to select a file. The 'save' parameter allows you to choose between on 'open' or a 'save' dialog.
askDirectory(msg,path)
[static]
Open a file dialog with a specified title, in order to select a directory.
message(msg,buttons)
[static]
Open a window containing a text field and a set of buttons. The 'Buttons' parameter is a list of strings. The function returns the index of the clicked button.
closeDocument()
Close the document.
loadDocumentAt(path)
Load a document at a given path.
saveDocument()
Save the document.
saveDocumentAt(path)
Save the document at a given path.
getDocumentName()
Returns the document display name.
setDocumentName(name)
Set the document display name.
backgroundProcessActive()
Returns True if the background analysis is still running.
requestBackgroundProcessStop()
Request the background analysis to stop as soon as possible, and wait for its termination.
waitForBackgroundProcessToEnd()
Wait until the background analysis is ended.
assemble(instr,address,syntax)
Assemble an instruction, and returns the bytes as an array. The instruction is NOT injected in the document: the address given to the function is used to encode the instruction. You wan use the writeByte method to inject an assembled instruction. The first argument is the instruction to be assembled. The second is the address of the instruction. The last parameter is the syntax variant index. For the Intel processor, syntax = 0 for Intel syntax, and 1 for AT&T syntax.
getDatabaseFilePath()
Returns the path of the current Hopper database for this document (the HOP file).
getExecutableFilePath()
Returns the path of the executable being analyzed.
setExecutableFilePath(path)
Set the path of the executable being analyzed.
log(msg)
Display a string message into the log window of the document.
rebase(new_base_address)
Change the file base address.
newSegment(start_address,length)
Create a new segment of 'length' bytes starting at 'start_address'.
deleteSegment(seg_index)
Delete the segment at a given index. Return True if succeeded.
renameSegment(seg_index,name)
Rename the segment at a given index. Return True if succeeded.
getSegmentCount()
Returns the number of segment the document contains.
getSegment(index)
Returns a segment by index. The returned object is an instance of the Segment class. If the index of not in the range [0;count[, the function returns None.
getSegmentByName(name)
Returns a segment by name. Return None if no segment with this name was found. If multiple segments have this name, the first one is returned.
getSectionByName(name)
Returns a section by name. Return None if no segment with this name was found. If multiple sections have this name, the first one is returned.
getSegmentsList()
Returns a list containing all the segments.
getSegmentIndexAtAddress(addr)
Returns the segment index for a particular address.
getSegmentAtAddress(addr)
Returns the segment for a particular address.
getSectionAtAddress(addr)
Returns the section for a particular address.
getCurrentSegmentIndex()
Returns the segment index where the cursor is. Returns -1 if the current segment cannot be located.
getCurrentSegment()
Returns the segment where the cursor is. Returns None if the current segment cannot be located.
getCurrentSection()
Returns the section where the cursor is. Returns None if the current section cannot be located.
getCurrentProcedure()
Returns the Procedure object where the cursor is. Returns None if there is no procedure there.
getCurrentAddress()
Returns the address where the cursor currently is.
setCurrentAddress(addr)
Set the address where the cursor currently is.
getSelectionAddressRange()
Returns a list, containing two addresses. Those address represents the range of bytes covered by the selection.
moveCursorAtAddress(addr)
Move the cursor at a given address.
selectAddressRange(addrRange)
Select a range of byte. The awaited argument is a list containing exactly two address.
getFileOffsetFromAddress(addr)
Returns the file offset corresponding to the given address.
getAddressFromFileOffset(offset)
Returns the address corresponding to the given file offset.
is64Bits()
Returns True if the disassembled document is interpreted as a 64 bits binary.
getEntryPoint()
Returns the entry point of the document.
moveCursorAtEntryPoint()
Move the cursor at the entry point.
getHighlightedWord()
Returns the word that is currently highlighted in the assembly view.
setNameAtAddress(addr,name)
Set the label name at a given address.
getNameAtAddress(addr)
Get the label name at a given address.
getAddressForName(name)
Get the address associated to a given name.
refreshView()
Force the assembly view to be refresh.
moveCursorOneLineDown()
Move the current line down, and remove the multiselection if needed. Returns True if cursor moved.
moveCursorOneLineUp()
Move the current line up, and remove the multiselection if needed. Returns True if cursor moved.
getRawSelectedLines()
Returns a list of strings corresponding to the current selection.
addTagAtAddress(tag,addr)
Add a tag at a particular address.
removeTagAtAddress(tag,addr)
Remove the tag at a particular address.
hasTagAtAddress(tag,addr)
Returns True if the tag is present at this address.
getTagCountAtAddress(addr)
Returns the number of tags at a given address.
getTagAtAddressByIndex(addr,index)
Returns the Nth tag present at a given address.
tagIteratorAtAddress(addr)
Iterates over all tags present at a given address.
getTagListAtAddress(addr)
Returns the list of all tags present at a given address
getTagCount()
Returns the total number of tags available.
getTagAtIndex(index)
Returns a Tag object, or None if the index does not exists.
tagIterator()
Iterate over all the tags.
getTagList()
Returns a list of all tags.
buildTag(name)
Build a tag with a given name. If a tag with the same name already exists, it return the existing tag.
getTagWithName(name)
Returns a Tag object if a tag with this name already exists, or None.
destroyTag(tag)
Remove the tag from every location, and delete it.
hasColorAtAddress(addr)
Returns True if a color has been defined at the given address.
setColorAtAddress(color,addr)
Sets the color at a given address. The color is a 32bits integer representing the hexadecimal color in the form #AARRGGBB.
getColorAtAddress(addr)
Returns the color at a given address. The color is a 32bits integer representing the hexadecimal color in the form #AARRGGBB.
removeColorAtAddress(addr)
Remove the color at a given address.
readBytes(addr,length)
Read bytes from a mapped segment, and return a string. Returns False if no segments was found for this range.
readByte(addr)
Read a byte from a mapped segment. Returns False if no segments was found for this address.
readUInt16LE(addr)
Read a 16 bits little endian integer from a mapped segment. Returns False if no segments was found for this address.
readUInt32LE(addr)
Read a 32 bits little endian integer from a mapped segment. Returns False if no segments was found for this address.
readUInt64LE(addr)
Read a 64 bits little endian integer from a mapped segment. Returns False if no segments was found for this address.
readUInt16BE(addr)
Read a 16 bits big endian integer from a mapped segment. Returns False if no segments was found for this address.
readUInt32BE(addr)
Read a 32 bits big endian integer from a mapped segment. Returns False if no segments was found for this address.
readUInt64BE(addr)
Read a 64 bits bif endian integer from a mapped segment. Returns False if no segments was found for this address.
writeBytes(addr,byteStr)
Write bytes to a mapped segment. Bytes are given as a string. Returns False if no segments was found for this range.
writeByte(addr,value)
Write a byte to a mapped segment. Returns True if succeeded.
writeUInt16LE(addr,value)
Write a 16 bits little endian integer to a mapped segment. Returns True if succeeded.
writeUInt32LE(addr,value)
Write a 32 bits little endian integer to a mapped segment. Returns True if succeeded.
writeUInt64LE(addr,value)
Write a 64 bits little endian integer to a mapped segment. Returns True if succeeded.
writeUInt16BE(addr,value)
Write a 16 bits big endian integer to a mapped segment. Returns True if succeeded.
writeUInt32BE(addr,value)
Write a 32 bits big endian integer to a mapped segment. Returns True if succeeded.
writeUInt64BE(addr,value)
Write a 64 bits big endian integer to a mapped segment. Returns True if succeeded.
getOperandFormat(addr,index)
Returns the format requested by the user for a given intruction operand.
getOperandFormatRelativeTo(addr,index)
Returns the address to which the format is relative. Usually used for FORMAT_ADDRESS_DIFF format.
setOperandFormat(addr,index,fmt)
Set the format of a given intruction operand.
setOperandRelativeFormat(addr,relto,index,fmt)
Set the relative format of a given intruction operand. This version allows one to provide an address used for the relative formats, like FORMAT_ADDRESS_DIFF.
getInstructionStart(address)
Returns the lowest address value of the instruction found at a particular address. If the given address is in the middle of an instruction, Hopper will look back to find the first byte of this instruction.
getObjectLength(address)
Returns the length in bytes of the object at this address. The object can be an instruction, a data, etc.
generateObjectiveCHeader()
Returns a bytearray object containing the generated Objective-C header extracted from the file's metadata.
produceNewExecutable(remove_sig=False)
Produces a new executable including all the modifications. The optional argument is a boolean indicating if the signature is to be removed in the case of a Mach-O file. Returns a string containing the produced executable.
setBookmarkAtAddress(address,name=None)
Set a bookmark at a given address, with an optional name.
removeBookmarkAtAddress(address)
Removes a bookmark at a given address.
hasBookmarkAtAddress(address)
Returns True if a bookmark is present at a given address.
renameBookmarkAtAddress(address,name)
Changes the name of an existing bookmark.
findBookmarkWithName(name)
Returns a list of all bookmarks of a given name.
getBookmarkName(address)
Returns the name of a bookmark at a given address.
getBookmarks()
Returns a list of all the addresses with a bookmark.
Class GlobalInformation
An object containing various information about the current version of Hopper.
getHopperMajorVersion()
[static]
Returns the major version number. If Hopper is at version 4.1.2, it'll return "4".
getHopperMinorVersion()
[static]
Returns the minor version number. If Hopper is at version 4.1.2, it'll return "1".
getHopperRevisionNumber()
[static]
Returns the revision version number. If Hopper is at version 4.1.2, it'll return "2".
getHopperVersion()
[static]
Returns a string with the complete Hopper's version number (ie, something like "4.1.2")