Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Самомодификация кода на стеке/куче

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Доброе время суток!
При отладке ниже приведеного кода (windows 7) обработчик ошибок выводит сообщение об ошибке:
 
Microsoft Visual C++ Debug Library
---------------------------
Debug Error!
 
Program: ...debug\ch3\AutomodificationCode\Debug\AutomodificationCode.exe
 
Invalid allocation size: 4294967286 bytes.
 
А это сам исходник:
 
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#define SELF_SIZE ((int)x_self_mod_end-(int)x_self_mod_code)
 
__declspec(naked)int x_self_mod_code(int a,int b)
{
    __asm
    {
begin_sm:
        mov eax,[esp+4]
        call get_eip
get_eip:
        add eax,[esp+8+4]
        pop edx
        xor byte ptr[edx],28h
        ret
    }
}
void x_self_mod_end(){};
 
int main()
{
    int a;
    int (__cdecl*self_mod_code)(int a,int b);
    //self_mod_code(4,2);
    //self_mod_code[SELF_SIZE];
    self_mod_code=(int (__cdecl*)(int,int))malloc(SELF_SIZE);
    memcpy(self_mod_code,x_self_mod_code,SELF_SIZE);
    for(a=1;a<10;a++)printf("%02X",self_mod_code(4,2));
    printf("\n");
    return 0;
}
 
Ошибку вызывает строка memcpy(self_mod_code,x_self_mod_code,SELF_SIZE). Как её исправить?

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 22:28 14-07-2015
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Попробуй #define SELF_SIZE 32

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 23:07 14-07-2015
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StillPhelix
в дебаг режиме число будет отличаться (отрицательное), если сделаете релиз - все будет ок

Всего записей: 15040 | Зарегистр. 20-09-2014 | Отправлено: 23:44 14-07-2015
opencl26

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
дебаг — зло, printf — наше фсьо

