Board.KolibriOS.org
http://board.kolibrios.org/

Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?
http://board.kolibrios.org/viewtopic.php?f=2&t=3733
Страница 1 из 2

Автор:  floppy121 [ Вс июн 24, 2018 1:08 am ]
Заголовок сообщения:  Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

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

Очень важно правильно определить начало области данных, но этого недостаточно: если мы укажем слишком маленький размер то сотрём не всё, а если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс

Автор:  Ray [ Вс июн 24, 2018 8:38 am ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Если ты внутри программы, то ты и так знаешь буфер и его размер, если вне её то ничего сделать не сможешь из-за защиты страниц (получить исключение #PF).

Автор:  0CodErr [ Вс июн 24, 2018 12:28 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Не совсем понимаю сути проблемы, но в любом случае, это не задача самого процесса.
Ведь процесс можно прибить, ничего ему не сказав, безо всякого "нажатия крестика" — через диспетчер задач.

Автор:  floppy121 [ Вс июн 24, 2018 1:16 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

0CodErr писал(а):
Не совсем понимаю сути проблемы
я ищу способ получить адрес начала области данных и её размер каким-то универсальным способом вроде системного вызова, который не будет зависеть от внутреннего устройства конкретной программы
0CodErr писал(а):
это не задача самого процесса.
Ведь процесс можно прибить, ничего ему не сказав, безо всякого "нажатия крестика" - через диспетчер задач.
Когда юзер закроет программу таким способом, будет сам виноват что его чат остался в оперативке :wink: Моя цель - обеспечить безопасность юзера когда он правильно выходит из программы
Ray писал(а):
Если ты внутри программы, то ты и так знаешь буфер и его размер, если вне её то ничего сделать не сможешь из-за защиты страниц (получить исключение #PF).
Если я нахожусь внутри программы, как определить адрес области данных и весь её размер? Просто если я буду очищать только конкретный буфер - то могу что-то упустить из виду: например неправильно определить его размеры и стереть не всё, или не заметить второй небольшой буфер который промежуточно где-то используется и содержит небольшие фрагменты чата

Поэтому я и ищу универсальный способ просто стереть всю область данных. А для этого мне нужно правильно определить её адрес и размер. Должен же быть какой-то способ получить эти значения? Начало и конец области данных как-то помечаются в оперативке, может быть специальными заголовками?

Автор:  GerdtR [ Чт июн 28, 2018 9:33 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Такое, наверное, только через драйвер реализовать можно. Фишка в том, что сначала прога получает кусок оперативы в границах от 0 до цифры указанной в заголовке проги. Дальше прога может вызвать ф68.12 и она будет выделен уже после памяти проги, причём через промежуток. Ну то есть виртуальное пространство проги будет что-то вроде: 0..4000h, 5000h..6000h. Если взять цифру из ф9 с инфой о потраченой опервативе, и зачистить с 0 по эту цифру... то вывалится в эксэпшн. А узнать, какие именно страницы выделены проге можно только от ядра. Так что гляди в сторону ядра. Реализовать реально, но несколько сложновато.
"если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс" - это точно не светит. Попытка писать в закрытую область убивает процесс.

Автор:  tsdima [ Пт июн 29, 2018 12:11 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

GerdtR писал(а):
Такое, наверное, только через драйвер реализовать можно.

Это не решит проблему, когда программа убивается диспетчером задач. Как вариант - хранить данные зашифрованными, расшифровывать маленькими кусочками, выводить на экран и тут-же обнулять область памяти с расшифрованными данными.

Автор:  0CodErr [ Сб июн 30, 2018 9:24 am ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

GerdtR писал(а):
"если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс" - это точно не светит.
Кстати, да, не можем: каждый процесс выполняется в своём адресном пространстве.
tsdima писал(а):
GerdtR писал(а):
Такое, наверное, только через драйвер реализовать можно.

Это не решит проблему, когда программа убивается диспетчером задач.
Действительно, не решит.
Но можно попытаться без драйвера обойтись(хотя всё равно так делать не рационально).
Можно попробовать вариант с SysFn68.24:SetExceptionHandler, у Page-Fault Exception (#PF) номер 14.
Сам я не использовал ни разу эту функцию, просто предположу:
    Пройтись по каждой странице адресного пространства и попробовать обратиться(читать\писать).
    Если #PF не возникло, то эта страница в данный момент выделена.
    Но страницы могли быть освобождены во время работы ещё до выхода.
    Если только сделать свою HeapFree, делающую что-то до вызова системной HeapFree.
Но самое логичное решение: если нужны указатели и размеры областей — нужно хранить эту информацию в программе и обращаться к ней по мере необходимости.
floppy121 писал(а):
Если я нахожусь внутри программы, как определить адрес области данных и весь её размер?
Размер выделенной области кратен размеру страницы.
В справке так и написано:
Цитата:
Функция выделяет целое число страниц (4 Кб)
А указатель возвращает системная функция при выделении памяти — просто сохраняй этот указатель для дальнейшего использования.

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

Автор:  0CodErr [ Пн июл 02, 2018 10:28 am ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

floppy121 писал(а):
Если я нахожусь внутри программы, как определить адрес области данных и весь её размер?
0CodErr писал(а):
Но самое логичное решение: если нужны указатели и размеры областей — нужно хранить эту информацию в программе и обращаться к ней по мере необходимости.
Вот правильное решение, то, что я имел в виду: http://websvn.kolibrios.org/filedetails ... 0#line-368
Код:
; Erase RAM areas which could contain the connection details
        xor     eax, eax
        mov     edi, irc_server_name
        mov     ecx, MAX_SERVER_NAME
        rep stosb
 
        mov     edi, user_nick
        mov     ecx, MAX_NICK_LEN
        rep stosb
 
        mov     edi, user_real_name
        mov     ecx, MAX_REAL_LEN
        rep stosb
 
        mov     edi, sockaddr1
        mov     ecx, SOCKADDR1_SIZE
        rep stosb

Автор:  Siemargl [ Ср июл 04, 2018 12:50 am ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.

Автор:  floppy121 [ Ср июл 04, 2018 7:20 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

0CodErr писал(а):
Да, это единственное решение которое пока работает: вручную искать все места в оперативке где могло что-то остаться,
и заполнять их нулями до того как программа высвободит память обратно в ОС. Полного успеха мы пока не добились:
осталось как минимум три буфера где остались важные данные, про это написал в WARNING здесь - viewtopic.php?f=11&p=70875

Возможно, проще было бы модифицировать код системной функции 68 - http://wiki.kolibrios.org/wiki/SysFn68/ru
- чтобы при вызове mcall 68, 13 для любой области памяти она заполнялась нулями перед освобождением,
но боюсь такой вариант не примут в "официальные исходники", а число "локальных модов" не хочется увеличивать

Автор:  0CodErr [ Чт июл 05, 2018 10:09 am ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Siemargl писал(а):
ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.
Прежде, чем чесать своим языком, стоило заглянуть в код ядра и убедиться, что никто ничего не стирает.
А потому что зачем?
Кому надо(приложению) — тот и обнуляет память.

А для тех, у кого всё-таки есть желание разбираться с кодом, вот тестовый пример, суть вот в этом месте:
Код:
.................................................
szAllZero      db "All Zero",0
szSomeNotZero  db "Some Not Zero",0
Result dd szAllZero
.................................................
SECTION .bss
MemoryBuffer resb 1024 * 1024 * 1024
.end:
.................................................
        mov    edi, MemoryBuffer
        mov    ecx, MemoryBuffer.end - MemoryBuffer
        xor    eax, eax
        repe   scasb
        je     .ok
        mov    Dword [Result], szSomeNotZero
.ok:
        push   Dword [Result]
        call   [con_write_asciiz]       
.................................................
Вложение:
testmem.7z [1.09 КБ]
18 скачиваний

Автор:  Siemargl [ Чт июл 05, 2018 7:51 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Serge писал

viewtopic.php?p=68348#p68348

Автор:  0CodErr [ Чт июл 05, 2018 8:21 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Siemargl писал(а):
Serge писал
А ты сам не в состоянии исходник посмотреть? :lol:
Код:
f68:
..............................................
.12:
        stdcall user_alloc, ecx
        mov     [esp+SYSCALL_STACK._eax], eax
        ret
..............................................               
proc user_alloc stdcall, alloc_size:dword
        push    ebx esi edi
        mov     ebx, [current_process]
        lea     ecx, [ebx+PROC.heap_lock]
        call    mutex_lock
        mov     ecx, [alloc_size]
        add     ecx, (4095+PAGE_SIZE)
        and     ecx, not 4095
        mov     esi, dword [ebx+PROC.heap_base] ; heap_base
        mov     edi, dword [ebx+PROC.heap_top]  ; heap_top
.scan:
        cmp     esi, edi
        jae     .m_exit

        mov     ebx, esi
        shr     ebx, 12
        mov     eax, [page_tabs+ebx*4]
        test    al, FREE_BLOCK
        jz      .test_used
        and     eax, 0xFFFFF000
        cmp     eax, ecx   ;alloc_size
        jb      .m_next
        jz      @f

        lea     edx, [esi+ecx]
        sub     eax, ecx
        or      al, FREE_BLOCK
        shr     edx, 12
        mov     [page_tabs+edx*4], eax
@@:
        or      ecx, USED_BLOCK
        mov     [page_tabs+ebx*4], ecx
        shr     ecx, 12
        inc     ebx
        dec     ecx
        jz      .no
@@:
        mov     dword [page_tabs+ebx*4], 2
        inc     ebx
        dec     ecx
        jnz     @B
.no:

        mov     edx, [current_process]
        mov     ebx, [alloc_size]
        add     ebx, 0xFFF
        and     ebx, not 0xFFF
        add     [edx+PROC.mem_used], ebx

        lea     ecx, [edx+PROC.heap_lock]
        call    mutex_unlock

        lea     eax, [esi+4096]

        pop     edi
        pop     esi
        pop     ebx
        ret
.test_used:
        test    al, USED_BLOCK
        jz      .m_exit

        and     eax, 0xFFFFF000
.m_next:
        add     esi, eax
        jmp     .scan
.m_exit:
        mov     ecx, [current_process]
        lea     ecx, [ecx+PROC.heap_lock]
        call    mutex_unlock

        xor     eax, eax
        pop     edi
        pop     esi
        pop     ebx
        ret
endp
Ну и см. пример выше viewtopic.php?p=70878#p70878

Автор:  0CodErr [ Чт июл 05, 2018 9:38 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Похоже проблема только с выделением .bss, а HeapAlloc вроде отрабатывает.
Хмм... а какую конкретно помять имел в виду Serge?
Serge писал(а):
память, выделяемую для приложения

Автор:  floppy121 [ Чт июл 05, 2018 11:48 pm ]
Заголовок сообщения:  Re: Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

Siemargl писал(а):
ОСистема заботится о стирании и недоступности данных из других/новых процессов
Если бы это было действительно так, то в дампе памяти виртуальной машины, снятой после закрытия приложения IRCC, я бы ничего не обнаружил (и этой темы бы не было). Но к сожалению там осталось по крайней мере три буфера, а это значит: после закрытия IRCC система не стала занулять память освобождённую IRCC, а просто пометила её страницы как доступные для использования новыми процессами

Страница 1 из 2 Часовой пояс: UTC+03:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/