Class JitDataFlowArithmetic
- All Implemented Interfaces:
PcodeArithmetic<JitVal>
This is used for intra-block data flow analysis. We leverage the same API as is used for concrete
p-code interpretation, but we use it for an abstraction. The type of the interpretation is
T:=
JitVal
, which can consist of constants and variables in the use-def graph. The
arithmetic must be provided to the JitDataFlowExecutor
. The intra-block portions of the
use-def graph are populated as each block is interpreted by the executor.
The general strategy for each of the arithmetic operations is to 1) generate the output SSA variable for the op, 2) generate the op node for the generated output and given inputs, 3) enter the op into the use-def graph as the definition of its output, 4) record the inputs and used by the new op, and finally 5) return the generated output.
There should only need to be one of these per data flow model, not per block.
-
Nested Class Summary
Nested classes/interfaces inherited from interface ghidra.pcode.exec.PcodeArithmetic
PcodeArithmetic.Purpose
-
Field Summary
Fields inherited from interface ghidra.pcode.exec.PcodeArithmetic
SIZEOF_SIZEOF
-
Constructor Summary
ConstructorsConstructorDescriptionJitDataFlowArithmetic
(JitAnalysisContext context, JitDataFlowModel dfm) Construct the arithmetic -
Method Summary
Modifier and TypeMethodDescriptionApply a binary operator to the given inputsApply a binary operator to the given inputConstruct the catenation of the given values to form the given output varnode.fromConst
(byte[] value) Convert the given constant concrete value to typeT
having the same size.Get the endianness of this arithmeticmodAfterLoad
(int sizeinOffset, AddressSpace space, JitVal inOffset, int sizeinValue, JitVal inValue) Apply any modifications after a value is loadedmodAfterLoad
(PcodeOp op, AddressSpace space, JitVal inOffset, JitVal inValue) Apply any modifications after a value is loadedmodBeforeStore
(int sizeinOffset, AddressSpace space, JitVal inOffset, int sizeinValue, JitVal inValue) Apply any modifications before a value is storedmodBeforeStore
(PcodeOp op, AddressSpace space, JitVal inOffset, JitVal inValue) Apply any modifications before a value is storedshaveFromLeft
(int amt, JitVal in1) Removeamt
bytes from the left of the value.shaveFromRight
(int amt, JitVal in1) Removeamt
bytes from the right of the value.long
Get the size in bytes, if possible, of the given abstract valueCompute the subpiece of a value.byte[]
toConcrete
(JitVal value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete byte arraytruncFromLeft
(Varnode in1Vn, int amt, JitVal in1) Removeamt
bytes from the left of the varnode.truncFromRight
(Varnode in1Vn, int amt, JitVal in1) Removeamt
bytes from the right of the varnode.Apply a unary operator to the given inputApply a unary operator to the given input
-
Constructor Details
-
JitDataFlowArithmetic
Construct the arithmetic- Parameters:
context
- the analysis contextdfm
- the owning data flow model
-
-
Method Details
-
getEndian
Description copied from interface:PcodeArithmetic
Get the endianness of this arithmeticOften T is a byte array, or at least represents one abstractly. Ideally, it is an array where each element is an abstraction of a byte. If that is the case, then the arithmetic likely has to interpret those bytes as integral values according to an endianness. This should return that endianness.
If the abstraction has no notion of endianness, return null. In that case, the both
PcodeArithmetic.fromConst(BigInteger, int, boolean)
andPcodeArithmetic.fromConst(long, int)
must be overridden. Furthermore, unlessPcodeArithmetic.toConcrete(Object, Purpose)
is guaranteed to throw an exception, thenPcodeArithmetic.toBigInteger(Object, Purpose)
andPcodeArithmetic.toLong(Object, Purpose)
must also be overridden.- Specified by:
getEndian
in interfacePcodeArithmetic<JitVal>
- Returns:
- the endianness or null
-
truncFromRight
Removeamt
bytes from the right of the varnode."Right" is considered with respect to the machine endianness. If it is little endian, then the byte are shaved from the left of the value. This should be used when getting values from the state to remove pieces from off-cut values. It should be applied before the pieces are ordered according to machine endianness.
- Parameters:
in1Vn
- the varnode representing the inputamt
- the number of bytes to removein1
- the input (really a value read from the state)- Returns:
- the resulting value
-
truncFromLeft
Removeamt
bytes from the left of the varnode."Left" is considered with respect to the machine endianness. If it is little endian, then the byte are shaved from the right of the value. This should be used when getting values from the state to remove pieces from off-cut values. It should be applied before the pieces are ordered according to machine endianness.
- Parameters:
in1Vn
- the varnode representing the inputamt
- the number of bytes to removein1
- the input (really a value read from the state)- Returns:
- the resulting value
-
shaveFromRight
Removeamt
bytes from the right of the value.The value is unaffected by the machine endianness, except to designate the output varnode.
- Parameters:
amt
- the number of bytes to removein1
- the input- Returns:
- the output
-
shaveFromLeft
Removeamt
bytes from the left of the value.The value is unaffected by the machine endianness, except to designate the output varnode.
- Parameters:
amt
- the number of bytes to removein1
- the input- Returns:
- the output
-
subpiece
Compute the subpiece of a value.The result is added to the use-def graph. The output varnode is computed from the input varnode and the subpiece parameters. This is used to handle variable retrieval when an access only include parts of a value previously written. Consider the x86 assembly:
MOV RAX, qword ptr [...] MOV dword ptr [...], EAX
The second line reads
EAX
, which consists of only the lower part ofRAX
. Thus, we synthesize a subpiece op. These are distinct from an actualPcodeOp.SUBPIECE
op, since we sometimes needs to filter out synthetic ops.- Parameters:
size
- the size of the output variable in bytesoffset
- the subpiece offset (number of bytes shifted right)v
- the input value- Returns:
- the output value
-
catenate
Construct the catenation of the given values to form the given output varnode.The result is added to the use-def graph. This is used to handle variable retrieval when the pattern of accesses indicates catenation. Consider the x86 assembly:
MOV AH, byte ptr [...] MOV AL, byte ptr [...] MOV word ptr [...], AX
On the third line, the value in
AX
is the catenation of whatever values were written intoAH
andAL
. Thus, we synthesize a catenation op node in the use-def graph.- Parameters:
outVn
- the output varnodeparts
- the list of values to catenate, ordered by machine endianness- Returns:
- the output value
- See Also:
-
unaryOp
Description copied from interface:PcodeArithmetic
Apply a unary operator to the given inputThis provides the full p-code op, allowing deeper inspection of the code. For example, an arithmetic may wish to distinguish immediate (constant) values from variables. By default, this unpacks the details and defers to
PcodeArithmetic.unaryOp(int, int, int, Object)
.- Specified by:
unaryOp
in interfacePcodeArithmetic<JitVal>
- Parameters:
op
- the operationin1
- the input value- Returns:
- the output value
-
unaryOp
Description copied from interface:PcodeArithmetic
Apply a unary operator to the given inputNote the sizes of variables are given, because values don't necessarily have an intrinsic size. For example, a
BigInteger
may have a minimum encoding size, but that does not necessarily reflect the size of the variable from which is was read.- Specified by:
unaryOp
in interfacePcodeArithmetic<JitVal>
- Parameters:
opcode
- the p-code opcodesizeout
- the size (in bytes) of the output variablesizein1
- the size (in bytes) of the input variablein1
- the input value- Returns:
- the output value
-
binaryOp
Description copied from interface:PcodeArithmetic
Apply a binary operator to the given inputThis provides the full p-code op, allowing deeper inspection of the code. For example, an arithmetic may wish to distinguish immediate (constant) values from variables. By default, this unpacks the details and defers to
PcodeArithmetic.binaryOp(int, int, int, Object, int, Object)
.- Specified by:
binaryOp
in interfacePcodeArithmetic<JitVal>
- Parameters:
op
- the operationin1
- the first (left) input valuein2
- the second (right) input value- Returns:
- the output value
-
binaryOp
Description copied from interface:PcodeArithmetic
Apply a binary operator to the given inputsNote the sizes of variables are given, because values don't necessarily have an intrinsic size. For example, a
BigInteger
may have a minimum encoding size, but that does not necessarily reflect the size of the variable from which is was read.- Specified by:
binaryOp
in interfacePcodeArithmetic<JitVal>
- Parameters:
opcode
- the operation's opcode. SeePcodeOp
.sizeout
- the size (in bytes) of the output variablesizein1
- the size (in bytes) of the first (left) input variablein1
- the first (left) input valuesizein2
- the size (in bytes) of the second (right) input variablein2
- the second (right) input value- Returns:
- the output value
-
modBeforeStore
Apply any modifications before a value is storedThis provides the full p-code op, allowing deeper inspection of the code. NOTE: STORE ops always quantize the offset.
We override this to record the
store
op into the use-def graph. As "output" we just returninValue
. The executor will callsetVal
, but the state will just ignore it, because it will be an indirect memory write.- Specified by:
modBeforeStore
in interfacePcodeArithmetic<JitVal>
- Parameters:
op
- the operationspace
- the address spaceinOffset
- the value used as the offsetinValue
- the value to store- Returns:
- the modified value to store
-
modBeforeStore
public JitVal modBeforeStore(int sizeinOffset, AddressSpace space, JitVal inOffset, int sizeinValue, JitVal inValue) Description copied from interface:PcodeArithmetic
Apply any modifications before a value is storedThis implements any abstractions associated with
PcodeOp.STORE
. This is called on the offset and the value before the value is actually stored into the state. NOTE: STORE ops always quantize the offset.- Specified by:
modBeforeStore
in interfacePcodeArithmetic<JitVal>
- Parameters:
sizeinOffset
- the size (in bytes) of the variable used for indirectionspace
- the address spaceinOffset
- the value used as the address (or offset)sizeinValue
- the size (in bytes) of the variable to store and of the output variableinValue
- the value to store- Returns:
- the modified value to store
-
modAfterLoad
Apply any modifications after a value is loadedThis provides the full p-code op, allowing deeper inspection of the code. NOTE: LOAD ops always quantize the offset.
We override this to record the op into the use-def graph. For our
inValue
, thestate
will have just returned thedummy indirect
variable definition. We must not "use" this. Instead, we must take our other parameters to construct the load op and return its output.- Specified by:
modAfterLoad
in interfacePcodeArithmetic<JitVal>
- Parameters:
op
- the operationspace
- the address spaceinOffset
- the value used as the offsetinValue
- the value loaded- Returns:
- the modified value loaded
-
modAfterLoad
public JitVal modAfterLoad(int sizeinOffset, AddressSpace space, JitVal inOffset, int sizeinValue, JitVal inValue) Description copied from interface:PcodeArithmetic
Apply any modifications after a value is loadedThis implements any abstractions associated with
PcodeOp.LOAD
. This is called on the address/offset and the value after the value is actually loaded from the state. NOTE: LOAD ops always quantize the offset.- Specified by:
modAfterLoad
in interfacePcodeArithmetic<JitVal>
- Parameters:
sizeinOffset
- the size (in bytes) of the variable used for indirectionspace
- the address spaceinOffset
- the value used as the offsetsizeinValue
- the size (in bytes) of the variable loaded and of the output variableinValue
- the value loaded- Returns:
- the modified value loaded
-
fromConst
Description copied from interface:PcodeArithmetic
Convert the given constant concrete value to typeT
having the same size.- Specified by:
fromConst
in interfacePcodeArithmetic<JitVal>
- Parameters:
value
- the constant value- Returns:
- the value as a
T
-
toConcrete
Description copied from interface:PcodeArithmetic
Convert, if possible, the given abstract value to a concrete byte array- Specified by:
toConcrete
in interfacePcodeArithmetic<JitVal>
- Parameters:
value
- the abstract valuepurpose
- the purpose for which the emulator needs a concrete value- Returns:
- the array
-
sizeOf
Description copied from interface:PcodeArithmetic
Get the size in bytes, if possible, of the given abstract valueIf the abstract value does not conceptually have a size, throw an exception.
- Specified by:
sizeOf
in interfacePcodeArithmetic<JitVal>
- Parameters:
value
- the abstract value- Returns:
- the size in bytes
-