Ghidra 11.3.2
Ghidra internal decompiler documentation.
Loading...
Searching...
No Matches
ghidra::StringSequence Class Reference

A class for collecting sequences of COPY ops writing characters to the same string. More...

#include <constseq.hh>

Inheritance diagram for ghidra::StringSequence:
[legend]
Collaboration diagram for ghidra::StringSequence:
[legend]

Public Member Functions

 StringSequence (Funcdata &fdata, Datatype *ct, SymbolEntry *ent, PcodeOp *root, const Address &addr)
 Set-up for recovering COPY ops into a memory range, given a Symbol and an Address being COPYed into.
 
bool transform (void)
 Transform COPYs into a single memcpy user-op.
 
- Public Member Functions inherited from ghidra::ArraySequence
 ArraySequence (Funcdata &fdata, Datatype *ct, PcodeOp *root)
 Constructor.
 
bool isValid (void) const
 Return true if sequence is found.
 

Private Member Functions

bool collectCopyOps (int size)
 Collect ops COPYing constants into the memory region.
 
PcodeOpbuildStringCopy (void)
 Build the strncpy,wcsncpy, or memcpy function with string as input.
 
void removeCopyOps (PcodeOp *replaceOp)
 Remove all the COPY ops from the basic block.
 
VarnodeconstructTypedPointer (PcodeOp *insertPoint)
 Construct a Varnode, with data-type, that acts as a pointer (in)to the Symbol to the root Address.
 

Static Private Member Functions

static void removeForward (const WriteNode &curNode, map< PcodeOp *, list< WriteNode >::iterator > &xref, list< WriteNode > &points, vector< WriteNode > &deadOps)
 Analyze output descendants of the given PcodeOp being removed.
 

Private Attributes

Address rootAddr
 Address within the memory region associated with the root PcodeOp.
 
Address startAddr
 Starting address of the memory region.
 
SymbolEntryentry
 Symbol at the root Address.
 

Additional Inherited Members

- Static Public Attributes inherited from ghidra::ArraySequence
static const int4 MINIMUM_SEQUENCE_LENGTH = 4
 Minimum number of sequential characters to trigger replacement with CALLOTHER.
 
static const int4 MAXIMUM_SEQUENCE_LENGTH = 0x20000
 
- Protected Member Functions inherited from ghidra::ArraySequence
bool checkInterference (void)
 Find maximal set of ops containing the root with no interfering ops in between.
 
int4 formByteArray (int4 sz, int4 slot, uint8 rootOff, bool bigEndian)
 Put constant values from COPYs into a single byte array.
 
uint4 selectStringCopyFunction (int4 &index)
 Pick either strncpy, wcsncpy, or memcpy function used to copy string.
 
- Static Protected Member Functions inherited from ghidra::ArraySequence
static bool interfereBetween (PcodeOp *startOp, PcodeOp *endOp)
 Check for interfering ops between the two given ops.
 
- Protected Attributes inherited from ghidra::ArraySequence
Funcdatadata
 The function containing the sequence.
 
PcodeOprootOp
 The root PcodeOp.
 
DatatypecharType
 Element data-type.
 
BlockBasicblock
 Basic block containing all the COPY/STORE ops.
 
int4 numElements
 Number of elements in the final sequence.
 
vector< WriteNodemoveOps
 COPY/STORE into the array memory region.
 
vector< uint1 > byteArray
 Constants collected in a single array.
 

Detailed Description

A class for collecting sequences of COPY ops writing characters to the same string.

Given a starting Address and a Symbol with a character array as a component, a class instance collects a maximal set of COPY ops that can be treated as writing a single string into memory. Then, if the transform() method is called, an explicit string is constructed, and the COPYs are replaced with a strncpy or similar CALLOTHER that takes the string as its source input.

Constructor & Destructor Documentation

◆ StringSequence()

ghidra::StringSequence::StringSequence ( Funcdata fdata,
Datatype ct,
SymbolEntry ent,
PcodeOp root,
const Address addr 
)

Set-up for recovering COPY ops into a memory range, given a Symbol and an Address being COPYed into.

