Class PivotFinder
Defined in File PivotFinder.h
Class Documentation
-
class PivotFinder
Finds suitable stack pivots and stack shifting gadgets within a payload.
Public Functions
-
PivotFinder(const Pivots &pivots, Register buf_reg, Payload &payload)
Constructs a PivotFinder object with a single buffer register.
- Parameters:
pivots – The collection of available pivot gadgets.
buf_reg – The single register pointing to the target buffer.
payload – The payload object to operate on.
-
PivotFinder(const Pivots &pivots, std::vector<Register> buf_regs, Payload &payload)
Constructs a PivotFinder object with multiple buffer registers.
- Parameters:
pivots – The collection of available pivot gadgets.
buf_regs – A vector of registers pointing to the target buffer.
payload – The payload object to operate on.
-
bool CheckRegister(const RegisterUsage ®)
Checks if a given register usage is compatible with the buffer registers and doesn’t overlap with reserved space in the payload.
Note
This function has TODOs related to more advanced checks for RIP control and skipping used space.
- Parameters:
reg – The RegisterUsage to check.
- Returns:
True if the register usage is valid for pivoting, false otherwise.
-
bool CheckOneGadget(const OneGadgetPivot &pivot, uint64_t free_bytes_after = 0)
Checks if a One-Gadget pivot is valid for the current payload state.
- Parameters:
pivot – The OneGadgetPivot to check.
free_bytes_after – The minimum number of free bytes required after the pivot’s next RIP offset.
- Returns:
True if the One-Gadget pivot is valid, false otherwise.
-
bool CheckPushIndirect(const PushIndirectPivot &pivot, uint64_t free_bytes_after = 0)
Checks if a Push/Indirect pivot is valid for the current payload state.
- Parameters:
pivot – The PushIndirectPivot to check.
free_bytes_after – The minimum number of free bytes required after the pivot’s next RIP offset.
- Returns:
True if the Push/Indirect pivot is valid, false otherwise.
-
std::vector<StackPivot> FindAll()
Finds all suitable stack pivot gadgets.
- Returns:
A vector containing all found StackPivot objects.
-
std::optional<StackShiftPivot> FindShift(uint64_t min_shift, uint64_t upper_bound = std::numeric_limits<uint64_t>::max())
Finds a stack shift gadget with a shift amount greater than or equal to
min_shift
and less thanupper_bound
.- Parameters:
min_shift – The minimum required stack shift amount.
upper_bound – The exclusive upper bound for the stack shift amount.
- Returns:
An optional StackShiftPivot if a suitable gadget is found, otherwise
std::nullopt
.
-
std::optional<StackPivot> Find(uint64_t free_bytes_after = 0)
Finds a single suitable stack pivot gadget.
- Parameters:
free_bytes_after – The minimum number of free bytes required after the pivot’s next RIP offset.
- Returns:
An optional StackPivot object. Contains a value if a pivot is found, otherwise
std::nullopt
.
-
std::optional<StackShiftingInfo> GetShiftToOffset(uint64_t from_offset, uint64_t min_to_offset)
Finds a sequence of stack shift gadgets to shift the stack pointer from a given offset to at least a minimum target offset.
- Parameters:
from_offset – The starting offset of the stack pointer.
min_to_offset – The minimum desired offset for the stack pointer.
- Returns:
An optional StackShiftingInfo object. Contains a value if a sequence of shifts is found, otherwise
std::nullopt
.
-
std::optional<StackShiftingInfo> GetShiftToRop(uint64_t from_offset, uint64_t byte_size, bool include_extra_slot, uint64_t min_rop_start = 0)
Finds a sequence of stack shift gadgets to shift the stack pointer to accommodate a ROP chain of a given size.
- Parameters:
from_offset – The starting offset of the stack pointer.
byte_size – The size of the ROP chain in bytes.
include_extra_slot – If true, includes an extra 8 bytes in the required space.
- Returns:
An optional StackShiftingInfo object. Contains a value if a sequence of shifts is found, otherwise
std::nullopt
.
-
std::optional<StackShiftingInfo> FindShiftsInternal(uint64_t from_offset, std::optional<uint64_t> min_to_offset, std::optional<uint64_t> min_next_space)
Internal helper function to find a sequence of stack shift gadgets using a breadth-first search.
The search aims to find a path of stack shifts that results in a stack pointer offset that meets either the minimum target offset or provides sufficient free space.
- Parameters:
from_offset – The starting offset of the stack pointer.
min_to_offset – An optional minimum desired offset for the stack pointer.
min_next_space – An optional minimum required free space at the final stack pointer offset.
- Throws:
ExpKitError – if both
min_to_offset
andmin_next_space
are not set.- Returns:
An optional StackShiftingInfo object. Contains a value if a sequence of shifts is found, otherwise
std::nullopt
.
-
StackShiftingInfo GetShiftInfoFromChain(const std::vector<StackShiftPivot> &chain, uint64_t from_offset)
Converts a chain of StackShiftPivot gadgets into a StackShiftingInfo structure.
This function calculates the resulting offsets and populates the
StackShiftInfo
vector based on the provided chain of gadgets and the starting offset.- Parameters:
chain – The vector of StackShiftPivot gadgets forming the chain.
from_offset – The starting offset of the stack pointer before the shifts.
- Returns:
A StackShiftingInfo structure describing the sequence of shifts.
-
uint64_t ApplyShift(uint64_t kaslr_base, uint64_t from_offset, uint64_t min_to_offset)
Applies a sequence of stack shifts to the payload to reach at least a minimum target offset.
- Parameters:
kaslr_base – The Kernel Address Space Layout Randomization base address.
from_offset – The starting offset of the stack pointer.
min_to_offset – The minimum desired offset for the stack pointer.
- Throws:
ExpKitError – if a suitable stack shift gadget sequence cannot be found.
- Returns:
The final offset of the stack pointer after applying the shifts.
-
RopPivotInfo PivotToRop(const RopChain &rop)
Attempts to find a stack pivot and a sequence of stack shifts to pivot to a given Rop chain.
Note
This function iterates through found pivots and attempts to apply shifts until a working combination is found.
- Parameters:
rop – The ROP chain to pivot to.
- Throws:
ExpKitError – if a suitable pivot and shift sequence cannot be found.
- Returns:
A RopPivotInfo structure containing information about the successful pivot and shifts.
-
std::optional<PopRspPivot> GetPopRsp()
Finds a simple “pop rsp; ret” gadget that doesn’t change the stack before the RSP update and has its next RIP immediately after the gadget.
- Returns:
An optional PopRspPivot. Contains a value if such a gadget is found, otherwise
std::nullopt
.
-
StackShiftPivot GetSingleRet()
Finds a simple “ret” gadget that shifts the stack by 8 bytes and jumps to the shifted location.
- Returns:
A StackShiftPivot representing a simple “ret”.
-
PivotFinder(const Pivots &pivots, Register buf_reg, Payload &payload)