The main idea behind Return-oriented Programming (ROP) is that rather than setting the return address to point to the shellcode, attackers can set the return address to redirect the execution to some existing code inside the program or any of its modules. Let's say the attacker carefully sequences small snippets of code, like this one:
mov eax, 1
pop ebx
ret
On Windows, the attacker can redirect the execution to the VirtualProtect API to change permissions for the part of the stack (or heap) that the shellcode is in and execute the shellcode. Alternatively, it is possible to use combinations such as VirtualAlloc and memcpy or WriteProcessMemory, HeapAlloc and any memory copy API, or SetProcessDEPPolicy and NtSetInformationProcess APIs to disable DEP.
The trick here is to use the Import Address Table (IAT) of a module to get the address of any of these APIs so that the attacker can redirect the execution to the beginning of this API. In the ROP chain,...