Skip to content
PeOpenFromMemoryCopy

PeOpenFromMemoryCopy

Description

Parse a PE image from an in-memory byte range – R-value / copy form (mirrors VecInsertR).

Parser allocates its own buffer through alloc and MemCopys the caller’s bytes in. Caller’s pointer is never retained.

Success

Returns true; out owns an independent copy of data.

Failure

Returns false; out zeroed; caller’s data untouched.

Usage example (Cross-references)

Usage examples (Cross-references)
    bool pe_open_from_memory_copy(Pe *out, const u8 *data, size data_size, Allocator *alloc) {
        if (!out || !data || !alloc) {
            LOG_FATAL("PeOpenFromMemoryCopy: NULL argument (contract violation)");
        }
        Buf copy = BufInit(alloc);
        Buf copy = BufInit(alloc);
        if (!BufReserve(&copy, (u64)data_size)) {
            LOG_ERROR("PeOpenFromMemoryCopy: allocation failed ({} bytes)", (u64)data_size);
            return false;
        }
    
        Pe   pe;
        bool ok = PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), base);
        if (!ok) {
            DefaultAllocatorDeinit(&alloc);
        build_pe_blob();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), base)) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe   pe;
        bool ok = !PeOpenFromMemoryCopy(&pe, garbage, sizeof(garbage), base);
    
        DefaultAllocatorDeinit(&alloc);
        build_pe_blob();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), base)) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        build_pe_blob();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), base)) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        DefaultAllocator alloc = DefaultAllocatorInit();
        Pe               pe;
        bool             opened = PeOpenFromMemoryCopy(&pe, bytes, len, ALLOCATOR_OF(&alloc));
        if (opened)
            PeDeinit(&pe);
        build_pe_blob_m1();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u64(&blob[OPT_HDR_OFF + 24], 0x7766554433221100ull);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        build_pe32_blob();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u32(&blob[OPT_HDR_OFF + 28], 0x00410000u);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        // confirm the normal (well-within-file) blob is accepted.
        Pe   pe;
        bool ok = PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc));
        if (ok)
            PeDeinit(&pe);
        wr_u16(&bad[FILE_HDR_OFF + 16], 1900);
        Pe   pe;
        bool opened = PeOpenFromMemoryCopy(&pe, bad, sizeof(bad), ALLOCATOR_OF(&alloc));
        if (opened)
            PeDeinit(&pe);
        u64  want_len = (u64)OPT_HDR_OFF + OPT_HDR_SIZE_PEPP; // exact fit to EOF
        Pe   pe;
        bool ok = PeOpenFromMemoryCopy(&pe, exact, want_len, ALLOCATOR_OF(&alloc));
        if (ok) {
            ok = ok && pe.size_of_image == PE_SIZE_OF_IMAGE;
        wr_u32(&blob[OPT_HDR_OFF + 108], 7); // NumberOfRvaAndSizes = 7
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        // absent kills that mutation.
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        build_pe_blob_m1();
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        blob[CV_REC_RAW_OFF] = 'N';
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u32(&blob[DEBUG_RAW_OFF + 12], 9); // Type != CODEVIEW
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
            cv[24 + i] = (u8)('A' + i); // no NUL anywhere in the region
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        cv[28] = '\0'; // terminator is the last in-region byte
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        cv[24] = '\0';                         // empty path, NUL-terminated
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u32(&blob[DEBUG_RAW_OFF + 16], 24); // one below minimum
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u32(&blob[DEBUG_RAW_OFF + 16], (u32)(BLOB_SIZE - CV_REC_RAW_OFF + 4));
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        put_cv_entry_sz(0x300, 0x200, 0x300);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        put_cv_entry_sz(0x300, 0x500, 0x300);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        wr_u32(&blob[OPT_HDR_OFF + 112 + 6 * 8 + 4], BLOB_SIZE);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        put_cv_entry(DIR_RAW, 0x500); // CodeView in entry 0, record at 0x500
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        put_cv_entry(DIR_RAW, 0x500); // record at 0x500 (in-bounds)
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        cv[28] = '\0'; // NUL sits exactly AT region_end (one past the region)
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        put_cv_entry(0x300 + 28, 0x500); // entry1 (just past declared count)
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        MemCopy(&cv2[24], kPdbPath, plen + 1);
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, total, ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe   pe;
        bool opened = PeOpenFromMemoryCopy(&pe, blob, total, ALLOCATOR_OF(&alloc));
        if (opened)
            PeDeinit(&pe);
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, total, ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Pe pe;
        if (!PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), base)) {
            DebugAllocatorDeinit(&alloc);
            return false;
    
        Pe   pe;
        bool opened = PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc));
        // Real code: rejected AND `out` zeroed by PeDeinit on the fail path.
        bool ok = !opened && BufData(&pe.data) == NULL && BufLength(&pe.data) == 0 && VecLen(&pe.sections) == 0;
    
        Pe   pe;
        bool ok = PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc));
        if (ok)
            PeDeinit(&pe);
    
        Pe   pe;
        bool opened = PeOpenFromMemoryCopy(&pe, blob, sizeof(blob), ALLOCATOR_OF(&alloc));
        if (opened)
            PeDeinit(&pe);
Last updated on