📄 portableexecutable.cpp
字号:
}
// Fix offset of all sections that go after pSection
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if ((*i).m_hdr.PointerToRawData >= pToAdd->m_hdr.PointerToRawData) {
(*i).m_hdr.PointerToRawData += pToAdd->m_hdr.SizeOfRawData;
}
}
// Increase number of section in file header
m_Headers.m_hdrNt.FileHeader.NumberOfSections++;
m_lstSections.insert(iNext, *pToAdd);
}
FixImageSize();
m_Headers.FixSizeOfHeaders();
return(PE_NONE);
}
// Fix ImageSize field
PE_ERROR CPortableExecutable::FixImageSize(void)
{
DWORD dwImageSize;
sctIterator i;
CSection *pLast;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
FixSectionSizes();
pLast = GetLastSectionInMemory();
dwImageSize = pLast->m_hdr.VirtualAddress + pLast->m_hdr.Misc.VirtualSize;
dwImageSize = m_Headers.SectionAlignment(dwImageSize);
m_Headers.m_hdrNt.OptionalHeader.SizeOfImage = dwImageSize;
return(PE_NONE);
}
// Get last section in memory of the portable executable
CSection * CPortableExecutable::GetLastSectionInMemory(void)
{
CSection *pLast;
sctIterator i;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(NULL);
pLast = NULL;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if (i == m_lstSections.begin()) {
pLast = &(*i);
} else {
if ((*i).m_hdr.VirtualAddress > pLast->m_hdr.VirtualAddress)
pLast = &(*i);
}
}
return(pLast);
}
// Get first section in memory of the portable executable
CSection * CPortableExecutable::GetFirstSectionInMemory(void)
{
CSection *pFirst;
sctIterator i;
BOOL bFoundFirst;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(NULL);
pFirst = NULL;
bFoundFirst = FALSE;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if (i == m_lstSections.begin() || bFoundFirst == FALSE) {
if ((*i).m_hdr.VirtualAddress) {
pFirst = &(*i);
bFoundFirst = TRUE;
}
} else {
if ((*i).m_hdr.VirtualAddress)
if ((*i).m_hdr.VirtualAddress < pFirst->m_hdr.VirtualAddress)
pFirst = &(*i);
}
}
return(pFirst);
}
// Get first section in file
CSection * CPortableExecutable::GetFirstSectionInFile(void)
{
CSection *pFirst;
sctIterator i;
BOOL bFoundFirst;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(NULL);
pFirst = NULL;
bFoundFirst = FALSE;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if (i == m_lstSections.begin() || bFoundFirst == FALSE) {
if ((*i).m_hdr.PointerToRawData) {
pFirst = &(*i);
bFoundFirst = TRUE;
}
} else {
if ((*i).m_hdr.PointerToRawData)
if ((*i).m_hdr.PointerToRawData < pFirst->m_hdr.PointerToRawData)
pFirst = &(*i);
}
}
return(pFirst);
}
// Get last section in file
CSection * CPortableExecutable::GetLastSectionInFile()
{
CSection *pLast;
sctIterator i;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(NULL);
pLast = NULL;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if (i == m_lstSections.begin()) {
pLast = &(*i);
} else {
if ((*i).m_hdr.PointerToRawData > pLast->m_hdr.PointerToRawData)
pLast = &(*i);
}
}
return(pLast);
}
// Realign the portable executable according to the FileAlignment
PE_ERROR CPortableExecutable::Realign(void)
{
sctIterator i;
sctIterator j;
CSection *pSection;
CSection *pSection2;
DWORD dwFAlign;
LPBYTE lpData;
DWORD dwSize;
BOOL flFirst;
DWORD dwFix;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
// Fix offsets (remove junk traces)
FixSectionOffsets();
// Fix section sizes
FixSectionSizes();
// Assign alignment value to local var for comfort
dwFAlign = m_Headers.m_hdrNt.OptionalHeader.FileAlignment;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
pSection = &(*i);
// Alignment
if (pSection->m_pData) {
dwSize = m_Headers.FileAlignment(pSection->m_hdr.SizeOfRawData);
// If VirtualSize wasn't aligned we need to align it too
if (pSection->m_hdr.Misc.VirtualSize < dwSize) {
pSection->m_hdr.Misc.VirtualSize = dwSize;
}
// Adjust file offset of further sections
for (j = m_lstSections.begin(); j != m_lstSections.end(); j++) {
pSection2 = &(*j);
if (pSection2->m_hdr.PointerToRawData > pSection->m_hdr.PointerToRawData) {
pSection2->m_hdr.PointerToRawData += (dwSize - pSection->m_hdr.SizeOfRawData);
}
}
// Replace data with aligned data
lpData = new BYTE [dwSize];
if (lpData) {
ZeroMemory(lpData, dwSize);
CopyMemory(lpData, pSection->m_pData, min(pSection->m_hdr.SizeOfRawData, dwSize));
pSection->m_hdr.SizeOfRawData = dwSize;
pSection->SetData(lpData, dwSize);
delete [] lpData;
}
}
}
FixImageSize();
m_Headers.FixSizeOfHeaders();
// Adjust file offsets for sections (to follow PE header)
flFirst = TRUE;
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
pSection = &(*i);
if (pSection->m_hdr.PointerToRawData) {
if (flFirst) {
dwFix = pSection->m_hdr.PointerToRawData - m_Headers.m_hdrNt.OptionalHeader.SizeOfHeaders;
flFirst = FALSE;
}
pSection->m_hdr.PointerToRawData -= dwFix;
}
}
return(PE_NONE);
}
// Fix section offsets (so no junk between them)
PE_ERROR CPortableExecutable::FixSectionOffsets(void)
{
sctIterator si;
list<CSection *> lstSorted; // Pointers to sections sorted by PointerToRawData
list<CSection *>::iterator i;
list<CSection *>::iterator j;
list<CSection *>::iterator temp;
list<CSection *>::iterator temp2;
CSection *scti;
CSection *sctj;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
// First create a copy of the unsorted list
for (si = m_lstSections.begin(); si != m_lstSections.end(); si++) {
if ((*si).m_hdr.PointerToRawData)
lstSorted.push_back(&(*si));
}
// Sort the list by PointerToRawData
for (i = lstSorted.begin(); i != lstSorted.end(); i++) {
i++;
j = i;
i--;
while (j != lstSorted.end()) {
if ((*i)->m_hdr.PointerToRawData > (*j)->m_hdr.PointerToRawData) {
scti = *i;
sctj = *j;
// Swap
temp = i;
temp2 = j;
lstSorted.insert(i, sctj);
lstSorted.insert(j, scti);
temp--;
temp2--;
lstSorted.erase(i);
lstSorted.erase(j);
i = temp;
j = temp2;
}
j++;
}
}
// Fix offsets
for (i = lstSorted.begin(); i != lstSorted.end(); i++) {
scti = *i;
if (i != lstSorted.begin()) {
// Get previous section
i--;
j = i;
i++;
sctj = *j;
scti->m_hdr.PointerToRawData = sctj->m_hdr.PointerToRawData + sctj->m_hdr.SizeOfRawData;
}
}
// Clear list
lstSorted.clear();
return(PE_NONE);
}
// Insert as last section
PE_ERROR CPortableExecutable::AddSection(CSection *pSection)
{
IMAGE_SECTION_HEADER hdrSection;
IMAGE_SECTION_HEADER hdrTemp;
CSection *pTemp;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
// Fix section sizes
FixSectionSizes();
if (pSection) {
pSection->GetHeader(hdrSection);
// Fix Raw offset
pTemp = GetLastSectionInFile();
if (pTemp) {
pTemp->GetHeader(hdrTemp);
hdrSection.PointerToRawData = hdrTemp.PointerToRawData + hdrTemp.SizeOfRawData;
// Fix virtual offset
pTemp = GetLastSectionInMemory();
if (pTemp) {
pTemp->GetHeader(hdrTemp);
hdrSection.VirtualAddress = hdrTemp.VirtualAddress + m_Headers.SectionAlignment(hdrTemp.Misc.VirtualSize);
pSection->SetHeader(hdrSection);
}
// Add section
return(InsertSection(pSection, NULL));
}
}
return(PE_NULL);
}
// Get section by name
CSection * CPortableExecutable::GetSectionByName(LPSTR pName)
{
CSection *pSection;
sctIterator i;
// Check if a file was loaded
if (m_flIsLoaded == FALSE)
return(NULL);
pSection = NULL;
// Search which section contains the RVA
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
if (strncmp((char *)(*i).m_hdr.Name, pName, 8) == 0) {
pSection = &(*i);
break;
}
}
// RVA isn't in the file limits
if (i == m_lstSections.end())
return(NULL);
// Return the section that the RVA is within
return(pSection);
}
// Calculate PE checksum
DWORD CPortableExecutable::CalcCheckSum(void)
{
DWORD dwSave;
DWORD dwSum;
sctIterator i;
DWORD dwSize;
if (m_flIsLoaded == FALSE)
return(PE_INVALID);
// Set checksum field to zero first
dwSave = m_Headers.m_hdrNt.OptionalHeader.CheckSum;
m_Headers.m_hdrNt.OptionalHeader.CheckSum = 0;
// Sum the headers
dwSum = GetCheckSum((LPWORD )&m_Headers.m_hdrDos, sizeof(IMAGE_DOS_HEADER), 0);
dwSum = GetCheckSum((LPWORD )m_DOSStub.m_pData, m_Headers.m_hdrDos.e_lfanew - sizeof(IMAGE_DOS_HEADER), dwSum);
dwSum = GetCheckSum((LPWORD )&m_Headers.m_hdrNt, sizeof(IMAGE_NT_HEADERS), dwSum);
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
dwSum = GetCheckSum((LPWORD )&(*i).m_hdr, sizeof(IMAGE_SECTION_HEADER), dwSum);
}
dwSize = m_Headers.m_hdrNt.OptionalHeader.SizeOfHeaders;
// Restore checksum field
m_Headers.m_hdrNt.OptionalHeader.CheckSum = dwSave;
// Sum the sections
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
dwSum = GetCheckSum((LPWORD )(*i).m_pData, (*i).m_dwSize, dwSum);
dwSize += (*i).m_dwSize;
}
// Finalize checksum
dwSum = ((dwSum & 0xFFFF) + (dwSum >> 16)) & 0xFFFF; // Add hi/lo words and zero hi word
dwSum += dwSize; // Add size
return(dwSum);
}
// Get checksum (without finalizing) of data
DWORD CPortableExecutable::GetCheckSum(LPWORD pwData, DWORD dwSize, DWORD dwSum)
{
DWORD dwCount;
if (IsBadReadPtr((LPVOID )pwData, dwSize) == TRUE) return(0);
dwCount = dwSize / sizeof(WORD); // We count words
while (dwCount--) {
dwSum += *pwData;
pwData++;
}
dwSum = (dwSum >> 16) + (dwSum & 0xFFFF); // Add low/high words
return(dwSum);
}
CSection * CPortableExecutable::GetSectionByIndex(DWORD dwIndex)
{
sctIterator i;
if (m_flIsLoaded == FALSE)
return(NULL);
if (dwIndex < m_lstSections.size()) {
i = m_lstSections.begin();
while (dwIndex--) i++;
return(&(*i));
}
return(NULL);
}
// Fix non-standard virtual sizes of section
PE_ERROR CPortableExecutable::FixSectionSizes(void)
{
sctIterator i;
IMAGE_SECTION_HEADER hdr;
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
(*i).GetHeader(hdr);
hdr.Misc.VirtualSize = max(hdr.Misc.VirtualSize, hdr.SizeOfRawData);
(*i).SetHeader(hdr);
}
return(PE_NONE);
}
// Set new DOS stub
PE_ERROR CPortableExecutable::SetNewStub(LPBYTE pbStub, DWORD cbStub)
{
signed long lFix;
sctIterator i;
IMAGE_SECTION_HEADER hdr;
PIMAGE_DOS_HEADER phdrDos;
CSection *pSection;
DWORD dwOld;
DWORD dwNew;
if (m_flIsLoaded == FALSE)
return(PE_LOAD);
// Calculate fix value
lFix = - (signed long )m_DOSStub.Get(NULL);
lFix += (signed long )(cbStub - sizeof(IMAGE_DOS_HEADER));
// Set new stub
phdrDos = (PIMAGE_DOS_HEADER )pbStub;
phdrDos->e_lfanew = cbStub;
m_Headers.SetDos(*phdrDos);
m_DOSStub.Set(pbStub + sizeof(IMAGE_DOS_HEADER), cbStub - sizeof(IMAGE_DOS_HEADER));
// Fix section offsets
pSection = GetFirstSectionInFile();
pSection->GetHeader(hdr);
dwOld = hdr.PointerToRawData;
dwNew = hdr.PointerToRawData = m_Headers.FileAlignment(cbStub + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * m_lstSections.size());
pSection->SetHeader(hdr);
for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
(*i).GetHeader(hdr);
if (hdr.PointerToRawData) {
if (&(*i) != pSection) {
hdr.PointerToRawData -= dwOld;
hdr.PointerToRawData += dwNew;
(*i).SetHeader(hdr);
}
}
}
return(PE_NONE);
}
DWORD CPortableExecutable::GetNumSections(void)
{
return(m_lstSections.size());
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -