LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

Reconstructing IAT can break PE files

Open Catminusminus opened this issue 5 years ago • 0 comments

Describe the bug Applying IAT reconstruction by patch_imports(true) and build_imports(true) can produce broken PE files.

To Reproduce

  1. Clone the LIEF repository and modify LIEF/examples/cpp/pe_builder.cpp to the following code.
#include <iostream>
#include <memory>
#include <fstream>
#include <algorithm>
#include <iterator>

#include <LIEF/PE.hpp>

using namespace LIEF::PE;
int main(int argc, char **argv) {
  std::cout << "PE Rebuilder" << std::endl;
  if (argc != 3) {
    std::cerr << "Usage: " << argv[0] << " <Input Binary> <Output Binary>" << std::endl;
    return -1;
  }

  std::unique_ptr<Binary> binary{Parser::parse(argv[1])};
  binary->optional_header().remove(DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE);
  Builder builder{binary.get()};

  builder
    .build_imports(true)
    .patch_imports(true)
    .build_tls(false)
    .build_resources(false);

  builder.build();
  builder.write(argv[2]);
  std::cout << binary->name() << std::endl;

  return 0;
}
  1. Build LIEF and the example codes including the above modified LIEF/examples/cpp/pe_builder.cpp. This makes modified version of pe_builder.

3.1. Applyfing IAT reconstruction to the PE file whose sha256 is edef8b955468236c6323e9019abb10c324c27b4f5667bc3f85f3a097b2e5159a.

./pe_builder  edef8b955468236c6323e9019abb10c324c27b4f5667bc3f85f3a097b2e5159a.exe snake.exe

3.2. Run snake.exe and you will see that it hangs.

4.1. Applyfing IAT reconstruction to the PE file whose sha256 is 7601bb7c75658a2e6d3ea40258d34f70c26351a99c8730f37220286d7fd48e81.

./pe_builder  7601bb7c75658a2e6d3ea40258d34f70c26351a99c8730f37220286d7fd48e81.exe azorult.exe

4.2 Run azorult.exe and you will see that it exits abnormally.

Expected behavior snake.exe does not hang and azorult.exe does not exit abnomally.

Environment (please complete the following information):

  • System and Version : [e.g. Ubuntu 16.04] Ubuntu18.04
  • Target format (PE, ELF, Mach-O) PE
  • LIEF commit version: python -c "import lief;print(lief.__version__)" or the one from LIEF/config.h 0.12.0-5bbbdad

Additional context This is due to the assumption of the current IAT reconstruction mechanism. First, the file whose sha256 is edef8b955468236c6323e9019abb10c324c27b4f5667bc3f85f3a097b2e5159a has IAT and ILT in separate section. Especially, calculating offsetIAT causes an arithmetic overflow.

Next, the OFT of the file whose sha256 is 7601bb7c75658a2e6d3ea40258d34f70c26351a99c8730f37220286d7fd48e81 file is 0, so that calculating offsetTable causes an arithmetic overflow.

Catminusminus avatar Feb 12 '21 08:02 Catminusminus