|
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMoveResDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMoveResDlg::OnOK()
{
// TODO: Add extra validation here
#define MAX_SEC_NUMS 16 //Assuming that the section table does not exceed 16
#define MAX_RES_DIR_ENTRYS 1024 //Assuming that there are no more than 1024 resource directories
//
DWORD dwOldResStartRVA = 0; //Start RVA of the old resource section
//
IMAGE_RELOCATION sReloc;
char bufferSection[sizeof(IMAGE_SECTION_HEADER)*MAX_SEC_NUMS];
memset(bufferSection,0,sizeof(IMAGE_SECTION_HEADER)*MAX_SEC_NUMS);
//
char *pTempNewRes = NULL;
//
IMAGE_DOS_HEADER sDogHead;
IMAGE_NT_HEADERS sPeHead;
IMAGE_DATA_DIRECTORY sPeDataDirOfResource;
//
IMAGE_RESOURCE_DIRECTORY sResDir;
IMAGE_RESOURCE_DIRECTORY_ENTRY sResDirEntry[MAX_RES_DIR_ENTRYS];
memset((char*)&sResDirEntry[0],0,sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)*MAX_RES_DIR_ENTRYS);
IMAGE_RESOURCE_DATA_ENTRY sResDataEntry;
IMAGE_RESOURCE_DIR_STRING_U sResDirStringU;
IMAGE_RESOURCE_DIRECTORY_STRING sResDirString;
//
CFile theFile;
short theErr = theFile.Open(m_szPeFile, CFile::modeReadWrite,NULL);
if(theErr == 0)
{
//error.
MessageBox("Error opening PE file!");
return;
}
//Read Dos header
theFile.SeekToBegin();
theErr = theFile.Read((char*)&sDogHead,sizeof(IMAGE_DOS_HEADER));
if(theErr==0)
{
MessageBox("Error reading PE file!");
theFile.Close();
return;
}
//Read PE header
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theErr = theFile.Read((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
if(theErr==0)
{
MessageBox("Error reading PE file!");
theFile.Close();
return;
}
//
if(sPeHead.Signature != 0x4550) //"PE"
{
MessageBox("Not a valid PE file!");
theFile.Close();
return;
}
//Read section table
theErr = theFile.Read(bufferSection,sizeof(IMAGE_SECTION_HEADER) * sPeHead.FileHeader.NumberOfSections);
if(theErr==0)
{
MessageBox("Error reading PE file!");
theFile.Close();
return;
}
sPeDataDirOfResource = sPeHead.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if(sPeDataDirOfResource.VirtualAddress == 0 || sPeDataDirOfResource.Size == 0)
{
MessageBox("This PE file has no resource table!");
theFile.Close();
return;
}
//
if(m_dwNewResStartRVA% 4 != 0)
{
DWORD nAlign = 4-(m_dwNewResStartRVA% 4);
m_dwNewResStartRVA += nAlign;
CString temp;
temp.Format("%x",m_dwNewResStartRVA);
m_EditNewResRVA.SetWindowText(temp);
MessageBox("The starting address of the new resource table is not a double word boundary,"\
"\n will be forced to be 4 byte aligned!\n"\
"The new address RVA is: 0x"+temp);
}
//
dwOldResStartRVA = sPeDataDirOfResource.VirtualAddress;
pTempNewRes = new char[sPeDataDirOfResource.Size];
memset(pTempNewRes,0,sPeDataDirOfResource.Size);
//
DWORD dwPEMaxRVA = 0;
//Convert the old resource RVA into fileOffset
DWORD dwOldResStartFileOffset = ConvertAddrToFileOffset(&sPeHead,
dwOldResStartRVA,
bufferSection,
dwPEMaxRVA,
TRUE);
//
if(m_dwNewResStartRVA+sPeDataDirOfResource.Size> dwPEMaxRVA)
{
MessageBox("Maximum address of new resource of PE file: (starting address + resource size) out of bounds)!");
theFile.Close();
return;
}
//Convert the new resource RVA into fileOffset
DWORD dwNewResStartFileOffset = ConvertAddrToFileOffset(&sPeHead,
m_dwNewResStartRVA,
bufferSection,
dwPEMaxRVA,
TRUE);
if( dwOldResStartFileOffset == -1)
{
MessageBox("The starting resource address of the PE file is illegal!");
theFile.Close();
return;
}
if(dwNewResStartFileOffset == -1 ||
m_dwNewResStartRVA <sPeHead.OptionalHeader.SizeOfHeaders ||
m_dwNewResStartRVA <0x1000
)
{
MessageBox("The new starting address of the PE file resource is illegal!");
theFile.Close();
return;
}
//Read all resources to pTempNewRes
theFile.Seek(dwOldResStartFileOffset,CFile::begin);
theFile.Read(pTempNewRes,sPeDataDirOfResource.Size);
//
//Adjust the relevant RVA in the resource according to m_dwNewResStartRVA
DWORD dwDelta = dwOldResStartRVA-m_dwNewResStartRVA;
AdjustRVA(pTempNewRes,(IMAGE_RESOURCE_DIRECTORY*)pTempNewRes,dwDelta);
//
//Write the adjusted resources to PE
theFile.Seek(dwNewResStartFileOffset,CFile::begin);
theFile.Write(pTempNewRes,sPeDataDirOfResource.Size);
//
//Modify the PE header to make the resource point to m_dwNewResStartRVA
sPeHead.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = m_dwNewResStartRVA;
//Write PE header
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theFile.Write((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
//
if(pTempNewRes)
{
delete pTempNewRes;
pTempNewRes = NULL;
}
theFile.Close();
//
//------------------------------------------------ -----------------------
/* MapFileAndCheckSum() return value.
CHECKSUM_OPEN_FAILURE Could not open the file.
CHECKSUM_MAP_FAILURE Could not map the file.
CHECKSUM_MAPVIEW_FAILURE Could not map a view of the file.
CHECKSUM_UNICODE_FAILURE Could not convert the file name to Unicode.
*/
char buffer[255];
strcpy(buffer,m_szPeFile);
DWORD dwHeaderSum;
DWORD dwCheckSum;
DWORD dwRet = MapFileAndCheckSum(buffer,&dwHeaderSum,&dwCheckSum);
if( dwRet == CHECKSUM_SUCCESS)
{
//
theErr = theFile.Open(m_szPeFile, CFile::modeReadWrite,NULL);
//Read Dos header
theFile.SeekToBegin();
theErr = theFile.Read((char*)&sDogHead,sizeof(IMAGE_DOS_HEADER));
//Read PE header
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theErr = theFile.Read((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
//Modify the checksum
sPeHead.OptionalHeader.CheckSum = dwCheckSum;
//
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theFile.Write((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
theFile.Close();
}
//------------------------------------------------ -----------------------
//
MessageBox("The starting address of the new resource of the PE file has been modified successfully!");
//CDialog::OnOK();
} |
|