The SymbolEntry and Address are passed in, with an expected data-type. Check if there is an array of the data-type within the Symbol, and if so, initialize the memory range for the the sequence. Follow on with gathering PcodeOps and testing if the sequence is viable. If not, the the size the memory range will be set to zero.

Parameters
fdatais the function containing the root COPY
ctis the specific data-type for which there should be an array
entis the given Symbol
rootis the COPY holding the constant
addris the Address being COPYed into

References ghidra::ArraySequence::checkInterference(), collectCopyOps(), entry, ghidra::ArraySequence::formByteArray(), ghidra::SymbolEntry::getAddr(), ghidra::SymbolEntry::getFirst(), ghidra::PcodeOp::getIn(), ghidra::Datatype::getMetatype(), ghidra::Address::getOffset(), ghidra::Varnode::getOffset(), ghidra::SymbolEntry::getSize(), ghidra::Datatype::getSize(), ghidra::Address::getSpace(), ghidra::Datatype::getSubType(), ghidra::SymbolEntry::getSymbol(), ghidra::Symbol::getType(), ghidra::Address::isBigEndian(), ghidra::ArraySequence::numElements, rootAddr, ghidra::ArraySequence::rootOp, startAddr, and ghidra::TYPE_ARRAY.

Member Function Documentation

◆ buildStringCopy()

PcodeOp * ghidra::StringSequence::buildStringCopy ( void  )
private

Build the strncpy,wcsncpy, or memcpy function with string as input.

A built-in user-op that copies string data is created. Its first (destination) parameter is constructed as a pointer to the array holding the character data, which may be nested in other arrays or structures. The second (source) parameter is an internal string constructed from the byteArray. The third parameter is the constant indicating the length of the string. The user-op is inserted just before the last PcodeOp moving a character into the memory region.

Returns
the constructed PcodeOp representing the memcpy

References ghidra::ArraySequence::byteArray, ghidra::ArraySequence::charType, constructTypedPointer(), ghidra::CPUI_CALLOTHER, ghidra::ArraySequence::data, ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getArch(), ghidra::Funcdata::getInternalString(), ghidra::Datatype::getSize(), ghidra::TypeFactory::getSizeOfPointer(), ghidra::Address::getSpace(), ghidra::TypeFactory::getTypePointer(), ghidra::AddrSpace::getWordSize(), ghidra::PcodeOp::inputTypeLocal(), ghidra::ArraySequence::moveOps, ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::UserOpManage::registerBuiltin(), rootAddr, ghidra::ArraySequence::selectStringCopyFunction(), ghidra::Architecture::types, ghidra::Varnode::updateType(), and ghidra::Architecture::userops.

Referenced by transform().

◆ collectCopyOps()

bool ghidra::StringSequence::collectCopyOps ( int  size)
private

Collect ops COPYing constants into the memory region.

The COPYs must be in the same basic block. If any COPY size does not match the copyType, return false. If there is a COPY to the array entry before rootVn, return false. Otherwise earlier COPYs are skipped. No COPYs are collected after the first gap (entry with no COPY to it).

Parameters
sizeis the number of bytes in the memory region
Returns
true to indicate legal COPY ops of constants were recovered.

