⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portableexecutable.cpp

📁 一个用BCB写的壳!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        }

        // 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 + -