2014-04-24 1 views
6

Ich versuche, Symbole aus .exe-Dateien in Windows mit Win32gui extrahieren. Ich habe die Funktionalitäten ExtractIconEx() und ExtractIcon() gefunden.Wie extrahiert man 128x128 Symbol Bitmap-Daten von EXE in Python

Ich bin in der Lage, Icons der Größe 32x32 oder 16x16 nur von den oben genannten Funktionen zu erhalten. Der folgende Link beantwortet nur Wege, um 32x32 Bilder zu extrahieren. How to extract 32x32 icon bitmap data from EXE and convert it into a PIL Image object?

Ich muss Symbole der Größe entweder 128x128 oder größer als das extrahieren.Any Ideen, wie die Largersize-Symbole aus EXE-Dateien extrahieren?

Antwort

8

Ich habe einige Recherchen gemacht und auch gepostet. Wenn Sie nur den Ergebniscode sehen möchten (ich hoffe, es ist genau das, was Sie fragen), können Sie es nach der "horizontalen Regel" unten finden.

Zuerst habe ich versucht, den nächsten Code zu verwenden, um festzustellen, welche Symbolgrößen in den Ressourcen der Datei gespeichert:

# 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)) 

Während Datei nur 16x16 und 32x32 Pixel enthält Symbole wird alles in Ordnung sein, hier die Ausgabe für Windows XP-Rechner:

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 

Einmal hat mich mit großen Symbol auf Datei habe ich versucht, die Ausnahme erhalten habe:

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') 

Nach einigen Recherchen habe ich herausgefunden, dass große Symbol nicht in ico Format gespeichert ist, aber in png (für meinen Fall).

Natürlich weiß ich nicht, was genau Ihre .exe-Datei (es Interna), aber nachdem ich .exe Dateien analysieren mehrere haben, die ich in meinem PC gefunden haben, habe ich erfahren, dass große Symbole als 32x32 oder 16x16 Pixel meisten wahrscheinlich dargestellt durch .png Dateien (Sie könnten es überprüfen mit z. B. PE Explorer, Testversion existiert).

Also, um Bild von Ressourcen zu lesen Ich habe die guide auf C++ verwendet. Das Hauptziel besteht darin, einen Zeiger auf die realen Daten der Bildressource zu erhalten und sie in den Python-Puffer zu kopieren. Und der letzte Schritt ist es in die Datei zu speichern (ich denke, du könntest es selbst in PIL übersetzen).


COMPLETE CODE LARGE RESOURCE ZU LESEN:

# 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 

AKTUALISIERT:

-Code automatisch nicht-Symbol Ressourcen zu suchen und extrahieren ", um Datei mit dem Namen 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 
+0

habe ich versucht, den Code Einstellung von PATH = „C Einstellung: \ Programme \ VideoLAN \ VLC \ vlc.exe " Es gibt leere Bilder, ich habe mehrere verschiedene Dateien ausprobiert. Fehle ich irgendetwas? – sj7

+0

Ich habe versucht auf http://www.splashtop.com/ funktioniert es für mich. Gibt es eine Ausnahme oder nur leere Datei (kann Backslash sein maskiert)? Und sind Sie sicher, dass Sie gültige Ressource-ID (icon_name) definiert? Ich versuche jetzt auf VLC. Ich werde die Antwort so bald wie möglich aktualisieren. – Alexei

+0

@ sj7 Ich habe es getestet funktioniert für mich auf vlc: http : //get.videolan.org/vlc/2.1.3/win32/vlc-2.1.3-win32.zip Zuerst muss ich Backslashes entziffern (sonst funktioniert LoadLibrary nicht) und die zweite rechte Ressource (png Icon) hat id 3. 'PATH =" c: \\ vlc-2.1.3 \\ vlc.exe "' und 'icon_name = 3'. Ist das Hilfe? – Alexei

1

Ich möchte das Standardsymbol und die verschiedenen Größen extrahieren. Basierend auf Alexei's Antwort und Audionautics 'Antwort im 32x32 Thread, hier ist der Code.

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

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

# 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 

# patch FindResourceW, ctypes.windll.kernel32.SizeofResource 
FindResourceW = ctypes.windll.kernel32.FindResourceW 
FindResourceW.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] 
FindResourceW.restype = ctypes.c_void_p 
SizeofResource = ctypes.windll.kernel32.SizeofResource 
SizeofResource.argtypes = [ctypes.c_void_p, ctypes.c_void_p] 
SizeofResource.restype = ctypes.c_size_t 

# Using LoadLibrary (rather than CreateFile) is required otherwise 
# LoadResource, FindResource and others will fail 
PATH = "C:\\Program Files\\Internet Explorer\\iexplore.exe" 
hlib = win32api.LoadLibraryEx(PATH, 0, 2) 

# get icon groups, default is the first group 
icon_groups = win32api.EnumResourceNames(hlib, win32con.RT_GROUP_ICON) 
group_name = icon_groups[0] 
print group_name 
hRes = win32api.LoadResource(hlib, win32con.RT_GROUP_ICON, group_name) 
mem_icon_dir = ctypes.windll.kernel32.LockResource(hRes) 

# 32 bits color; 16 and 256 colors are too old 
# iterate through the common sizes 
icon_sizes = (16, 24, 32, 48, 96, 256) 
for icon_size in icon_sizes: 
    icon_name = ctypes.windll.user32.LookupIconIdFromDirectoryEx(mem_icon_dir, True, icon_size, icon_size, 0x00000000); 
    hResInfo = FindResourceW(hlib, icon_name, win32con.RT_ICON) 
    size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo) 
    rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) 
    mem_icon = 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_icon, size)  
    hIconRet = ctypes.windll.user32.CreateIconFromResourceEx(binary_data, size, True, 0x00030000, 0, 0, 0x00000000); 
    info = win32gui.GetIconInfo(hIconRet) 
    bminfo = win32gui.GetObject(info[4]) 

    # generate bitmap by drawing the icon 
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) 
    hbmp = win32ui.CreateBitmap() 
    hbmp.CreateCompatibleBitmap(hdc, bminfo.bmWidth, bminfo.bmHeight) 
    hcdc = hdc.CreateCompatibleDC() 
    hcdc.SelectObject(hbmp) 
    win32gui.DrawIconEx(hcdc.GetHandleOutput(), 0, 0, hIconRet, bminfo.bmWidth, bminfo.bmHeight, 0, 0, 0x0003) 
    hbmp.SaveBitmapFile(hcdc, "icon-%03dx%03d-%05d-%03d.bmp" % (bminfo.bmWidth, bminfo.bmHeight, group_name, icon_name)) 
    win32gui.DestroyIcon(hIconRet) 
Verwandte Themen