Tải bản đầy đủ - 0 (trang)
CHƯƠNG 2: CƠ CHẾ QUẢN LÝ HEAP

CHƯƠNG 2: CƠ CHẾ QUẢN LÝ HEAP

Tải bản đầy đủ - 0trang

2.1. Những loại Heap

Mỗi tiến trình có ít nhất một heap: tiến trình heap mặc định. Heap mặc

định được tạo ra khi khởi động q trình và khơng bao giờ bị xóa trong suốt

q trình hoạt động của tiến trình. Mặc định có kích thước 1 MB, nhưng nó

có thể được làm lớn hơn bằng cách xác định kích thước bắt đầu trong tệp

hình ảnh bằng cách sử dụng cờ liên kết /HEAP. Kích thước này chỉ là dự trữ

ban đầu, tuy nhiên, nó sẽ tự động mở rộng khi cần thiết. (Bạn cũng có thể chỉ

định kích thước cam kết ban đầu trong tệp hình ảnh.)

Heap mặc định có thể được sử dụng một cách rõ ràng bởi một chương

trình hoặc ngầm sử dụng bởi một số chức năng Windows nội bộ. Một ứng

dụng có thể truy vấn heap quá trình mặc định bằng cách thực hiện cuộc gọi

đến hàm GetProcessHeap của Windows. Các quy trình cũng có thể tạo thêm

heap riêng với chức năng HeapCreate. Khi quá trình khơng còn cần một heap

riêng, nó có thể phục hồi không gian địa chỉ ảo bằng cách gọi HeapDestroy.

Một mảng với tất cả các heaps được duy trì trong mỗi q trình, và một sợi

có thể truy vấn chúng với các chức năng Windows GetProcessHeaps.

Một heap có thể quản lý phân bổ trong các vùng bộ nhớ lớn được lưu trữ

từ bộ quản lý bộ nhớ thông qua VirtualAlloc hoặc từ các đối tượng tệp ánh xạ

trên bộ nhớ ánh xạ trong khơng gian địa chỉ của tiến trình. Cách tiếp cận thứ

hai hiếm khi được sử dụng trong thực tế, nhưng nó phù hợp với các kịch bản

mà nội dung của các khối cần phải được chia sẻ giữa hai tiến trình hoặc giữa

một chế độ hạt nhân và một thành phần chế độ người dùng. Trình điều khiển

hệ thống con GUI Win32 (Win32k.sys) sử dụng một heap để chia sẻ GDI và

User các đối tượng với chế độ người dùng. Nếu một đống được xây dựng trên

đầu trang của vùng tệp được ánh xạ bộ nhớ, một số ràng buộc nhất định áp

dụng đối với thành phần có thể gọi hàm heap. Thứ nhất, các cấu trúc heap

bên trong sử dụng con trỏ, và do đó khơng cho phép remapping đến các địa

chỉ khác nhau trong các quá trình khác. Thứ hai, q trình đồng bộ hóa qua

nhiều quá trình hoặc giữa một thành phần hạt nhân và q trình người dùng

khơng được hỗ trợ bởi các chức năng heap. Ngoài ra, trong trường hợp chia

sẻ heap giữa chế độ người dùng và chế độ hạt nhân, lập bản đồ chế độ người

dùng phải là chỉ đọc để ngăn chặn mã chế độ người dùng làm hỏng các cấu

trúc nội bộ của heap, dẫn tới sự sụp đổ của hệ thống. Trình điều khiển chế độ

hạt nhân cũng chịu trách nhiệm về việc không đưa bất kỳ dữ liệu nhạy cảm

nào vào một đống chia sẻ để tránh rò rỉ nó vào chế độ người dùng.

2.2. Cấu trúc của Heap Manager

Như trong hình dưới, cấu trúc của trình quản lý Heap gồm 2 lớp: lớp tùy

chỉnh front-end và lõi Heap. Lõi heap xử lý các chức năng cơ bản và phổ biến

nhất là usermode và kernel-mode triển khai Heap. Chức năng lõi bao gồm

10



quản lý khối bên trong phân đoạn, quản lý phân đoạn, chính sách mở rộng

heap, cam kết và phân hủy bộ nhớ, và quản lý các khối lớn.



Hình 2.2 : Cấu trúc của trình quản lý Heap

Chỉ với user-mode heaps, một lớp tùy chọn front-end heap có thể tồn tại

bên trên các chức năng lõi hiện tại. Giao diện đầu cuối duy nhất được hỗ trợ

trên Windows là Low Fragmentation Heap (LFH). Tại một thời điểm, chỉ có

một lớp front-end có thể sử dụng cho một heap.

2.3. Đồng bộ hóa Heap

Trình quản lý heap theo mặc định sẽ hỗ trợ truy cập đồng thời từ nhiều

luồng. Tuy nhiên, nếu một tiến trình đơn luồng hoặc sử dụng một cơ chế bên

ngồi để đồng bộ hóa, nó có thể báo cho heap manager để tránh chi phí của

việc đồng bộ hóa bằng cách chỉ định HEAP_NO_SERIALIZE khi tạo ra heap

hoặc trên mỗi cơ sở phân bổ.

Một tiến trình cũng có thể khóa tồn bộ heap và ngăn chặn các đối tượng

khác thực hiện các hoạt động heap cho các hoạt động mà sẽ yêu cầu các trạng

thái phù hợp trên nhiều cuộc gọi heap. Ví dụ, liệt kê các khối heap trong một

heap với chức năng Windows HeapWalk yêu cầu khóa heap nếu nhiều luồng

có thể thực hiện các hoạt động heap cùng một lúc.

Nếu đồng bộ hóa heap được kích hoạt, có một khóa mỗi heap để bảo vệ

tất cả các cấu trúc heap bên trong. Trong các ứng dụng đa luồng (đặc biệt là

khi chạy trên các hệ thống đa xử lý), khóa heap có thể trở thành một điểm

11



tranh luận quan trọng. Trong trường hợp đó, hiệu suất có thể được cải thiện

bằng cách kích hoạt front-end heap, được mơ tả trong phần sắp tới.

2.4. Các phân mảnh thấp Heap (The Low Fragmentation Heap – LFH)

Nhiều ứng dụng đang chạy trong Windows có mức sử dụng bộ nhớ heap

tương đối nhỏ (thường ít hơn 1 MB). Đối với loại ứng dụng này, chính sách

phù hợp nhất của bộ quản lý heap giúp duy trì bộ nhớ thấp cho mỗi tiến trình.

Tuy nhiên, chiến lược này khơng phù hợp cho các tiến trình lớn và những

máy đa xử lý. Trong những trường hợp này, bộ nhớ sẵn có cho việc sử dụng

heap có thể bị giảm do sự phân mảnh của heap. Hiệu suất có thể bị ảnh hưởng

trong các kịch bản chỉ với một số kích thước nhất định được sử dụng đồng

thời từ các luồng khác nhau được lên lịch chạy trên các bộ vi xử lý khác

nhau. Điều này xảy ra vì một số bộ vi xử lý cần phải sửa đổi vị trí bộ nhớ

tương tự (ví dụ như đầu của danh sách dành cho kích thước cụ thể đó) cùng

một lúc, do đó gây ra xung đột đáng kể cho dòng bộ nhớ cache tương ứng.

LFH tránh phân mảnh bằng cách quản lý khối được phân chia trong các

phạm vi khối được xác định trước khác nhau được gọi là nhóm. Khi một tiến

trình phân chia bộ nhớ từ heap, LFH sẽ chọn nhóm chứa bản đồ với khối nhỏ

nhất đủ lớn để giữ kích thước yêu cầu (khối nhỏ nhất là 8 byte). Nhóm đầu

tiên được sử dụng để phân bổ từ 1 đến 8 byte, thứ hai để phân bổ từ 9 đến 16

byte, và như vậy, cho đến khi nhóm thứ 32, được sử dụng cho phân bổ từ 249

đến 256 byte, tiếp theo là nhóm thứ 33, được sử dụng cho phân bổ giữa 257

và 272 byte, v.v ... Cuối cùng, nhóm thứ 128, là lần cuối cùng, được sử dụng

để phân bổ giữa 15,873 và 16,384 byte. (Đây được gọi là hệ thống nhị phân).

Bảng dưới đây tóm tắt các nhóm khác nhau, mức độ chi tiết và phạm vi kích

thước mà chúng ánh xạ tới.



