|
|
本帖最后由 红毛樱木 于 2025-12-28 05:03 编辑
- //LOGS * %&CurDir%\log.log
- ENVI^ ENVIMODE=1
- SET$ NL=0d 0a
- // PECMD2012 内部本身就是宽字符Unicode。路径\\可以直接写真实路径\,自动转义。
- //ENVI &exePath=%&CurDir%\Photoshop.exe
- //ENVI &exePath=%&CurDir%\sti_ci.dll
- ENVI &exePath=%&SystemROOT%\explorer.exe
- //ENVI &exePath=%&CurDir%\explorerx64.exe
- //ENVI &exePath=%&CurDir%\explorerx86.exe
- //ENVI &exePath=%&CurDir%\explorer.exe
- CALL GetFirstIconGroupID "%&exePath%" &iconId
- MESS. 是否获取成功(0为失败,1为成功):%&error%%&NL%%&NL%第一个图标ID: %&iconId%@
- _SUB GetFirstIconGroupID
- EXIT= 0
- ENVI-ret %~2=0
- ENVI &&exePath=%~1
- ENVI &&GENERIC_READ=0x80000000
- ENVI &&FILE_SHARE_READ=0x00000001
- ENVI &&OPEN_EXISTING=3
- ENVI &&INVALID_HANDLE_VALUE=-1
- CALL$--qd --ret:&&hFile Kernel32.dll,CreateFileW,$%&exePath%,#%&GENERIC_READ%,#%&FILE_SHARE_READ%,#0,#%&OPEN_EXISTING%,#0,#0 // C中的NULL就是0,在PECMD中用数值 #0
- IFEX #%&hFile%=%&INVALID_HANDLE_VALUE%,
- {*
- ENVI-ret %~2=0
- EXIT _SUB
- }
- CALL$--qd --ret:&&fileSize Kernel32.dll,GetFileSize,#%&hFile%,#0
- ENVI &&PAGE_READONLY=0x02
- CALL$--qd --ret:&&hMap Kernel32.dll,CreateFileMappingW,#%&hFile%,#0,#%&PAGE_READONLY%,#0,#%&fileSize%,0 //CreateFileMapping 要用实际的 CreateFileMappingW
- ENVI &&FILE_MAP_READ=0x0004
- CALL$--qd --16 --ret:&&pBase Kernel32.dll,MapViewOfFile,#%&hMap%,#%&FILE_MAP_READ%,#0,#0,#0
- //MESS. %&pBase%@&pBase
- IFEX #%&pBase%=0,
- {*
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- ENVI-ret %~2=0
- EXIT _SUB
- }
- // PIMAGE_DOS_HEADER 的结构体 IMAGE_DOS_HEADER 64字节
- //SET$# &dos=*64 0
- SET-mkfixdummy &dos=%&pBase%@0;*64
- SET?longs dos=&&dos.e_lfanew:60
- //MESS. %&dos.e_lfanew%@&dos.e_lfanew
- // PIMAGE_NT_HEADERS 的结构体(64位为 IMAGE_NT_HEADERS64 大小 264字节)(32位为 IMAGE_NT_HEADERS32 大小 248字节)
- IFEX #0, //判断错误,应该直接判断PE文件头是32位还是64位。
- {*
- IFEX #%&bX64%=3,
- {*
- //SET$# &nt=*264 0
- SET-mkfixdummy &nt=(%&pBase%+%&dos.e_lfanew%)@0;*264
- }!
- {*
- //SET$# &nt=*248 0
- SET-mkfixdummy &nt=(%&pBase%+%&dos.e_lfanew%)@0;*248
- }
- }
- ENVI &&IMAGE_NT_OPTIONAL_HDR32_MAGIC=0x10b //32位
- ENVI &&IMAGE_NT_OPTIONAL_HDR64_MAGIC=0x20b //64位
- SET?short (%&pBase%+%&dos.e_lfanew%)=&&nt.OptionalHeader.Magic:24
- //MESS. %&nt.OptionalHeader.Magic%@&nt.OptionalHeader.Magic
- IFEX #%&nt.OptionalHeader.Magic%=%&IMAGE_NT_OPTIONAL_HDR32_MAGIC%,
- {*
- SET-mkfixdummy &nt=(%&pBase%+%&dos.e_lfanew%)@0;*248
- }!
- {*
- IFEX #%&nt.OptionalHeader.Magic%=%&IMAGE_NT_OPTIONAL_HDR64_MAGIC%,
- {*
- SET-mkfixdummy &nt=(%&pBase%+%&dos.e_lfanew%)@0;*264
- }!
- {*
- CALL$--qd --bool --ret:&&UnmapViewOfFileRet Kernel32.dll,UnmapViewOfFile,#%&pBase%;
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- ENVI-ret %~2=0
- EXIT _SUB
- }
- }
- //GETF &nt,0#*,&&nt_Hex
- //MESS. %&nt_Hex%@&nt_Hex
- SET?long nt=&&nt.Signature:0
- //MESS. %&nt.Signature%@&nt.Signature
- ENVI &&IMAGE_NT_SIGNATURE=0x00004550 // PE00
- IFEX #%&nt.Signature%<>%&IMAGE_NT_SIGNATURE%,
- {*
- CALL$--qd --bool --ret:&&UnmapViewOfFileRet Kernel32.dll,UnmapViewOfFile,#%&pBase%;
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- ENVI-ret %~2=0
- EXIT _SUB
- }
-
- // 定位资源目录
- // auto& resDir = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
- ENVI &&IMAGE_DIRECTORY_ENTRY_RESOURCE=2 // Resource Directory
- //ENVI &&IMAGE_DIRECTORY_ENTRY_RESOURCE=0 // 测试
- IFEX #0,
- {*
- IFEX #%&bX64%=3,
- {*
- SET-mkfixdummy &resDir=&nt@(4+20+112+(8*%&IMAGE_DIRECTORY_ENTRY_RESOURCE%));*8
- }!
- {*
- SET-mkfixdummy &resDir=&nt@(4+20+96+(8*%&IMAGE_DIRECTORY_ENTRY_RESOURCE%));*8
- }
- }
- IFEX #%&nt.OptionalHeader.Magic%=%&IMAGE_NT_OPTIONAL_HDR32_MAGIC%,
- {*
- SET-mkfixdummy &resDir=&nt@(4+20+96+(8*%&IMAGE_DIRECTORY_ENTRY_RESOURCE%));*8
- }!
- {*
- IFEX #%&nt.OptionalHeader.Magic%=%&IMAGE_NT_OPTIONAL_HDR64_MAGIC%,
- {*
- SET-mkfixdummy &resDir=&nt@(4+20+112+(8*%&IMAGE_DIRECTORY_ENTRY_RESOURCE%));*8
- }!
- {*
- CALL$--qd --bool --ret:&&UnmapViewOfFileRet Kernel32.dll,UnmapViewOfFile,#%&pBase%;
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- ENVI-ret %~2=0
- EXIT _SUB
- }
- }
- //GETF &resDir,0#*,&&resDir_Hex
- //MESS. %&resDir_Hex%@&resDir_Hex
- SET?long resDir=&&resDir.VirtualAddress:0
- //MESS. %&resDir.VirtualAddress%@&resDir.VirtualAddress
-
- // 定位资源节(.rsrc)
- ENVI &&i=0
- SET?shorts nt=&&nt.FileHeader.NumberOfSections:(4+2) //WORD 2 字节,用short和wchar都可以
- //MESS. %&nt.FileHeader.NumberOfSections%@&nt.FileHeader.NumberOfSections
- SET?shorts nt=&&nt.FileHeader.SizeOfOptionalHeader:(4+2+2+4+4+4)
- //MESS. %&nt.FileHeader.SizeOfOptionalHeader%@&nt.FileHeader.SizeOfOptionalHeader
- //SET-mkfixdummy §ion=&nt
-
- LOOP #%&i%<%&nt.FileHeader.NumberOfSections%,
- {*
- //#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)(ntheader) + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + ((ntheader))->FileHeader.SizeOfOptionalHeader ))
- SET-mkfixdummy §ion=(%&pBase%+%&dos.e_lfanew%+(4+20+%&nt.FileHeader.SizeOfOptionalHeader%))@(40*%&i%);*40 // 相当于 section++
- //GETF §ion,0#40,&§ion_Hex
- //MESS. %§ion_Hex%@§ion_Hex
- SET?long section=&§ion.VirtualAddress:12
- //MESS. §ion.VirtualAddress:%§ion.VirtualAddress%@%&i%
- SET?long section=&§ion.Misc.VirtualSize:8
- //MESS. IFEX #[ ( %&resDir.VirtualAddress% >= %§ion.VirtualAddress% ) & ( %&resDir.VirtualAddress% < ( %§ion.VirtualAddress% + %§ion.Misc.VirtualSize% ) ) ],@%&i%
- //IFEX #[ ( %&resDir.VirtualAddress% >= %§ion.VirtualAddress% ) & ( %&resDir.VirtualAddress% < ( %§ion.VirtualAddress% + %§ion.Misc.VirtualSize% ) ) ], // IFEX 存在BUG,不能这样嵌套使用,先算出来吧。
- IFEX #%&resDir.VirtualAddress% >= %§ion.VirtualAddress%,
- {*
- CALC &&Fix=%§ion.VirtualAddress% + %§ion.Misc.VirtualSize%
- IFEX #%&resDir.VirtualAddress% < %&Fix%,
- {*
- EXIT LOOP
- }
- }
- CALC #&i=%&i% + 1
- }
- // 计算资源目录在文件中的实际偏移
- SET?long section=&§ion.PointerToRawData:20
- CALC #&&resOffset=%&resDir.VirtualAddress% - %§ion.VirtualAddress% + %§ion.PointerToRawData%
- //MESS. %&resOffset%<&i:%&i%><CALC #&&resOffset=%&resDir.VirtualAddress% - %§ion.VirtualAddress% + %§ion.PointerToRawData%>@&resOffset
- SET-mkfixdummy &rootDir=(%&pBase%+%&resOffset%)@0;*16
- SET?short rootDir=&&rootDir.NumberOfIdEntries:(4+4+2+2+2)
- //MESS. %&rootDir.NumberOfIdEntries%@&rootDir.NumberOfIdEntries
-
- // 遍历资源类型,找到 RT_GROUP_ICON(ID=14)
- //SET-mkfixdummy &typeEntry=(%&pBase%+%&resOffset%)@16;*8
- //GETF &typeEntry,0#8,&&typeEntry_Hex
- //MESS. %&typeEntry_Hex%@&typeEntry_Hex
-
- ENVI &&i=0
- LOOP #%&i%<%&rootDir.NumberOfIdEntries%,
- {*
- SET-mkfixdummy &typeEntry=(%&pBase%+%&resOffset%)@(16+(8*%&i%));*8
- SET?short typeEntry=&&typeEntry.Id:0
- //MESS. %&typeEntry.Id%@%&i%
- IFEX #%&typeEntry.Id%=14, // RT_GROUP_ICON = 14
- {*
- // 获取第一个图标ID(进入ID目录的第一个条目)
- SET?long typeEntry=&&typeEntry.OffsetToDirectory:4
- CALC #&typeEntry.OffsetToDirectory=%&typeEntry.OffsetToDirectory% & 0x7FFFFFFF
- SET-mkfixdummy &iconDir=(%&pBase%+%&resOffset%)@%&typeEntry.OffsetToDirectory%;*16
- SET-mkfixdummy &iconIdEntry=(%&pBase%+%&resOffset%)@(%&typeEntry.OffsetToDirectory%+16);*8
- SET?long iconIdEntry=&&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME:0
- //CALC &&NameIsString=shr(%&iconIdEntry?long%,31) // 可以
- CALC #&&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME.NameIsString=shr(%&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME%,31) & 0x1
- //MESS. %&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME.NameIsString%@
- IFEX #%&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME.NameIsString%=1, //判断是否为字符串
- {*
- //CALC -base=16 &&NameOffset=shl(%&iconIdEntry?long%,1) // 不行
- //CALC -base=16 &&NameOffset=%&iconIdEntry?long% & 0x7FFFFFFF // 可以
- CALC -base=16 &&NameOffset=%&iconIdEntry.DUMMYUNIONNAME.DUMMYSTRUCTNAME% & 0x7FFFFFFF // 可以
- SET?short (%&pBase%+%&resOffset%+%&NameOffset%)=&&pIMAGE_RESOURCE_DIR_STRING_U.Length
- //SET-make &pIMAGE_RESOURCE_DIR_STRING_U.NameString=(%&pBase%+%&resOffset%+%&NameOffset%)@2;$%&pIMAGE_RESOURCE_DIR_STRING_U.Length% 或者下面的更直接
- SET-make &pIMAGE_RESOURCE_DIR_STRING_U.NameString=(%&pBase%+%&resOffset%+%&NameOffset%+2);$%&pIMAGE_RESOURCE_DIR_STRING_U.Length%
- ENVI-ret~ %~2=&pIMAGE_RESOURCE_DIR_STRING_U.NameString
- EXIT= 1
- }!
- {*
- SET?short iconIdEntry=&&iconIdEntry.Id:0
- CALC &&firstIconId=%&iconIdEntry.Id% // 不知道源码这里为什么用DWORD计算WORD
- ENVI-ret~ %~2=&firstIconId
- EXIT= 1
- }
- //MESS. %&firstIconId%@
-
- CALL$--qd --bool --ret:&&UnmapViewOfFileRet Kernel32.dll,UnmapViewOfFile,#%&pBase%;
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- //ENVI-ret~ %~2=&firstIconId
- EXIT _SUB
- }
- CALC #&i=%&i% + 1
- }
- CALL$--qd --bool --ret:&&UnmapViewOfFileRet Kernel32.dll,UnmapViewOfFile,#%&pBase%;
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hMap%
- CALL$--qd --bool --ret:&&CloseHandleRet Kernel32.dll,CloseHandle,#%&hFile%
- ENVI-ret %~2=0
- _END
复制代码
试试看。应该可以了。最近修行的快成仙了
|
|