mirror of
https://github.com/malwarefrank/dnfile
synced 2026-06-08 15:39:09 +00:00
77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
import fixtures
|
|
|
|
import dnfile
|
|
from dnfile.utils import LazyList
|
|
from dnfile.mdtable import TypeRefRow, MemberRefRow
|
|
|
|
|
|
def test_lazy_loading():
|
|
path = fixtures.get_data_path_by_name("hello-world.exe")
|
|
|
|
dn = dnfile.dnPE(path, clr_lazy_load=True)
|
|
dn.parse_data_directories()
|
|
|
|
assert dn.net
|
|
assert dn.net.mdtables
|
|
|
|
assert dn.net.mdtables.MemberRef
|
|
assert isinstance(dn.net.mdtables.MemberRef.rows, LazyList)
|
|
|
|
# LazyList is initialized as a list of `None`.
|
|
# list.__getitem__ bypasses lazy loading.
|
|
assert list.__getitem__(dn.net.mdtables.MemberRef.rows, 1) is None
|
|
memref_row = dn.net.mdtables.MemberRef.rows[1]
|
|
assert isinstance(memref_row, MemberRefRow)
|
|
|
|
assert memref_row.Name
|
|
# __dict__ access bypasses lazy loading.
|
|
assert "Signature" not in memref_row.__dict__
|
|
assert memref_row.Signature
|
|
assert "Signature" in memref_row.__dict__
|
|
|
|
# The first item of the rows list is a special case, because it is
|
|
# initialized without data before lazy-loading is setup.
|
|
# Make sure that it behaves the same as any other row when accessed.
|
|
# We can also verify that slicing works, since it too needs to be
|
|
# handled appropriately.
|
|
typeref_row = dn.net.mdtables.TypeRef.rows[:3:2][0]
|
|
assert isinstance(typeref_row, TypeRefRow)
|
|
|
|
assert "ResolutionScope" not in typeref_row.__dict__
|
|
# TypeRefRow.Class should trigger a full load of all tables and rows.
|
|
assert memref_row.Class
|
|
# This should not have been lazy-loaded, but will still have been loaded
|
|
# because of accessing the Class attribute.
|
|
assert "ResolutionScope" in typeref_row.__dict__
|
|
|
|
# _resources is the underlying lazy-loaded field for the ClrResource list.
|
|
assert dn.net._resources is None
|
|
assert dn.net.resources is not None
|
|
assert dn.net._resources is not None
|
|
|
|
|
|
def test_non_lazy_loading():
|
|
path = fixtures.get_data_path_by_name("hello-world.exe")
|
|
|
|
dn = dnfile.dnPE(path, clr_lazy_load=False)
|
|
dn.parse_data_directories()
|
|
|
|
assert dn.net
|
|
assert dn.net.mdtables
|
|
|
|
assert dn.net.mdtables.MemberRef
|
|
assert not isinstance(dn.net.mdtables.MemberRef.rows, LazyList)
|
|
|
|
# list.__getitem__ would bypass any lazy loading.
|
|
memref_row = list.__getitem__(dn.net.mdtables.MemberRef.rows, 1)
|
|
assert isinstance(memref_row, MemberRefRow)
|
|
# __dict__ access would bypass any lazy loading.
|
|
assert "Signature" in memref_row.__dict__
|
|
|
|
typeref_row = dn.net.mdtables.TypeRef.rows[0]
|
|
assert isinstance(typeref_row, TypeRefRow)
|
|
assert "ResolutionScope" in typeref_row.__dict__
|
|
|
|
# _resources is the underlying field that would be lazy-loaded.
|
|
assert dn.net._resources is not None
|