References ghidra::Funcdata::beginLoc(), ghidra::ArraySequence::block, ghidra::ArraySequence::charType, ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::ArraySequence::data, ghidra::Funcdata::endLoc(), ghidra::Datatype::getAlignSize(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Address::getOffset(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getParent(), ghidra::Datatype::getSize(), ghidra::Varnode::getSize(), ghidra::Varnode::isConstant(), ghidra::Varnode::isWritten(), ghidra::ArraySequence::MINIMUM_SEQUENCE_LENGTH, ghidra::ArraySequence::moveOps, rootAddr, and startAddr.

Referenced by StringSequence().

◆ constructTypedPointer()

Varnode * ghidra::StringSequence::constructTypedPointer ( PcodeOp insertPoint)
private

Construct a Varnode, with data-type, that acts as a pointer (in)to the Symbol to the root Address.

First, a PTRSUB is built from the base register to the Symbol. Then depending on its data-type, additional PTRSUBs and PTRADDs are buit to get from the start of the Symbol to the memory region holding the character data. All the new Varnodes have the appropriate pointer data-type set. The final Varnode holding the pointer to the memory region is returned.

Parameters
insertPointis the point before which all new PTRSUBs and PTRADDs are inserted

References ghidra::AddrSpace::byteToAddress(), ghidra::ArraySequence::charType, ghidra::Funcdata::constructConstSpacebase(), ghidra::Funcdata::constructSpacebaseInput(), ghidra::CPUI_INT_ADD, ghidra::CPUI_PTRADD, ghidra::CPUI_PTRSUB, ghidra::ArraySequence::data, entry, ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getArch(), ghidra::SymbolEntry::getFirst(), ghidra::Datatype::getMetatype(), ghidra::Address::getOffset(), ghidra::Varnode::getSize(), ghidra::Address::getSpace(), ghidra::Datatype::getSubType(), ghidra::SymbolEntry::getSymbol(), ghidra::AddrSpace::getType(), ghidra::Symbol::getType(), ghidra::TypeFactory::getTypePointer(), ghidra::TypeFactory::getTypePointerStripArray(), ghidra::AddrSpace::getWordSize(), ghidra::IPTR_SPACEBASE, ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newUniqueOut(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), rootAddr, ghidra::TYPE_ARRAY, ghidra::Architecture::types, and ghidra::Varnode::updateType().

Referenced by buildStringCopy().

◆ removeCopyOps()

void ghidra::StringSequence::removeCopyOps ( PcodeOp replaceOp)
private

Remove all the COPY ops from the basic block.

The COPY ops are removed. Any descendants of the COPY output are redefined with an INDIRECT around the a CALLOTHER op. If the COPYs feed into a PIECE op (as part of a CONCAT stack), the PIECE is removed as well, which may cascade into removal of other PIECE ops in the stack.

Parameters
replaceOpis the CALLOTHER op creating the INDIRECT effect

References ghidra::PcodeOp::code(), ghidra::CPUI_INDIRECT, ghidra::ArraySequence::data, ghidra::PcodeOp::getAddr(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getSize(), ghidra::Funcdata::markIndirectCreation(), ghidra::ArraySequence::moveOps, ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnodeIop(), ghidra::Funcdata::opDestroy(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opSetOutput(), and removeForward().

Referenced by transform().

◆ removeForward()

void ghidra::StringSequence::removeForward ( const WriteNode curNode,
map< PcodeOp *, list< WriteNode >::iterator > &  xref,
list< WriteNode > &  points,
vector< WriteNode > &  deadOps 
)
staticprivate

Analyze output descendants of the given PcodeOp being removed.

Record any points where the output is being read, for later replacement. Keep track of CPUI_PIECE ops whose input is from a PcodeOp being removed, and if both inputs are visited, remove the input points and add the CPUI_PIECE to the list of PcodeOps being removed.

Parameters
curNodeis the given PcodeOp being removed
xrefare the set of CPUI_PIECE ops with one input visited
pointsis the set of input points whose PcodeOp is being removed
deadOpsis the current collection of PcodeOps being removed

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, ghidra::Varnode::endDescend(), ghidra::PcodeOp::getOut(), ghidra::PcodeOp::getSlot(), ghidra::ArraySequence::WriteNode::offset, and ghidra::ArraySequence::WriteNode::op.

Referenced by removeCopyOps().

◆ transform()

bool ghidra::StringSequence::transform ( void  )

Transform COPYs into a single memcpy user-op.

The transform can only fail if the byte array does not encode a valid string, in which case false is returned. Otherwise, a CALLOTHER representing memcpy is constructed taking the string constant as its source pointer. The original COPY ops are removed.

Returns
true if the transform succeeded and the CALLOTHER is created

References buildStringCopy(), and removeCopyOps().

Referenced by ghidra::RuleStringCopy::applyOp().


The documentation for this class was generated from the following files: