Самоудаляющийся код С++

Я хочу создать самоудаляющийся код - функцию для стирания других. Я пытался это сделать, но иногда (в большинстве случаев) я запускаю его - он не работает так, как должен работать. Я хочу сделать что-то вроде этого:

int func(int a)
{

return a+1;

}

int main()
{
func(5);
erase(func);
...
//execute other things
...
}

Я уже создал функцию для этого, но она немного глючная - она ​​ничего не пропускает, пока не найдет код операции ret, я знаю, что адрес начала функции (DWORD) func, но как мне найти адрес конца функции? Я видел пример в Интернете с чем-то вроде:

void func()
_asm __volatile__ beg
{
...
...
...
_asm __volatile__ end
}

но у меня это не работает - я использую VS 2013. Вот мой код:

void destruct(BYTE *pAddress, DWORD dwLen)
{
    DWORD dwOldProtect, dwBkup;
    VirtualProtect(pAddress, dwLen, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    for(DWORD x = 0x0; x < dwLen; x++)
        *(pAddress + x) = 0x90;
    VirtualProtect(pAddress, dwLen, dwOldProtect, &dwBkup);
}

как dwLen я передаю длину, рассчитанную в другой функции - от начала до следующего оператора ret. Под функцией удаления я подразумеваю заполнение его тела NOP или мусором - я хочу "стереть" функцию, которая будет использоваться при запуске программы только один раз, она мне не нужна позже, я просто не хочу, чтобы кто-то сбрасывал мое приложение и отменить его и т. д.


person mlgpro    schedule 11.04.2015    source источник
comment
Что вернет функция после ее удаления? Это не пустота...   -  person sashoalm    schedule 11.04.2015
comment
@sashoalm Я хочу стереть функцию после того, как она использовалась в приложении в последний раз, не беспокойтесь об этом, я просто хочу стереть ее.   -  person mlgpro    schedule 11.04.2015
comment
Что вы подразумеваете под удалением функции?   -  person quantdev    schedule 11.04.2015
comment
@quantdev посмотри на вопрос, он уже отредактирован, так что он более понятен.   -  person mlgpro    schedule 11.04.2015
comment
Я не эксперт по Windows, но вполне вероятно, что буквальный программный код для функций будет храниться в защищенной памяти, доступной только для чтения. Я понятия не имею, зачем вам эта функция.   -  person Galik    schedule 11.04.2015
comment
Функция по-прежнему будет находиться в exe-файле, если только она не была создана во время выполнения. На самом деле все, что вам нужно знать, — это размер функции во время выполнения.   -  person sashoalm    schedule 11.04.2015
comment
@Galik, возможно, это так, не знаю, но моя функция работает, но я не знаю, как найти конец функции, поэтому я могу сделать ее ненужной. Я хочу уничтожить его, чтобы никто не мог отменить его.   -  person mlgpro    schedule 11.04.2015
comment
почему ты хочешь его стереть? Создание какой-то вредоносной программы, которой есть что скрывать ?? Никто не может его отменить: слишком поздно, он в вашем exe, а может быть и на диске в области подкачки!   -  person Christophe    schedule 11.04.2015
comment
@ Кристоф, это процедура проверки лицензии, я делаю это при запуске и хочу стереть ее после проверки лицензии, чтобы никто не мог ее отменить.   -  person mlgpro    schedule 11.04.2015
comment
@sashoalm спасибо за ссылку, я нашел там решение stackoverflow.com/a/10071330/4777874, если хотите, добавьте ответ, и я приму его.   -  person mlgpro    schedule 11.04.2015
comment
Я предлагаю расшифровать функцию в буфер, выполнить ее и очистить весь буфер. (Конечно, это создает еще одну проблему — поиск размера требуемого буфера... но вы можете безопасно превысить его — и, что более важно, получить зашифрованную версию кода функции). Вероятно, вам следует начать с компиляции временного кода как отдельный модуль компиляции и НЕ связывает его с вашим приложением.   -  person Ben Voigt    schedule 11.04.2015
comment
@mlgpro Это очень интересный вопрос, но обратите внимание, что стирание кода в памяти не помешает людям отменить его. Было бы тривиально поставить точку останова в функции erase и скопировать весь код прямо перед тем, как он сможет что-либо удалить.   -  person tux3    schedule 11.04.2015
comment
Это не сработает. Любой опытный человек будет выполнять ваш код шаг за шагом во время процедуры проверки, а не после нее. Если пропустил в первый раз, перезапустит экзешник и во второй раз завел. Не говоря уже об инструментах мониторинга реестра, которые будут регистрировать все, что ваша программа делает в реестре.   -  person Christophe    schedule 11.04.2015
comment
Люди, вероятно, просто запустят его в отладчике и остановят его выполнение в начале main().   -  person Galik    schedule 11.04.2015
comment
@mlgpro Нет смысла дублировать ответ, просто нажмите большую синюю кнопку «Да, спасибо», чтобы ваш вопрос был закрыт как дубликат. Дубликаты допустимы, поскольку вопрос А сводится к ситуациям вопроса Б.   -  person sashoalm    schedule 11.04.2015
comment
@Galik, tux3: Ну, существуют различные методы борьбы с отладкой, которые усложняют эту задачу.   -  person Ben Voigt    schedule 11.04.2015
comment
@BenVoigt Верно. Но если бы мне пришлось идти против реверс-инжиниринга, я бы написал свой код непосредственно на ASM, вместо того, чтобы бороться с компилятором и запускать Страуструп знает сколько неопределенных поведений. Я не уверен, что ОП движется в правильном направлении.   -  person tux3    schedule 11.04.2015
comment
@tux3: Хорошо, засунь его в отдельный блок компиляции, скомпилируй с опцией вывода на ассемблере, еще немного измени и т. д.   -  person Ben Voigt    schedule 11.04.2015
comment
@BenVoigt Я полагаю, хотя ASM, созданный компилятором, может быть довольно сложным для понимания. Конечно, чище написать это напрямую.   -  person tux3    schedule 11.04.2015
comment
@ tux3 это хорошая идея, я подумаю об этом - и сгенерированный компилятором asm может быть прокомментирован эквивалентными строками кода C ++, vs имеет эту функцию, поэтому его легче понять   -  person mlgpro    schedule 11.04.2015
comment
Попытка написать безопасный код, не будучи экспертом, сопряжена с риском. Вы почти наверняка напишете очень небезопасный код.   -  person David Heffernan    schedule 11.04.2015