Board.KolibriOS.org

Official KolibriOS board
It is currently Wed Apr 24, 2019 5:45 am

All times are UTC+03:00




Post new topic  Reply to topic  [ 22 posts ]  Go to page 1 2 Next
Author Message
PostPosted: Sun Jun 24, 2018 1:08 am 
Offline

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

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


Top
   
PostPosted: Sun Jun 24, 2018 8:38 am 
Offline

Joined: Sun Aug 09, 2015 3:41 pm
Posts: 109
Если ты внутри программы, то ты и так знаешь буфер и его размер, если вне её то ничего сделать не сможешь из-за защиты страниц (получить исключение #PF).


Top
   
PostPosted: Sun Jun 24, 2018 12:28 pm 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Не совсем понимаю сути проблемы, но в любом случае, это не задача самого процесса.
Ведь процесс можно прибить, ничего ему не сказав, безо всякого "нажатия крестика" — через диспетчер задач.


Top
   
PostPosted: Sun Jun 24, 2018 1:16 pm 
Offline

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

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


Top
   
PostPosted: Thu Jun 28, 2018 9:33 pm 
Offline
User avatar

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

_________________
Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!


Top
   
PostPosted: Fri Jun 29, 2018 12:11 pm 
Offline

Joined: Wed Mar 26, 2008 12:44 pm
Posts: 225
GerdtR wrote:
Такое, наверное, только через драйвер реализовать можно.

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


Top
   
PostPosted: Sat Jun 30, 2018 9:24 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
GerdtR wrote:
"если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс" - это точно не светит.
Кстати, да, не можем: каждый процесс выполняется в своём адресном пространстве.
tsdima wrote:
GerdtR писал(а):
Такое, наверное, только через драйвер реализовать можно.

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

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


Top
   
PostPosted: Mon Jul 02, 2018 10:28 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
floppy121 wrote:
Если я нахожусь внутри программы, как определить адрес области данных и весь её размер?
0CodErr wrote:
Но самое логичное решение: если нужны указатели и размеры областей — нужно хранить эту информацию в программе и обращаться к ней по мере необходимости.
Вот правильное решение, то, что я имел в виду: http://websvn.kolibrios.org/filedetails ... 0#line-368
Code:
; 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


Top
   
PostPosted: Wed Jul 04, 2018 12:50 am 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 432
ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.


Top
   
PostPosted: Wed Jul 04, 2018 7:20 pm 
Offline

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

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


Top
   
PostPosted: Thu Jul 05, 2018 10:09 am 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Siemargl wrote:
ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.
Прежде, чем чесать своим языком, стоило заглянуть в код ядра и убедиться, что никто ничего не стирает.
А потому что зачем?
Кому надо(приложению) — тот и обнуляет память.

А для тех, у кого всё-таки есть желание разбираться с кодом, вот тестовый пример, суть вот в этом месте:
Code:
.................................................
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]       
.................................................
Attachment:
testmem.7z [1.09 KiB]
Downloaded 42 times


Top
   
PostPosted: Thu Jul 05, 2018 7:51 pm 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 432
Serge писал

viewtopic.php?p=68348#p68348


Top
   
PostPosted: Thu Jul 05, 2018 8:21 pm 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Siemargl wrote:
Serge писал
А ты сам не в состоянии исходник посмотреть? :lol:
Code:
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


Top
   
PostPosted: Thu Jul 05, 2018 9:38 pm 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Похоже проблема только с выделением .bss, а HeapAlloc вроде отрабатывает.
Хмм... а какую конкретно помять имел в виду Serge?
Serge wrote:
память, выделяемую для приложения


Top
   
PostPosted: Thu Jul 05, 2018 11:48 pm 
Offline

Joined: Mon Dec 05, 2016 11:04 am
Posts: 129
Siemargl wrote:
ОСистема заботится о стирании и недоступности данных из других/новых процессов
Если бы это было действительно так, то в дампе памяти виртуальной машины, снятой после закрытия приложения IRCC, я бы ничего не обнаружил (и этой темы бы не было). Но к сожалению там осталось по крайней мере три буфера, а это значит: после закрытия IRCC система не стала занулять память освобождённую IRCC, а просто пометила её страницы как доступные для использования новыми процессами


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 22 posts ]  Go to page 1 2 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Limited