Hình 2.3 : Bảng mức độ chi tiết và phạm vi kích thước của các nhóm



12



LFH giải quyết những vấn đề này bằng cách sử dụng trình quản lý lõi

heap và các danh sách dành riêng. Trình quản lý heap của Windows thực hiện

một thuật toán điều chỉnh tự động, có thể cho phép LFH thực hiện mặc định

theo các điều kiện nhất định, chẳng hạn như khóa cạnh tranh hoặc sự có mặt

của các phân bổ kích thước phổ biến đã cho thấy hiệu suất tốt hơn với LFH

được kích hoạt. Đối với các heap lớn, một tỷ lệ đáng kể các khoản phân bổ

thường được phân nhóm trong một số lượng tương đối nhỏ nhóm có kích

thước nhất định. Chiến lược phân bổ được sử dụng bởi LFH là để tối ưu hóa

việc sử dụng cho các mơ hình này bằng cách hiệu quả các khối kích thước

tương tự.

Để giải quyết khả năng mở rộng, LFH mở rộng các cấu trúc nội bộ

thường xuyên truy cập vào một số khe gấp hai lần so với số bộ xử lý hiện tại

trên máy. Việc gán các luồng đến các khe này được thực hiện bởi một thành

phần LFH được gọi là trình quản lý mối quan hệ. Ban đầu, LFH bắt đầu sử

dụng khe đầu tiên cho việc phân bổ heap. Tuy nhiên, nếu một cuộc xung đột

được phát hiện khi truy cập vào một số dữ liệu nội bộ, LFH sẽ chuyển đổi

luồng hiện tại để sử dụng một khe khác. Những sự xung đột khác sẽ lan

truyền trên nhiều khe. Các khe này được kiểm soát cho mỗi nhóm một dung

lượng để cải thiện vùng và giảm thiểu tiêu thụ bộ nhớ tổng thể.

Ngay cả khi LFH được kích hoạt như là một front-end heap, kích thước

phân bổ ít thường xun hơn, thì vẫn có thể tiếp tục sử dụng các chức năng

của lõi heap để phân bổ bộ nhớ, trong khi các lớp phân bổ phổ biến nhất sẽ

được thực hiện từ LFH. LFH cũng có thể bị vơ hiệu hóa bằng cách sử dụng

API HeapSetInformation với class HeapCompatibilityInformation.

2.5. Tính năng bảo mật của Heap

Khi việc quản lý Heap được phát triển, nó đã có vai trò quan trọng trong

phát hiện sớm các lỗi sử dụng heap và trong làm giảm ảnh hưởng của các

khai thác tiềm tàng trên heap-based. Các biện pháp này tồn tại để làm giảm

khả năng ảnh hưởng của các lỗ hổng tiềm tàng trong các ứng dụng. Siêu dữ

liệu được sử dụng bởi các heap để quản lý nội bộ được đóng gói với mức độ

cao ngẫu nhiên để làm nó khó khăn cho nỗ lực khai thác để vá các cấu trúc

bên trong để ngăn ngừa các xung đột hoặc che giấu các nỗ lực tấn công. Các

khối này cũng phải tn theo cơ chế kiểm tra tính tồn vẹn trên header để

phát hiện các lỗi đơn giản như tràn bộ đệm. Cuối cùng heap cũng sử dụng

một mức độ nhỏ ngẫu nhiên của địa chỉ cơ bản (hoặc xử lý). Bằng việc sử

dụng API HeapSetInformation và lớp HeapEnableTerminationOnCorruption,

các tiến trình có thể chọn để hủy bỏ tự động trong trường hợp phát hiện các

mâu thuẫn để tránh thực thi mã không tin cậy.



13



Như một kết quả của các khối siêu dữ liệu ngẫu nhiên, sử dụng trình gỡ

rối để đơn giản kết xuất một khối header như một vùng của bộ nhớ là khơng

cần thiết. Ví dụ, kích thước của các khối và cho dù nó đang sử dụng hoặc là

không dễ dàng phát hiện từ một kết xuất thường xuyên. Tương tự với các

khối LFH; chúng có một loại siêu dữ liệu khác nhau được lưu trữ ở phần

header, một phần ngẫu nhiên tương tự.

