Reputation: 423
I am trying to get the header of the .text-section. What seems to work is:
// Get the DOS header.
pDosHeader = (PIMAGE_DOS_HEADER) hMap;
// Get header of first section
pSectionHeader = (PIMAGE_SECTION_HEADER) ((DWORD) hMap + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);
But I don't exactly get why. I would have thought that the last instruction has to be:
// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1) * sizeof(IMAGE_SECTION_HEADER);
So that the pointer is moved section-header-wise.
Also, is (pNtHeaders->FileHeader.NumberOfSections - 1)
really the .text-section?
Upvotes: 1
Views: 5597
Reputation: 139
The .text
section is not always .text
.
Notice this:
PE code section have a IMAGE_SCN_CNT_CODE
flag. Why don't use it?
Please note the sizeof(IMAGE_NT_HEADERS)
only get the bytes needed for allocating, use IMAGE_NT_HEADERS->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)
instead.
Also, there's the BaseOfCode
present in optional header.
Code for checking (a C code):
PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS)(hMod + ((PIMAGE_DOS_HEADER)hMod)->e_lfanew);
PIMAGE_SECTION_HEADER SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
PIMAGE_SECTION_HEADER codeSection2;
for (WORD SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++)
{
PIMAGE_SECTION_HEADER SectionHeader = &SectionHeaders[SectionIndex];
if (SectionHeader->Characteristics & IMAGE_SCN_CNT_CODE){
codeSection2 = SectionHeader;
break;
}
}
IMAGE_SECTION_HEADER codeSection = *codeSection2;
Upvotes: 0
Reputation: 1
Here you go :
// Get DOS and PE Header
PIMAGE_DOS_HEADER hdos = (PIMAGE_DOS_HEADER)pe_file.data();
PIMAGE_NT_HEADERS hpe = (PIMAGE_NT_HEADERS)((DWORD)hdos + hdos->e_lfanew);
// Get header of first section
DWORD section_offset = (DWORD)hdos + hdos->e_lfanew + sizeof(IMAGE_NT_HEADERS);
PIMAGE_SECTION_HEADER text_section = (PIMAGE_SECTION_HEADER)(section_offset);
Upvotes: 0
Reputation: 1528
The reason that
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);
is correct, is that pSectionHeader
is of type PIMAGE_SECTION_HEADER
. When you add an integer value to a pointer in C, the value will first be multiplied by the size of the object pointed to (which is IMAGE_SECTION_HEADER
). That's just how pointer arithmetic works!
You should not make assumptions about the order in which the linker has placed the different sections. It would be better to loop through all the section headers, and e.g. match the name of the section against .text
.
Also, I wouldn't recommend using sizeof(IMAGE_NT_HEADERS)
to skip the optional header. This is because the IMAGE_OPTIONAL_HEADER
structure (contained in IMAGE_NT_HEADERS
) ends with IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
, and you do not actually have any guarantee that all data directories are present in the PE image. A better approach is to read the optional header, and use the NumberOfRvaAndSizes
field to determine how many data directories you should skip to find the section header table.
Finally, I would recommend that you use the IMAGE_XYZ32
and IMAGE_XYZ64
versions of the structures, instead of just IMAGE_XYZ
, depending on whether you want to parse PE32 (32-bit) or PE32+ (64-bit). Else, you will default to the architecture size that is default on your system.
Upvotes: 3