Всего записей: 319 | Зарегистр. 17-09-2014 | Отправлено: 00:00 15-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Правка
Цитата:
#define SELF_SIZE 32
не работает. Режимы Debuger и Release возвращает ошибку доступа. А без этой правки, режим Release возвращает ошибку доступа.  
В Windows 7 есть защита от выполнения данных в стеке (DEP). Т.к. программа самомодифицирующаяся то скорее всего это работа DEP. Тем более, что ошибка возникает глубоко в недрах библиотек Microsoft C++ при попытке чтото скопировать (функция memcpy()). Похоже в Windows 7 нельзя реализовать этот самомодифицирующийся код без отключения DEP (отключать не буду). Или я ошибаюсь? Если ошибаюсь, то как исправить этот код?
 

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 13:08 15-07-2015
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
#include <windows.h>
//...
     self_mod_code=(int (__cdecl*)(int,int))VirtualAlloc(NULL, SELF_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//...
    VirtualFree(self_mod_code, 0, MEM_RELEASE);
    return 0;

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 13:24 15-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ne_viens, под отладчиком Visual studio программа работает нормально,  
а если её запускать не из-под среды Visual studio, то происходит аварийное завершение работы с предложением отладить программу. После запуска отладки Visual studio сразу возвращает причину аварийного завершения: Unhandled exception at 0x00273090 in AutomodificationCode.exe: 0xC0000005: Access violation.
 
Добавлено:
При отладке программы в IDA ошибку вызывает всё та же строка: memcpy(self_mod_code,x_self_mod_code,SELF_SIZE). При этом на экран IDA выводит сообщение:
 
---------------------------
Warning
---------------------------
871550: The instruction at 0x871550 referenced memory at 0x871550. The memory could not be executed -> 0000000000871550 (exc.code c0000005, tid 3292)
---------------------------
OK    
---------------------------
 
Память не может исполнятся. Как это побороть?

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 15:04 15-07-2015
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ну незнаю, у меня исправно работает на 2 компах при включеном DEPе (для всех программ и сервисов).

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 17:03 15-07-2015
opencl26

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ne_viens дело пишет, попробовал на http://webcompiler.cloudapp.net/ всё работает

Всего записей: 319 | Зарегистр. 17-09-2014 | Отправлено: 17:35 15-07-2015
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StillPhelix

Цитата:
Т.к. программа самомодифицирующаяся то скорее всего это работа DEP

выведите для себя или посмотрите значение
Цитата:
SELF_SIZE
, поймете в чем причина.
сообщение
Цитата:
Invalid allocation size: 4294967286 bytes

говорит о том, что полученное число, скорее всего, отрицательное.
то есть адреса функций идут не подряд, а даже порядок расположения в памяти иной.

Всего записей: 15040 | Зарегистр. 20-09-2014 | Отправлено: 18:46 15-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mavrikii, даже если SELF_SIZE поставить правильным (в данном случае 20) не заработает всёравно. Весь вопрос в том, как Visual studio 2010 в режиме Release поборол эту проблему. Ведь запускается нормально только из-под Visual studio 2010.
 
Добавлено:
После компиляции под другим компилятором всё заработало. Однако вопрос как добиться того же под Visual studio 2010 остаётся актуальным.

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 20:18 15-07-2015
opencl26

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
особенности строения, формируемого конкретным компилятором, pe-формата, зачем вам это надо, сушить голову подобными пустяками?
в мире так много прекрасного, непонятого нами

Всего записей: 319 | Зарегистр. 17-09-2014 | Отправлено: 23:16 15-07-2015 | Исправлено: opencl26, 10:51 16-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Большая дорога начинается с маленького шага.
Дорогу одолеет идущий.

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 12:26 16-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Аргумент self_mod_code (адрес назначения) функции memcpy в процессе выполнения программы получается =0. А кто ж туда пустут в здравом уме? Как это в visual studio 2010 исправить?

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 13:42 17-07-2015
opencl26

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
вы воюете с ветряными мельницами, вот такой вариант правильный

Код:
 
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include <windows.h>
#define SELF_SIZE ((int)x_self_mod_end-(int)x_self_mod_code)
 
__declspec(naked)int x_self_mod_code(int a,int b)
{
    __asm
    {
begin_sm:
        mov eax,[esp+4]
        call get_eip
get_eip:
        add eax,[esp+8+4]
        pop edx
        xor byte ptr[edx],28h
        ret
    }
}
void x_self_mod_end(){};
 
int main()
{
    int a;
    int (__cdecl*self_mod_code)(int a,int b);
    //self_mod_code(4,2);
    //self_mod_code[SELF_SIZE];
    //self_mod_code=(int (__cdecl*)(int,int))malloc(SELF_SIZE);
    self_mod_code=(int (__cdecl*)(int,int))VirtualAlloc(NULL, SELF_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);  
    memcpy(self_mod_code,x_self_mod_code,SELF_SIZE);
    for(a=1;a<10;a++)printf("%02X",self_mod_code(4,2));
    printf("\n");
    VirtualFree(self_mod_code, 0, MEM_RELEASE);
    return 0;
}  
 

остальное - проблемы реализации компилятора, а их может миллион
поверьте, вы не ту дорогу одолеваете..

Всего записей: 319 | Зарегистр. 17-09-2014 | Отправлено: 14:06 17-07-2015 | Исправлено: opencl26, 14:08 17-07-2015
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
>StillPhelix Сразу за VirtualAlloc() поставь printf("error=0x%X, size=0x%X\n", GetLastError(), SELF_SIZE);
По коду ошибки может можно будет определить.
Скорее всего компилятор не правильно определяет расстояние между функциями x_self_mod_code() и x_self_mod_end(); , что довольно обычное явление. Надо смотреть в ассемблере и определить константу самому. Или взять с запасом, VirtualAlloc() всё равно как минимум 0х10000 выделяет.

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 14:10 17-07-2015 | Исправлено: ne_viens, 14:11 17-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ne_viens, с помощью IDA определил размер копируемой функции (SELF_SIZE 0х18). Вставленый printf  
выводит: error=0х0, size=0х18. IDA возвращает ошибку при попытке прохождения цикла
Цитата:
 for(a=1;a<10;a++)printf("%02X",self_mod_code(4,2));  
, при вызове
Цитата:
self_mod_code(4,2)
. Текст ошибки:

Цитата:
20E0FFF: The instruction at 0x20E0FFF referenced memory at 0x20E1000. The memory could not be executed -> 00000000020E1000 (exc.code c0000005, tid 1268)

 

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 20:44 17-07-2015
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
The instruction at 0x20E0FFF referenced memory at 0x20E1000.

значит, по видимому, что то не так произошло при выделении памяти.
вызов из 0x20E0FFF идет следующего байта 0x20E1000, что вряд ли должно происходить.

Всего записей: 15040 | Зарегистр. 20-09-2014 | Отправлено: 23:23 17-07-2015 | Исправлено: Mavrikii, 23:38 17-07-2015
StillPhelix



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
значит, по видимому, что то не так произошло при выделении памяти.
вызов из 0x20E0FFF идет следующего байта 0x20E1000, что вряд ли должно происходить.  

 
Как это исправить в visual studoi 2010?

Всего записей: 173 | Зарегистр. 18-08-2013 | Отправлено: 11:15 18-07-2015
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Выложи нерабочий exe.

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 15:40 18-07-2015
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Самомодификация кода на стеке/куче


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru