📄 pe_sections.idc
字号:
comment = comment + "\n 0x0080 - " + ((flags & 0x0080) ? "1 - big" : "0 - little") + " endian byte order";
if(flags & 0x0100)
{
comment = comment + "\n 0x0100 - 1 - 32-bit word architecture";
}
if(flags & 0x0200)
{
comment = comment + "\n 0x0200 - 1 - debug information stripped";
}
if(flags & 0x0400)
{
comment = comment + "\n 0x0400 - 1 - copy and run image from swap file (if on removable media)";
}
if(flags & 0x0800)
{
comment = comment + "\n 0x0800 - 1 - copy and run image from swap file (if remote)";
}
if(flags & 0x1000)
{
comment = comment + "\n 0x1000 - 1 - system file";
}
comment = comment + "\n 0x2000 - " + ((flags & 0x2000) ? "1 - Dynamic Link Library (DLL)" : "0 - Executable (EXE)");
if(flags & 0x4000)
{
comment = comment + "\n 0x4000 - 1 - run only on uniprocessor machines";
}
comment = comment + "\n 0x8000 - " + ((flags & 0x8000) ? "1 - big" : "0 - little") + " endian word order";
Message(comment + "\n\n");
MySeek(fhandle, PEoffset + 0x5e, 0);
DLLflags = readshort(fhandle, 0);
if(DLLflags != 0)
{
Message("- DLL flags (loader requirements) (%.4X):\n", DLLflags);
comment = "";
if(DLLflags & 0x0001)
{
comment = comment + "\n 0x0001 - per-process library initialization (reserved)";
}
if(DLLflags & 0x0002)
{
comment = comment + "\n 0x0002 - per-process library termination (reserved)";
}
if(DLLflags & 0x0004)
{
comment = comment + "\n 0x0004 - per-thread library initialization (reserved)";
}
if(DLLflags & 0x0008)
{
comment = comment + "\n 0x0008 - per-thread library termination (reserved)";
}
if(DLLflags & 0x0800)
{
comment = comment + "\n 0x0800 - do not bind image";
}
if(DLLflags & 0x2000)
{
comment = comment + "\n 0x2000 - driver is a WDM driver";
}
if(DLLflags & 0x8000)
{
comment = comment + "\n 0x8000 - image is terminal server aware";
}
Message(comment + "\n\n");
}
Message("- %d sections (excluding header) found at file offset %.8X:\n\n", numberSections, PEsections);
headerVSize = 0x7fffffff; // largest long (just below the 2G limit)
actualImageSize = 0;
for(i = 0; i < numberSections; i++)
{
auto valid, baseRVA;
MySeek(fhandle, PEsections + 0x28*i + 8, 0); // the vSize field of the section
valid = readlong(fhandle, 0);
baseRVA = readlong(fhandle, 0);
if(!valid)
{
// vSize is zero. Windows just uses pSize instead and so will we.
valid = readlong(fhandle, 0); // the pSize field of the section
}
if(!baseRVA)
{
auto phyOffset;
// zero RVA lets check the
phyOffset = readlong(fhandle, 0);
if(!phyOffset)
{
numberSections = i;
valid = 0;
Message("* Invalid section count detected, adjusted to %i\n\n", numberSections);
}
}
if(valid)
{
if(actualImageSize < (baseRVA + valid))
{
actualImageSize = (baseRVA + valid);
}
if((baseRVA >= 0) && (baseRVA < headerVSize))
{
headerVSize = baseRVA;
}
}
}
if(headerPSize < (PEoffset + NTheaderSize + 0x18 + numberSections*0x28))
{
// The physical size is too small.
// Windows NT/2000 won't load this file... (but we will ;)
comment = form("header physical size is too small (%.8X), ", headerPSize);
headerPSize = PEoffset + NTheaderSize + 0x18 + numberSections*0x28;
comment = comment + form("adjusted to (%.8X)", headerPSize);
Message(" * " + comment + "\n\n");
comment = "\n" + comment;
}
else
{
comment = "";
}
LargestPhysical = headerPSize;
imageDelta = 0;
if(!already_loaded)
{
auto next_seg;
next_seg = NextSeg(imageBase);
if((SegStart(imageBase) != BADADDR) || ((next_seg != BADADDR) && (actualImageSize > (next_seg - imageBase))))
{
auto newBase;
if(flags & 0x0001) // relocs stripped
{
already_loaded = AskYN(0, "image does not have relocations, relocate anyway?");
// -1 - we return from this function.
// 0 - we return from this function.
// 1 - we reload all section data.
if(already_loaded <= 0)
{
return already_loaded;
}
already_loaded = 0;
}
// we must relocate the image
newBase = 0x10000000; // we will start searching for a free block from the 1st GB
while((SegStart(newBase) != BADADDR) || ((next_seg != BADADDR) && (actualImageSize > (next_seg - newBase))))
{
next_seg = NextSeg(newBase);
if(SegStart(newBase) != BADADDR)
{
newBase = SegEnd(newBase);
}
}
imageDelta = newBase - imageBase;
Message("- Address collision detected at %08X-%08X\n", imageBase, imageBase + actualImageSize - 1);
Message(" - Relocating image to %08X-%08X (delta:%08X)\n\n", newBase, newBase + actualImageSize - 1, imageDelta);
imageBase = newBase;
}
else
{
already_loaded = 1;
}
}
CreateSection(fhandle, DLL_name + PE_HEADER_SECTION_NAME, imageBase, headerVSize, 0, headerPSize, load_section_data);
MakeComm(imageBase + PEoffset, commentTimeStamp + comment);
Message("\n name: %s\n", PE_HEADER_SECTION_NAME);
Message(" file offset: 00000000\n");
Message(" file size: %.8X (ends at %.8X)\n", headerPSize, headerPSize);
Message(" relative virtual address: --------\n");
Message(" virtual size: %.8X\n", headerVSize);
Message(" flags: --------\n\n");
if((PEentry || !(flags & 0x2000)) && (PEentry < headerVSize))
{
Message(" * The entry point is in the " + PE_HEADER_SECTION_NAME + " section\n");
if(PEentry > headerPSize)
{
Message(" * WARNING: no physical data to backup the entry point\n\n");
}
Message("\n");
}
if(CreateMZStruct(imageBase, DLL_name) == -1)
return -1;
if(CreatePEStruct(imageBase, PEoffset, DLL_name) == -1)
return -1;
if(CreatePESStruct(imageBase, DLL_name) == -1)
return -1;
ForceName(imageBase + PEsections, DLL_name + "pe_section_table");
for(i = 0; i < numberSections; i++)
{
auto vSize, RVA, phySize, phyAddr;
auto l, printPhySize, printVSize;
auto flagsComment, warningComment;
auto vExtra;
auto printPhyAddr;
auto tmpStr;
auto sectionflags;
MySeek(fhandle, PEsections + i*0x28, 0);
findString = fgetStr(fhandle, 8);
vSize = readlong(fhandle, 0);
RVA = readlong(fhandle, 0);
phySize = readlong(fhandle, 0);
phyAddr = readlong(fhandle, 0);
printPhyAddr = phyAddr;
printPhySize = phySize;
printVSize = vSize;
MySeek(fhandle, 0x0c, 1);
sectionflags = readlong(fhandle, 0);
warningComment = "";
comment = "(";
comment = comment + ((sectionflags & 0x40000000) ? "r" : "-");
comment = comment + ((sectionflags & 0x80000000) ? "w" : "-");
comment = comment + ((sectionflags & 0x20000000) ? "x" : "-");
comment = comment + ((sectionflags & 0x00000020) ? "c" : "-");
comment = comment + ((sectionflags & 0x00000040) ? "i" : "-");
comment = comment + ((sectionflags & 0x00000080) ? "u" : "-");
comment = comment + ")";
if(sectionflags & 0x10000000)
{
comment = comment + " shared";
}
if(sectionflags & 0x01000000)
{
comment = comment + " ext relocs";
}
if(sectionflags & 0x02000000)
{
comment = comment + " discardable";
}
if(sectionflags & 0x04000000)
{
comment = comment + " don't cache";
}
if(sectionflags & 0x08000000)
{
comment = comment + " don't page";
}
flagsComment = comment;
comment = "flags" + comment;
if((vSize == 0) && (phySize != 0))
{
// Win9x specific (NT will refuse to load the application)
vSize = phySize;
tmpStr = "virtual size is zero --> using physical size instead";
comment = comment + "\n" + tmpStr;
warningComment = warningComment + " * " + tmpStr + "\n\n";
}
if(phyAddr == 0)
{
phySize = 0;
tmpStr = "file offset is zero --> using zero for the physical size";
comment = comment + "\n" + tmpStr;
warningComment = warningComment + " * " + tmpStr + "\n\n";
}
// adjusting phyAddr to valid values
if((phyAddr & 0x1ff) && (subsystem != 1) && (strange_alignment >= 0))
{
// Windows adjusts the physical offset to a 200h boundary (sector size?)
// Note:
// This check is done AFTER the zero check.
// and is not done for programs running under native subsystem.
// apparently pre Win95 SP2 did not adjust the offset like this.
if(strange_alignment == 0)
{
strange_alignment = AskYN(1, form("Strange section alignment (%08X), adjust to 200h?", phyAddr));
if(strange_alignment < 0)
{
return -1;
}
if(strange_alignment == 0)
{
strange_alignment = -1;
}
}
if(strange_alignment > 0)
{
phyAddr = phyAddr & 0xfffffe00;
tmpStr = form("file offset is not on a 200h boundary --> adjusted to %08X", phyAddr);
comment = comment + "\n" + tmpStr;
warningComment = warningComment + " * " + tmpStr + "\n\n";
}
}
// adjusting sizes to alignment values
vExtra = (phyAddr + phySize) % FileAlignment;
if(vExtra != 0)
{
vExtra = FileAlignment - vExtra;
phySize = phySize + vExtra;
}
vExtra = (RVA + vSize) % SectionAlignment;
if(vExtra != 0)
{
vExtra = SectionAlignment - vExtra;
vSize = vSize + vExtra;
}
// making sure that we don't try to read data that isn't there.
if(vSize < phySize)
{
phySize = vSize;
}
if(phySize != 0)
{
if(fileSize > phyAddr)
{
if(fileSize < (phyAddr + phySize))
{
phySize = fileSize - phyAddr;
}
if(fileSize < (phyAddr + printPhySize))
{
Warning(findString + " section ends outside of the file, part of the physical data is missing!");
warningComment = warningComment + " * " + findString + " section ends outside of the file\n * part of its physical data is missing!\n\n";
comment = comment + "\nSection ends outside of the file\npart of the physical data is missing!";
}
}
else
{
phySize = 0;
if(printPhySize != 0)
{
Warning(findString + " section starts outside of the file! No physical data available!");
warningComment = warningComment + " * " + findString + " section starts outside of the file\n * no physical data is available for it\n\n";
comment = comment + "\nSection starts outside of the file\nNo physical data available";
}
}
}
if(LargestPhysical < (phyAddr + phySize))
{
LargestPhysical = phyAddr + phySize;
}
CreateSection(fhandle, DLL_name + findString, imageBase + RVA, vSize, phyAddr, phySize, load_section_data);
Message("\n name: %s\n", findString);
Message(" file offset: %.8X\n", printPhyAddr);
Message(" file size: %.8X (ends at %.8X)\n", printPhySize, phyAddr + printPhySize);
Message(" relative virtual address: %.8X\n", RVA);
Message(" virtual size: %.8X\n", printVSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -