holley 发表于 2024-11-27 16:47:21

本帖最后由 holley 于 2024-11-27 16:48 编辑

借用老大的普适代码,让gpt弄了个GUI,右键图标不知道为什么不生效
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <WinAPIGdi.au3>
#include <WinAPIShellEx.au3>

Opt("MustDeclareVars", 1)

Func IsPEFile64($FilePath)
    Local $hFile = FileOpen($FilePath, 16)
    If $hFile = -1 Then Return "无法打开文件"

    Local $Bin = FileRead($hFile, 1024)
    FileClose($hFile)

    Local $aBin
    For $i = 0 To UBound($aBin) - 1
      $aBin[$i] = Number(BinaryMid($Bin, $i + 1, 1))
    Next

    Local $Index = $aBin + $aBin * 256 + $aBin * 65536 + $aBin * 16777216

    If $aBin <> 77 Or $aBin <> 90 Or $aBin[$Index] <> 80 Or $aBin[$Index + 1] <> 69 Then
      Return "非PE文件"
    EndIf

    If $aBin[$Index + 4] = 100 And $aBin[$Index + 5] = 134 Then
      Return "64位"
    EndIf

    Return "32位"
EndFunc

Func GetFileType($FilePath)
    Local $fileParts = StringSplit($FilePath, ".")
    If @error Then Return "未知文件类型"

    Local $fileExtension = StringLower($fileParts[$fileParts])
    If $fileExtension = "exe" Then
      Return "EXE"
    ElseIf $fileExtension = "dll" Then
      Return "DLL"
    Else
      Return "未知文件类型"
    EndIf
EndFunc

GUICreate("文件位数查看器", 800, 600)
Local $listView = GUICtrlCreateListView("文件名|文件路径|文件位数", 10, 10, 780, 550)
GUICtrlSendMsg($listView, $LVM_SETTEXTBKCOLOR, 0, 0xFFFFFF)
Local $contextMenu = GUICtrlCreateContextMenu($listView)
Local $menuItem1 = GUICtrlCreateMenuItem("添加文件", $contextMenu)
GUICtrlCreateMenuItem("", $contextMenu)
Local $menuItemExit = GUICtrlCreateMenuItem("退出", $contextMenu)

Local $hIcon1 = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 128)
Local $hIconExit = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 136)

_SetMenuItemIcon($contextMenu, $menuItem1, $hIcon1)
_SetMenuItemIcon($contextMenu, $menuItemExit, $hIconExit)

GUICtrlSetResizing($listView, 1)

Func AddFilesToList($listView)
    Local $FilePaths = FileOpenDialog("请选择一个或多个可执行文件或 DLL 文件", "", "可执行文件 (*.exe; *.dll)|所有文件 (*.*)", 1 + 4)

    If @error Then Return

    Local $fileArray = StringSplit($FilePaths, "|")
    Local $aItems
    Local $validItemCount = 0

    For $i = 1 To $fileArray
      Local $filePath = $fileArray[$i]
      If FileExists($filePath) And Not StringRegExp($filePath, "\.exe$|\.dll$", 0) Then
            ContinueLoop
      EndIf

      If FileExists($filePath) Then
            Local $fileName = StringRegExp($filePath, "[^\\]+$", 3)
            Local $fileType = GetFileType($filePath)
            Local $peStatus = IsPEFile64($filePath)

            $aItems[$validItemCount] = $fileName
            $aItems[$validItemCount] = _WinAPI_GetFullPathName($filePath)
            $aItems[$validItemCount] = $fileType & " (" & $peStatus & ")"
            $validItemCount += 1
      EndIf
    Next

    If $validItemCount > 0 Then
      ReDim $aItems[$validItemCount]
      _GUICtrlListView_AddArray($listView, $aItems)
      For $j = 0 To 2
            DllCall("user32.dll", "int", "SendMessage", "hwnd", $listView, "int", $LVM_SETCOLUMNWIDTH, "int", $j, "int", $LVSCW_AUTOSIZE)
      Next
    EndIf
