SAMP при применении анимаций записывает их библиотеку и название в буффер длинной
256 байт.
Однако скриптовая функция, которую вызывает SAMP (taskPlayAnimNonInterruptable), принимает библиотеку и название в буфферы длинной
16 и 24 байт соответственно и при этом
не проверяет длину входящей строки. Благодаря этому мы получаем
переполнение буффера на стэке, хоть и ограниченное — мы
не можем записывать нулевые байты (но мы можем их писать в буффер SAMPа, что нам очень пригодится).
Чтобы обойти ограничение, мы можем перезаписать адрес возврата функции на гаджет, заранее подготовленный через RPC_ScrSetGravity
(я использовал следующий гаджет: sub esp, ecx; ret;
), а также значение регистра ECX
(в который идут следующие 4 байта после названия анимации). Таким образом мы получаем возможность
произвольно смещать ESP (единственным ограничением служит то, что в смещении не должно быть нулевых байт, но оно легко обходится заменой sub на add и наоборот). Его я сместил на буффер библиотеки анимации SAMPа + 4 байта
(я использовал библиотеку анимаций: BAR + нулевой байт, так как она должна быть действительной, чтобы SAMP проиграл анимацию), в который я предварительно
записал ROP-чейн и чуть модифицированный шеллкод отсюда.
Таким образом, мы получили возможность
подгружать любую DLL в SAMP с сервера на последней версии — SAMP 0.3.7-R5.