Để kết xuất các thông tin chi tiết này, lệnh !heap –i trong trình gỡ rối thực

hiện tất các cơng việc để lấy các trường siêu dữ liệu từ các khối, gắn cờ kiểm

tra toàn vẹn hoặc danh sách các mâu thuẫn nếu chúng tồn tại. Lệnh hoạt động

cho cả LFH và các khối heap thường lệ. Tổng kích thước các khối, yêu cầu

kích thước người sử dụng, các segment sở hữu của khối cũng như kiểm tra

tình tồn vẹn từng phần có đang có sẵn trong đầu ra, như thể hiện trong các

mẫu sau đây. Bởi vì các thuật tốn ngẫu nhiên sử dungk heap granularity, nên

lệnh !heap –i nên được sử dụng chỉ trong các bối cảnh thích hợp của heap bao

gồm các khối. Trong ví dụ, heap xử lý là 0x001a0000. Nếu bối cảnh của các

heap là khác nhau thì việc giải mã của header sẽ là khơng chính xác. Để thiết

lập đúng ngữ cảnh, lệnh !heap –i với heap xử lý như một đối số cần được

thực hiện trước.

0:000> !heap -i 001a0000

Heap context set to the heap 0x001a0000

0:000> !heap -i 1e2570

Detailed information for block entry 001e2570

Assumed heap : 0x001a0000 (Use !heap -i NewHeapHandle to change)

Header content : 0x1570F4EC 0x0C0015BE (decoded : 0x07010006

0x0C00000D)

Owning segment : 0x001a0000 (offset 0)

Block flags : 0x1 (busy )

Total block size : 0x6 units (0x30 bytes)

Requested size : 0x24 bytes (unused 0xc bytes)

Previous block size: 0xd units (0x68 bytes)

Block CRC : OK - 0x7

Previous block : 0x001e2508

Next block : 0x001e25a0

2.6. Tính năng gỡ lỗi Heap

Trình quản lý heap ấn định 8 byte được sử dụng để lưu trữ siêu dữ liệu

nội bộ như là một điểm kiểm tra tính nhất quán, làm cho các lỗi sử dụng heap



14



tiềm ẩn trở nên rõ ràng hơn và cũng bao gồm một số tính năng để giúp phát

hiện lỗi bằng cách sử dụng các hàm heap sau:

Bật kiểm tra cuối: sự kết thúc của mỗi chuỗi mang một chữ ký đã được

kiểm tra khi khối được tạo ra. Nếu lỗi tràn bộ đệm phá hủy một phần hoặc

toàn bộ chữ ký, heap sẽ báo cáo lại lỗi này.

Bật kiểm tra miễn phí: một khối heap tự do được lấp đầy bằng các mẫu

kiểm tra tại nhiều điểm khác nhau khi trình quản lý heap cần truy cập vào

khối (chẳng hạn như loại bỏ các danh sách tự do để đáp ứng yêu cầu phân

bổ). Nếu các tiến trình tiếp tục ghi vào các khối sau khi đã giải phóng nó, thì

trình quản lý heap sẽ phát hiện các thay đổi trong mẫu và các lỗi sẽ được báo

cáo.

Kiểm tra tham số: hàm này bao gồm chức năng kiểm tra bao quát các

tham số truyền tới các hàm heap

Xác nhận heap: toàn bộ heap được xác nhận tại mỗi lệnh heap.

Gắn thẻ heap và hỗ trợ dò ngăn xếp: hàm này hỗ trợ xác định các thẻ

và/ hoặc thu thập dò ngăn xếp ở chế độ người dùng cho các lệnh gọi heap để

thu hẹp các nguyên nhân có thể xảy ra một lỗi heap

Ba tùy chọn đầu tiên được phép mặc định nếu bộ nạp phát hiện một tiến

trình được bắt đầu dưới sự kiểm sốt của một trình gỡ rối. (Một trình gỡ rối

có thể ghi đè lên các hành vi này và tắt các tính năng này.) Các tính năng gỡ

lỗi có thể được chỉ định cho một image thực thi bằng cách thiết lập nhiều cờ

gỡ lỗi khác nhau trong image header sử dụng công cụ Gflags. ( Xem phần

“Windows Global Flags” chương 3 phần 1). Hoặc các tùy chọn gỡ rối có thể

