What is the maximum PE file header size? - portable-executable

Does someone know the maximum PE file header size? I can find information on the maximum PE file size only.

PE header is usually about 500 bytes (might be slightly longer if you define a lot of sections, but you would heve real trouble going over 1024, i guess

Related

What's the Maximum Size of a PE Section?

Same as title, I'm trying to find out what is the max size of the PE section, I've read all the PE and libloaderapi documentations from Microsoft, and I cannot find any information about the maximum section size, or is the PE section have maximum size?
The total size limit of a PE file is 4 GiB (Windows will refuse to run it if it is any larger). I would imagine that the section size limit is somewhat close to 4 GiB.

BITMAPFILEHEADER.bfSize doesn't match the file size?

Reading the specs for BITMAPFILEHEADER structure says bfSize is the number of bytes in the file.
But when I look at a .bmp file here on my drive it's actually 2 bytes smaller than the file size? Is that just a mistake or does it not count the bfType ? I've seen other examples where it matches the size?

Why is sometimes .data section virtual size bigger than raw size?

Recently I found out, that .data section in PE can have virtual size bigger than raw size (in file). This is quite suprising. Some people say that this is an effect of uninitialized data somewhere.
But after analyzing some PE, I can't really find this extra data. Here is link to PEDump results of some program:
"Hello world" PEDump
As you can see, .data section has bigger virtual size than raw size. Why is it like this in this particular example?
Values for any initialized data is stored in the section, if the binary wants to reserve space in memory for any uninitialized data, then the virtual size will be larger than the raw data size.
You won't find this data in the file, because it doesn't need to be there. The addresses that reference the data (in the code section) are baked into the binary so that they will point to the correct location when it is loaded into memory.
If the loader didn't reserve this space up front, then globals, etc. would have to be allocated on the heap before they could be used.
From the PE spec:
[SizeOfRawData is the] size of the section (for object files) or the
size of the initialized data on disk (for image files). For executable
images, this must be a multiple of FileAlignment from the optional
header. If this is less than VirtualSize, the remainder of the section
is zero-filled. Because the SizeOfRawData field is rounded but the
VirtualSize field is not, it is possible for SizeOfRawData to be
greater than VirtualSize as well. When a section contains only
uninitialized data, this field should be zero.
Edit: Respond to the question about the SizeOfUninitializedData.
The SizeOfUninitializedData field in the Optional Header is just the size of the .bss section (or the sum of them if there are multiple). Your binary didn't have a separate section for that data, so it was zero. Since sections are aligned on specific boundaries, it may be more efficient to save some space at the end of an existing section than to use a separate one.

what is the maximum size of a PE file on 64-bit Windows?

It seems to me it's always going to be 4GB, because it uses the same size datatype (A DWORD)? Isn't a DWORD for the SizeOfImage always going to be 32-bits? Or am I mistaken about this limitation?
Answer
4GB does indeed to seem to be the hard limit of ALL Portable Executable's (32-bit and 64-bit PE+).
According to the spec it is 32-bit unsigned value for a PE32+ image just like a PE32 image.
However, in my testing with both 32-bit and 64-bit applications (PE32/PE32+ files) on Windows 7 SP1 Home Premium x64, the maximum file size for either is between 1.8-1.85GB.
I tested by creating a very basic C executable with Visual Studio (~8K for 32-bit and 9K for 64-bit) and the added an empty code section to the PE header until Windows would no longer load it, and then binary searched for the limit. Looking at the process with vmmap showed that almost all of the entire first 2GB of address space were the image (including any subsequently loaded DLLs such as kernel32.dll). The limit was the same for me with both 32 and 64-bit processes. The 64-bit process did have the flag set in it's NT Header's File Header's section stating that it could handle addresses >2GB. It also could allocate memory for non-image sections above the 2GB limit.
It seems like the image is required to fit in it's entirety in the lower 2GB of VA space for the process, which means the SizeOfImage is being treated a signed 32-bit integer by the loader effectively.
According to the COFF/PE32 spec, the image size for a valid PE32+ (64 bit/(PE+) file is a 4 byte unsigned value.
The ImageSize field in the PE headers is largely unrelated to the file size on-disk of the PE file. ImageSize is the in-memory size of the loaded image i.e. the size of all sections (each rounded to the SectionAlignment boundary) + size of the PE headers (given in the next header field, SizeOfHeaders). This value cannot be > 2GB for either PE32 or PE32+ because a) the spec says so and b) there exist 31-bit RVAs in the spec, e.g. in the import lookup table. RVAs are memory references given as offsets from the in-memory base address.
That's in memory though. The file on disk can contain data that is not loaded into memory (e.g. debug data, cert data). File pointer fields in the PE spec are 32-bit unsigned values. So the theoretical maximum size of a PE file according to the spec is 4GB.
That's according to the spec. There may be file-system, loader, OS limits outside of the PE spec that reduce the maximum further.

memory_limit=80M. what is the maximum image size for imagecreateformjpeg()?

i have a webhosting that gives maximum memory_limit of 80M (i.e. ini_set("memory_limit","80M");).
I'm using photo upload that uses the function imagecreatefromjpeg();
When i upload large images it gives the error
"Fatal error: Allowed memory size of 83886080 bytes exhausted"
What maximum size (in bytes) for the image i can restrict to the users?
or the memory_limit depends on some other factor?
The memory size of 8388608 is 8 Megabytes, not 80. You may want to check whether you can still increase the value somewhere.
Other than that, the general rule for image manipulation is that it will take at least
image width x image height x 3
bytes of memory to load or create an image. (One byte for red, one byte for green, one byte for blue, possibly one more for alpha transparency)
By that rule, a 640 x 480 pixel image will need at least 9.2 Megabytes of space - not including overhead and space occupied by the script itself.
It's impossible to determine a limit on the JPG file size in bytes because JPG is a compressed format with variable compression rates. You will need to go by image resolution and set a limit on that.
If you don't have that much memory available, you may want to look into more efficient methods of doing what you want, e.g. tiling (processing one part of an image at a time) or, if your provider allows it, using an external tool like ImageMagick (which consumes memory as well, but outside the PHP script's memory limit).
Probably your script uses more memory than the just the image itself. Trying debugging your memory consumption.
One quick-and-dirty way is to utilize memory_get_usage and memory_get_usage memory_get_peak_usage on certain points in your code and especially in a custom error_handler and shutdown_function. This can let you know what exact operations causes the memory exhaustion.

Resources