Windows 95 System Programming SECRENTS Learning Notes --- Chapter 5 (3)

xiaoxiao2021-03-06  52

Next, VirtualalloC processes various flag values ​​from the FDWallocationType parameter. First, it looks at whether there is an unapproved 0x80000000 mark, which means to assign 2GB or more memory. VirtualAlalloc ignores the MEM_TOP_DOWN flag. Then it tested whether you only pass the MEM_COMMIT or MEM_RESERVED flag. Any other logo will trigger a warning message for the debug version. Finally, the function code calls MmpageToPC, which is an auxiliary function (next section), convert the FDWProtect parameter flag to the flag used by VMM _PageReServe.

At this time, the function soldiers divided into two ways. If you don't care about the memory to keep, just do one. If the caller specifies a specific range of memory, then another way is executed. Whether it is the way, if the memory is reserved, Virtualalloc calls Win32 Service 00010000, which is an outsourcing function of the VMM's _PageReServe function. After retaining this memory, if the caller also specifies the MEM_COMMIT flag, Virtualalloc calls Win32 Service 00010001, which is an outsourcing function of the VMM's _PageCommit function. If the caller specifies a specific address range, Virtualalloc will check it under 0xC0000000 (the beginning of the VXD field).

In the entire function code, Virtualalloc is constantly checking back to _PageReServe and _PageCommit. If anything fails, it generates a debug diagnostic information and then exits from a unique outlet. The exit will release the previously retained memory.

Virtual code of the VirtualAlloc function

// Parameters

// LPVOID LPVADDRESS

// DWORD CBSIZE

// dword fdwallocationType

// DWORD FDWPROTECT

// locals:

// DWORD Address, StartPage

// DWORD SIZEINPAGES

// DWORD PCFLAGS // RETURN from MmpAgetopc

// Bool FRESERVE

IF (CBSIZE> 0x7FC00000) // 2GB - 4MB

{

_Debugout ("Virtualalloc: DWSIZE TOO BIG / N / R", SLE_WARNING

Fstoponring3MemoryError);

INTERNALSETLASTERROR (error_not_enough_memory);

Return 0;

}

Address = lpvaddress;

// Calculate How Many Pages Will Be spanned by this Memory Request

SiZEINPAGE = lpvaddress & 0x00000FFF;

SizeInPage = CBSIZE;

SIZEINPAGE = 0x00000FFF;

SiZEINPAGE = SIZEINPAGE >> 12;

StartPage = pr_private; // 0x80000400 from vmm.inc this value can be be each Either

// An actual page number or apr_equate.

IF (fdWallocationType & 0x80000000) // undocumented shared mem flag {

StartPage = pr_shared; // 0x80000000 in vmm.inc

FDWALLOCATIONTYPE & = ~ 0x80000000; // Don't Need this flag Anymore

}

FDWALLOCATIONTYPE & = ~ MEM_TOP_DOWN; // ignore the MEM_TOP_DOWN FLAG

// You can Specify MEM_COMMIT AND / OR MEM_RESERVE, But no Other Flags

// (The undocunted One Above Not with Standing).

IF ((FDWALLOCATIONTYPE! = MEM_COMMIT)

&& (FDWALLOCATIONTYPE! = MEM_RESERVE)

&& (FDWALLOCATIONTYPE! = (MEM_RESERVE | MEM_COMMIT)))))))

{

_Debugout ("VirtualaLalloc: Bad FlalocationType / N / R",

SLE_WARNING FSTOPONRING3MEMORYERROR);

INTERNALSETLASTERROR (ERROR_INVALID_PARER);

Return 0;

}

// Convert the fdwprotect flags inTo the pc_flag value used by

// vmm.vxd Pseudocode Follows this function

Pcflags = Mmpagetopc (fdwprotect);

IF (pcflags == -1) // Something Error

Return 0;

IF (lpvaddress == 0) // Don't Care Where The memory is allocated.

{

// Reserve the memory block. StartPage Should Be Either

// pr_private or pra_shared

LPVAddress = vxdcall (_PageReserve, StartPage, SizeInpages, PCFLAGS);

IF (lpvaddress == -1)

{

_Debugout ("VirtualAlloc: reserver failed / n",

SLE_WARNING FSTOPONRING3MEMORYERROR);

INTERNALSETLASTERROR (error_not_enough_memory);

Return 0;

}

// if Caller is Just Reserving, We're Finished.

IF (! (fdWallocationType & Mem_Commit)

Return LPVAddress;

// Caller HAS Specified MEM_COMMIT

IF (vxdcall, lpvaddress >> 12, sizeInpages, 1, 0, pcflags))

Return LPVAddress; // SUCCESS!

// OOOPS. Something Went Wrong. Tell The User, Ten Fall Through

// to the code to free the page._debugout ("Virtualloc: commit failed / n",

SLE_WARNING FSTOPONRING3MEMORYERROR);

INTERNALSETLASTERROR (error_not_enough_memory);

}

Else

{

IF (Address> 0xBFFFFFF)

{

_Debuout ("Virtualalloc: BAD BAD BASE Address / N",

SLE_WARNING FSTOPONRING3MEMORYERROR);

INTERNALSETLASTERROR (ERROR_INVALID_ADDRESS);

Return 0;

}

FRESERVE = FDWALLOCATIONTYPE & MEM_RESERVE;

IF (FRESERVE)

{

// Call VMM _PageRserve to Allocate the memory. Note That

// the caller-specified lpvaddress is Rounded Down to the THE

// nearest 4KB Page. Note That it's not down to 64kb like

// The doc says. However, _PageReserve Still Rounds it down.

LPVADDRESS = VXDCall (_PageReServe, Address >> 12, sizeInpages, pcflags);

IF (lpvaddress == -1)

{

_Debugout ("VirtualaLalloc: Reserve Failed / N",

SLE_WANING FSTOPONRING3MEMROYERROR);

INTERNALSETLASTERROR (error_not_enough_memory);

Return 0;

}

// hmmm .... It Turns Out this kernel32 Will Complain if you

// Didn't Specify An Address Aligned ON A 64KB Boundary!

IF (lpvaddress! = (address & 0xffff0000))

{

_Debugoout ("VirtualaLalloc: Reserve in Wrong Place / N",

SLE_ERROR);

}

}

IF (! (fdWallocationType & Mem_Commit)

{

Return LPVAddress;

}

LPVADDRESS & = 0xffff000;

IF (vxdcall, lpvaddress >> 12, sizeInpages, 1, 0, pcflags))

Return LPVAddress;

Else

{

_Debugout ("Virtualalloc: commit failed / n",

SLE_WARNING FSTOPONRING3MEMORYERROR);

INTERNALSETLASTERROR (error_not_enough_memory);

IF (! FRESERVE)

Return 0;

}

}

// unreserve the memory allocated earlier.

Vxdcall (_pagefree, lpvaddress & 0xffff0000, 0);

Return_0:

LPVADDRESS = 0;

Return_lpvaddress:

Return LPVAddress;

Mmpagetopc

This function is used by Virtualallocc, VirtualaLalkEx, VirtualProtect and other functions. It converts the PAGE_XXX flag defined in Winuser.h to the corresponding PC_XXX flag. The PC_XXX flag is defined with VMM.inc and is used by the VMM's _PageCommit function.

Among the flags used by Windows 95, there is a use of this page is protected. When the program attempts to write the protected PAGE, a Page Fault is triggered, so the operating system must submit (commit) additional memory to the bottom of Stack to allow Stack to grow down. However, it is obvious that you cannot request a protected Page with Virtualall, because MmpageTopc will drop the Page_Guard flag. This function is also ignored by the Page_nocacche flag. The main content of MmpageTopc is simple to correspond to a variety of Page_xxx logo. In addition to page_noaccess, the converted flags are included in the PC_USER bit, meaning that this page can be accessed by the RING3 code. If the page should be writable, PC_WRITEABLE will also be placed in the returned flag. For a statement, all Page_xxx flags are mapped to PC_USER or PC_USER | PC_WRITEABLE.

