|

楼主 |
发表于 2020-8-2 23:15:01
|
显示全部楼层
// 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 //假设节表不超过16个
#define MAX_RES_DIR_ENTRYS 1024 //假设资源目录不超过1024个
//
DWORD dwOldResStartRVA = 0; //老的资源节的起始 RVA
//
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("打开PE文件错误!");
return;
}
//读取Dos头
theFile.SeekToBegin();
theErr = theFile.Read((char*)&sDogHead,sizeof(IMAGE_DOS_HEADER));
if(theErr==0)
{
MessageBox("读取PE文件错误!");
theFile.Close();
return;
}
//读取PE头
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theErr = theFile.Read((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
if(theErr==0)
{
MessageBox("读取PE文件错误!");
theFile.Close();
return;
}
//
if(sPeHead.Signature != 0x4550) //"PE"
{
MessageBox("不是有效的PE文件!");
theFile.Close();
return;
}
//读取节表
theErr = theFile.Read(bufferSection,sizeof(IMAGE_SECTION_HEADER) * sPeHead.FileHeader.NumberOfSections);
if(theErr==0)
{
MessageBox("读取PE文件错误!");
theFile.Close();
return;
}
sPeDataDirOfResource = sPeHead.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if(sPeDataDirOfResource.VirtualAddress == 0 || sPeDataDirOfResource.Size == 0)
{
MessageBox("本PE文件没有资源表!");
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("新的资源表起始地址不是双字边界,"\
"\n将强制改为4字节对齐!\n"\
"新的地址RVA为:0x"+temp);
}
//
dwOldResStartRVA = sPeDataDirOfResource.VirtualAddress;
pTempNewRes = new char[sPeDataDirOfResource.Size];
memset(pTempNewRes,0,sPeDataDirOfResource.Size);
//
DWORD dwPEMaxRVA = 0;
//将老的资源 RVA 转换成 fileOffset
DWORD dwOldResStartFileOffset = ConvertAddrToFileOffset(&sPeHead,
dwOldResStartRVA,
bufferSection,
dwPEMaxRVA,
TRUE);
//
if(m_dwNewResStartRVA+sPeDataDirOfResource.Size > dwPEMaxRVA)
{
MessageBox("PE文件新资源最大地址:(起始地址+资源大小) 越界)!");
theFile.Close();
return;
}
//将新的资源 RVA 转换成 fileOffset
DWORD dwNewResStartFileOffset = ConvertAddrToFileOffset(&sPeHead,
m_dwNewResStartRVA,
bufferSection,
dwPEMaxRVA,
TRUE);
if( dwOldResStartFileOffset == -1)
{
MessageBox("PE文件起始资源地址非法!");
theFile.Close();
return;
}
if(dwNewResStartFileOffset == -1 ||
m_dwNewResStartRVA < sPeHead.OptionalHeader.SizeOfHeaders ||
m_dwNewResStartRVA < 0x1000
)
{
MessageBox("PE文件资源新的起始地址非法!");
theFile.Close();
return;
}
//读取全部资源到 pTempNewRes
theFile.Seek(dwOldResStartFileOffset,CFile::begin);
theFile.Read(pTempNewRes,sPeDataDirOfResource.Size);
//
//根据 m_dwNewResStartRVA 调整资源中相关 RVA
DWORD dwDelta = dwOldResStartRVA - m_dwNewResStartRVA;
AdjustRVA(pTempNewRes,(IMAGE_RESOURCE_DIRECTORY*)pTempNewRes,dwDelta);
//
//将调整后的资源写入 PE
theFile.Seek(dwNewResStartFileOffset,CFile::begin);
theFile.Write(pTempNewRes,sPeDataDirOfResource.Size);
//
//修改 PE 头,使资源指向 m_dwNewResStartRVA
sPeHead.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = m_dwNewResStartRVA;
//写入PE头
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);
//读取Dos头
theFile.SeekToBegin();
theErr = theFile.Read((char*)&sDogHead,sizeof(IMAGE_DOS_HEADER));
//读取PE头
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theErr = theFile.Read((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
//修改校验和
sPeHead.OptionalHeader.CheckSum = dwCheckSum;
//
theFile.Seek(sDogHead.e_lfanew,CFile::begin);
theFile.Write((char*)&sPeHead,sizeof(IMAGE_NT_HEADERS));
theFile.Close();
}
//-----------------------------------------------------------------------
//
MessageBox("PE文件新资源起始地址修改成功!");
//CDialog::OnOK();
} |
|