11import pytest
22import time
33import zlib
4+ import base64
45import ctypes
56import windows
67
@@ -20,6 +21,23 @@ def pe(request):
2021 yield proc .peb .modules [2 ].pe
2122 proc .exit (0 )
2223
24+ PE_DOTNET32_DLL_NAME = "test_pe_dotnet32.dll"
25+
26+ @pytest .fixture (scope = "session" )
27+ def pe_dotnet32 (tmpdir_factory ):
28+ tmpdir = tmpdir_factory .mktemp ("pe_dotnet32_test_dir" )
29+ pe_dotnet32_data = zlib .decompress (base64 .decodebytes (PE_DOTNET32_DLL_BASE64 ))
30+ fullpath = str (tmpdir .join (PE_DOTNET32_DLL_NAME ))
31+ with open (fullpath , "wb" ) as f :
32+ f .write (pe_dotnet32_data )
33+
34+ try :
35+ yield fullpath
36+ finally :
37+ try :
38+ os .unlink (fullpath )
39+ except WindowsError as e :
40+ pass # Ignore delete fail, may happend if injected process is cleaned after the dll..
2341
2442def test_pe_imports (pe ):
2543 imports = pe .imports
@@ -66,10 +84,13 @@ def test_pe_parsing_strange_optional_header_size(tmp_path, proc32):
6684 # Also check that section retrieval works (as its position is based on OptionalHeader Size)
6785 assert set (s .name for s in mod .pe .sections ) == {".text" , ".data" , ".l1" }
6886
87+
88+
89+
6990# Make a test from current_process parsing ?
70- def test_pe_parsing_dotnet_32_process_64 (proc64 ):
91+ def test_pe_parsing_dotnet32_process_64 (proc64 , pe_dotnet32 ):
7192 # .NET pe32 loadable in 64bit process -> rewrite of the OptionalHeader
72- mod = proc64 .load_library (r"C:\Windows\System32\stordiag.exe" )
93+ mod = proc64 .load_library (pe_dotnet32 )
7394 # It was a PE32
7495 assert mod .pe .get_NT_HEADER ().FileHeader .Machine == gdef .IMAGE_FILE_MACHINE_I386
7596 # Now Optional Header should be 64b
@@ -83,17 +104,54 @@ def test_pe_parsing_dotnet_32_process_64(proc64):
83104 assert mod .pe .sections
84105 assert ".text" in set (s .name for s in mod .pe .sections )
85106
86- def test_pe_parsing_dotnet_32_current_process_64 (proc64 ):
107+ def test_pe_parsing_dotnet32_current_process_64 (proc64 , pe_dotnet32 ):
87108 # .NET pe32 loadable in 64bit process -> rewrite of the OptionalHeader
88109 # So we injecte python code in a the remote proc64 to test the parsing from itself
89110 PIPE_NAME = "PFW_TEST_Pipe"
90- mod = proc64 .load_library (r"C:\Windows\System32\stordiag.exe" )
91- assert proc64 .peb .modules [- 1 ].name == "stordiag.exe"
111+ mod = proc64 .load_library (pe_dotnet32 )
112+ assert proc64 .peb .modules [- 1 ].name == PE_DOTNET32_DLL_NAME
92113 proc64 .execute_python ("import sys; import windows; import windows.pipe" )
93- proc64 .execute_python ("""pemod = [x for x in windows.current_process.peb.modules if x.name == 'stordiag.exe '][0].pe""" )
114+ proc64 .execute_python ("""pemod = [x for x in windows.current_process.peb.modules if x.name == '{0} '][0].pe""" . format ( PE_DOTNET32_DLL_NAME ) )
94115 with windows .pipe .create (PIPE_NAME ) as np :
95116 rcode = """windows.pipe.send_object("{pipe}", (list(pemod.imports), [sec.name for sec in pemod.sections]))"""
96117 proc64 .execute_python (rcode .format (pipe = PIPE_NAME ))
97118 imported_dlls , sections_names = np .recv ()
98119 assert imported_dlls == ['mscoree.dll' ]
99120 assert ".text" in sections_names
121+
122+ # A "Portable Executable 32 .NET Assembly" DLL
123+ # Result of compiling a simple hello-world
124+ # Can be loaded into a 64b process to witness 32 -> 64b PE conversion at load time
125+ PE_DOTNET32_DLL_BASE64 = b"""
126+ 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
157+ """
0 commit comments