Skip to content

Commit

Permalink
feat: support parse png icon from pe file
Browse files Browse the repository at this point in the history
  • Loading branch information
dafenghuang committed Feb 12, 2025
1 parent ed7fd35 commit d4273cc
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
46 changes: 46 additions & 0 deletions icon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package pe

import (
"bytes"
"errors"
"image/png"
)

func (pe *File) ParsePngIcon() ([]byte, error) {
var iconEntry *ResourceDirectoryEntry
for _, e := range pe.Resources.Entries {
if e.ID != RTIcon {
continue
}
if len(e.Directory.Entries) == 0 {
return nil, errors.New("no entries found in resource directory")
}
iconEntry = &e
break
}
if iconEntry == nil {
return nil, errors.New("no icon found in resource directory")
}

for _, iconItem := range iconEntry.Directory.Entries {
if len(iconItem.Directory.Entries) == 0 {
continue
}

iconData := &iconItem.Directory.Entries[0]

offset, size := pe.GetOffsetFromRva(iconData.Data.Struct.OffsetToData), iconData.Data.Struct.Size

b, err := pe.ReadBytesAtOffset(offset, size)
if err != nil {
return nil, err
}

_, err = png.Decode(bytes.NewBuffer(b))
if err != nil {
continue
}
return b, nil
}
return nil, errors.New("no valid png icon found")
}
30 changes: 30 additions & 0 deletions icon_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pe

import (
"os"
"testing"
)

func Test_ParseIcon(t *testing.T) {
file, err := New("/Users/dafenghuang/Downloads/WeChatSetup.exe", &Options{})
if err != nil {
t.Errorf("open file failed, err %v", err)
return
}

err = file.Parse()
if err != nil {
t.Errorf("parse file failed, err %v", err)
return
}

iconBytes, err := file.ParsePngIcon()
if err != nil {
t.Errorf("parse icon failed, err %v", err)
return
}

os.WriteFile("test.png", iconBytes, 0644)

t.Logf("length %d", len(iconBytes))
}

0 comments on commit d4273cc

Please sign in to comment.