A200K / IDA-Pro-SigMaker

Signature maker plugin for IDA 8.x and 9.x
Other
328 stars 62 forks source link

Suggestion to change way FILE_BUFFER is initialized. #17

Closed BehindTheCode1337 closed 2 months ago

BehindTheCode1337 commented 2 months ago

I noticed that on bigger binaries this takes up to 13 seconds.

static std::vector<uint8_t> ReadSegmentsToBuffer() 

In my fork I changed it to:

static std::vector<uint8_t> ReadFullFileFromDisk() {
    // Get the name of the loaded file
    char filePath[MAXSTR];
    if (get_input_file_path(filePath, sizeof(filePath)) == 0) {
        msg("Failed to get input file path.\n");
        return {};
    }

    msg("Loading file: %s\n", filePath);

    // Open the file in binary mode
    std::ifstream file(filePath, std::ios::binary | std::ios::ate);
    if (!file.is_open()) {
        msg("Failed to open the file.\n");
        return {};
    }

    // Get the size of the file
    std::streamsize fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    // Create a buffer of the appropriate size
    std::vector<uint8_t> buffer(fileSize);

    // Read the entire file into the buffer
    if (!file.read(reinterpret_cast<char*>(buffer.data()), fileSize)) {
        msg("Failed to read the file.\n");
        return {};
    }
    return buffer;
}

Which resulted in loading speeds as fast as 120ms (from 13 seconds before). For me this method also had other benefits, like easy access to PE Header, but that's probably less relevant for this project.

A200K commented 2 months ago

@BehindTheCode1337 may I ask why you closed that? The idea looks good, to be honest

BehindTheCode1337 commented 2 months ago

saw before I left that it introduced a new bug in siq scanner, wanted to check it out first before suggesting it!

BehindTheCode1337 commented 2 months ago

to get this to work i had to change FindSignatureOccurencesQis somewhat.

        auto fileOffset = ((currentPtr - FILE_BUFFER.data()) + occurence);

        // Convert file offset to RVA
        ea_t rva = OffsetToRva(fileOffset);
        if (rva != BADADDR) {
            // Map RVA to EA using the image base address
            ea_t ea = get_imagebase() + rva;
            results.push_back(ea);
        }
        else {
            msg("Failed to convert file offset %08X to RVA.\n", fileOffset);
        }

        currentPtr = FILE_BUFFER.data() + fileOffset + 1;       

This contains the changes.

ea_t OffsetToRva(ea_t fileOffset) {
    auto ntHeaders = GetNTHeaders();
    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
    for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i, ++section) {
        // Check if the file offset falls within the section's raw data range
        if (fileOffset >= section->PointerToRawData && fileOffset < section->PointerToRawData + section->SizeOfRawData) {
            // Calculate RVA: adjust for the difference between raw offset and VA
            ea_t rva = (fileOffset - section->PointerToRawData) + section->VirtualAddress;
            return rva;
        }
    }
    return BADADDR;  // Couldn't find a matching section
}

You can check my fork, its a poc for some ideas. It all works, but its a mess