LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

Cannot add section and rebuild PE on Windows 10

Open stevielavern opened this issue 7 years ago • 12 comments

Rebuilding a binary after adding a section on Windows 10 doesn't seem to produce a valid PE file.

Steps to reproduce:

  1. Verify that parsing + rebuilding a PE without modifications produces a valid file
In [1]: import lief

In [2]: pe = lief.parse('C:/Windows/System32/ntdll.dll')

In [3]: b = lief.PE.Builder(pe)

In [4]: b.build_imports(True)
Out[4]: <_pylief.PE.Builder at 0x536f730>

In [5]: b.patch_imports(True)
Out[5]: <_pylief.PE.Builder at 0x536f730>

In [6]: b.build()

In [7]: b.write('test1.dll')

In [8]: import ctypes

In [9]: ctypes.CDLL('test1.dll')
Out[9]: <CDLL 'test1.dll', handle 4c5a0000 at 5387198>

In [10]: # works as expected
  1. Reproduce the same steps, but try to add a new section:
In [1]: import lief

In [2]: pe = lief.parse('C:/Windows/System32/ntdll.dll')

In [3]: s = lief.PE.Section(".test")

In [4]: s.content = [0xCC] * 0x1000

In [5]: s.virtual_address = 0x00420000

In [6]: pe.add_section(s, lief.PE.SECTION_TYPES.TEXT)
Out[6]: <_pylief.PE.Section at 0x4d8e228>

In [7]: b = lief.PE.Builder(pe)

In [8]: b.build_imports(True)
Out[8]: <_pylief.PE.Builder at 0x4d8e810>

In [9]: b.patch_imports(True)
Out[9]: <_pylief.PE.Builder at 0x4d8e810>

In [10]: b.build()

In [11]: b.write('test2.dll')

In [12]: import ctypes

In [13]: ctypes.CDLL('test2.dll')
---------------------------------------------------------------------------
WindowsError                              Traceback (most recent call last)
<ipython-input-13-cd55e62c6b23> in <module>()
----> 1 ctypes.CDLL('test2.dll')

c:\python27-x64\lib\ctypes\__init__.pyc in __init__(self, name, mode, handle, use_errno, use_last_error)
    360
    361         if handle is None:
--> 362             self._handle = _dlopen(self._name, mode)
    363         else:
    364             self._handle = handle

WindowsError: [Error 193] %1 is not a valid Win32 application

Version info:

  • Windows 10 x64 Version 1703 (OS Build 15063.674)
  • Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
  • LIEF 0.8.2 (installed with pip)

stevielavern avatar Oct 26 '17 09:10 stevielavern

Hi, Could you try with:

b.build_imports(False)
b.patch_imports(False)

romainthomas avatar Oct 26 '17 09:10 romainthomas

Same error ("WindowsError: [Error 193] %1 is not a valid Win32 application")

stevielavern avatar Oct 26 '17 09:10 stevielavern

And by removing s.virtual_address = 0x00420000 ?

romainthomas avatar Oct 26 '17 09:10 romainthomas

That did it, thanks !

I can work with that, but ideally I'd prefer to manually specify the section's RVA. Do you have an idea why that fails?

stevielavern avatar Oct 26 '17 09:10 stevielavern

I will check why it fails but specifying an RVA can be dangerous as when rebuilding the binary new sections could be added by LIEF and my override the given RVA

romainthomas avatar Oct 26 '17 11:10 romainthomas

Same problem I met today, please @romainthomas fix it soon...QAQ

heyuanree avatar Jan 27 '18 14:01 heyuanree

Hey @romainthomas I am getting the same issue, when I try to rebuild a PE file after adding imports to it by using the .add_library() and add_entry() functions.

Is this an issue with the library? If so, is there any alternatives I could visit?

` binary = lief.parse(malware_pe)

        imports = [lib.name.lower() + ':' +
                e.name for lib in binary.imports for e in lib.entries]
        imports = process_imported_functions_output(imports)
        imports_len = len(imports)
        
        adversarial_len = len(adversarial_imports_set[index])
    
        logging.debug("Number of elements in original : " + str(len(imports)))
        logging.debug("Number of elements in adversial : " + str(len(adversarial_imports_set[index])))

        imports_to_be_added = list(
            set(adversarial_imports_set[index]).difference(set(imports)))
        logging.debug("Number of imports to be added : " +
                    str(len(imports_to_be_added)))

        if len(imports_to_be_added):
            for lib_func in (imports_to_be_added):
                
                library, function_name = lib_func.split(':')
                logging.debug("import --> " + lib_func)
                logging.debug("\tlibrary --> " + library)
                logging.debug("\tFunctionname --> " + function_name)

                lib = binary.add_library(library)
                lib.add_entry(function_name)

            builder = lief.PE.Builder(binary)
            builder.build_dos_stub(False)  # rebuild DOS stub

            builder.build_imports(True)  # rebuild IAT in another section
            # patch original import table with trampolines to new import table
            builder.patch_imports(True)

            builder.build_overlay(False)  # rebuild overlay
            # rebuild relocation table in another section
            builder.build_relocations(False)
            # rebuild resources in another section
            builder.build_resources(False)
            builder.build_tls(False)  # rebuilt TLS object in another section

            logging.debug("Building binary ...")
            builder.build()  # perform the build process

            malware_file = os.path.join(output_path,"PE _generated_" + str(index) + ".exe")
            builder.write(malware_file)
            logging.debug("Binary has been generated at : " + str(malware_file))

        else:
            logging.debug("There are no new imports to be added ...")

`

bedangSen avatar Aug 17 '19 17:08 bedangSen

Any updates on this? @romainthomas

bedangSen avatar Sep 25 '19 11:09 bedangSen

Hello @bedangSen I didn't work yet on this issue but I will update it when I'll start to handle the problem.

romainthomas avatar Oct 02 '19 05:10 romainthomas

same problem for me.

waruqi avatar May 28 '20 14:05 waruqi

I have the same problem

romanholidaypancakes avatar Feb 10 '22 08:02 romanholidaypancakes