Узнать начало/размер области данных программы, чтобы всё стереть при выходе из неё?

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

    Поэтому я и ищу универсальный способ просто стереть всю область данных. А для этого мне нужно правильно определить её адрес и размер. Должен же быть какой-то способ получить эти значения? Начало и конец области данных как-то помечаются в оперативке, может быть специальными заголовками?
  • Такое, наверное, только через драйвер реализовать можно. Фишка в том, что сначала прога получает кусок оперативы в границах от 0 до цифры указанной в заголовке проги. Дальше прога может вызвать ф68.12 и она будет выделен уже после памяти проги, причём через промежуток. Ну то есть виртуальное пространство проги будет что-то вроде: 0..4000h, 5000h..6000h. Если взять цифру из ф9 с инфой о потраченой опервативе, и зачистить с 0 по эту цифру... то вывалится в эксэпшн. А узнать, какие именно страницы выделены проге можно только от ядра. Так что гляди в сторону ядра. Реализовать реально, но несколько сложновато.
    "если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс" - это точно не светит. Попытка писать в закрытую область убивает процесс.
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • GerdtR wrote:Такое, наверное, только через драйвер реализовать можно.
    Это не решит проблему, когда программа убивается диспетчером задач. Как вариант - хранить данные зашифрованными, расшифровывать маленькими кусочками, выводить на экран и тут-же обнулять область памяти с расшифрованными данными.
  • GerdtR wrote:"если слишком большой - выйдем за пределы области данных и можем повредить соседний процесс" - это точно не светит.
    Кстати, да, не можем: каждый процесс выполняется в своём адресном пространстве.
    tsdima wrote:GerdtR писал(а):
    Такое, наверное, только через драйвер реализовать можно.

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

    Ещё один не менее тупой способ:
    • попытаться освободить каждую страницу адресного пространства(кроме области кода, ещё каких-либо нужных для продолжения работы данных)
      а затем выделить один большой кусок и делать с ним, что хочешь
  • floppy121 wrote:Если я нахожусь внутри программы, как определить адрес области данных и весь её размер?
    0CodErr wrote:Но самое логичное решение: если нужны указатели и размеры областей — нужно хранить эту информацию в программе и обращаться к ней по мере необходимости.
    Вот правильное решение, то, что я имел в виду: http://websvn.kolibrios.org/filedetails ... e-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[/code]
  • ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.
  • 0CodErr wrote:Вот правильное решение, то, что я имел в виду: http://websvn.kolibrios.org/filedetails ... 0#line-368
    Да, это единственное решение которое пока работает: вручную искать все места в оперативке где могло что-то остаться,
    и заполнять их нулями до того как программа высвободит память обратно в ОС. Полного успеха мы пока не добились:
    осталось как минимум три буфера где остались важные данные, про это написал в WARNING здесь - viewtopic.php?f=11&p=70875

    Возможно, проще было бы модифицировать код системной функции 68 - http://wiki.kolibrios.org/wiki/SysFn68/ru
    - чтобы при вызове mcall 68, 13 для любой области памяти она заполнялась нулями перед освобождением,
    но боюсь такой вариант не примут в "официальные исходники", а число "локальных модов" не хочется увеличивать
  • Siemargl wrote:ОСистема заботится о стирании и недоступности данных из других/новых процессов. Тема бесполезна.
    Прежде, чем чесать своим языком, стоило заглянуть в код ядра и убедиться, что никто ничего не стирает.
    А потому что зачем?
    Кому надо(приложению) — тот и обнуляет память.

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

    Code: Select all

    .................................................
    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 KiB)
    Downloaded 408 times
  • Siemargl wrote:Serge писал
    А ты сам не в состоянии исходник посмотреть? :lol:

    Code: Select all

    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
    Ну и см. пример выше http://board.kolibrios.org/viewtopic.php?p=70878#p70878
  • Похоже проблема только с выделением .bss, а HeapAlloc вроде отрабатывает.
    Хмм... а какую конкретно помять имел в виду Serge?
    Serge wrote:память, выделяемую для приложения
  • Siemargl wrote:ОСистема заботится о стирании и недоступности данных из других/новых процессов
    Если бы это было действительно так, то в дампе памяти виртуальной машины, снятой после закрытия приложения IRCC, я бы ничего не обнаружил (и этой темы бы не было). Но к сожалению там осталось по крайней мере три буфера, а это значит: после закрытия IRCC система не стала занулять память освобождённую IRCC, а просто пометила её страницы как доступные для использования новыми процессами
  • Who is online

    Users browsing this forum: Bing [Bot], Egor00f and 5 guests