được phép sử dụng lệnh !heap trong các trình gỡ rối chuẩn của Windows.

(Xem trợ giúp trình gỡ lỗi để biết thêm thơng tin.)

Bật tùy chọn gỡ rối heap ảnh hưởng tới tất các các heap trong tiến trình.

Ngồi ra nếu một trong bất kỳ các tùy chọn được kích hoạt, LFH sẽ tự động

bị vơ hiệu hóa và các heap lõi sẽ được sử dụng(với các tùy chọn gỡ lỗi được

yêu cầu bật). LFH cũng không được sử dụng cho các heap khơng thể mở rộng

được(bởi vì các phần phụ được thêm vào cấu trúc heap hiện có) hoặc các

heap mà khơng cho phép tuần tự.

2.7. Pageheap

Bởi vì các tùy chọn kiểm tra cuối và kiểm tra tự do được trình bày ở phần

trước đó có thể phát hiện ra các lỗi xảy ra trước khi phát hiện vấn đề, một khả

năng gỡ lỗi heap được bổ sung, được gọi là pageheap , được cung cấp nhằm

điều khiển tất cả hoặc một phần các lệnh gọi heap đến một trình quản lý heap

15



khác. Pageheap được kích hoạt bằng cách sử dụng cơng cụ Gflags (nó là một

phần của các cơng cụ gỡ lỗi cho Windows ). Khi được kích hoạt, trình quản

lý heap sắp xếp phân bổ ở cuối các trang và để riêng ngay trang kế tiếp. Do

các trang dành riêng không thể truy cập được, nếu xảy ra sự tràn bộ đệm sẽ

gây ra sự vi phạm quyền truy cập, làm cho việc phát hiện mã vi phạm trở nên

dễ dàng hơn. Theo tùy chọn, pageheap cho phép đặt các khối ở đầu trang, với

trang được đặt trước, để phát hiện các vấn đề về tràn bộ đệm.(Đây là sự biến

cố hiếm hoi.) Pageheap cũng có thể bảo vệ bất các trang được giải phóng

khỏi bất kỳ truy cập nào liên quan tới các khối heap sau khi chúng được giải

phóng.

Lưu ý rằng việc sử dụng pageheap có thể dẫn tới việc hết khơng gian địa

chỉ. Ngồi ra, hiệu suất có thể chịu ảnh hưởng như một kết quả của sự gia

tăng liên quan tới các trang không yêu cầu, mất vị trí, các chi phí bổ sung gây

ra bởi các lệnh gọi thường xuyên để xác nhận các cấu trúc heap. Một tiến

trình có thể làm giảm tác động bằng cách xác định pageheap chỉ được sử

dụng cho các khối có kích thước nào đó, dải địa chỉ, và/hoặc DLLs gốc.

2.8. Fault Tolerant Heap

Sự hư hỏng của siêu dữ liệu heap đã được Microsoft xác định là một

trong những nguyên nhân phổ biến nhất của ứng dụng. Windows bao gồm

một tính năng gọi là The fault tolerant heap, hay FTH, nhằm giảm thiểu các

vấn đề và cung cấp tài nguyên giải quyết các vấn đề tốt hơn cho các nhà phát

triển. The fault tolerant heap được thực hiện trong hai phần chính là : thành

phần phát hiện, hoặc máy chủ FTH, hoặc thành phần giảm nhẹ, hoặc máy

trạm FTH

Thành phần phát hiện là một DLL, Fthsvc.dl, nó được nạp bởi dịch vụ

Security Center Windows (Wscsvc.dll, nó chạy trong các tiến trình chia sẻ

dịch vụ dưới các dịch vụ tài khoản cục bộ). Nó được thơng báo về sự cố của

ứng dụng bởi dịch vụ báo lỗi của Windows

Khi một ứng dụng bị treo trong Ntdll.dll, với tình trạng lỗi cho biết một

trong những vi phạm truy cập hoặc một ngoại lệ lỗi heap, nếu nó khơng phải

trong danh sách “theo dõi” ứng dụng của dịch vụ FTH, thì dịch vụ tạo ra một

“vé” cho ứng dụng để giữ dữ liệu của FTH. Nếu ứng dụng sau đó xảy ra lỗi

