Skip to content

Commit 3783ef4

Browse files
committed
Fix crash in setting new resource table #1
1 parent 96ba920 commit 3783ef4

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

lib/libpe.ex

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,17 +263,26 @@ defmodule LibPE do
263263
LibPE.ResourceTable.parse(virtual_data, virtual_address)
264264

265265
nil ->
266-
nil
266+
%LibPE.ResourceTable{}
267267
end
268268
end
269269

270-
def set_resources(%LibPE{coff_sections: sections} = pe, resources = %LibPE.ResourceTable{}) do
270+
defp ensure_resource_section(%LibPE{coff_sections: sections} = pe) do
271+
idx = Enum.find_index(sections, fn %LibPE.Section{name: name} -> name == ".rsrc" end)
272+
273+
if idx == nil do
274+
%LibPE{pe | coff_sections: sections ++ [%LibPE.Section{name: ".rsrc"}]}
275+
else
276+
pe
277+
end
278+
end
279+
280+
def set_resources(pe, resources = %LibPE.ResourceTable{}) do
271281
# need to ensure that the virtual_address is up-to-date
272-
pe = update_layout(pe)
282+
%LibPE{coff_sections: sections} = pe = update_layout(ensure_resource_section(pe))
273283

274284
# now fetching and setting the resource
275285
idx = Enum.find_index(sections, fn %LibPE.Section{name: name} -> name == ".rsrc" end)
276-
277286
section = %LibPE.Section{virtual_address: virtual_address} = Enum.at(sections, idx)
278287
data = LibPE.ResourceTable.encode(resources, virtual_address)
279288
section = %LibPE.Section{section | virtual_data: data}

lib/libpe/section.ex

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@ defmodule LibPE.Section do
22
@moduledoc false
33
alias LibPE.Section
44

5-
defstruct [
6-
:name,
7-
:padding,
8-
:virtual_data,
9-
:virtual_size,
10-
:virtual_address,
11-
:raw_data,
12-
:size_of_raw_data,
13-
:pointer_to_raw_data,
14-
:pointer_to_relocations,
15-
:pointer_to_linenumbers,
16-
:number_of_relocations,
17-
:number_of_linenumbers,
18-
:flags
19-
]
5+
defstruct name: nil,
6+
padding: "\0",
7+
virtual_data: "",
8+
virtual_size: 0,
9+
virtual_address: 0,
10+
raw_data: "",
11+
size_of_raw_data: 0,
12+
pointer_to_raw_data: 0,
13+
pointer_to_relocations: 0,
14+
pointer_to_linenumbers: 0,
15+
number_of_relocations: 0,
16+
number_of_linenumbers: 0,
17+
flags: 0
2018

2119
def parse(rest, number, full_image) do
2220
List.duplicate(nil, number)

test/hello.exe

487 KB
Binary file not shown.

test/libpe_test.exs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ defmodule LibPETest do
4444
end
4545
end
4646

47+
test "set icon" do
48+
{:ok, pe} = LibPE.parse_file("test/hello.exe")
49+
50+
resource_table = LibPE.get_resources(pe)
51+
52+
data = File.read!("test/logo.ico")
53+
type = LibPE.ResourceTypes.encode("RT_ICON")
54+
resource_table = LibPE.ResourceTable.set_resource(resource_table, type, data)
55+
56+
raw =
57+
LibPE.set_resources(pe, resource_table)
58+
|> LibPE.update_layout()
59+
|> LibPE.update_checksum()
60+
|> LibPE.encode()
61+
62+
File.write!("test/hello-out.exe", raw)
63+
end
64+
4765
# defp tip(rsrc) do
4866
# clean_data(hd(rsrc.entries))
4967
# end

test/logo.ico

27.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)