Instrumentation Utilities


DR_EXPORT bool drutil_init (void)
DR_EXPORT void drutil_exit (void)
DR_EXPORT bool drutil_insert_get_mem_addr (void *drcontext, instrlist_t *bb, instr_t *where, opnd_t memref, reg_id_t dst, reg_id_t scratch)
DR_EXPORT bool drutil_insert_get_mem_addr_ex (void *drcontext, instrlist_t *bb, instr_t *where, opnd_t memref, reg_id_t dst, reg_id_t scratch, DR_PARAM_OUT bool *scratch_used)
DR_EXPORT uint drutil_opnd_mem_size_in_bytes (opnd_t memref, instr_t *inst)
DR_EXPORT bool drutil_expand_rep_string (void *drcontext, instrlist_t *bb)
DR_EXPORT bool drutil_expand_rep_string_ex (void *drcontext, instrlist_t *bb, DR_PARAM_OUT bool *expanded, DR_PARAM_OUT instr_t **stringop)
DR_EXPORT bool drutil_instr_is_stringop_loop (instr_t *inst)

Detailed Description

Function Documentation

◆ drutil_exit()

DR_EXPORT void drutil_exit ( void  )

Cleans up the drutil extension.

◆ drutil_expand_rep_string()

DR_EXPORT bool drutil_expand_rep_string ( void *  drcontext,
instrlist_t bb 

Expands single-instruction string loops (those using the rep or repne prefixes) into regular loops to simplify memory usage analysis. This is accomplished by arranging for each single-instruction string loop to occupy a basic block by itself (by truncating the prior block before the loop, and truncating instructions after the loop) and then exanding it into a multi-instruction loop.

Clients applying this expansion are encouraged to use emulation-aware instrumentation via drmgr_orig_app_instr_for_fetch() and drmgr_orig_app_instr_for_operands() in order to observe the original string loop opcode with the expanded memory operands.

WARNING: The added multi-instruction loop contains several control-transfer instructions and is not straight-line code, which can complicate subsequent analysis routines.

WARNING: The added instructions have translations that are in the middle of the original string loop instruction. This is to prevent passes that match exact addresses from having multiple hits and doing something like inserting 6 clean calls.

WARNING: The added instructions include a jecxz instruction which will not be transformed into a 32-bit-reach instruction: thus, excessive added instrumentation may result in a reachability problem.

The client must use the drmgr Extension to order its instrumentation in order to use this function. This function must be called from the application-to-application ("app2app") stage (see drmgr_register_bb_app2app_event()).

This transformation is deterministic, so the caller can return DR_EMIT_DEFAULT from its event.

whether successful.

◆ drutil_expand_rep_string_ex()

DR_EXPORT bool drutil_expand_rep_string_ex ( void *  drcontext,
instrlist_t bb,
DR_PARAM_OUT bool *  expanded,
DR_PARAM_OUT instr_t **  stringop 

Identical to drutil_expand_rep_string() but returns additional information.

[in]drcontextThe opaque context
[in]bbInstruction list passed to the app2app event
[out]expandedWhether any expansion occurred
[out]stringopThe string instruction in the expanded loop
whether successful.

◆ drutil_init()

DR_EXPORT bool drutil_init ( void  )

Initializes the drutil extension. Must be called prior to any of the other routines. Can be called multiple times (by separate components, normally) but each call must be paired with a corresponding call to drutil_exit().

whether successful.

◆ drutil_insert_get_mem_addr()

DR_EXPORT bool drutil_insert_get_mem_addr ( void *  drcontext,
instrlist_t bb,
instr_t where,
opnd_t  memref,
reg_id_t  dst,
reg_id_t  scratch 

Inserts instructions prior to where in bb that determine and store the memory address referred to by memref into the register dst. May clobber the register scratch. Supports far memory references. For far memory references via DS and ES, we assume that the segment base is 0.

All registers used in memref must hold their original application values in order for the proper address to be computed into dst. The dst register may overlap with the registers used in memref. On ARM, scratch must be different from those used in memref (as well as from dst). On x86, scratch will not be used unless memref is a far reference that either uses dst or is a base-disp with both a base and an index, or memref is a reference in the OP_xlat instruction.

To obtain each memory address referenced in a single-instruction string loop, use drutil_expand_rep_string() to transform such loops into regular loops containing (non-loop) string instructions.

whether successful.

◆ drutil_insert_get_mem_addr_ex()

DR_EXPORT bool drutil_insert_get_mem_addr_ex ( void *  drcontext,
instrlist_t bb,
instr_t where,
opnd_t  memref,
reg_id_t  dst,
reg_id_t  scratch,
DR_PARAM_OUT bool *  scratch_used 

Identical to drutil_insert_get_mem_addr() except it returns in the optional OUT parameter scratch_used whether or not scratch was written to.

◆ drutil_instr_is_stringop_loop()

DR_EXPORT bool drutil_instr_is_stringop_loop ( instr_t inst)

Returns whether the given instr is a stringop loop.

[in]instThe instr to inspect.
whether given instr is a stringop loop.

◆ drutil_opnd_mem_size_in_bytes()

DR_EXPORT uint drutil_opnd_mem_size_in_bytes ( opnd_t  memref,
instr_t inst 

Returns the size of the memory reference memref in bytes. To handle OP_enter, requires the containing instruction inst to be passed in. For single-instruction string loops, returns the size referenced by each iteration.

If the instruction is part of the xsave family of instructions, this returns an incomplete computation of the xsave instruction's written xsave area's size. Specifically, it

  • Ignores the user state mask components set in edx:eax, because they are dynamic values. The real output size of xsave depends on the instruction's user state mask AND the user state mask as supported by the CPU based on the XCR0 control register.
  • Ignores supervisor state component PT (enabled/disabled by user state component mask bit 8).
  • Ignores the user state component PKRU state (enabled/disabled by user state component mask bit 9).
  • Ignores the xsaveopt flavor of xsave.
  • Ignores the xsavec flavor of xsave (compacted format).

It computes the expected size for the standard format of the x87 user state component (enabled/disabled by user state component mask bit 0), the SSE user state component (bit 1), the AVX user state component (bit 2), the MPX user state components (bit 2 and 3) and the AVX-512 user state component (bit 7).