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

📄 cpipefindsync.cpp

📁 研读AxCrypt对加解密的处理方法
💻 CPP
字号:
/*! \file
    \brief Implementation of AxPipe::Stock::CPipeFindSync, skip until sync

    @(#) $Id: CPipeFindSync.cpp,v 1.2 2004/02/02 12:10:47 svante Exp $

    AxPipe - Binary Stream Framework

    Copyright (C) 2003 Svante Seleborg/Axon Data, All rights reserved.

    This program is free software; you can redistribute it and/or modify it 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;
    if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    Boston, MA 02111-1307 USA

    The author may be reached at mailto:axpipe@axondata.se and http://axpipe.sourceforge.net

    Why is this framework released as GPL and not LGPL? See http://www.gnu.org/philosophy/why-not-lgpl.html

----
\verbatim
    E-mail                          YYYY-MM-DD              Reason
    axpipe@axondata.se              2003-12-01              Initial
\endverbatim
*/
#include "stdafx.h"
#include "CPipeFindSync.h"

/// Initialize the pattern to sync with. Note that the we only save a reference
/// to the pattern, so it must not be destructed before this object.
/// Use a negative value of iSkipTo to indicate that you'd like to pass data
/// _until_ the given number of patterns are detected.
/// \param p The pattern, do not destruct before this object.
/// \param cb The length of the pattern in p
/// \param fInvert Set to true if the pattern should be bitflipped before comparison
/// \param iSkipTo The number of syncs to find before starting/stopping pass-through
/// \return A pointer to 'this'
AxPipe::Stock::CPipeFindSync *
AxPipe::Stock::CPipeFindSync::Init(const void *p, size_t cb, bool fInvert, int iSkipTo) {
    m_pPattern = (const unsigned char *)p;
    m_cbPattern = cb;
    m_iNext = 0;
    if (m_fSkipAfterSync = ((m_iSkipTo = iSkipTo) < 0)) {
        m_iSkipTo = -m_iSkipTo;
    }
    m_iInvert = fInvert ? 0xff : 0;

    return this;
}
/// Regenerate a partial sync sequence that we've already passed
/// \param cbMunched The number of sync sequence bytes to re-generate
void AxPipe::Stock::CPipeFindSync::PumpBuf(size_t cbBuf) {
    if (cbBuf) {
        CSeg *pBufSeg = new CSeg(m_pPattern, cbBuf);
        for (size_t i = 0; i < cbBuf; i++) {
            pBufSeg->PtrWr()[i] ^= m_iInvert;
        }
        Pump(pBufSeg);
        pBufSeg = NULL;
    }
}

/// Accepted segements of pushed data, skipping m_iSkipTo number of occurrences of
/// of the pattern represented by m_pPattern and m_cbPattern before starting to
/// to pass segments through.
/// \param pSeg The AxPipe::CSeg that contains the next data segment
void AxPipe::Stock::CPipeFindSync::Out(AxPipe::CSeg *pSeg) {
    // Already matched the right number of patterns?
    if (!m_iSkipTo) {
        if (m_fSkipAfterSync) {
            // Already skipping
            pSeg->Release();
        } else {
            // We've already matched the required number, so let's send it onwards
            Pump(pSeg);
        }
        return;
    }
    // Step one byte at a time, attempting to find a match. The pattern buffer
    // serves a dual purpose - to record previously seen, and matched, bytes
    // and of course to serve as the comparison to find matches. The idea is that
    // we do not need to store previous matched bytes, since they by definition
    // must be a part of the pattern - otherwise they should be output or skipped.
    // m_iNext keeps track of the next byte we want to match in the pattern.
    const unsigned char *pData = pSeg->PtrRd();
    size_t cbDataRemain = pSeg->Len();  // Can't be zero
    size_t iPrevBuf = m_iNext;          // Number of old bytes from previous segment(s)
    size_t iOutPrevBuf = 0;             // Number of old bytes not part of buffer after this seg

    // While more data to compare against the pattern
    while (cbDataRemain--) {
        // If we still have a pattern match
        if (*pData++ == (m_pPattern[m_iNext] ^ m_iInvert)) {
            m_iNext++;
            if (m_iNext == m_cbPattern) {
                // If we've matched the entire pattern - bingo!
                if (--m_iSkipTo) {
                    // Still not zero. Must match more patterns.
                    m_iNext = 0;
                } else {
                    // Now we've found the right number of syncs.
                    // Reduce the length so that data including and after this found sync
                    // is not part of the segment to pump. This is calculated by first reducing
                    // the length by cbDataRemain (these are the bytes after the sync).
                    // Then we either reduce by a whole sync length, or by the partial length
                    // we had to start with.
                    // cbDataRemain is only updated to the start of the matched sequence
                    if (m_fSkipAfterSync) {
                        // Pump what we've got so far, and start skipping....
                        Pump(pSeg->Len(pSeg->Len() - (cbDataRemain + (m_cbPattern - iPrevBuf))));
                    } else {
                        // Drop all up until the start of this sequence, then start...
                        PumpBuf(iPrevBuf);
                        Pump(pSeg->Drop(pSeg->Len() - (cbDataRemain + (m_cbPattern - iPrevBuf))));
                    }
                    return;
                }
            }
        } else {
            if (m_iNext) {
                for (size_t i = 0; i < m_iNext; i++) {
                    if (iPrevBuf) {
                        iPrevBuf--;
                        iOutPrevBuf++;
                    }
                    if (i && (memcmp(m_pPattern, &m_pPattern[i], m_iNext - i) == 0)) {
                        break;
                    }
                }
                m_iNext -= i;
                continue;
            }
        }
    }
    if (m_fSkipAfterSync) {
        // Pump 'i' bytes that were buffered, but no match.
        PumpBuf(iOutPrevBuf);

        // Pump the whole segment, except for newly buffered bytes, if any.
        Pump(pSeg->Len(pSeg->Len() - (m_iNext - iPrevBuf)));
    } else {
        // We're to skip before sync, and since we've exhausted this seg,
        // we just drop it.
        pSeg->Release();
    }
}

⌨️ 快捷键说明

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