findwindow获取托盘区图标程序的句柄_C/C++编程笔记:替换windows应用图标

好多年前的一些恶作剧程序就是将windows上其他的程序图标全部换成一个;

或者将一个用户常用的一个应用(比如QQ)图标替换到一个其他程序上,然后将该应用替换伪装成这个常用的应用。

当用户点击的时候,运行的可能是意想不到的程序。

抛开恶作剧的想法,我们单从技术角度去看这个问题,如何去实现呢?

0c5e12deaea80800a9bef42619fdd2ce.png

都是资源

程序图标都是资源图片,在打包的时候,由打包程序拷贝到exe的程序文件里面去了。

因为exe文件是有对应的格式的,不同的数据存储在对应位置,而且格式比较复杂。

有兴趣的小伙伴可以百度搜索相关的exe文件格式介绍,并且还有一个PEView的文件查看器。

抛开繁杂的exe文件格式,我们如何去进行操作呢?

WIN32 API

微软提供了繁多的API,供我们来使用。

其中 LoadLibraryEx 函数可以加载dll或者exe,返回模块句柄;

再通过 EnumResourceNames 函数枚举出对应的资源(比如图标),通过传入的回调函数进行操作;

在回调函数中通过 UpdateResource 函数操作资源,这样就可以实现对exe文件中资源的更换。

需要注意的是在替换之前,需要将需要替换的exe文件里面的资源删除;再将另一个exe文件的资源(比如图标)更新到该exe里面,这样我们就实现了程序图标的替换,以假乱真。

具体实现

代码很短,且有详细的注释,请看:

删除图标回调函数BOOL CALLBACK DelIcons(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) {    HANDLE hUpdate = (HANDLE)lParam;    void* pData = 0;  // 数据为空,即为删除    int nSizeOfIconRes = 0;    UpdateResource(hUpdate,lpszType,lpszName,MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),pData,nSizeOfIconRes);    return TRUE;}替换图标回调函数BOOL CALLBACK UpdateIcons(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) {    HANDLE hUpdate = (HANDLE)lParam;    HRSRC hRes = FindResource(hModule,lpszName,lpszType); // 查找数据源    HGLOBAL hResLoaded = LoadResource(hModule, hRes); // 加载数据源    void* pData = LockResource(hResLoaded);  // 加锁    int nSizeOfIconRes = SizeofResource(hModule,hRes);  // 获取资源大小    UpdateResource(hUpdate,lpszType,lpszName,MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),pData,nSizeOfIconRes);    UnlockResource(hResLoaded); // 解锁    FreeResource(hResLoaded); // 释放资源    return TRUE;}// brief changeIcon 改变程序图标( eg: changeIcon("xxx.exe", "QQ.exe");///        将 QQ.exe 的企鹅图标 换到  xxx.exe;)/// param dstApp  要改图标的程序名称/// param srcApp  图标来源图标///void changeIcon(const char*dstApp, const char*srcApp) {    HANDLE hUpdate = BeginUpdateResourceA(dstApp, false);    // 加载目的文件,并删除图标    HMODULE hdst = LoadLibraryExA(dstApp, 0, LOAD_LIBRARY_AS_DATAFILE);    EnumResourceNames(hdst,RT_ICON,DelIcons,(long)hUpdate);    EnumResourceNames(hdst,RT_GROUP_ICON,DelIcons,(long)hUpdate);    FreeLibrary(hdst);    // 加载源文件,并更新图标    HMODULE hsrc = LoadLibraryExA(srcApp, 0, LOAD_LIBRARY_AS_DATAFILE);    EnumResourceNames(hsrc,RT_ICON,UpdateIcons,(long)hUpdate);    EnumResourceNames(hsrc,RT_GROUP_ICON,UpdateIcons,(long)hUpdate);    FreeLibrary(hsrc);    EndUpdateResource(hUpdate,FALSE);}

使用的时候,只需要简单的传入两个对应的exe路径即可:

int main(int argc, char* argv[]){    changeIcon("X:/xxx/xxx.exe", "X:/xxx/QQ.exe");    return 0;}

总结

希望大家看后能够对exe文件有所理解,其实它也只是一个有着对应格式的二进制文件而已,只是windows赋予它可执行权限而已。

此文仅作为技术讨论,请勿乱用,否则后果自负,与本人无关!

如果觉得我写的还不错的话,求赞,求关注哦!(^▽^)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值