Virtualfree

VirtualFree performs VirtualAlloc opposite features. It can change the status of Pages from Committed to RESERVED, or change from committed to Free, or change from reserved to Free. The first part of the function first checks if the incoming is a legal address and a reasonable size. The address must be below 3GB, the size must be less than 2GB-4MB (that is, the size of the application private address space).

You can make a MEM_RELEASE or MEM_DECOMMIT flag, but cannot be specified in both. MEM_RELEASE causes the VirtualFree to call the vmm's_pagefree function, all of the entire Pages "decommit" (if needed) and "unreserve". In this case, you must specify the size of 0, so that the VirtualFree releases the entire space allocated by VirtualAlloc. If you pass into mem_decommit, you will cause the VirtualFree to call VMMM's_PageDecommit, drop a range of Pages "Decommit".

VirtualQueryex

This may be the most playful function in Windows 95. It provides a rich information about a memory type for an address. For example, give any address in the process address space, VirtualQueryex can tell you which EXE or DLL has this block. This function can display a memory layout for any specified process.

VirtualQueryex is originally not in the WINDOWS 95 WIN32 function list, which is shocking for the development of a system-level tool software such as debugger, etc.). Fortunately, the Windows 95 team is as good as a run, and finally incorporates VirtualQueryex.

VirtualQueryex fills the information of an address in the Memory_basic_information structure. This structure looks like this:

Pvoid ​​Baseaddress;

PVOID AllocationBase; DWORD AllocationProtect;

SIZE_T Regions;

DWORD

State

;

DWORD protect;

DWORD TYPE;

These members have described in Win32 files. Here I must specifically explain one of them. AllocationBase sounds not good, but it is the most important member. Technically, it represents the base address of the memory block that is originally distributed in Virtualalloc. More importantly, when VirtualQueryex's LPVAddress parameter falls in an EXE or DLL module, AllocationBase is the base address of this EXE or DLL. That is, the Hinstance / HModule of AllocationBase and EXE or DLL is the same. The PWalk program attached to NT SDK is to use this to traverse the address space of a process and put the name of the owner (EXE or DLL) for each area. The debugger can use this feature to calculate which EXE or DLL association to a certain problem address.

VirtualQueryex is basically only calling Vwin32.vxd Win32 Service (also vxdcall 002a0040). This service is called the _pageQuery function in the VMM. The DDK file says the _pageQuery function requires a parameter, pointing to the Memory_basic_information structure.

Perhaps it is to avoid the uncoordinated value (in the Memory_basic_information structure), so VirtualQueryex will first get KRN32MUTEX first, release it when leaving. It is to complete these work with unprecedented kernel32_entersysysledel and the _leavesyslevel function.

No. 43H VWIN32 Service, but also fills in the Memory_basic_information structure, which is more than a simple _pagequery outsourcing function. At present, I can't say it exactly what it did. However, it is clear that this function must know the address of the Ring0 Stack of the current thread of the query object (process). Therefore, before calling the VWIN32 Service, VirtualQueryex uses the HProcess parameter to point a pointer, pointing to the structure of the process PDB. From that place, VirtualQueryex gave the current thread Database to hand over the VWIN32 Service. Interestingly, after careful observation of Vwin32 Service several times, honestly said that I have not found this program code in addition to calling _PageQuery.

VirtualQuery and IvirtualQuery

VirtualQuery is only a special case of VirtualQueryex. VirtualQuery Gets information about an address in the current process, and VirtualQueryex can get address information of any process.

