如何从EXE中的python中提取128x128图标位图数据 [英] How to extract 128x128 icon bitmap data from EXE in python

查看:85
本文介绍了如何从EXE中的python中提取128x128图标位图数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用win32gui从Windows中的.exe文件提取图标.我发现了ExtractIconEx()和ExtractIcon()的功能.

I'm trying to extract icons from .exe files in windows using win32gui. I found the functionalities ExtractIconEx() and ExtractIcon().

我只能从上述功能中获得大小为32x32或16x16的图标.以下链接仅回答了提取32x32图像的方法.

I am able to get Icons of size 32x32 or 16x16 only from the above functionalities. the following link only answers way to extract 32x32 images. How to extract 32x32 icon bitmap data from EXE and convert it into a PIL Image object?

我需要提取大小为128x128或更大的图标.是否有关于如何从exe文件提取大尺寸图标的想法?

I need to extract icons of size either 128x128 or greater than that.Any ideas on how to extract the largersize icons from exe files?

推荐答案

我进行了一些研究并将其发布.如果您只想看一下结果代码(希望它就是您所要的),则可以在下面的水平规则"之后找到它.

I've made some researches and also post it. If you would like just see the result code (I hope it's exactly what you ask) you could find it after the "horizontal rule" below.

首先,我尝试使用下面的代码来确定文件资源中存储的图标大小:

First I tried to use the next code to determine what icon sizes stored in the resources of the file:

# Using LoadLibrary (rather than CreateFile) is required otherwise 
# LoadResource, FindResource and others will fail
PATH = ...  # Valid file path
hlib = win32api.LoadLibrary(PATH)

# This loop should print sizes of resources icons
icon_names = win32api.EnumResourceNames(hlib, win32con.RT_ICON)
for icon_name in icon_names:
    rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name)
    hicon = win32gui.CreateIconFromResource(rec, True)
    info = win32gui.GetIconInfo(hicon)
    bminfo = win32gui.GetObject(info[3])
    print("%2d: 0x%08X -> %d %d " % (icon_name, hicon, bminfo.bmWidth, bminfo.bmHeight))

虽然文件仅包含16x16和32x32像素的图标,但一切正常,这是Windows XP计算器的输出:

While file contains only 16x16 and 32x32 pixels icons everything will be Ok, here the output for Windows XP calculator:

 1: 0x0093051B -> 32 32
 2: 0x005B0513 -> 32 32
 3: 0x007004CB -> 32 32
 4: 0x002E04C9 -> 32 32
 5: 0x033A04C5 -> 32 32
 6: 0x00780487 -> 32 32
 7: 0x0052045D -> 32 32
 8: 0x055D053D -> 32 32

一旦我尝试了带有大图标的文件,就会遇到异常:

Once I've tried on file with large icon I've get the exception:

Traceback (most recent call last):
  File "extract_icon.py", line 50, in <module>
    hicon = win32gui.CreateIconFromResource(rec, True)
pywintypes.error: (0, 'CreateIconFromResource', 'No error message is available')

经过一些研究,我发现大图标不是以ico 格式存储,而是以png格式存储(对于我的情况).

After some researches I've figured out that large icon stored not in ico format but in png (for my case).

当然我不知道您的.exe文件到底是什么(它是内部文件),但是在分析了我位于PC中的几个.exe文件后,我发现图标大于32x32或.png文件最有可能表示16x16像素(您可以使用 PE Explorer 进行检查,已有试用版).

Of course I don't know what exactly your .exe file (it's internals) but after I've analyze several .exe files that I have located in my PC I've find out that icons large than 32x32 or 16x16 pixels most probably represented by mean of .png files (you could check it using e.g. PE Explorer, trial-version existed).

因此,要从资源中读取图像,我使用了

So to read image from resources I've used the guide on C++. The main goal here is to obtain pointer to the image resource real data and copy it to the Python buffer. And the finish step is save it to the file (I think you could translate it to PIL by yourself).

要读取大资源的完整代码:

# Use wchar_t function version (FindResourceW rather than FindResourceA)
from __future__ import unicode_literals

# pywin32 imports
import pywintypes
import win32ui
import win32gui
import win32con
import win32api
import win32file

# ctypes configuring. pywin32 has no a lot of required functions
import ctypes
import ctypes.util

# memcpy used to copy data from resource storage to our buffer
libc = ctypes.CDLL(ctypes.util.find_library('c'))
libc.memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]
libc.memcpy.restype = ctypes.c_char_p

# All Windows backslashes must be escaped to LoadLibrary worked correctly '\' -> '\\'
PATH = ...

# WARNING: Assumed that icon_name - VALID resource ID
# It can be determined in loop when enumerating resources:
# if exception at CreateIconFromResource raised than this code appropriate
# otherwise resource is standard icon and first code snippet can be used.
# If resources Id exactly known then it can be hardcoded as in this code
icon_name = 1

try:
    hlib = win32api.LoadLibrary(PATH)

    # This part almost identical to C++ 
    hResInfo = ctypes.windll.kernel32.FindResourceW(hlib, icon_name, win32con.RT_ICON)
    size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo)
    rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name)
    mem_pointer = ctypes.windll.kernel32.LockResource(rec)

    # And this is some differ (copy data to Python buffer)
    binary_data = (ctypes.c_ubyte * size)()
    libc.memcpy(binary_data, mem_pointer, size)

    # Save it
    with open("icon.png", "wb") as test_file:
        test_file.write(bytearray(binary_data))

except pywintypes.error as error:
    print "ERROR: %s" % error.strerror
    raise


已更新:

自动查找非图标资源并将其提取到名为"Resource_XX"的文件中的代码:

Code to automatically look up non-icon resources and extract it to file named "Resource_XX":

# Same IMPORT's as previously should be used

# All Windows backslashes must be escaped to LoadLibrary worked correctly '\' -> '\\'
PATH = ...


def extract(rec):
    try:
        hicon = win32gui.CreateIconFromResource(rec, True)
    except pywintypes.error as error:
        # Check on appropriate error
        if error.winerror != 6:
            raise

        print("Resource %2d isn't .ico, extract" % icon_name)
        # This part almost identical to C++ 
        hResInfo = ctypes.windll.kernel32.FindResourceW(hlib, icon_name, win32con.RT_ICON)
        size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo)
        mem_pointer = ctypes.windll.kernel32.LockResource(rec)

        # And this is some differ (copy data to Python buffer)
        binary_data = (ctypes.c_ubyte * size)()
        libc.memcpy(binary_data, mem_pointer, size)

        # Save it
        with open("Resource_%s.png" % icon_name, "wb") as extract_file:
            extract_file.write(bytearray(binary_data))
    else:
        info = win32gui.GetIconInfo(hicon)
        bminfo = win32gui.GetObject(info[3])
        print("Resource %2d is .ico: 0x%08X -> %d %d " % 
                  (icon_name, hicon, bminfo.bmWidth, bminfo.bmHeight))


try:
    hlib = win32api.LoadLibrary(PATH)
    icon_names = win32api.EnumResourceNames(hlib, win32con.RT_ICON)
    for icon_name in icon_names:
        rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name)
        extract(rec)

except pywintypes.error as error:
    print "ERROR: %s" % error.strerror
    raise

这篇关于如何从EXE中的python中提取128x128图标位图数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