compressdlg.cpp
来自「一些初级的网络编程」· C++ 代码 · 共 1,352 行 · 第 1/3 页
CPP
1,352 行
pStubSecHdr++;
}
else
{
fGevFound = TRUE;
break;
}
}
if(fGevFound)
{
pgev = (GlobalExternalVars*)((DWORD)lpBuf + pStubSecHdr->PointerToRawData);
pgev->dwOEP = dwOldOEP;
pgev->dwRVAStubEntry = dwRvaStart + dwStubEntryPoint;
pgev->dwIATAddress = dwOriginalIAT;
pgev->dwRVACompressedResourceSize = dwNewResourceSize;
// Copy icon count
pgev->dwFirstGroupIconCount = gev.dwFirstGroupIconCount;
// TLS directory stuff
if(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0)
{
memcpy(&(pgev->tlsOriginal), &(gev.tlsOriginal), sizeof(IMAGE_TLS_DIRECTORY));
// complicated TLS stuff to fix problems with Delphi 7 apps
DWORD dwStubOffsetIndex = (DWORD)&pgev->dwAddressOfIndex - (DWORD)lpBuf;
dwStubOffsetIndex -= dwPointerToStubRawData;
dwStubOffsetIndex += dwPointerNew;
dwStubOffsetIndex = OffsetToRVA(dwStubOffsetIndex, lpMapping);
pgev->tlsOriginal.AddressOfIndex = (DWORD*)(dwStubOffsetIndex + pNtHdr->OptionalHeader.ImageBase);
//pgev->tlsOriginal.AddressOfIndex = (dwStubOffsetIndex + pNtHdr->OptionalHeader.ImageBase);
DWORD dwTlsOffset = (DWORD)(&(gev.tlsOriginal)) - (DWORD)(&(gev));
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = dwStubRvaStart + (pStubSecHdr->PointerToRawData - dwPointerToStubRawData) + dwTlsOffset;
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof(IMAGE_TLS_DIRECTORY);
}
// encrypt gev section
BYTE* lpbUncompressedBuffer = 0;
DWORD dwUncompressedSize = 0;
BYTE* lpbCompressedBuffer = 0;
DWORD dwCompressedSize = 0;
lpbUncompressedBuffer = (BYTE*)pgev;
dwUncompressedSize = (DWORD)&pgev->tlsOriginal - (DWORD)pgev;
lpbCompressedBuffer = (BYTE*)Compress(lpbUncompressedBuffer, dwUncompressedSize, &dwCompressedSize, 0);
// clear raw GEV and replace with compressed
memset(pgev, 0, dwUncompressedSize);
memcpy(pgev, lpbCompressedBuffer, dwCompressedSize);
free(lpbCompressedBuffer);
lpbCompressedBuffer = 0;
}
// end find gev
// Write new section to disk
SetFilePointer(hFile, dwPointerNew, NULL, FILE_BEGIN);
WriteFile(hFile, ((char*)lpBuf + dwPointerToStubRawData), CalcStubSize(pStubDosHdr), &dwWritten, NULL);
// truncation
BYTE* lpbTruncateBuffer = 0;
DWORD dwTruncateSize = ValidAlignment(CalcStubSize(pStubDosHdr), 0x200) - CalcStubSize(pStubDosHdr);
lpbTruncateBuffer = (BYTE*)malloc(dwTruncateSize);
memset(lpbTruncateBuffer, 0, dwTruncateSize);
WriteFile(hFile, lpbTruncateBuffer, dwTruncateSize, &dwWritten, NULL);
free(lpbTruncateBuffer);
// unmap backup
UnmapViewOfFile(lpBackupMapping);
CloseHandle(hBackupMapping);
CloseHandle(hBackupFile);
DeleteFile(szTempFile);
// unmap target
UnmapViewOfFile(lpMapping);
CloseHandle(hMapping);
SetEndOfFile(hFile);
//dwOrigSize = dwNewSize;
dwNewSize = GetFileSize(hFile, 0);
//printf(" Compressing shrunk from %dk to %dk\n", dwOrigSize/1024, dwNewSize/1024);
CloseHandle(hFile);
// Set compsize progress bar
double fPercent = 0.0;
fPercent = ((double)(dwNewSize)/(double)(dwOrigSize))*100;
m_ctrlCompessedSize.SetPos((int)fPercent);
m_FileSize.Format("%.02f%%", fPercent);
UpdateData(FALSE);
return 0;
}
int CCompressDlg::TranslateAddresses(BYTE* pBuffer, DWORD dwLength, DWORD dwSourceVA, DWORD dwDestinationVA, DWORD dwRVAPage)
{
// == 0x3F Warning: you should avoid to use this byte in patterns
#define _XX_ '?'
unsigned char PAT_Address[] = { _XX_, _XX_, _XX_, _XX_ };
DWORD dwAddress = 0;
BYTE* pOrigBuffer = pBuffer;
DWORD dwDelta = dwSourceVA - dwDestinationVA;
DWORD dwMask = 0xffffff00;
DWORD dwDontCare = 0x0000003f;
DWORD* pAddress;
DWORD* pPattern;
// Setup search pattern
pPattern = (DWORD*)&PAT_Address;
// masking need to be figured out more
*pPattern = ((dwSourceVA & 0xffff0000) | dwRVAPage ) & dwMask;
*pPattern = *pPattern | (~*pPattern & dwDontCare);
// Search and replace all addresses in range
dwAddress = PatternSearch(PAT_Address, sizeof(PAT_Address), pBuffer, dwLength);
while(((int)dwAddress >= 0) && (pBuffer < (pOrigBuffer + dwLength)))
{
pAddress = (DWORD*)((DWORD)pBuffer + dwAddress);
*pAddress -= dwDelta;
pBuffer = pBuffer + dwAddress + sizeof(PAT_Address);
dwAddress = PatternSearch(PAT_Address, sizeof(PAT_Address), pBuffer, dwLength);
}
return 0;
}
int CCompressDlg::PatternSearch(unsigned char *SearchString, int StringLen, unsigned char *SearchBuff, int BuffSize)
{
int i,j;
if (BuffSize < StringLen) return -64;
for(i=0;i<(BuffSize-StringLen);i++)
{
for(j=0;j<StringLen;j++)
{
if (
(SearchString[j] != _XX_) &&
(SearchString[j] != SearchBuff[i+j])
)
break;
}
if (j==StringLen) return i;
}
return -100;
}
int CCompressDlg::CalcStubSize(PIMAGE_DOS_HEADER pDosHdr)
{
PIMAGE_NT_HEADERS pNtHdr = 0;
PIMAGE_SECTION_HEADER pSecHdr = 0;
LONG lJmp = 0;
DWORD dwSecStart = 0;
DWORD dwResult = 0;
DWORD dwKatSup = 0;
WORD wNumSections = 0;
WORD wSizeO = 0;
lJmp = pDosHdr->e_lfanew;
dwKatSup = (DWORD)pDosHdr;
dwKatSup += lJmp;
pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;
wNumSections = pNtHdr->FileHeader.NumberOfSections;
wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;
dwSecStart = (DWORD)pNtHdr;
dwSecStart += 24;
dwSecStart += wSizeO;
pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;
dwResult = pSecHdr->SizeOfRawData;
pSecHdr++;
dwResult += pSecHdr->SizeOfRawData;
pSecHdr++;
dwResult += pSecHdr->SizeOfRawData;
return dwResult;
}
void CCompressDlg::PerformStubRelocations(LPVOID lpMapping, DWORD dwStubVA)
{
PIMAGE_DOS_HEADER pDosHdr = 0;
PIMAGE_NT_HEADERS pNtHdr = 0;
PIMAGE_BASE_RELOCATION pIBRCurrent = 0;
PIMAGE_BASE_RELOCATION pIBREnd = 0;
DWORD dwKatSup = 0;
LONG lJmp = 0;
DWORD* pAddress = 0;
DWORD dwDelta = 0;
pDosHdr = (PIMAGE_DOS_HEADER) lpMapping;
lJmp = pDosHdr->e_lfanew;
dwKatSup = (DWORD)pDosHdr;
dwKatSup += lJmp;
pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;
if(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
{
pIBRCurrent = (PIMAGE_BASE_RELOCATION)RVAToMappedOffset((DWORD)pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, lpMapping);
pIBREnd = (PIMAGE_BASE_RELOCATION)&((BYTE*)pIBRCurrent)[pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size];
while((pIBRCurrent<pIBREnd) && (pIBRCurrent->VirtualAddress != 0))
{
DWORD dwRVAPage = pIBRCurrent->VirtualAddress;
DWORD dwRelocation = 0;
DWORD dwSectionOffset = 0;
DWORD dwVirtualAddress = 0;
DWORD dwRelocationCount = (pIBRCurrent->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / sizeof(WORD);
WORD* awRelType = (WORD*)((BYTE*)pIBRCurrent + IMAGE_SIZEOF_BASE_RELOCATION);
for(DWORD dw=0; dw<dwRelocationCount; ++dw)
{
WORD wType = awRelType[dw] >> 12;
WORD wValue = awRelType[dw] & 0x0fff;
if(wType == IMAGE_REL_BASED_HIGHLOW)
{
dwRelocation = dwRVAPage + wValue;
pAddress = (DWORD*)RVAToMappedOffset(dwRelocation, lpMapping);
DWORD dwTempAddress = (*pAddress) & 0x0000ffff;
dwSectionOffset = RVAToSectionRawDataSize(dwTempAddress, lpMapping);
dwVirtualAddress = RVAToSectionVirtualAddress(dwTempAddress, lpMapping);
dwDelta = (dwStubVA + dwSectionOffset) - (pNtHdr->OptionalHeader.ImageBase + dwVirtualAddress);
*pAddress = *pAddress + dwDelta;
}
pIBRCurrent = (PIMAGE_BASE_RELOCATION)&((BYTE*)pIBRCurrent)[pIBRCurrent->SizeOfBlock];
}
}
}
}
void CCompressDlg::CompressSections(LPVOID lpMapping, LPVOID lpBackup)
{
PIMAGE_DOS_HEADER pDosHdr = 0;
PIMAGE_NT_HEADERS pNtHdr = 0;
PIMAGE_SECTION_HEADER pSecHdr = 0;
DWORD dwSecStart = 0;
DWORD dwKatSup = 0;
DWORD dwBytesWritten = 0;
LONG lJmp = 0;
WORD wNumSections = 0;
WORD wSizeO = 0;
PIMAGE_DOS_HEADER pBackupDosHdr = 0;
PIMAGE_NT_HEADERS pBackupNtHdr = 0;
PIMAGE_SECTION_HEADER pBackupSecHdr = 0;
DWORD dwBackupSecStart = 0;
DWORD dwBackupKatSup = 0;
LONG lBackupJmp = 0;
WORD wBackupNumSections = 0;
WORD wBackupSizeO = 0;
BYTE* lpbBuffer = 0;
DWORD dwBufferSize = 0;
DWORD dwBufferPos = 0;
int i = 0;
DWORD dwTempPointerToRawData = 0;
bool bResource;
BYTE* lpbNewResourceSection = 0;
bool bSkipedZeroSizeSection;
bool bBigger = false;
pDosHdr = (PIMAGE_DOS_HEADER) lpMapping;
lJmp = pDosHdr->e_lfanew;
dwKatSup = (DWORD)pDosHdr;
dwKatSup += lJmp;
pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;
wNumSections = pNtHdr->FileHeader.NumberOfSections;
wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;
dwSecStart = (DWORD)pNtHdr;
dwSecStart += 24;
dwSecStart += wSizeO;
pBackupDosHdr = (PIMAGE_DOS_HEADER) lpBackup;
lBackupJmp = pBackupDosHdr->e_lfanew;
dwBackupKatSup = (DWORD)pBackupDosHdr;
dwBackupKatSup += lBackupJmp;
pBackupNtHdr = (PIMAGE_NT_HEADERS)dwBackupKatSup;
wBackupNumSections = pBackupNtHdr->FileHeader.NumberOfSections;
wBackupSizeO = pBackupNtHdr->FileHeader.SizeOfOptionalHeader;
dwBackupSecStart = (DWORD)pBackupNtHdr;
dwBackupSecStart += 24;
dwBackupSecStart += wBackupSizeO;
// TLS directory stuff
if(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0)
{
PIMAGE_TLS_DIRECTORY tlsOriginal = 0;
tlsOriginal = (PIMAGE_TLS_DIRECTORY)RVAToMappedOffset((DWORD)pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress, lpMapping);
// Copy original and blank original
memcpy(&(gev.tlsOriginal), tlsOriginal, sizeof(IMAGE_TLS_DIRECTORY));
memset(tlsOriginal, 0, sizeof(IMAGE_TLS_DIRECTORY));
}
DWORD dwTempSize = 0;
m_ProgressFileSize = 0;
m_ProgressOffset = 0;
for(i = 0; i < wNumSections-1; i++)
{
pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;
m_ProgressFileSize += pSecHdr->Misc.VirtualSize;
// move to next section header
dwSecStart += sizeof(IMAGE_SECTION_HEADER);
}
dwSecStart = (DWORD)pNtHdr;
dwSecStart += 24;
dwSecStart += wSizeO;
for(i = 0; i < wNumSections; i++)
{
// Reset resource flag
bResource = false;
pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;
pBackupSecHdr = (PIMAGE_SECTION_HEADER)dwBackupSecStart;
if(strcmp((char*)pBackupSecHdr->Name, ".rsrc") == 0)
{
// we are at resource section
bResource = true;
}
// skip sections with raw size = 0
if(pBackupSecHdr->SizeOfRawData == 0)
{
// move to next section header
dwSecStart += sizeof(IMAGE_SECTION_HEADER);
pBackupSecHdr += sizeof(IMAGE_SECTION_HEADER);
bSkipedZeroSizeSection = true;
continue;
}
BYTE* lpbUncompressedBuffer = 0;
DWORD dwUncompressedSize = 0;
BYTE* lpbCompressedBuffer = 0;
DWORD dwCompressedSize = 0;
lpbUncompressedBuffer = (BYTE*)((DWORD)lpBackup + pBackupSecHdr->PointerToRawData);
dwUncompressedSize = pBackupSecHdr->SizeOfRawData;
if(bResource)
{
lpbNewResourceSection = (BYTE*)BuildNewResourceSection(lpBackup, &dwNewResourceSize);
// This is the resource section, so skip the directory and only compress the data afterwards
lpbUncompressedBuffer = (BYTE*)((DWORD)lpBackup + pBackupSecHdr->PointerToRawData);
dwUncompressedSize = pBackupSecHdr->SizeOfRawData;
}
lpbCompressedBuffer = (BYTE*)Compress(lpbUncompressedBuffer, dwUncompressedSize, &dwCompressedSize, &CallbackFunc);
double fPercent = ((double)dwCompressedSize/(double)dwUncompressedSize) * 100;
//printf("\r %s %.1f%% (comp: %d, uncomp: %d)\n", pSecHdr->Name, fPercent, dwCompressedSize, pSecHdr->SizeOfRawData);
// copy compressed buffer into original mapped file
DWORD dwNewAlignedSectionSize = ValidAlignment(dwCompressedSize, 0x200);
BYTE* lpbNewSectionBuffer = (BYTE*)malloc(dwNewAlignedSectionSize);
memset(lpbNewSectionBuffer, 0, dwNewAlignedSectionSize);
memcpy(lpbNewSectionBuffer, lpbCompressedBuffer, dwCompressedSize);
if(i==0)
{
memcpy((LPVOID)((DWORD)lpMapping + pBackupSecHdr->PointerToRawData), lpbNewSectionBuffer, dwNewAlignedSectionSize);
pSecHdr->SizeOfRawData = dwNewAlignedSectionSize;
}
else
{
if(bResource && lpbNewResourceSection)
{
memcpy((LPVOID)((DWORD)lpMapping + dwTempPointerToRawData), lpbNewResourceSection, dwNewResourceSize);
pSecHdr->PointerToRawData = dwTempPointerToRawData;
dwTempPointerToRawData += dwNewResourceSize;
memcpy((LPVOID)((DWORD)lpMapping + dwTempPointerToRawData), lpbNewSectionBuffer, dwNewAlignedSectionSize);
pSecHdr->SizeOfRawData = dwNewResourceSize + dwNewAlignedSectionSize;
free(lpbNewResourceSection);
}
else
{
memcpy((LPVOID)((DWORD)lpMapping + dwTempPointerToRawData), lpbNewSectionBuffer, dwNewAlignedSectionSize);
//pSecHdr->PointerToRawData = dwTempPointerToRawData;
pSecHdr->PointerToRawData = dwTempPointerToRawData;
// correct pointer to raw data if we skipped a zero size section
if(bSkipedZeroSizeSection == true)
{
PIMAGE_SECTION_HEADER pLastSecHdr = pSecHdr;
pLastSecHdr--;
pLastSecHdr->PointerToRawData = dwTempPointerToRawData;
bSkipedZeroSizeSection = false;
}
pSecHdr->SizeOfRawData = dwNewAlignedSectionSize;
}
}
dwTempPointerToRawData = pSecHdr->PointerToRawData + pSecHdr->SizeOfRawData;
free(lpbNewSectionBuffer);
free(lpbCompressedBuffer);
// Set VSize = RSize
pSecHdr->Misc.VirtualSize = ValidAlignment(pSecHdr->Misc.VirtualSize, 0x1000);
m_ProgressOffset += pSecHdr->Misc.VirtualSize;
// move to next section header
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?