Posted on August 14, 2021 (珠海)编程
同样的代码发布三个版本,不同的描述信息,不同的签名,太麻烦!
构建一个,拷贝一下,然后手工改 PE 文件描述信息,手工打签名。麻烦! 构建两次,选择不同的构建配置。时间!时间!pecopy.exe 解决你的烦恼!自动修改文件描述信息!下载地址:https://sunocean.life/tools/https://sunocean.life/tools/pecopy.exe
Resource Hacker图形界面版本。
早期版本:http://www.rpi.net.au/~ajohnson/resourcehacker 后期版本:http://www.angusj.com/resourcehacker/pecopy.exepecopy.exe 解决你的烦恼, 通过配置构建生成后事件,同时完成拷贝和修改描述信息 ,最后签名。
一气呵成,不用介入。 避免构建多次,崩溃点都变了。使用文档:
usage: "pecopy.exe" [-h] [-mcn COMPANYNAME] [-mfd FILEDESCRIPTION] [-mvc FILEVERSION] [-min INTERNALNAME] [-mlc LEGALCOPYRIGHT] [-mof ORIGINALFILENAME] [-mpn PRODUCTNAME] [-mpv PRODUCTVERSION] [-icon ICONFILE] [-mask ICONMASK] [-mcp CODEPAGE] -in INPUTFILE -out OUTPUTFILE [-debug DEBUG]optional arguments: -h, --helpshow this help message and exit -mcn COMPANYNAME, --CompanyName COMPANYNAME示例:酷哦软件科技有限公司 -mfd FILEDESCRIPTION, --FileDescription FILEDESCRIPTION示例:酷哦工具箱好帮手 -mvc FILEVERSION, --FileVersion FILEVERSION示例:2021,08,05,123 -min INTERNALNAME, --InternalName INTERNALNAME示例:toolhelper -mlc LEGALCOPYRIGHT, --LegalCopyright LEGALCOPYRIGHT示例:酷哦软件科技有限公司 -mof ORIGINALFILENAME, --OriginalFilename ORIGINALFILENAME示例:tool.exe -mpn PRODUCTNAME, --ProductName PRODUCTNAME示例:酷哦工具箱 -mpv PRODUCTVERSION, --ProductVersion PRODUCTVERSION示例:1,0,0,123 -icon ICONFILE, --IconFile ICONFILE示例:mainicon.ico -mask ICONMASK, --IconMask ICONMASK示例:ICONGROUP,107,2052(同时多个用半角分号隔开) -mcp CODEPAGE, --CodePage CODEPAGE示例:65001 -in INPUTFILE, --InputFile INPUTFILE示例:tool.exe -out OUTPUTFILE, --OutputFile OUTPUTFILE示例:shsign\tool.exe -debug DEBUG, --Debug DEBUG示例 1 修改版权C:\test>"pecopy.exe" -in "fastvc.exe" \ -out "shsign\fastvc.exe" \ --LegalCopyright "版权测试"构建机构建完成,直接上去拿改好并签好名的文件即可。
示例 2 修改描述信息"pecopy.exe" -in "$(TargetDir)\test.dll" \ -out "$(TargetDir)\shsign\test.dll" \ -mpn "TEST 模块" \ -mcn "哇哦软件科技有限公司" \ -mfd "哇哦模块" \ -mlc "哇哦软件科技有限公司"已知缺陷:语言都会变成中性。这个应该影响不大。如果此方案有帮助到项目组,记得豹趣积分打到 quanhai 账上。^_^
示例 3 修改图标先要用 resourcehacker 看好要替换图标的 mask 是多少,比如:ICONGROUP,107,2052 。
"pecopy.exe" -in "pecopy.exe" \ -out "..\..\dist\pecopy.exe" \ -icon "..\image\icon\iconall\shitou.ico" \ -mask ICONGROUP,107,2052 微软图标格式文档:Icons png2ico 代码工具:http://www.winterdrache.de/freeware/png2ico/ png2ico-win-2002-12-08.zip (90K) png2ico-src-2002-12-08.tar.gz (26K)微软图标设计文档:Icons (Design basics) C++ 如何将 Icon 转成 Bitmap,保留 Alpha 通道。http://www.noobyard.com/article/p-odzsipgl-hw.html 默认图标貌似是:ICONGROUP,MAINICON,0 。配置构建生成后任务 把 pecopy.exe 入库到工程合适目录(建议入到 git,这样本机和构建机可以同时完成 pecopy)。 把 tempdir 添加到根 .gitignore 。 配置生成后事件(一般根据工程当前的工程目录然后找到 pecopy.exe 的相对路径):"pecopy.exe" -in "$(TargetDir)fastvc.exe" \ -out "$(TargetDir)shsign\fastvc.exe" \ --LegalCopyright "版权测试"下载地址:https://sunocean.life/tools/https://sunocean.life/tools/pecopy.exe
其它2022-04-25 制作新版本,生成的文件会自动移除签名。
如果存在签名,修改描述前,最后用 VS 自带工具 signtool.exe 移除签名先。
signtool.exe remove /s target.dllPE 文件的校验和(CheckSum)note IMAGE_OPTIONAL_HEADER.CheckSum 为一个 DWORD(64 位下也是 DWORD)型的校验值,用于检查 PE 文件的完整性,在一些内核模式驱动及 DLL 中,该值必须是存在且正确的。
校验值的计算很简单:
将 IMAGE_OPTIONAL_HEADER.CheckSum 清 0(因为这部分在文件中也是有值的,计算时得去掉) 以 WORD 为单位对数据块进行累加,记住要用 adc 指令而不是 add。 将累加和加上文件的长度(还是用 adc)将计算结果与 IMAGE_OPTIONAL_HEADER.CheckSum 进行比较,不相等则说明文件被修改过或不完整。
ImageHlp Image Modification Functionshttps://docs.microsoft.com/zh-cn/windows/win32/debug/imagehlp-functions?redirectedfrom=MSDN
#include #include#pragma comment(lib, "ImageHlp.lib")void main(){DWORD HeaderCheckSum = 0;// PE 头里的校验值DWORD CheckSum = 0; // 计算下来的校验值MapFileAndCheckSum(L"C:\\Users\\q4692\\Desktop\\ObjectHook.sys", &HeaderCheckSum, &CheckSum);if (CheckSum == HeaderCheckSum){MessageBox(NULL, L"相等", NULL, 0);}}uint32_t calc_checksum(uint32_t checksum, void *data, int length) {if (length && data != nullptr) {uint32_t sum = 0;do {sum = *(uint16_t *)data + checksum;checksum = (uint16_t)sum + (sum >> 16);data = (char *)data + 2;} while (--length);}return checksum + (checksum >> 16);}uint32_t generate_pe_checksum(void *file_base, uint32_t file_size) {uint32_t file_checksum = 0;PIMAGE_NT_HEADERS nt_headers = ImageNtHeader(file_base);if (nt_headers) {uint32_t header_size = (uintptr_t)nt_headers - (uintptr_t)file_base +((uintptr_t)&nt_headers->OptionalHeader.CheckSum -(uintptr_t)nt_headers);uint32_t remain_size = (file_size - header_size - 4) >> 1;void *remain = &nt_headers->OptionalHeader.Subsystem;uint32_t header_checksum = calc_checksum(0, file_base, header_size >> 1);file_checksum = calc_checksum(header_checksum, remain, remain_size);if (file_size & 1){file_checksum += (uint16_t)*((char *)file_base + file_size - 1);}}return (file_size + file_checksum);}from pyinstaller
def set_exe_checksum(exe_path):"""Set executable's checksum in its metadata.This optional checksum is supposed to protect the executable againstcorruption but some anti-viral software have taken to flagging anythingwithout it set correctly as malware. See issue #5579."""import pefilepe = pefile.PE(exe_path)pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()pe.close()pe.write(exe_path)# You can use pe.verify_checksum() to verify that it is correct# https://github.com/pyinstaller/pyinstaller/blob/master/PyInstaller/utils/win32/winutils.py# https://github.com/pyinstaller/pyinstaller/blob/master/tests/functional/test_basic.py# https://github.com/pyinstaller/pyinstaller/blob/master/PyInstaller/building/api.py# Step 3: post-processingif is_win:# Set checksum to appease antiviral software. Also set build timestamp to current time to increase entropy# (but honor SOURCE_DATE_EPOCH environment variable for reproducible builds).logger.info("Fixing EXE headers")build_timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))winutils.set_exe_build_timestamp(build_name, build_timestamp)winutils.update_exe_pe_checksum(build_name)def fixup_exe_headers(exe_path, timestamp=None):"""Set executable's checksum and build timestamp in its headers.This optional checksum is supposed to protect the executable against corruption but some anti-viral software havetaken to flagging anything without it set correctly as malware. See issue #5579."""import pefilepe = pefile.PE(exe_path, fast_load=False) # full load because we need all headers# Set build timestamp.# See: https://0xc0decafe.com/malware-analyst-guide-to-pe-timestampsif timestamp is not None:timestamp = int(timestamp)# Set timestamp field in FILE_HEADERpe.FILE_HEADER.TimeDateStamp = timestamp# MSVC-compiled executables contain (at least?) one DIRECTORY_ENTRY_DEBUG entry that also contains timestamp# with same value as set in FILE_HEADER. So modify that as well, as long as it is set.debug_entries = getattr(pe, 'DIRECTORY_ENTRY_DEBUG', [])for debug_entry in debug_entries:if debug_entry.struct.TimeDateStamp:debug_entry.struct.TimeDateStamp = timestamp# Set PE checksumpe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()pe.close()pe.write(exe_path)如何移除已经签章的驱动程式https://steward-fu.github.io/website/driver/wdm/remove_sign.htm
#include #include #include #pragma comment(lib, "Imagehlp.lib")int main(int argc, char** argv){HANDLE hFile;hFile = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);ImageRemoveCertificate(hFile, 0);CloseHandle(hFile);return 0;}C/C++ 实现 PE 文件特征码识别 #include #include // 函数 MakeSureDirectoryPathExists() 所需头文件和 lib 库#include #pragma comment(lib, "imagehlp.lib")int main(){// 在 C 盘创建名为“test”文件夹,并在 test 文件夹下再创建名为“1203”的文件夹。int flag; // 保存返回值。如果目录存在,返回 TRUE;如果不存在但全部路径创建成功,返回 TRUE;如果不存在且创建失败,返回 FALSE。flag = MakeSureDirectoryPathExists("E:\\test\\1203\\");std::cout