EndFunc

AddFilesToList($listView)
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
            Exit
      Case $menuItem1
            AddFilesToList($listView)
      Case $menuItemExit
            Exit
    EndSwitch
WEnd

Func _SetMenuItemIcon($hMenu, $menuItem, $hIcon)
    Local $hBitmap = _ConvertIconToBitmap($hIcon)
    Local $tMii = DllStructCreate("uint;uint;ptr;ptr;uint;int;int;ptr;uint;uint")
    DllStructSetData($tMii, 1, BitOR(0x00000080, 0x00000010))
    DllStructSetData($tMii, 3, $hBitmap)
    DllStructSetData($tMii, 5, $menuItem)
    DllCall("user32.dll", "int", "SetMenuItemInfoW", "hwnd", $hMenu, "uint", $menuItem, "int", 0, "ptr", DllStructGetPtr($tMii))
EndFunc

Func _ConvertIconToBitmap($hIcon)
    Local $hDC = _WinAPI_GetDC(0)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 16, 16)
    Local $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    _WinAPI_DrawIconEx($hMemDC, 0, 0, $hIcon, 16, 16, 0, 0, 3)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_DeleteDC($hMemDC)
    Return $hBitmap
EndFunc

tubaba 发表于 2024-11-28 09:32:36

haijie1223 发表于 2024-11-23 11:03
凑个热闹

发哥的这个估计没几个人能看得懂,应该是解析PE文件的特征吧,我发个大家都能看得懂的

Func _GetArch($sFilePath)
        Local $hFile = FileOpen($sFilePath, 16)
        Local $bBinary = FileRead($hFile)
        FileClose($hFile)
        Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
        DllStructSetData($tBinary, 1, $bBinary) ; fill it
        Local $pPointer = DllStructGetPtr($tBinary)
        Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic;" & _
                        "word BytesOnLastPage;" & _
                        "word Pages;" & _
                        "word Relocations;" & _
                        "word SizeofHeader;" & _
                        "word MinimumExtra;" & _
                        "word MaximumExtra;" & _
                        "word SS;" & _
                        "word SP;" & _
                        "word Checksum;" & _
                        "word IP;" & _
                        "word CS;" & _
                        "word Relocation;" & _
                        "word Overlay;" & _
                        "char Reserved;" & _
                        "word OEMIdentifier;" & _
                        "word OEMInformation;" & _
                        "char Reserved2;" & _
                        "dword AddressOfNewExeHeader", _
                        $pPointer)
        $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header 移动到PE文件头
        Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
        If Not ($sMagic == "MZ") Then
                Return SetError(1, 0, 'unkown') ; MS-DOS header missing. MS-DOS标头丢失。
        EndIf
        Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
        ; Move pointer 移动指针
        $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure $tMAGE_NT_SIGNATURE结构的大小
        ; Check signature 检查签名
        If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
                Return SetError(2, 0, 'unkown') ; wrong signature. For PE image should be "PE\0\0" or 17744 dword.签名错误。对于PE,图像应为“PE\0\0”或17744双字。
        EndIf
        $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
        Local $tMagic = DllStructCreate("word Magic;", $pPointer)
        Local $iMagic = DllStructGetData($tMagic, 1)
        Select
                Case $iMagic = 267
                        Return 'x86'
                Case $iMagic = 523
                        Return 'x64'
                Case Else
                        Return 'unkown'
        EndSelect
EndFunc   ;==>_GetArch

haijie1223 发表于 2024-11-29 12:02:08

tubaba 发表于 2024-11-28 09:32
发哥的这个估计没几个人能看得懂,应该是解析PE文件的特征吧,我发个大家都能看得懂的




被大佬洞悉一切:face (24):
页: 1 [2]
查看完整版本: 判断dll或exe文件是32位还是64位的函数[已解决]