int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();
Как это работает? Строка передается в указатель функций
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();
Как это работает? Строка передается в указатель функций
c3
- это инструкция RET
. Когда машина x86 переходит к этой строке, интерпретируемой как код, она выполнит RET
и, следовательно, скачет прямо назад, ничего не выполнив (остальная часть строки игнорируется). Поскольку стандартное соглашение о вызове на x86 состоит в том, чтобы поместить ваше возвращаемое значение в eax
, но код ничего не делал перед возвратом, все, что уже было в eax
, все еще будет там, и в позиции для кода C для интерпретации он как "вернулся".
Это сильно зависит от того, что ваш компьютер является x86, и что вам разрешено отображать данные и указатели на функции (и выполнять результат) - очень системный взлом. Это не стандартное совместимое или портативное C любым растяжением!
(\xXX
- синтаксис C-escape для вставки одиночных нечитаемых символов в строки через их код ASCII в шестнадцатеричном формате, если вы не знали эту часть.)
0xc3
- код операции ret
в x86. Остальная часть струны есть только для аромата. Вся работа выполняется с помощью соглашения о вызове, а соглашение о вызове cdecl
(по умолчанию для языка C) говорит, что функция, возвращающая int
, возвращает ее в eax
.
Ваша функция фактически ничего не делает, она просто возвращает, как только она вызывается, но любой код, который вызывает int foo = eax()
, все еще ожидает, что он вернет свое возвращаемое значение в регистр eax
, поэтому он собираемся скопировать содержимое регистра eax
в foo
.