VirtualQuery's virtual code does not seem to be worth mentioning, it is just the legality of the test parameters. It see if a buffer refers to the pointer is not enough to accommodate the Memory_basic_information structure. Suppose the answer is yes, VirtualQuery jumps to IvirtualQuery. VirtualQuery first parameter test, skip to an internal function, this is a typical approach to many functions of System DLLS. For example: VirtualProtect is also true.

It is not more than some of the functions that only perform records in the debug version, IvirtualQuery is actually only calling VirtualQueryex, and is the first parameter in the current process. Please note that in Windows 95, IVRITUALQUERY calls VirtualQueryex. This is different from Win32S, the latter's VirtualQueryex calls VirtualQuery. The key difference between it is that each process in Win32S share the same address space, so VirtualQuery should be equivalent to VirtualQueryex. VirtualProtectex

VirtualProtectex can change a commcted page or a series of Pages to access protection. It can handle any process as long as you have a process of Handle. The key difference between VirtualProtectex and Virtualalloc is that you have "Committed", "Committed", you are intended to change its status ", while VirtualalloC allows you to assign, submit (commit) and then specify a certain page or some Pages.

VirtualProtectex's virtual code is very straightforward. Just like the other Virtual functions I have said, it first unveiled in some error inspection code. The address range to modify in the function is less than 2GB-4MB, whether the start address is less than 0xC0000000. The center of VirtualProtecte is call VWIN32 Service 0x3f. This service finally calls VMM's _PAGEMODIFYPERMISSION. Just like in VirtualQueryex, this VWIN32 CALL expects to get a pointer, pointing to the RING0 Stack of the current thread in the specified process. Some of the code is used to determine if this Ring0 Stack is available in VirtualQueryex. VirtualProtectex also got and hold KRN32Mutex as in VirtualQueryex, as VWIN32 Call execution

Vwin32 Service 0x3f returns the previous state of the modified PAGES (if the call is successful). However, this state is a VMM's PC_xxx logo, not the Page_xxx flag desired by the caller. VirtualProtectex is therefore a quick conversion. Finally, if the caller has a pointer to store an old Page property, the function code copies those Page_xxx logo into.

VirtualProtect and IvirtualProtect

VirtualProtect is a simplified version of VirtualProtectex. It is only valid for the calling process. VirtualProtect actually only tests the parameter test, the real code is in IvirtualProtect. The only test work in VirtualProtect is to determine the PfdWoldProtect pointer is a legitimate DWORD or 0.

IvirtualProtect is the outsourcing function of VirtualProtectex. The HProcess it uses is a virtual handle to represent the current process (0x7fffffff).

Virtuallock and VirtualUnlock

These two functions do not exist in Windows 95. On supporting their Win32 platforms (such as Windows NT), they allow the process "PageLock" to a range of Pages. The system guarantees those Pages that can always be mapped to the actual RAM. For the consumer who undertakes the Page Fault (for example, the equipment driver for time is very hot), it helps.

In Windows 95, VirtualLock and VirtualUnlock are jumped to the CommonUnImpstub code. That is a small code, all of the Win32 Apis for the implementation will jump to. The impact of CommonUnImpstub is double. First, in the debug version, Kernel32 will display a debug information on the terminal, like this: **** Unimplement Win32 API: VirtualLock

The second impact is the appropriate parameters in STACK. In an example of VirtualLock / VirtualUnlock, it is clear that 8 binary bits are cleared. Since CommonUnImpstub's parameters are not all the same, you need to clear the Stack size must first let CommonunUnImpstub know. It can also be known through the return of the CL register. The CL register is stored by the encoded value, not the number of direct binary locations.

Win32 HEAP function

Microsoft finally put some advanced HEAP management functions in the Win32 operating system. The DOS memory management mechanism establishes a space for a HEAP, often too slow too long. Win16 GlobalAlloc's minimum distribution limit is 20h binary position and is limited to 8192 Selectors. Win16's LocalHeap is more suitable for small amounts, but it is only 64KB. In addition, these functions do not have the ability of the memory leak tracking or Memroy overrun.

The Win32 HEAP function is excellent. In Windows 95, you only need to consume an additional 4bit at each area, and you can create a HEAP up to 2GB-4MB size. In addition, Windows 95 Win32 HEAP maintains four independent free linked lists for various sizes, which is to avoid excess of internal presence. Another advantage only acts in the debug version, that is, each assigned block adds additional data so that you can easily find out the spill, overflow, and know who is allocated this Block memory. I will also introduce how to use additional debug information. Unfortunately, the only thing that enables the inflow to take effect, using a slate, only Windows 95: HeapsetFlags. When I went down, Microsoft did not mention this function, but I got a message, saying it will be available.

In addition to these excellent functions, Windows 95 also allows the process to have more than one HEAP. This allows you to easily assign your memory to a different type in HEAP. This is often a good strategy to avoid internal presencers. Since Windows 95 supports more than more than one HEAP, you must provide a Heap Handle to any Win32 Heap function, used to represent the object you intend to operate. Heap Handle is actually the start address (linear address) of the HEAP.

Another good nature of Windows 95 Heaps is that they can grow. In this case, the Kernel32 assigns additional memory and associates it with the HEAP. I call this additional memory as subheaps. Figure 5-7 shows a complex HEAP.

The Win32 HEAP function includes HeapAlloc, HeapFree, HeapRealloc, and more. Perhaps you will think that these basic HEAP functions will be an inevitable choice for compilers that need to implement Malloc, Realloc, Free, New, Delete functions. But it is not the case. Boland and Microsoft avoid the use of Win32 HEAP functions in its Runtime Library. Win32 SDK Runtime Library (Crtdll.dll) is an exception, its Malloc and Free functions use HeapAlloc and HeapFree, respectively. Note that the crtdll.dll used by NT and 95 is a different version. Correctly revelation:

Before this book is about to pay, I found Visual C 4.0 using the Win32 HEAP function to complete its C / C Runtime HEAP.

In Windows 95 Win32 HEAP service, you will find GlobalAlloc and Localalloc. They are all done with the HeapAlloc family. Localalloc is not just another packaging of Heapalloc, because some Win16 programmers have played some difficult tricks (translation: so-called sub-allocation), Win32 version of Localalocation must take into account backward compatibility. I will discuss this topic in detail in subsequent chapters. In the lower layer of the Win32 HEAP function, VMM is used for Win32 VXD Services for memory management. However, I didn't see anything in these functions, there is no way to implement the Virtual function (I am discussed later). Because of this, I believe that the Win32 HEAP function is actually the upper layer of the Win32 Virtual function. Interestingly, the HEAP structure used by the VMM's _heapxxx function (providing the HEAP mechanism to VXD) is the same as the HEAP structure used for the RING3 process with the kernel32.

Win32 HEAP HEADER and Heap Arenas

All zero components of a Windows 95 HEAP are from the memory allocated by VMM_PageRereve. This memory is divided into two. The front is a HEAP header. This header (later we will detail) contain some information to manage HEAP, like a free linked list, HEAP size, HEAP generating mark, and more. The head is the Heap block. Each HEAP block starts a so-called ARENA structure, with information on the block. The block of the block is tightly followed by the tail of the previous block. All blocks extend to the tail of the HEAP space, but not each of them must be mapped to the actual RAM. Figure 5-8 shows a typical HEAP layout.

Remember, each HEAP block, whether it is free or in use, starting with an Arena structure. Its format is not the same in the debug version of Windows 95 and the retail version. If the HEAP block is free, some additional structural members will also appear. This has led to four changes in Arena layout: Retail Free, Retail In-use, Debug Free, Debug in-use.

Each Heap Arena has a DWORD at the beginning of the HEAP, and the size of the HEAP is included. This size includes space used by Arena. However, you can simply remove the first DWORD and use it as the size of the block. What is this? Because some bits are not related to the size of the block in this first DWORD. The higher level of this DWORD is always 0xA0, and its meaning is not clear, I guess it is a "bit pattern", used to tell Kernel32 say that this Arena is overwritten. Other bits that are unrelated to the size of the block, because all the size of the HEAP block is always 4 times, so the least two bits are always not used, which can be used as a sign. The actual significance of these two bits is as follows: The first bit: If set, this block is free. 0 indicates that this block has been assigned.

Second: If set, it means that the previous block of this block is a free block. This bit will only be set in blocks that have been assigned. If this block is free, it can be coupled with the previous free block. If the bit is not set up, it means that the previous block is not free, so it does not need to be coupled to the block.

It is easy to calculate all the positions in consideration. This is to make the first DWORD and value 0x5fffffffc can make an operation, this operation shields all the bits of DWORD are not used to indicate the size of the block size. The earlier method is to make the first ARENA DWORD and the value to the AND operation. To calculate how many memory can also be used by the caller, just reduce the block size to the ARENA size.

In-USE block of Windows 95 Retail Edition (Retail Version)

The type of Arena in this block is the simplest:

DWORD SIZE // OR'ed with 0xa0000000 or 0xa0000002

Windows 95 Retail Edition (RETIL VERSION) FREE block

The ARENA type of this block is the same as the previous one, but adds Prev and Next members.

DWord size // OR'ed with 0xa0000001

DWORD prev // Point to the Previous Heap Arena

DWord next // Point to the next Heap arena

In-use block of Windows 95 debug version (Debug Version)

Similar to the retail version, but add some members:

DWORD SIZE

DWord Allocating EIP // The Eip Value That Called HeapAlloc / HeapRealloc

DWORD THREAD NUMBER // The Thread Number (Not ID) That Allocated The Block.

Word signature // 0x4842 == "bh"

DWord Checksum // a Checksum of The Previous Three DWords

These members are used to track memory overflow and HEAP is destroyed. A member of the "Allocating EIP" stores a program address, the block is assigned to it. This can be used to test (WHERE A Block of Code That Somehow Wsan't Free Was Allocated). The role of Thread Number members is similar, but it is used to identify that thread allocated this space. Note that Thread Number and Thread ID are not the same, or the value returned by getCurrentThreadID. Thread Number is an index that points to the current thread link. You can use the "thread" command of Softice / W to see this index value. For in-USE blocks, Signature members should always be 0x4842. If not, this ARENA may be destroyed. The last member of Arena provides more powerful Heap destruction. This member contains three DWORDS's calibration sum. Its algorithm will be described when checksumheapblock is later. Although this member is always maintained, but the kernel32 debug version never automatically verifies it, you have to push it, it will move. This nature is "Paranoid Heap Corruption Checking" and determines whether the role is determined by the HeapSetflags function.

Windows 95 debug version of the Free block of Debug Version

ARENA of these blocks is a mixture of retail version of Free Arena and debugging IN-Use Arena. It also has a member of Prev and Next, also members of Thread Number, Signature, Checksum. Signature is changed from 0x4842 to 0x4846. CHECKSUM algorithm also has slight change. Because of multiple DWORDs, Kernel32 is used to check this Arena, it uses the first four (rather than the first three) DWORDS.

DWORD SIZE

DWORD Prev

DWORD THREAD NUMBER

DWORD SIGNATURE

DWord Next

DWORD CHECKSUM

Windows 95's Heap Header (Head Structure)

The beginning of each HEAP is a HEAP header structure. The so-called Heap Handle, for example, you get obtained by getProcessHeap, just a pointer, pointing to Heap's head structure. The main task of the HeapCreate function, in addition to keeping the memory to HEAP, is initializing the head structure. The retail version of the Windows 95 and the debug version of the Heap header structure change is changed (but its format is not changed). The first HEAP block of Arena is followed by the header.

Windows 95 Retail Edition (Retail Version) HEAP Head

00h Word Dwsize

Keep the total amount of memory to this HEAP. Each process has a default HEAP with a size of 1MB 4KB.

04H dword nextblock

If you call HeapCreate, specify the DWMaximum parameter as 0, then this HEAP is generated, the size can also be expanded. In this case, if the caller required by the caller is too large, the kernel32 retains other memory and sets SubHeaps. SubHeaps also use Heap Arena, but does not use the entire header structure. In order to track these SubHeaps, kernel32 stores them in a linked list. The chain head is recorded in the position of the main table head structure. Pointer to a Subheap is placed at the 04 offset location of each subheap. Once HEAP is destroyed, the kernel32 will traverse each subheaps in the chain table, release their Pages to the system. 08h free_list_header_retail freelistArray [4]

In order to minimize memory fragmentation, accelerate search of free blocks, each HEAP header maintains four free linked lists. Respectively Management 32 (0x20) bit or less, 128 (0x80) bit or less, 512 (0x200) bit or less, 0xFFFFFFFF bit consisting of the following blocks. KERNEL32 will open the search action for the most appropriate linked list. If you need a 24 (0x18) size space, kernel32 searches for the first linked list. If you need a 256 (0x100) size space, kernel32 searches for a third linked list.

These four freetles are represented by an array composed of four simple structures, which are as follows:

l DWORD MAXBLOCKSIZE This is the largest block in the list. It can be 0x20,0 x80, 0x200, 0xffffff.

l Free Arena This Arena and the retail version of Free Arena, but its SIZE member is 0. Prev members point to the first Free Arena. Since size is 0, the search will never be included in considerations.

48H PVOID NEXTHEAP

In the HEAP of the Windows 95 Retail Edition, this member is a pointer, pointing to a HEAP that was created in HeapCreate. Note that the next HEAP is not the next SubHeaps (recorded at 04 offset) but a 10,000 hinge. This member is 0 unless you call CREATEHEAP.

4ch hcritical_section hcriticalsection

This member contains CIRTICAL Section Handle. That is the Heap function used to synchronize. Note that this member is not stored in the critical_section itself, but a pointer pointing to a internal structure related to Cirtical Section in Kernel32.

50h critical_section criticalsection

This member contains critical_section itself (defined in WinBase.h). When the program code needs to control synchronous control, KERNEL32 handles a pointer to this member to EntercriticalSection. The initialization action of each member of this structure is done when the process calls initializecriticalsection. If you don't need synchronous control (for example, you only have a thread), you can pass the Heap_no_Serialize flag to HeapCreate, HeapAlloc.

68h dword unknown1 [2]

This member is meaningless

70h byte flags

This member contains a logo value, which can be handed over to HeapCreate:

HEAP_NO_SERIALIZE

HEAP_GROWABLE

HEAP_GENERATE_EXEPTIONSHEAP_ZERO_MEMORY

HEAP_REALLOC_IN_PLACE_ONLY

HEAP_TALL_CHECKING_ENABLED

HEAP_FREE_CHECKING_ENABED

HEAP_DISABLE_COALESCE_ON_FREE

Two items in the Windows 95 technical file: HEAP_NO_SERIALIZE and HEAP_GENERATE_EXCESS

71h btye unknow2

This member is unambiguous, which may be used to reserve the extended Heap_xxx logo.

72H Word Signature

In legal Windows 95 HEAP, this member should be 0x4948 ("hi")

Heap header of Windows 95 debug version (Debug Version)

The debug version of the Heap header is very similar to the retail version of the HEAP head. However, the FREE ARENA structure embedded in it is relatively large, and there are more additional members.

Detailed structural description, here is not listed, please refer to the original book.

转载请注明原文地址:https://www.9cbs.com/read-70678.html

New Post(0)