Инструкция ассемблера для изменения адреса возврата в вызываемой функции - PullRequest
0 голосов
/ 23 февраля 2019

Я довольно новичок в ассемблере, и я все еще не знаю большинство инструкций.

Я пытаюсь добавить несколько строк asm в программу на C (просто для удовольствия, играя с ней), чтобыизмените адрес возврата функции.

Код C выглядит так:

int my_function()
{
    int my_number = 1;

    __asm__ ("nop"); 
    __asm__ ("nop"); 

    return my_number;
}

int main(int argc, char *argv[])
{
    //declarations

    ...lots of stuff

    int my_number = my_function();

    do_something;

    ...lots of stuff

    do_other_thing;

    ... lots of stuff (46 bits in assembler)

    return 0;
}

, поэтому я пытаюсь изменить адрес возврата в стеке один раз на my_functionпоэтому при возврате он переходит к do_other_thing вместо do_something

Чтобы сделать это красиво и динамично, я предпочитаю не жестко кодировать адрес возврата, поэтому я хотел бы добавить эти46 битЯ знаю также, что обратный адрес в EBP + 4.Я проверил его вручную в x32dgb, и он работает.

Думаю, мне придется:

  1. получить содержимое, указанное EBP + 4 (возможно, в EAX)
  2. сумма 46 в EAX
  3. запишите это значение в EBP + 4

, пока я это понимаю, но не уверен, как закодировать это в предложения ASM...

можешь мне помочь ??

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

просто будьте осторожны с кодификацией и символами в вашем C

, как упоминает @ zx489, попробуйте что-то вроде:

__asm__(".intel_syntax prefix");
__asm__("add dword ptr [%ebp + 4], 46");

, которое может работать ...

0 голосов
/ 23 февраля 2019

Я пытаюсь добавить несколько строк asm в программу на Си (просто для удовольствия, играя с ней), чтобы изменить адрес возврата функции.

Не.

Для кода, написанного на C;компилятор владеет стеком, компилятор генерирует код запуска функции для себя и своих оптимизаций, а компилятор генерирует код выхода в соответствии со своим собственным кодом запуска.Любая встроенная сборка, которая делает какие-либо предположения о расположении стека, является «хрупкой» - крошечное изменение в любом месте (даже просто изменение невинной локальной переменной, изменение аргумента командной строки компилятора или обновление компилятора до следующей версии) может и в конечном итоге приведет кРазличия в расположении стека, которые могут нарушить встроенную сборку.На практике это на самом деле намного хуже, чем это - компилятор может и будет генерировать несколько разных версий одной и той же «функции C» (и встроить некоторые версии в другие функции, чтобы избежать затрат на вызов функции и т. Д.), Так что вы в конечном итоге получитеодин и тот же фрагмент встроенной сборки, который пытается (и гарантированно потерпит неудачу) обрабатывать несколько совершенно разных макетов стека;и даже если вы успешно вернетесь куда-то еще, вы не сможете надежно избежать путаницы после того, как ваша функция вернулась.

Другая проблема заключается в том, что почти никогда не бывает разумной причины хотеть сделать это в первую очередь;даже если вы пишете на ассемблере, где у вас есть полный контроль над компоновкой стека (и не пишете на языке C на встроенном ассемблере, где вы не можете контролировать компоновку стека).

По существу;есть чрезвычайно большое количество вещей, которые более важны для того, кто пытается изучать ассемблер, чтобы тратить свое время на изучение (которые не являются «хрупкими» и бесполезными).Это похоже на то, как учиться водить машину, стоя на руках (используя лицо на педали акселератора / тормоза и не видя ничего вокруг себя) - это бесполезно.

...