hdis86-0.2: Interface to the udis86 disassembler for x86 and x86-64 / AMD64




Interface to the udis86 disassembler.

The goal at this level of wrapping is to provide the maximum feature-set from the underlying C library, with the minimum of C-related headaches. Therefore, this module's API is thoroughly imperative, but uses Haskellish types and automatic resource management.

For a higher-level, IO-free API, see Hdis86.Pure.

This module is fully thread-safe: any number of threads may manipulate one or several UD objects at the same time. The individual operations exported by this module are guaranteed to be atomic.



data UD Source

Abstract type representing an instance of the disassembler.


newUD :: IO UDSource

Create a new disassembler instance.

There is no deleteUD. Associated resources will be freed automatically after this UD value becomes unreachable.

Input sources

setInputBuffer :: UD -> ByteString -> IO ()Source

Set up the UD instance to read machine code from a ByteString.

This library does not copy the contents of the ByteString. It will hold onto the value until another input source is selected, or until the UD value becomes unreachable.

This means that setInputBuffer is both safe and efficient, but it may inhibit garbage collection of a larger ByteString containing the input. To prevent this, use ByteString.copy.

type InputHook = IO (Maybe Word8)Source

A custom input source.

Each time this action is executed, it should return a single byte of input, or Nothing if there are no more bytes to read.

setInputHook :: UD -> InputHook -> IO ()Source

Register an InputHook to provide machine code to disassemble.

unsetInput :: UD -> IO ()Source

Clear any previous input source setting.

This allows the UD instance to free any resources associated with the input source. Those resources would be freed automatically after the UD value becomes unreachable, but you can use unsetInput to force this to happen earlier.


advance :: UD -> IO (Maybe Word)Source

Disassemble the next instruction and return its length in bytes, or Nothing if there are no more instructions.

skip :: UD -> Word -> IO ()Source

Skip the next n bytes of the input.

setIP :: UD -> Word64 -> IO ()Source

Set the instruction pointer, i.e. the disassembler's idea of where the current instruction would live in memory.

run :: UD -> IO a -> IO [a]Source

A convenience function which calls advance repeatedly while instructions remain.

At each instruction the user-specified action is performed, and the results are collected. The UD value is not passed as an argument, but it's easy enough to close over it when defining your action.

Inspecting the output

getInstruction :: UD -> IO InstructionSource

Get the current instruction.

getLength :: UD -> IO WordSource

Get the length of the current instruction in bytes.

getOffset :: UD -> IO Word64Source

Get the offset of the current instruction. This value is set by getIP and updated after each call to advance.

getHex :: UD -> IO StringSource

Get the current instruction's machine code as a hexadecimal string.

getBytes :: UD -> IO ByteStringSource

Get the current instruction's machine code as a ByteString.

The bytes are copied out of internal state.

getAssembly :: UD -> IO StringSource

Get the assembly syntax for the current instruction.

See also setSyntax.

getMetadata :: UD -> IO MetadataSource

Get all metadata about the current instruction, along with the instruction itself.


setConfig :: UD -> Config -> IO ()Source

Set an overall configuration.

Calls each of setVendor, setCPUMode, setSyntax, setIP.

setVendor :: UD -> Vendor -> IO ()Source

Choose an instruction set variation.

setCPUMode :: UD -> CPUMode -> IO ()Source

Set the CPU mode, i.e. 16-bit, 32-bit, or 64-bit.

setSyntax :: UD -> Syntax -> IO ()Source

Set the assembly syntax to be used by getAssembly.

This takes effect after the next call to disassemble.


setCallback :: UD -> IO () -> IO ()Source

Register an action to be performed after each instruction is disassembled.

This is not necessary for using the library. An alternative is to perform the action in a loop which also calls advance.

This disables updating of the string returned by getAssembly.

Unsafe operations

unsafeSetInputPtr :: UD -> Ptr Word8 -> Word -> IO ()Source

Set up the UD instance to read directly from memory.

Given are a pointer to a memory region, and the length of that region.

This is an unsafe operation because the contents of the memory region might change, especially if it's part of the heap managed by GHC's garbage collector.

You are responsible for ensuring that the memory pointed to does not change or become invalid until another input source is selected. You cannot rely on garbage collection of the UD value, because finalization may be delayed arbitrarily long after the value becomes unreachable.

It should be safe to use this on the static code segment of your process, which is useful when your Haskell program needs to disassemble itself.

unsafeRunLazy :: UD -> IO a -> IO [a]Source

Lazy version of run; calls into the C library as elements of its result list are forced.

This has roughly the same caveats as unsafeInterleaveIO.