⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_mach.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    &&  exe_filesize_max < msegcmd[k].filesize) {        exe_filesize_max = msegcmd[k].filesize;    }    int nx = 0;    for (k = 0; k < n_segment; ++k)    if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd    &&  0!=msegcmd[k].filesize ) {        x.offset = msegcmd[k].fileoff;        x.size   = msegcmd[k].filesize;        if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset            unsigned const delta = mhdri.sizeofcmds;            x.offset    += delta;            x.size      -= delta;        }        bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)            && 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);        packExtent(x, total_in, total_out,            (do_filter ? &ft : 0 ), fo, hdr_u_len );        if (do_filter) {            exe_filesize_max = 0;        }        hdr_u_len = 0;        ++nx;    }    for (k = 0; k < n_segment; ++k) {        x.size = find_SEGMENT_gap(k);        if (x.size) {            x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;            packExtent(x, total_in, total_out, 0, fo);        }    }    if ((off_t)total_in != file_size)        throwEOFException();    segcmdo.filesize = fo->getBytesWritten();}#undef PAGE_MASK#undef PAGE_SIZE#define PAGE_MASK (~0u<<12)#define PAGE_SIZE -PAGE_MASKvoid PackMachPPC32::pack1_setup_threado(OutputFile *const fo){    threado.cmd = Mach_segment_command::LC_UNIXTHREAD;    threado.cmdsize = sizeof(threado);    threado.flavor = my_thread_flavor;    threado.count =  my_thread_state_word_count;    memset(&threado.state, 0, sizeof(threado.state));    fo->write(&threado, sizeof(threado));}void PackMachI386::pack1_setup_threado(OutputFile *const fo){    threado.cmd = Mach_segment_command::LC_UNIXTHREAD;    threado.cmdsize = sizeof(threado);    threado.flavor = my_thread_flavor;    threado.count =  my_thread_state_word_count;    memset(&threado.state, 0, sizeof(threado.state));    fo->write(&threado, sizeof(threado));}template <class T>void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/)  // generate executable header{    mhdro = mhdri;    mhdro.ncmds = 2;    mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;    mhdro.flags = Mach_header::MH_NOUNDEFS;    fo->write(&mhdro, sizeof(mhdro));    segcmdo.cmd = Mach_segment_command::LC_SEGMENT;    segcmdo.cmdsize = sizeof(segcmdo);    strncpy((char *)&segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));    segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK +        msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );    segcmdo.vmsize = 0;    // adjust later    segcmdo.fileoff = 0;    segcmdo.filesize = 0;  // adjust later    segcmdo.initprot = segcmdo.maxprot =        Mach_segment_command::VM_PROT_READ |        Mach_segment_command::VM_PROT_WRITE |        Mach_segment_command::VM_PROT_EXECUTE;    segcmdo.nsects = 0;    segcmdo.flags = 0;    fo->write(&segcmdo, sizeof(segcmdo));    pack1_setup_threado(fo);    sz_mach_headers = fo->getBytesWritten();    memset((char *)&linfo, 0, sizeof(linfo));    fo->write(&linfo, sizeof(linfo));    return;}template <class T>void PackMachBase<T>::unpack(OutputFile *fo){    overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +        my_thread_command_size + sizeof(linfo);    fi->seek(overlay_offset, SEEK_SET);    p_info hbuf;    fi->readx(&hbuf, sizeof(hbuf));    unsigned orig_file_size = get_native32(&hbuf.p_filesize);    blocksize = get_native32(&hbuf.p_blocksize);    if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)        throwCantUnpack("file header corrupted");    ibuf.alloc(blocksize + OVERHEAD);    b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));    fi->readx(&bhdr, sizeof(bhdr));    ph.u_len = get_native32(&bhdr.sz_unc);    ph.c_len = get_native32(&bhdr.sz_cpr);    ph.method = bhdr.b_method;    ph.filter = bhdr.b_ftid;    ph.filter_cto = bhdr.b_cto8;    // Uncompress Macho headers    fi->readx(ibuf, ph.c_len);    Mach_header *const mhdr = (Mach_header *)new upx_byte[ph.u_len];    decompress(ibuf, (upx_byte *)mhdr, false);    unsigned const ncmds = mhdr->ncmds;    msegcmd = new Mach_segment_command[ncmds];    unsigned char *ptr = (unsigned char *)(1+mhdr);    for (unsigned j= 0; j < ncmds; ++j) {        msegcmd[j] = *(Mach_segment_command *)ptr;        ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;    }    // Put LC_SEGMENT together at the beginning, ascending by .vmaddr.    qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command);    n_segment = 0;    for (unsigned j= 0; j < ncmds; ++j) {        n_segment += (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd);    }    unsigned total_in = 0;    unsigned total_out = 0;    unsigned c_adler = upx_adler32(NULL, 0);    unsigned u_adler = upx_adler32(NULL, 0);    Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);    unsigned k;    fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR);    for (        k = 0;        k < ncmds;        (++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))    ) {        if (Mach_segment_command::LC_SEGMENT==sc->cmd        &&  0!=sc->filesize ) {            unsigned filesize = sc->filesize;            unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));        }    }    for (unsigned j = 0; j < ncmds; ++j) {        unsigned const size = find_SEGMENT_gap(j);        if (size) {            unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;            if (fo)                fo->seek(where, SEEK_SET);            unpackExtent(size, fo, total_in, total_out,                c_adler, u_adler, false, sizeof(bhdr));        }    }}template <class T>bool PackMachBase<T>::canPack(){    fi->seek(0, SEEK_SET);    fi->readx(&mhdri, sizeof(mhdri));    if (Mach_header::MH_MAGIC         !=mhdri.magic    ||  my_cputype                    !=mhdri.cputype    ||  Mach_header::MH_EXECUTE       !=mhdri.filetype    )        return false;    rawmseg = (Mach_segment_command *)new char[mhdri.sizeofcmds];    fi->readx(rawmseg, mhdri.sizeofcmds);    msegcmd = new Mach_segment_command[mhdri.ncmds];    unsigned char *ptr = (unsigned char *)rawmseg;    for (unsigned j= 0; j < mhdri.ncmds; ++j) {        msegcmd[j] = *(Mach_segment_command *)ptr;        ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;    }    // Put LC_SEGMENT together at the beginning, ascending by .vmaddr.    qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command);    // Check that LC_SEGMENTs form one contiguous chunk of the file.    for (unsigned j= 0; j < mhdri.ncmds; ++j) {        if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) {            if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {                return false;            }            if (0 < j) {                unsigned const sz = ~0xfff                                  & (0xfff + msegcmd[j-1].filesize);                if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {                    return false;                }            }            ++n_segment;            sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;        }    }    // info: currently the header is 36 (32+4) bytes before EOF    unsigned char buf[256];    fi->seek(-(off_t)sizeof(buf), SEEK_END);    fi->readx(buf, sizeof(buf));    checkAlreadyPacked(buf, sizeof(buf));    // set options    opt->o_unix.blocksize = file_size;    return 0 < n_segment;}template class PackMachBase<MachClass_BE32>;template class PackMachBase<MachClass_LE32>;PackMachFat::PackMachFat(InputFile *f) : super(f){    bele = &N_BELE_RTP::le_policy;  // sham}PackMachFat::~PackMachFat(){}const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const{    static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };    return m_nrv2e;  // sham}const int *PackMachFat::getFilters() const{    static const int filters[] = { 0x49, FT_END };    return filters;  // sham}void PackMachFat::pack(OutputFile *fo){    unsigned const in_size = this->file_size;    fo->write(&fat_head, sizeof(fat_head.fat) +        fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));    unsigned length = 0;    for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {        unsigned base = fo->unset_extent();  // actual length        base += ~(~0u<<fat_head.arch[j].align) & (0-base);  // align up        fo->seek(base, SEEK_SET);        fo->set_extent(base, ~0u);        ph.u_file_size = fat_head.arch[j].size;        fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);        switch (fat_head.arch[j].cputype) {        case PackMachFat::CPU_TYPE_I386: {            PackMachI386 packer(fi);            packer.initPackHeader();            packer.canPack();            packer.updatePackHeader();            packer.pack(fo);        } break;        case PackMachFat::CPU_TYPE_POWERPC: {            PackMachPPC32 packer(fi);            packer.initPackHeader();            packer.canPack();            packer.updatePackHeader();            packer.pack(fo);        } break;        }  // switch cputype        fat_head.arch[j].offset = base;        length = fo->unset_extent();        fat_head.arch[j].size = length - base;    }    ph.u_file_size = in_size;    fi->set_extent(0, in_size);    fo->seek(0, SEEK_SET);    fo->rewrite(&fat_head, sizeof(fat_head.fat) +        fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));    fo->set_extent(0, length);}void PackMachFat::unpack(OutputFile *fo){    fo->seek(0, SEEK_SET);    fo->write(&fat_head, sizeof(fat_head.fat) +        fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));    unsigned length;    for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {        unsigned base = fo->unset_extent();  // actual length        base += ~(~0u<<fat_head.arch[j].align) & (0-base);  // align up        fo->seek(base, SEEK_SET);        fo->set_extent(base, ~0u);        ph.u_file_size = fat_head.arch[j].size;        fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);        switch (fat_head.arch[j].cputype) {        case PackMachFat::CPU_TYPE_I386: {            PackMachI386 packer(fi);            packer.initPackHeader();            packer.canUnpack();            packer.unpack(fo);        } break;        case PackMachFat::CPU_TYPE_POWERPC: {            PackMachPPC32 packer(fi);            packer.initPackHeader();            packer.canUnpack();            packer.unpack(fo);        } break;        }  // switch cputype        fat_head.arch[j].offset = base;        length = fo->unset_extent();        fat_head.arch[j].size = length - base;    }    fo->unset_extent();    fo->seek(0, SEEK_SET);    fo->rewrite(&fat_head, sizeof(fat_head.fat) +        fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));}bool PackMachFat::canPack(){    struct Mach_fat_arch *arch = &fat_head.arch[0];    fi->readx(&fat_head, sizeof(fat_head));    if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic    ||  N_FAT_ARCH < fat_head.fat.nfat_arch) {        return false;    }    for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {        fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);        switch (arch[j].cputype) {        default: return false;        case PackMachFat::CPU_TYPE_I386: {            PackMachI386 packer(fi);            if (!packer.canPack())                return false;        } break;        case PackMachFat::CPU_TYPE_POWERPC: {            PackMachPPC32 packer(fi);            if (!packer.canPack())                return false;        } break;        }  // switch cputype    }    // info: currently the header is 36 (32+4) bytes before EOF    unsigned char buf[256];    fi->seek(-(off_t)sizeof(buf), SEEK_END);    fi->readx(buf, sizeof(buf));    checkAlreadyPacked(buf, sizeof(buf));    return true;}int PackMachFat::canUnpack(){    struct Mach_fat_arch *arch = &fat_head.arch[0];    fi->readx(&fat_head, sizeof(fat_head));    if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic    ||  N_FAT_ARCH < fat_head.fat.nfat_arch) {        return false;    }    for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {        fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);        switch (arch[j].cputype) {        default: return false;        case PackMachFat::CPU_TYPE_I386: {            PackMachI386 packer(fi);            if (!packer.canUnpack())                return 0;            ph.format = packer.getFormat(); // FIXME: copy entire PackHeader        } break;        case PackMachFat::CPU_TYPE_POWERPC: {            PackMachPPC32 packer(fi);            if (!packer.canUnpack())                return 0;            ph.format = packer.getFormat(); // FIXME: copy entire PackHeader        } break;        }  // switch cputype    }    return 1;}void PackMachFat::buildLoader(const Filter */*ft*/){    assert(false);}Linker* PackMachFat::newLinker() const{    return new ElfLinkerX86;  // sham}void PackMachFat::list(){    assert(false);}/*vi:ts=4:et*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -