Выделение памяти с аттрибутами чтения, записи и выполнения

Тема в разделе "WASM.BEGINNERS", создана пользователем Xerx, 15 янв 2008.

  1. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Собственно как реализовать? Т.е. нужно выделить кусок памяти, в который можно писать и читать, а после формирования в нем кода и выполнить. Точек входа может быть несколько. Адресное пространство - как и в основной программе (должна быть возможность обращения к адресам, доступным из "основного кода" - глобальные переменные и т.п.).

    P.S. Если важно: ring3, компилятор и Я.П. - произвольные (ну естественно, asm или C/C++), операционка - желательно под любую Win32.
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Я что-то недопонимаю, или хватит VirtualAlloc с параметром PAGE_READWRITE_EXECUTE?
     
  3. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Mika0x65
    Может PAGE_EXECUTE_READWRITE? А адресное пространство то же? Мне важно, чтобы код, сформированный в дальнейшем в этой области при доступе по адресам, доступным их основной программы, также корректно работал, а не вываливался с generic access... или возвращал совершенно не то...
     
  4. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    похоже на то
     
  5. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Mika0x65 & Freeman
    Спасибо. Попробую дома, когда до него доберусь.
     
  6. bPED

    bPED New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2008
    Сообщения:
    52
    а не проще ли атрибуты на секцию кода поставить, чем память для этого выделять?
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    размер может быть неизвестен заранее
     
  8. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    bPED
    Программа должна динамически выделять память, формировать в этом участке нужный код и выполнять его по необходимости. Как я это через параметры секции кода сделаю?
     
  9. xh4ck

    xh4ck New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2005
    Сообщения:
    60
    Адрес:
    Russia
    странный вопрос какой-то.. "формировать код" научились, а память выделять - нет
     
  10. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    xh4ck
    Да все как-то линкер писал просто поток байт, выводимый в дальнейшем в файл. А вот выполнять то, что скомпилировал сразу в памяти еще не доводилось.
     
  11. bPED

    bPED New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2008
    Сообщения:
    52
    section '.UPX!' code executable readable writeable ;)
     
  12. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    bPED
    Ну я же не зря написал
    Соответственно, таких блоков может быть неопределенное число, их размеры неизвестны. Соответственно, никаких уже готовых секций в бинарнике.

    P.S. Если кто еще захочет что написать в этой ветке (уже 5 дней пишут, хотя я вроде ничего нового не писал ) ): меня интересует именно выделение памяти во время работы, НЕ НАДО больше предлагать параметры секций, пожалуйста! Я не это спрашивал. rei3er вот правильно написал.
     
  13. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    а как должно выглядеть:
    b dd ?
    ...
    mov eax,
    ...
     
  14. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    Потому что вместо CODE юзай QUOTE

    Узри разницу...

    Код (Text):
    1. [b]тест[/b]
     
  15. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Какие кучи, чтото я не пойму, недостаточно чтоли ZwAllocateVirtualMemory?
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    я чтото тоже не пойму чем автора не устраивает предложенная в самом начале VirtualAlloc/ZwAllocateVirtualMemory
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Great
    +1
    Xerx, я понял, тебе надо по типу стека?
    Зарезервировано несколько страниц, выделяются по мере необходимости.
    Если не нравится, можеш обрабатывать STATUS_ACCESS_VIOLATION и выделять память.
    Код (Text):
    1. ;Windows Vista, NTDLL: 6.0.6000.16386).
    2. RtlCreateUserStack proc uses ebx esi edi ProcessHandle:HANDLE, SizeOfStackReserve:ULONG, SizeOfStackCommit:ULONG, ZeroBits:ULONG, UserStack:PUSER_STACK
    3. Local BasicInformation:SYSTEM_BASIC_INFORMATION
    4. Local OldProtect:ULONG,PhysicalPageSize:ULONG,StackBase:PVOID   ;-0C,-8,-4
    5.     xor ebx,ebx
    6.     call ZwQuerySystemInformation,SystemBasicInformation,addr BasicInformation,SizeOf SYSTEM_BASIC_INFORMATION,Ebx
    7.     .if !Eax
    8.     mov edi,ProcessHandle
    9. .if Edi==NtCurrentProcess
    10.     mov eax,dword ptr fs:[18h]
    11.     assume eax:PTEB
    12.     mov eax,[eax].Peb
    13.     assume eax:PPEB
    14.     invoke RtlImageNtHeader,[eax].ImageBaseAddress
    15.     .if !Eax
    16.     mov eax,STATUS_INVALID_IMAGE_FORMAT
    17.     jmp exit_
    18.     .endif
    19.     .if SizeOfStackReserve==Ebx     ;+C
    20.     assume eax:PIMAGE_NT_HEADERS
    21.     mov ecx,[eax].OptionalHeader.SizeOfStackReserve     ;Default:100000h    +60h
    22.     mov P2,ecx
    23.     .endif
    24.     .if SizeOfStackCommit==Ebx      ;+10
    25.     mov eax,[eax].OptionalHeader.SizeOfStackCommit  ;Default:1000h  +64h
    26.     mov SizeOfStackCommit,eax
    27.     .endif 
    28. .else
    29.     .if SizeOfStackCommit==Ebx
    30.     mov eax,BasicInformation.PhysicalPageSize
    31.     mov SizeOfStackCommit,eax
    32.     .endif
    33.     .if SizeOfStackReserve==Ebx
    34.     mov eax,BasicInformation.AllocationGranularity
    35.     mov SizeOfStackReserve,eax
    36.     .endif
    37. .endif
    38.     mov eax,dword ptr fs:[18h]
    39.     assume eax:PTEB
    40.     mov eax,[eax].Peb
    41.     assume eax:PPEB
    42.     mov eax,[eax].MinimumStackCommit
    43.     mov edx,SizeOfStackCommit
    44.     .if eax!=ebx && edx<eax ;Eax=MinimumStackCommit
    45.     mov edx,eax
    46.     .endif
    47.     mov ecx,SizeOfStackReserve
    48.     .if ecx<edx
    49.     lea ecx,dword ptr [edx+0FFFFFh]
    50.     and ecx,0FFF00000h
    51.     .endif
    52.     mov eax,BasicInformation.PhysicalPageSize
    53.     lea edx,dword ptr [eax+edx-1]       ;Edx=PhysicalPageSize+Edx-1
    54.     dec eax ;Eax=PhysicalPageSize-1
    55.     not eax
    56.     and edx,eax
    57.     mov eax,BasicInformation.AllocationGranularity
    58.     lea ecx,dword ptr [eax+ecx-1]   ;Ecx=AllocationGranularity+SizeOfStackReserve-1
    59.     dec eax
    60.     not eax
    61.     and ecx,eax
    62.     mov SizeOfStackCommit,edx
    63.     mov SizeOfStackReserve,ecx
    64.     mov StackBase,ebx   ;BaseAddress
    65.     invoke ZwAllocateVirtualMemory,edi,addr StackBase,ZeroBits,addr SizeOfStackReserve,MEM_RESERVE,PAGE_READWRITE
    66.     .if !Eax
    67.     mov ecx,StackBase
    68.     mov eax,SizeOfStackReserve
    69.     mov esi,UserStack   ;+18
    70.     assume esi:PUSER_STACK
    71.     mov [esi].ExpandableStackBottom,ecx ;StackBase
    72.     add ecx,eax
    73.     mov [esi].ExpandableStackBase,ecx   ;StackLimit = SizeOfStackReserve + StackBase
    74.     mov ecx,eax
    75.     sub ecx,SizeOfStackCommit
    76.     mov [esi].FixedStackBase,ebx        ;NULL
    77.     add BaseAddress,ecx ;StackBase = StackBase + SizeOfStackReserve - SizeOfStackCommit
    78.     mov [esi].FixedStackLimit,ebx   ;NULL
    79.     .if Eax<=SizeOfStackCommit
    80.     mov byte ptr [ebp+0Bh],bl
    81.     .else
    82.     mov eax,BasicInformation.PhysicalPageSize
    83.     sub BaseAddress,eax
    84.     add SizeOfStackCommit,eax
    85.     mov byte ptr [ebp+0Bh],1
    86.     .endif
    87.     call ZwAllocateVirtualMemory,edi,addr StackBase,ebx,addr SizeOfStackCommit,MEM_COMMIT,PAGE_READWRITE
    88.     mov ecx,StackBase
    89.     mov [esi].ExpandableStackLimit,ecx
    90.     .if !Eax
    91.     .if byte ptr [ebp+0Bh]!=bl
    92.     mov eax,BasicInformation.PhysicalPageSize
    93.     mov PhysicalPageSize,eax
    94.     invoke ZwProtectVirtualMemory,edi,addr StackBase,addr PhysicalPageSize,PAGE_GUARD or PAGE_READWRITE,addr OldProtect
    95.     .if !Eax
    96.     mov eax,PhysicalPageSize
    97.     add [esi].ExpandableStackLimit,eax
    98.     xor eax,eax
    99.     .endif
    100.     .endif
    101.     .endif
    102.     .endif
    103.     .endif
    104. exit_:      ;7C933F37,7C933F36
    105.     ret
    106. RtlCreateUserStack endp
     
  18. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Clerk и Great
    Где я написал, что меня это не устраивает? Наоборот, я написал, что посмотрю. Это мне уже потом начали предлагать варианты с атрибутами секции, хотя я НЕ ПИСАЛ, что вариант VirtualAlloc мне не подходит.
    Меня вполне устраивает этот вариант. Просто я отвечаю на новые посты.

    Clerk
    Нет, мне не стек нужен. Просто независимые области памяти в адресном пространстве основного кода.

    Все, чтобы больше не было недопониманий и ненужных постов: тема закрыта, всем спасибо.
     
  19. bPED

    bPED New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2008
    Сообщения:
    52
    Я извиняюсь за свою невнимательность. А ты сам пробовал написать? Принцип ведь тебе понятен.
    И тем не менее - если память будет выделяться динамически есть вероятность что она очень скоро закончиться.
    Придется выставлять проверки на размер выделяемой памяти. В итоге получаем опять же ограничение - то есть фиксированный блок. Поэтому я думаю проще сделать несколько блоков памяти, связать их и гнать в них данные.
    если даже один блок к примеру 1 байт а данных 14 бит, т.е. больше, просто запоминать где остановились, данные передавать дальше, буфер очищать и гнать данные дальше с момента остановки. Далее просто передавать управление на адреса, куда записаны данные.
     
  20. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    bPED
    Ну где я написал, что мне нужно кучу памяти? Я бы уточнил. Мне нужно выделять порядка 10-100 блоков памяти (можно в принципе и в один объединить, но это сути не меняет) размером порядка 100Б - 5КБ каждый.
    если бы у меня была необходимость выделения действительно больших объёмов памяти, я бы обязательно написал об этом - понимаю, что это сильно влияет на ответ.

    А в данный момент меня вполне устраивает работа VirtualAlloc.