您的位置:首页 > 其它

最近写的一个图标互换工具(技术+部分源码)

2011-05-27 15:59 423 查看
主要是两个技术,一个是在两个exe中搜索相同图标大小的资源进行替换。如果找不到相同的资源,用UpdateResource()函数添加新的资源到各自图标中·~

给力代码:

bool PEHelp::GetPos(CString path,DWORD *pos,DWORD *size,DWORD& Num)
{
IMAGE_DOS_HEADER dosHead;
_IMAGE_NT_HEADERS ntHead;
_IMAGE_SECTION_HEADER secHead;

int posNum=0;
int sizeNum=0;

if (IsPeFile(path)==false)
return false;

CFile fp;
fp.Open(path,CFile::modeRead);
fp.Read(&dosHead,sizeof(_IMAGE_DOS_HEADER));//移动文件指针到MZ Header末

fp.Seek(dosHead.e_lfanew,CFile::begin); //读取PE Header的位置
fp.Read(&ntHead,sizeof(_IMAGE_NT_HEADERS)); //将文件指针移动到PE

int i=0;
for(;i<ntHead.FileHeader.NumberOfSections;i++)
{
fp.Read(&secHead,sizeof(_IMAGE_SECTION_HEADER));
if(strcmp((char*)secHead.Name,".rsrc")==0)
{
break;
}
}
if (i==ntHead.FileHeader.NumberOfSections)
{
AfxMessageBox("区段可能被加密");
return false;
}

_IMAGE_RESOURCE_DIRECTORY dirResource;
fp.Seek(secHead.PointerToRawData,CFile::begin); //读取资源根节点开始的位置
DWORD Temppos=fp.GetPosition();
fp.Read(&dirResource,sizeof(_IMAGE_RESOURCE_DIRECTORY));

_IMAGE_RESOURCE_DIRECTORY_ENTRY ResourceType;

_IMAGE_RESOURCE_DIRECTORY ResourceName; //第二层
_IMAGE_RESOURCE_DIRECTORY_ENTRY name;

_IMAGE_RESOURCE_DIRECTORY ResourcePage; //第三层
_IMAGE_RESOURCE_DIRECTORY_ENTRY LanguageID;
_IMAGE_RESOURCE_DATA_ENTRY entryData; //资源入口

for(i=0;i<dirResource.NumberOfIdEntries+dirResource.NumberOfNamedEntries;i++)
{
fp.Read(&ResourceType,sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY));

if(ResourceType.Name==3)//该资源是图标
{
fp.Seek(Temppos+ResourceType.OffsetToDirectory,CFile::begin);
fp.Read(&ResourceName,sizeof(_IMAGE_RESOURCE_DIRECTORY));

DWORD Temppos2=fp.GetPosition();

for(int k=0;k<ResourceName.NumberOfIdEntries;k++)//遍历各个入口点指示的目录
{
fp.Read(&name,sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY));

if(name.DataIsDirectory >0) //还有子目录
{
fp.Seek(Temppos+name.OffsetToDirectory,CFile::begin);
fp.Read(&ResourcePage,sizeof(_IMAGE_RESOURCE_DIRECTORY));

fp.Read(&LanguageID,sizeof(_IMAGE_RESOURCE_DIRECTORY));

fp.Seek(Temppos+LanguageID.OffsetToData,CFile::begin);
fp.Read(&entryData,sizeof(_IMAGE_RESOURCE_DATA_ENTRY));

if(entryData.Size>44)//找到图标
{
size[sizeNum++]=entryData.Size;//
pos[posNum++]=Temppos+entryData.OffsetToData - secHead.VirtualAddress;//图标起始
}
fp.Seek(Temppos2+(k+1)*sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY),CFile::begin);//指针回滚

}
}
}
}

fp.Close();

Num=posNum;

return true;
}

bool PEHelp::ReplaceICO(LPCTSTR lpszApp,char *buf,DWORD size,int ID)
{
HANDLE hApp;
if (NULL==(hApp =::BeginUpdateResource(lpszApp,NULL)))
{
return FALSE;
}

//标记更新资源
::UpdateResource(hApp,RT_ICON,MAKEINTRESOURCE(ID),0,buf,size);

//写入新资源
if (!::EndUpdateResource(hApp,FALSE))
{
return FALSE;
}
return TRUE;
}

bool PEHelp::ReplaceIcon(CString path1,CString path2)
{
DWORD pos1[256],size1[256],pos2[256],size2[256];
DWORD pos1Num,pos2Num;

if(::GetFileAttributes(path1)==-1||::GetFileAttributes(path2)==-1)
{
AfxMessageBox("目标文件或源文件不存在",MB_ICONERROR);
return false;
}

GetPos(path1,pos1,size1,pos1Num);
GetPos(path2,pos2,size2,pos2Num);

//获取最高分辨率图标下标
int index1,index2;
GetMaxResIndex(size1,pos1Num,index1);
GetMaxResIndex(size2,pos2Num,index2);

/****获取最高分辨率资源****/
CFile fp;
fp.Open(path1,CFile::modeRead);
fp.Seek(pos1[index1],CFile::begin);
char *buf1=(char*)malloc(size1[index1]);
DWORD TempSize1=size1[index1];
fp.Read(buf1,size1[index1]);
fp.Close();

CFile fp2;
fp2.Open(path2,CFile::modeRead);
fp2.Seek(pos2[index2],CFile::begin);
char *buf2=(char*)malloc(size2[index2]);
DWORD TempSize2=size2[index2];
fp2.Read(buf2,size2[index2]);
fp2.Close();
//同大小直接替换资源,节约体积
for (int k=0;k<(int)pos1Num;k++)
{
for (int j=0;j<(int)pos2Num;j++)
{
if (size1[k]==size2[j])
{
//读取第一个文件图标数据
CFile fp;
fp.Open(path1,CFile::modeRead);
fp.Seek(pos1[k],CFile::begin);
char *buf1=(char*)malloc(size1[k]);
fp.Read(buf1,size1[k]);
fp.Close();

//读取第二个文件图标数据
CFile fp2;
fp2.Open(path2,CFile::modeRead);
fp2.Seek(pos2[j],CFile::begin);
char *buf2=(char*)malloc(size2[j]);
fp2.Read(buf2,size2[j]);
fp2.Close();

//将1写入2
fp.Open(path2,CFile::modeWrite);
fp.Seek(pos2[j],CFile::begin);
fp.Write(buf1,size1[k]);
fp.Close();
//将2写入1
fp.Open(path1,CFile::modeWrite);
fp.Seek(pos1[k],CFile::begin);
fp.Write(buf2,size2[j]);
fp.Close();

free(buf1);
free(buf2);
}
}
}

//没有相同大小资源的更新新资源进exe文件

for (k=0;k<(int)pos1Num;k++)
{
int j=0;
while (size1[k]!=size2[j] && j!=(int)pos2Num)
{
j++;
}
if(j==(int)pos2Num)//没找到相同大小的资源,用最大资源替换
{
pos1[k]=0;//pos数组没用了,这边做标记用
}
}

for (k=0;k<(int)pos2Num;k++)
{
int j=0;
while (size2[k]!=size1[j] && j!=(int)pos1Num)
{
j++;
}
if(j==(int)pos1Num)//没找到相同大小的资源,用最大资源替换
{
pos2[k]=0;//pos数组没用了,这边做标记用
}
}
for (k=0;k<(int)pos1Num;k++)
{
if (pos1[k]==0)
{
ReplaceICO(path1,buf2,TempSize2,k+1);
}
}
for (k=0;k<(int)pos2Num;k++)
{
if (pos2[k]==0)
{
ReplaceICO(path2,buf1,TempSize1,k+1);
}
}
free(buf1);
free(buf2);
return true;

}
另外,要说的是UpdateResource函数对48*48图标的添加会出现问题~~so。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