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

📄 filter.cpp

📁 UPX 源代码
💻 CPP
字号:
/* filter.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   All Rights Reserved.   UPX and the UCL library are free software; you can redistribute them   and/or modify them under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "filter.h"#include "file.h"/*************************************************************************// util**************************************************************************/static //inlinevoid initFilter(Filter *f, upx_byte *buf, unsigned buf_len){    f->buf = buf;    f->buf_len = buf_len;    // clear output parameters    f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;}/*************************************************************************// get a FilterEntry**************************************************************************/const FilterImp::FilterEntry *FilterImp::getFilter(int id){    static bool done = false;    static unsigned char filter_map[256];    if (!done)    {        // init the filter_map[]        assert(n_filters <= 254);       // as 0xff means "empty slot"        memset(filter_map, 0xff, sizeof(filter_map));        for (int i = 0; i < n_filters; i++)        {            int filter_id = filters[i].id;            assert(filter_id >= 0 && filter_id <= 255);            assert(filter_map[filter_id] == 0xff);            filter_map[filter_id] = (unsigned char) i;        }        done = true;    }    if (id < 0 || id > 255)        return NULL;    unsigned index = filter_map[id];    if (index == 0xff)                  // empty slot        return NULL;    assert(filters[index].id == id);    return &filters[index];}bool Filter::isValidFilter(int filter_id){    const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);    return fe != NULL;}bool Filter::isValidFilter(int filter_id, const int *allowed_filters){    if (!isValidFilter(filter_id))        return false;    if (filter_id == 0)        return true;    if (allowed_filters == NULL)        return false;    while (*allowed_filters != FT_END)        if (*allowed_filters++ == filter_id)            return true;    return false;}/*************************************************************************// high level API**************************************************************************/void Filter::init(int id_, unsigned addvalue_){    this->id = id_;    initFilter(this, NULL, 0);    // clear input parameters    this->addvalue = addvalue_;    this->preferred_ctos = NULL;    // clear input/output parameters    this->cto = 0;    this->n_mru = 0;}bool Filter::filter(upx_byte *buf_, unsigned buf_len_){    initFilter(this, buf_, buf_len_);    const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);    if (fe == NULL)        throwInternalError("filter-1");    if (fe->id == 0)        return true;    if (buf_len < fe->min_buf_len)        return false;    if (fe->max_buf_len && buf_len > fe->max_buf_len)        return false;    if (!fe->do_filter)        throwInternalError("filter-2");    // save checksum    this->adler = 0;    if (clevel != 1)        this->adler = upx_adler32(this->buf, this->buf_len);    //printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);    //OutputFile::dump("filter.dat", buf, buf_len);    int r = (*fe->do_filter)(this);    //printf("filter: %02x %d\n", fe->id, r);    if (r > 0)        throwFilterException();    if (r == 0)        return true;    return false;}void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum){    initFilter(this, buf_, buf_len_);    const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);    if (fe == NULL)        throwInternalError("unfilter-1");    if (fe->id == 0)        return;    if (buf_len < fe->min_buf_len)        return;    if (fe->max_buf_len && buf_len > fe->max_buf_len)        return;    if (!fe->do_unfilter)        throwInternalError("unfilter-2");    //printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);    int r = (*fe->do_unfilter)(this);    //printf("unfilter: %02x %d\n", fe->id, r);    if (r != 0)        throwInternalError("unfilter-3");    //OutputFile::dump("unfilter.dat", buf, buf_len);    // verify checksum    if (verify_checksum && clevel != 1)    {        if (this->adler != upx_adler32(this->buf, this->buf_len))            throwInternalError("unfilter-4");    }}void Filter::verifyUnfilter(){    // Note:    //   This verify is just because of complete paranoia that there    //   could be a hidden bug in the filter implementation, and    //   it should not be necessary at all.    //   Maybe we will remove it at some future point.    //    // See also:    //   Packer::verifyOverlappingDecompression()    //printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);    if (clevel != 1)        unfilter(this->buf, this->buf_len, true);}bool Filter::scan(const upx_byte *buf_, unsigned buf_len_){    // Note: must use const_cast here. This is fine as the scan    //   implementations (fe->do_scan) actually don't change the buffer.    upx_byte *b = const_cast<upx_byte *>(buf_);    initFilter(this, b, buf_len_);    const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);    if (fe == NULL)        throwInternalError("scan-1");    if (fe->id == 0)        return true;    if (buf_len < fe->min_buf_len)        return false;    if (fe->max_buf_len && buf_len > fe->max_buf_len)        return false;    if (!fe->do_scan)        throwInternalError("scan-2");    //printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);    int r = (*fe->do_scan)(this);    //printf("filter: %02x %d\n", fe->id, r);    if (r > 0)        throwFilterException();    if (r == 0)        return true;    return false;}/*vi:ts=4:et*/

⌨️ 快捷键说明

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