Получение размера динамической памяти приложения (Heap)
Heap или куча - особая структура данных, с помощью которой приложению выделяется динамически распределяемая память. Крайне удобная штука, когда надо быстренько выделить немного памяти под сиюминутные нужды. Но при активной работе с кучей может возникнуть ситуация, когда надо узнать размер оставшейся памяти, общий размер кучи или максимальный размер непрерывных данных, которые туда можно записать. Что-то из этого можно узнать при помощи штатных функций, а что-то придется получать копанием в недрах системы. Но сперва несколько структур и констант для работы. Их нет даже в MSDN, не говоря уже о FASM.Code (Assembler) : Убрать нумерацию
- struct DEBUG_BUFFER
- SectionHandle dd ?
- SectionBase dd ?
- RemoteSectionBase dd ?
- SectionBaseDelta dd ?
- EventPairHandle dd ?
- Unknown rd 2
- RemoteThreadHandle dd ?
- InfoClassMask dd ?
- SizeOfInfo dd ?
- AllocatedSize dd ?
- SectionSize dd ?
- ModuleInformation dd ?
- BackTraceInformation dd ?
- HeapInformation dd ?
- LockInformation dd ?
- Reserved rd 8
- ends
- struct DEBUG_HEAP_INFORMATION
- Base dd ?
- Flags dd ?
- Granularity dw ?
- Unknown dw ?
- Allocated dd ?
- Committed dd ?
- TagCount dd ?
- BlockCount dd ?
- Reserved rd 7
- Tags dd ?
- Blocks dd ?
- ends
- PDI_HEAPS = 0x04
- PDI_HEAP_BLOCKS = 0x10
Code (Assembler) : Убрать нумерацию
- ; Зарезервировать буфер для отладочной информации
- invoke RtlCreateQueryDebugBuffer,0,FALSE
- mov [debug_buf],eax
- ; Получить информацию о кучах текущего процесса
- invoke GetCurrentProcessId
- invoke RtlQueryProcessDebugInformation,eax,\
- PDI_HEAPS+PDI_HEAP_BLOCKS,[debug_buf]
- mov eax,[debug_buf]
- ; Указатель на информацию о кучах
- mov eax,[eax+DEBUG_BUFFER.HeapInformation]
- ; Количество записей
- mov ecx,[eax]
- ; Пропустить заголовок
- add eax,4
- .loc_heap_scan:
- or ecx,ecx
- jz .loc_heap_done
- ; Это наша куча?
- mov edx,[eax+DEBUG_HEAP_INFORMATION.Base]
- cmp edx,[hHeap]
- jne .loc_heap_next
- ...
- ; В структуре DEBUG_HEAP_INFORMATION информация о куче
- ...
- jmp .loc_heap_done
- .loc_heap_next:
- add eax,sizeof.DEBUG_HEAP_INFORMATION
- dec ecx
- jmp .loc_heap_scan
- .loc_heap_done:
- ; Прибраться за собой
- invoke RtlDestroyQueryDebugBuffer,[debug_buf]
Ну и раз уж мы затронули работу с объектом кучи, то давайте извлечем содержащиеся в нем данные. Для этого нам понадобятся следующие структуры и константы:
Code (Assembler) : Убрать нумерацию
- struct BLOCK
- hMem dd ?
- dwReserved rd 3
- ends
- struct REGION
- dwCommittedSize dd ?
- dwUnCommittedSize dd ?
- lpFirstBlock dd ?
- lpLastBlock dd ?
- ends
- struct PROCESS_HEAP_ENTRY
- lpData dd ?
- cbData dd ?
- cbOverhead db ?
- iRegionIndex db ?
- wFlags dw ?
- union
- Block BLOCK
- Region REGION
- ends
- ends
- PROCESS_HEAP_ENTRY_BUSY = 0x0004
Code (Assembler) : Убрать нумерацию
- ; Начать с первой записи
- mov [hentry.lpData],0
- .loc_scan_heap:
- ; Получить информацию о записи
- invoke HeapWalk,[hHeap],hentry
- ; Записи закончились?
- or eax,eax
- jz .loc_scan_done
- ; Это данные?
- test [hentry.wFlags],PROCESS_HEAP_ENTRY_BUSY
- jz .loc_scan_heap
- ...
- ; [hentry.lpData] -> сохраненные данные
- ; [hentry.cbData] -> размер выделенного блока
- ...
- jmp .loc_scan_heap
- .loc_scan_done:
В приложении примеры программ с исходными текстами, одна из которых получает информацию об объекте кучи текущего процесса, а вторая отображает содержащиеся в нем данные.
Просмотров: 1467 | Комментариев: 0
Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария