In C/C ++ code, a large number of structures are mixed with common types and arrays. For example, the IMAGE_OPTIONAL_HEADER structure that defines the PE File Header structure is defined as follows:
- typedef struct _IMAGE_DATA_DIRECTORY {
- DWORD VirtualAddress;
- DWORD Size;
- }
- IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
- #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
- typedef struct _IMAGE_OPTIONAL_HEADER {
- WORD Magic;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- }
In C/C ++, it is completely correct to use arrays in the structure because these arrays will serve as part of the entire structure and directly access the memory block where the structure is located when operating on the structure. However, in C #, this type of language cannot be used directly, because arrays exist as a special C # reference type array, such as definition:
- public struct IMAGE_DATA_DIRECTORY
- {
- public uint VirtualAddress;
- public uint Size;
- }
- public struct IMAGE_OPTIONAL_HEADER
- {
- public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
- public ushort Magic;
- public uint NumberOfRvaAndSizes;
- public IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- }
If you use the C # reference-type array like definition syntax, as shown in figure
- public struct IMAGE_OPTIONAL_HEADER
- {
- public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
- public ushort Magic;
- public uint NumberOfRvaAndSizes;
- public IMAGE_DATA_DIRECTORY[] DataDirectory =
new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- }
The initialization of the reference type is not allowed in the structure, which is different from the initialization of the class. In this way, the array initialization can only be placed in the constructor, and the structure cannot have any default constructor parameters, which is really troublesome.
- public struct IMAGE_OPTIONAL_HEADER
- {
- public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
-
- public ushort Magic;
-
- public uint NumberOfRvaAndSizes;
-
- public IMAGE_DATA_DIRECTORY[] DataDirectory;
-
- public IMAGE_OPTIONAL_HEADER(IntPtr ptr)
- {
- Magic = 0;
- NumberOfRvaAndSizes = 0;
-
- DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- }
- }
This seems to work, but if you use Marshal. SizeOf (typeof (IMAGE_OPTIONAL_HEADER), you will find that the length is basically different from the length defined in C/C ++. The problem still lies in the array in the structure. Although it seems that this array is defined in the structure, there is actually only one pointer to the IMAGE_DATA_DIRECTORY [] array type in this structure, the array content that should have been stored in the unknown DataDirectory is in the managed heap.
The problem is how to put the C # reference type array in a value type structure.
- Analysis of C # Insecure code
- Analysis on C # Calling ImageAnimator
- C # connect to Access and SQL Server databases
- C # fixed and active Variables
- Describes the value types in C #.