value (in the range of 0x00 - 0xff) that can be inter-
preted by the CPU as a legitimate opcode and ends
with the value of the opcode of a return instruction
(e.g., 0xc3 on the Intel platforms), of a call instruc-
tion (0xff on the Intel platforms), or of any instruc-
tion with the semantics of return in their execution
context (Onarlioglu et al., 2010). These gadgets are
like short subroutines, always ending in a return, so
that when CPU hits the return instruction of a gadget
it fetches the return address on the stack to execute the
next gadget. If the stack is purposely filled with data
of malicious intent as a result of system vulnerability
such as buffer overflow being exploited, a sequence
of gadgets can be chained up to execute unintended
logic.
To thwart ROP attacks, it is critical to prevent at-
tackers from exploiting gadgets. Previous work has
focused on gadget removal (Onarlioglu et al., 2010)
and analysis of program execution sequences (Wang
and Jiang, 2010)(Abadi et al., 2009). Gadget removal
has been shown to be an inadequate protection since
gadget removal is not always possible (Checkoway
et al., 2010). Program execution sequence analysis
can be prone to inaccuracies as well as system effi-
ciency issues. The high-level idea of the LITPR sys-
tem is that by changing the memory locations of pages
containing code (resulting in changed gadget loca-
tions) frequently enough, an attacker could be pre-
vented from identifying the memory locations of all
the gadgets needed for composing an attack. With
this approach, there is a high likelihood of ROP at-
tack failure since memory locations of at least some
of the discovered gadgets would be obsolete by the
time attacks are launched.
ROP attacks require some amount of time invest-
ment from an attacker attempting to exploit an ar-
bitrary application. Address space layout random-
ization (ASLR) (Team, 2016) and gadget removal
(Onarlioglu et al., 2010) represent means to protect
against such attacks but recent research (Bittau et al.,
2014) on BROP (Blind ROP) has shown that the for-
mer is not sufficient protection while the latter is not
always feasible. Even more recent work (Gras et al.,
2017) shows that ASLR side-channel attacks can by-
pass ASLR without detection (crashes, exceptions,
etc.). However, searching for Page Table Entries
(PTEs) as suggested still suffers two flaws against
the LITPR system, namely the attack as demonstrated
took approximately 25 seconds to obtain a single ad-
dress and the attack assumes that knowledge of a sin-
gle data buffer location is sufficient to defeat the ad-
dress randomization defense. Our system deals with
both issues by periodically re-randomizing the code
and ensuring that knowledge of a data location does
not provide adequate knowledge about specific code
locations. Other attacks against ASLR include using
branch predictors (Evtyushkin et al., 2016), memory
de-duplication (Bosman et al., 2016), and other tim-
ing based attacks (Hund et al., 2013). However, these
too assume knowledge of a single address at a mo-
ment in time is sufficient to bypass ASLR and while
this is true for ASLR, it is not sufficient to defeat the
proposed LITPR system.
Other systems have been proposed to perform
fine-grained address randomization even including re-
randomization such as (Giuffrida et al., 2012). How-
ever, these systems rely on the availability of source
code, heavy integration into a specific compiler and
have significant overhead associated with relinking
code at runtime. Our proposed LITPR system can
be run against binary code for which the source is
unavailable, does not rely on the compiler used to
perform the original compilation of the source and
should perform significantly faster at runtime (includ-
ing the ability to partially reorder code to minimize
impact on the running system).
1.2 ELF and Position Independent
Execution (PIE) Preliminaries
The LITPR system exploits and extends an existing
concept in the operating system known as dynamic
linking. Dynamically linked executables use a feature
called Position Independent Execution (PIE) provided
by the compiler to generate code that is not required
to be loaded at a fixed memory address (either physi-
cal or virtual). On the Linux operating system, these
executables are stored in the Executable and Linkable
Format (ELF). Knowing the details of the information
stored in this format allows us to make use of the dy-
namic linking information to change the ordering of
the code pages of the executable.
Dynamic linking at a high level works as fol-
lows. At the time a compiler generates object code,
it does not know where the subroutines will be loaded
into the memory. As a result, the resulting object
code generated by the compiler contains a number of
symbols that need to be replaced by the starting ad-
dresses of the subroutines after the object code has
been loaded into memory. This process is called dy-
namic linking. In fact, what we propose to do, in a
sense, can be regarded as dynamic re-linking. This is
because code pages in the physical memory will be
pointed to by different virtual pages due to page table
updates. Whenever a new virtual page replaces the
current virtual page as the index for a physical page,
it is necessary to update all the subroutine references
pointing to the current virtual page with the new vir-
ROP Defense in the Cloud through LIve Text Page-level Re-ordering - The LITPR System
193