public interface

IDState

com.pnfsoftware.jeb.core.units.code.android.ir.IDState

Class Overview

dexdec IR state (referred as "State"), used to perform IR evaluations, emulation and sandboxing.

Note: This interface exposes a significant subset of the State functionalities, but not all. In particular, the sandbox itself cannot be manipulated (it can only be enabled or disabled). Future API extensions may allow third-party clients to access those controls.

A State can be created or retrieved via the global IR context (the g attribute in optimizers inheriting AbstractDOptimizer), see methods createState() and getThreadSharedState().

The emulation of code takes place within a context. Each context has a stack of frames, holding the emulator state relative to the method being executed (the top frame for the current method, the second frame for the caller of the current method, etc.).

Note the special role of IDImm objects: they represent both immediate values, as well as object references living in a State object.

Summary

Constants
int DEFAULT_MAX_DURATION Default maximum duration, in milliseconds.
int DEFAULT_MAX_ITERCOUNT Default maximum iteration count.
int SUBEXEC_ALLOW_ALL Sub-routine execution policy: this special flag allows everything.
int SUBEXEC_ALLOW_EXTERNAL Sub-routine execution policy: this flag allows external routines.
int SUBEXEC_ALLOW_INTERNAL Sub-routine execution policy: this flag allows internal routines.
Public Methods
abstract boolean canRun()
Quickly determine whether this State is usable, that is, can code be emulated (e.g.
abstract IDImm cloneArray(IDImm arrayRef)
Clone an array.
abstract IDImm createArray(IJavaType arrayType, int len, List<? extends IDImm> initialValues)
Create an array.
abstract void createContext(String name)
Create and push a new execution context.
abstract void createFrame(String methodSignature)
Create and push a frame within the current (top) emulation context.
abstract IDImm createNewInstance(String constructorSignature, Collection<IDExpression> constructorParameters)
Create a new instance of an object.
abstract void deleteTopContext()
Delete the most recent (top) execution context.
abstract void deleteTopFrame()
Delete the most recent (top) frame of the current execution context.
abstract void enableEmulator(boolean enabled)
Enable or disable the emulator.
abstract void enableExceptionHandling(boolean enabled)
Enable or disable the handling of exceptions generated by the emulated code.
abstract boolean enableSandbox(boolean enabled)
Enable or disable the sandbox.
abstract IDImm execute(DExecutionParameters info)
Execute some IR.
abstract IDImm executeDexMethod(IDexMethod m, List<IDExpression> args)
Execute (emulate) an IR method within a new context.
abstract IDImm getArrayElement(IDImm arrayRef, int index)
Read an array element.@return
abstract Object getArrayObject(IDImm ref)
Retrieve an array by reference.@return
abstract int getArrayObjectLength(IDImm ref)
Get the length of an array.@return
abstract IDImm getClassReference(String classname)
Retrieve a classref reference by name.@return
abstract int getCountOfContexts()
Get the count of contexts.
abstract int getCountOfFrames(int context)
Get the number of frames in the provided context.
abstract long getCurrentDuration()
Set the emulator timeout value.
abstract int getCurrentIterationCount()
Retrieve the current total iteration count, that is, the total number of statements emulated or executed by this object.
abstract Collection<IDMethodExecutionHelper> getExecutionHelpers()
Retrieve the collection of all registered method execution helpers.
abstract IDGlobalContext getGlobalContext()
Retrieve the global IR context that was used to create this State.
abstract IDImm getInstanceField(String fsig, IDImm instance)
Retrieve the value of an instance field.@return
abstract int getIterationCountLeft()
Retrieve the number of iterations left.
abstract String getMethodSignature(int context, int frame)
Retrieve the method signature or name for a given frame.@return
abstract Object getObject(IDImm ref)
Retrieve an object value by its reference.@return
abstract int getPC(int context, int frame)
Retrieve the IR program counter in a given frame.@return
abstract IDImm getStaticField(String fsig)
Retrieve the value of a static field.
abstract String getStringObject(IDImm strOrRef)
Retrieve a string by reference.@return
abstract int getSubRoutineInvocationPolicy()
Retrieve the emulation policy for invoking sub-routines.
abstract long getTimeLeft()
Retrieve the amount of emulation time left.
abstract IJLSTypeAdapter getTypeAdapter()
Provide the type adapter used by the emulator and sandbox.
abstract IDImm getVariable(int context, int frame, long varid)
Retrieve the value of a variable in a given frame.@return
abstract boolean isEmulatorEnabled()
Determine whether the emulator is enabled.
abstract boolean isExceptionHandlingEnabled()
Determine whether handling of exceptions generated by the emulated code is enabled.
abstract boolean isInstanceOf(IDImm obj, IDImm clz)
Determine whether an object is assignment-compatible with a class type.@return
abstract boolean isSandboxEnabled()
Determine whether the sandbox is enabled.
abstract void loadClass(String csig)
Load a class.
abstract void registerExecutionHelper(IDMethodExecutionHelper helper)
Register a method execution helper.
abstract IDImm registerObject(Object o)
Register an object.
abstract Object releaseObject(IDImm ref)
Release an object currently living in this State.
abstract void setArrayElement(IDImm arrayRef, int index, IDImm val)
Write an array element.
abstract void setInstanceField(String fsig, IDImm instance, IDImm val)
Update the value of an instance field.
abstract void setMaxDuration(long maxDuration)
Set the emulator timeout value.
abstract void setMaxIterationCount(int maxInsnCount)
Set or reset the max iteration count.
abstract void setStaticField(String fsig, IDImm val)
Update the value of a static field.
abstract void setSubRoutineInvocationPolicy(int subRoutineInvocationPolicy)
Set the emulation policy for invoking sub-routines.
abstract void setVariable(int context, int frame, long varid, IDImm value)
Set the value of a variable in a given frame.
abstract boolean unregisterExecutionHelper(String methodSignature)
Remove a method execution helper.

Constants

public static final int DEFAULT_MAX_DURATION

Default maximum duration, in milliseconds.

Constant Value: 1000 (0x000003e8)

public static final int DEFAULT_MAX_ITERCOUNT

Default maximum iteration count.

Constant Value: 100 (0x00000064)

public static final int SUBEXEC_ALLOW_ALL

Sub-routine execution policy: this special flag allows everything.

Constant Value: 255 (0x000000ff)

public static final int SUBEXEC_ALLOW_EXTERNAL

Sub-routine execution policy: this flag allows external routines.

Constant Value: 2 (0x00000002)

public static final int SUBEXEC_ALLOW_INTERNAL

Sub-routine execution policy: this flag allows internal routines.

Constant Value: 1 (0x00000001)

Public Methods

public abstract boolean canRun ()

Quickly determine whether this State is usable, that is, can code be emulated (e.g. did we reach the max iteration count or timeout?)

public abstract IDImm cloneArray (IDImm arrayRef)

Clone an array.

Parameters
arrayRef source array reference
Returns
  • the cloned array (as defined by the JLS's array.clone protected method)

public abstract IDImm createArray (IJavaType arrayType, int len, List<? extends IDImm> initialValues)

Create an array. The array object will live in this emulator.

Parameters
len the length of the first dimension, re-using the examples above, would indicate an array int[N][][], String[N][], X[N]
initialValues a list of initial values, non-null, whose length must in [0, N]
Returns
  • the IR constant wrapping the array

public abstract void createContext (String name)

Create and push a new execution context. IR emulation takes place within the top emulation context.

public abstract void createFrame (String methodSignature)

Create and push a frame within the current (top) emulation context. A frame (method frame) contains the current PC, variables, etc.

public abstract IDImm createNewInstance (String constructorSignature, Collection<IDExpression> constructorParameters)

Create a new instance of an object. This method is similar to newInstance(); it allocates an object and executes a constructor method.

Parameters
constructorSignature full signature, e.g. Lcom/abc/Foo-><init>(II)V
constructorParameters parameters
Returns
  • the newly-created instance

public abstract void deleteTopContext ()

Delete the most recent (top) execution context.

public abstract void deleteTopFrame ()

Delete the most recent (top) frame of the current execution context.

public abstract void enableEmulator (boolean enabled)

Enable or disable the emulator. The emulator must be enabled to permit the execution of IDInstruction#evaluate().

public abstract void enableExceptionHandling (boolean enabled)

Enable or disable the handling of exceptions generated by the emulated code.

public abstract boolean enableSandbox (boolean enabled)

Enable or disable the sandbox. The sandbox is used to safely execute external code (not present in the form of dex bytecode in the application).

Returns
  • success indicator

public abstract IDImm execute (DExecutionParameters info)

Execute some IR.

The execution takes place in the current frame (i.e. no new context or frame is created, it is the responsibility of the caller to do so). That current frame is popped only if the method execution completes fully. On other cases (e.g., an exception is raised, null is returned return because pcExpectedTermination was provided and was reached, etc.), the current frame is left as-is to allow client code to examine it.

Parameters
info execution parameters, including the IR instructions
Returns
  • the execution return value

public abstract IDImm executeDexMethod (IDexMethod m, List<IDExpression> args)

Execute (emulate) an IR method within a new context. Upon completion (success or error), the newly-created context is auto-discarded. The execution result is provided; global objects created by the execution can be reviewed with methods like getObject(IDImm); the rest (frame variables, etc.) is discarded.

NOTE: This method is currently limited to the execution of dex internal methods (not pure references, not abstract or native). This method is not meant to execute constructor code (<init> methods); to create new objects, use createNewInstance(String, Collection).

Parameters
m a dex internal method
args method arguments
Returns
  • the return value upon completion, if there is one
Throws
DexDecEvaluationException an evaluation exception occurred

public abstract IDImm getArrayElement (IDImm arrayRef, int index)

Read an array element.@return

public abstract Object getArrayObject (IDImm ref)

Retrieve an array by reference.@return

public abstract int getArrayObjectLength (IDImm ref)

Get the length of an array.@return

public abstract IDImm getClassReference (String classname)

Retrieve a classref reference by name.@return

Parameters
classname fully-qualified name, e.g. Lcom/abc/Foo;

public abstract int getCountOfContexts ()

Get the count of contexts.

public abstract int getCountOfFrames (int context)

Get the number of frames in the provided context.

Parameters
context 0 means current (top) context

public abstract long getCurrentDuration ()

Set the emulator timeout value.

If a run exceeds the timeout, the emulation fails and a DexDecEvalTimeoutExceededException exception is raised.

Returns
  • in ms

public abstract int getCurrentIterationCount ()

Retrieve the current total iteration count, that is, the total number of statements emulated or executed by this object.

If the maximum iteration count is reached, a DexDecEvalItercountExceededException exception is be raised.

public abstract Collection<IDMethodExecutionHelper> getExecutionHelpers ()

Retrieve the collection of all registered method execution helpers.

public abstract IDGlobalContext getGlobalContext ()

Retrieve the global IR context that was used to create this State.

public abstract IDImm getInstanceField (String fsig, IDImm instance)

Retrieve the value of an instance field.@return

public abstract int getIterationCountLeft ()

Retrieve the number of iterations left.

public abstract String getMethodSignature (int context, int frame)

Retrieve the method signature or name for a given frame.@return

Parameters
context context number (0 means current context)
frame frame number within the context (0 means current frame)

public abstract Object getObject (IDImm ref)

Retrieve an object value by its reference.@return

public abstract int getPC (int context, int frame)

Retrieve the IR program counter in a given frame.@return

Parameters
context context number (0 means current context)
frame frame number within the context (0 means current frame)

public abstract IDImm getStaticField (String fsig)

Retrieve the value of a static field.

Note: field resolution is performed, just as the sget opcode does. Example: if type Y extends type X, X contains field i, and the caller attempts to read Y.i, this method will resolve the field to X.i.@return

public abstract String getStringObject (IDImm strOrRef)

Retrieve a string by reference.@return

public abstract int getSubRoutineInvocationPolicy ()

Retrieve the emulation policy for invoking sub-routines.

Returns
  • a combination of SUBEXEC_xxx flags

public abstract long getTimeLeft ()

Retrieve the amount of emulation time left.

Returns
  • in ms, always >= 0

public abstract IJLSTypeAdapter getTypeAdapter ()

Provide the type adapter used by the emulator and sandbox. Only internal, fully-qualified names are accepted by this adapter, e.g. Lcom/abc/Foo;

public abstract IDImm getVariable (int context, int frame, long varid)

Retrieve the value of a variable in a given frame.@return

Parameters
context context number (0 means current context)
frame frame number within the context (0 means current frame)
varid variable id (see getId())

public abstract boolean isEmulatorEnabled ()

Determine whether the emulator is enabled. The emulator must be enabled to permit the execution of IDInstruction#evaluate().

public abstract boolean isExceptionHandlingEnabled ()

Determine whether handling of exceptions generated by the emulated code is enabled. If not, any exception raised during emulation will bubble up as a DexDecEvaluationException.

public abstract boolean isInstanceOf (IDImm obj, IDImm clz)

Determine whether an object is assignment-compatible with a class type.@return

public abstract boolean isSandboxEnabled ()

Determine whether the sandbox is enabled.

public abstract void loadClass (String csig)

Load a class. The class may be internal (defined in dex) or external.

Parameters
csig fully-qualified signature, e.g. Lcom/abc/Foo;

public abstract void registerExecutionHelper (IDMethodExecutionHelper helper)

Register a method execution helper. A helper is preferred over bytecode emulation or sandbox execution.

Example: if a helper is provided for Ljava/lang/String;->indexOf(I)I, any attempt to emulate indexOf() will result in the helper being called. The helper is responsible for providing the result of execution.

public abstract IDImm registerObject (Object o)

Register an object.

public abstract Object releaseObject (IDImm ref)

Release an object currently living in this State. Watch out! References are not checked. Other objects may use the deleted object.@return

public abstract void setArrayElement (IDImm arrayRef, int index, IDImm val)

Write an array element.

public abstract void setInstanceField (String fsig, IDImm instance, IDImm val)

Update the value of an instance field.

public abstract void setMaxDuration (long maxDuration)

Set the emulator timeout value.

If a run exceeds the timeout, the emulation fails and a DexDecEvalTimeoutExceededException exception is raised.

Parameters
maxDuration in ms

public abstract void setMaxIterationCount (int maxInsnCount)

Set or reset the max iteration count.

If the maximum iteration count is reached, a DexDecEvalItercountExceededException exception is be raised.

public abstract void setStaticField (String fsig, IDImm val)

Update the value of a static field.

Note: field resolution is performed, just as the sput opcode does. Example: if type Y extends type X, X contains field i, and the caller attempts to write Y.i, this method will resolve the field to X.i.

public abstract void setSubRoutineInvocationPolicy (int subRoutineInvocationPolicy)

Set the emulation policy for invoking sub-routines.

Parameters
subRoutineInvocationPolicy a combination of SUBEXEC_xxx flags

public abstract void setVariable (int context, int frame, long varid, IDImm value)

Set the value of a variable in a given frame.

Parameters
context context number (0 means current context)
frame frame number within the context (0 means current frame)
varid variable id (see getId())
value new value (a true immediate or a reference)

public abstract boolean unregisterExecutionHelper (String methodSignature)

Remove a method execution helper.