最近写的一个图标互换工具(技术+部分源码)
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。。
给力代码:
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。。
相关文章推荐
- 做一个弹框玩玩,顺便熟悉最近新学习的插件封装技术
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 3 部分: Systemtap
- 转载一个很经典的--C# Socket TCP和UDP报文及端口测试工具的开发(提供源码)
- 开放源码 C/C++ 单元测试工具,第 1 部分: 了解 Boost 单元测试框架
- 一个文件重复生成的小工具[附源码和可执行文件]
- 开放源码 C/C++ 单元测试工具,第 1 部分: 了解 Boost 单元测试框架
- 一个生成各种进制格式IP的小工具(附源码)
- 最近在开发一个象frontpage的做网站的软件,里面用到的技术是WTL/ATL
- Python:一个多功能的抓图工具开发(附源码)
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap,第 1 部分: kprobe
- 一个非常适合IT团队的在线API文档、技术文档工具 (ShowDoc)
- 最近看到了一个远航财经直播不知道是用什么技术实现的
- 【Java】【反射技术】2个对象除了类名不一样,类的定义部分完全一样;当给定一个对象,转换成另一个类的对象。
- 一个java工程师的前6年工作部分技术积累(一)
- 2018年,腾讯微信开发者工具又出一个新伙伴,重大突破前端开发技术,彻底颠覆传统前端设计理念
- 一段源码,展示C# winform 如何识别 Ctrl+Shift+X组合键;如何选取离光标最近的一个单词。
- Java核心技术学习---多线程,锁,同步,条件对象部分应用源码
- 最近做的一个小工具
- 最近刚为公司完成的一款监视的小工具软件!用DELPHI 7 写的,可以从后台监控系统﹑键盘﹑鼠标﹑屏幕以及文件与目录!有源码!