| 914 | // Interface for loading files |
| 915 | |
| 916 | int PeLib::ImageLoader::Load( |
| 917 | ByteBuffer & fileData, |
| 918 | std::uint32_t loadFlags) |
| 919 | { |
| 920 | int fileError; |
| 921 | |
| 922 | // Remember the size of the file for later use |
| 923 | savedFileSize = fileData.size(); |
| 924 | |
| 925 | // Check and capture DOS header |
| 926 | fileError = captureDosHeader(fileData); |
| 927 | if(fileError != ERROR_NONE) |
| 928 | return fileError; |
| 929 | |
| 930 | // Check and capture NT headers. Don't go any fuhrter than here if the NT headers were detected as bad. |
| 931 | // Sample: retdec-regression-tests\tools\fileinfo\features\pe-loader-corruptions\001-pe-header-cut-001.ex_ |
| 932 | fileError = captureNtHeaders(fileData); |
| 933 | if(fileError != ERROR_NONE || ldrError == LDR_ERROR_NTHEADER_OUT_OF_FILE) |
| 934 | return fileError; |
| 935 | |
| 936 | // Check and capture section headers |
| 937 | fileError = captureSectionHeaders(fileData); |
| 938 | if(fileError != ERROR_NONE) |
| 939 | return fileError; |
| 940 | |
| 941 | // Performed by Vista+ |
| 942 | if(forceIntegrityCheckEnabled && checkForBadCodeIntegrityImages(fileData)) |
| 943 | setLoaderError(LDR_ERROR_IMAGE_NON_EXECUTABLE); |
| 944 | |
| 945 | // Shall we map the image content? |
| 946 | if(!(loadFlags & IoFlagHeadersOnly)) |
| 947 | { |
| 948 | // Large amount of memory may be allocated during loading the image to memory. |
| 949 | // We need to handle low memory condition carefully here |
| 950 | try |
| 951 | { |
| 952 | // If there was no detected image error, map the image as if Windows loader would do |
| 953 | if(isImageLoadable()) |
| 954 | { |
| 955 | fileError = captureImageSections(fileData, loadFlags); |
| 956 | |
| 957 | // If needed, also perform image load config directory check |
| 958 | if(fileError == ERROR_NONE) |
| 959 | { |
| 960 | if(checkImagePostMapping && checkForImageAfterMapping()) |
| 961 | setLoaderError(LDR_ERROR_IMAGE_NON_EXECUTABLE); |
| 962 | } |
| 963 | |
| 964 | // Fix for images that modify themselves via relocations |
| 965 | // Sample: 342EE6CCB04AB0194275360EE6F752007B9F0CE5420203A41C8C9B5BAC7626DD |
| 966 | // Modifies code and import directory via relocation table. |
| 967 | // This only works in Windows 7 or newer |
| 968 | if(ldrError == LDR_ERROR_NONE && checkForInvalidImageRange()) |
| 969 | { |
| 970 | // The image is gonna be relocated to address 0x10000, |
| 971 | // which is the first valid base address that can happen |
| 972 | // The relocation is done by ntdll!LdrpProtectAndRelocateImage -> ntdll!LdrRelocateImage |
| 973 | relocateImage(0x10000); |