nhiều hơn bốn lần trong một giờ, thì dịch vụ FTH sẽ cấu hình ứng dụng để

máy trạm FTH sử dụng trong tương lai.

Máy trạm FTH là một ứng dụng tương thích với shim. Cơ chế này được

sử dụng từ Windows XP để cho phép các ứng dụng phụ thuộc vào các hành vi

cụ thể của các hệ thống Windows cũ để chạy trên các hệ thống sau này. Trong

trường hợp này, cơ chế shim chặn các lệnh thường xuyên gọi tới heap và

16



chuyển hướng chúng tới mã riêng của nó. Mã FTH thực hiện một số “biện

pháp giảm nhẹ” cố gắng cho các ứng dụng tồn tại bất kể các lỗi liên quan

đến heap khác nhau.

Ví dụ, để bảo vệ chống lại lỗi tràn bộ đệm nhỏ, FTH thêm 8 byte đệm và

một khu vực dành riêng FTH cho mỗi lần cấp phát. Để giải quyết một tình

huống phổ biến trong đó một khối heap được truy cập sau khi nó được giải

phóng, lệnh Heapfree được thực hiện chỉ sau một trễ: “giải phóng” các khối

được đặt trong một danh sách và chỉ giải phóng khi tổng kích thước các khối

trong danh sách lớn hơn 4MB. Các nỗ lực để giải phóng các vùng khơng thực

sự thuộc về heap hoặc không là một phần của heap được xác định bởi đối số

heap handle đến HeapFree , chỉ đơn giản là bỏ qua. Ngồi ra, khơng có một

khối nào thực sự được giải phóng sau khi thốt hoặc RtlExitUserProcess đã

gọi.

Máy chủ FTH tiếp tục theo dõi tỷ lệ lỗi của ứng dụng sau khi các biện

pháp giảm thiểu đã được cài đặt. Nếu tỷ lệ thất bại không được cải thiện thì

các biện pháp giảm thiểu sẽ được loại bỏ.

Hoạt động của the fault tolerant heap có thể được quan sát trong Event

Viewer. Gõ eventvwr.msc tại Run prompt, và sau đó điều hướng trong ngăn

bên trái để đến Event Viewer, các ứng dụng và các bản ghi dịch vụ,

Microsoft, Windows, Fault-Tolerant-Heap. Nhấp vào nhật ký hoạt động. Nó

có thể bị tắt hoàn toàn trong registry: HKLM\Software\Microsoft\FTH, đặt

giá trị Bật thành 0

FTH khơng hoạt động bình thường trên các dịch vụ, chỉ các dịch vụ, và

nó bị vơ hiệu hóa trên các máy chủ Windows vì hiệu suất. Một quản trị viên

hệ thống có thể tự thực hiện shim hoặc dịch vụ thực thi bằng cách sử dụng

Application Compatibility Toolkit(Bộ công cụ tương thích ứng dụng)



17



KẾT LUẬN

Qua đề tài này, nhóm em đã tìm hiểu được heap là gì và đặc biệt là cơ chế

quản lý heap.

Tuy nhiên, do thời gian hạn chế và trình độ hiểu biết của bản thân nên

nhóm chúng em chưa thể hiểu sâu được, bài báo cáo vẫn chỉ mang tính chất

học hỏi, tìm hiểu và chưa thể đầy đủ hết được. Nhưng qua bài báo cáo này,

các thành viên trong nhóm đã học hỏi được nhiều kinh nghiệm trong q

trình làm việc theo nhóm, đồng thời cũng bổ sung kiến thức cho bản thân.



18



TÀI LIỆU THAM KHẢO

[1] “ Heap: Pleasures and Pains”, https://msdn.microsoft.com/enus/library/ms810466.aspx

[3] “Managing heap memory”

us/library/ms810603.aspx



,https://msdn.microsoft.com/en-



[2] “Windows Internals, Sixth Edition, Part 2 eBook”, Mark

Russinovich,

David

A.

Solomon,

Alex

Ionescu,

http://materias.fi.uba.ar/7508/WI6/Windows%20Internals%20Part

%202_6th%20Edition.pdf



19



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

CHƯƠNG 2: CƠ CHẾ QUẢN LÝ HEAP

Tải bản đầy đủ ngay(0 tr)

×