java/src/org/openantivirus/engine/censor/matcharray MatchArray.java,NONE,1.1 MatchArrayCensor.java,NONE,1.1

Kurt Huwig <[email protected]> Wed, 19 May 2004 07:33:43 +0000
Newsgroups gmane.comp.security.virus.openantivirus.cvs
Message-ID <[email protected]>
Update of /cvsroot/openantivirus/java/src/org/openantivirus/engine/censor/matcharray
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1513/src/org/openantivirus/engine/censor/matcharray

Added Files:
	MatchArray.java MatchArrayCensor.java 
Log Message:
Added MatchArrayCensor
Code cleanup
Virus name without offset

--- NEW FILE: MatchArray.java ---
/*
 * $Id: MatchArray.java,v 1.1 2004/05/19 07:33:40 kurti Exp $
 * 
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is OAV.
 *
 * The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
 * Portions created by the Initial Developer are Copyright (C) 2001-2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK *****
 */ 
package org.openantivirus.engine.censor.matcharray;

import java.util.*;

import org.openantivirus.engine.censor.*;

/**
 * Pattern matching by array
 *
 * @author  Kurt Huwig
 * @version $Revision: 1.1 $
 */
public class MatchArray implements StringSearch {
    public final static int MINIMUM_LENGTH = 2;
    
    private Collection[] colMatches = new Collection[1 << 16];
    private PositionFoundListener[][] matches =
        new PositionFoundListener[1 << 16][];
    
    public void addString(byte[] abPattern, PositionFoundListener pfl) {
        if (abPattern.length < MINIMUM_LENGTH) {
            throw new IllegalArgumentException("String too short");
        }
        final int match = ((abPattern[0] & 0xff) << 8)
                          | (abPattern[1] & 0xff);
        
        Collection colMatch = colMatches[match];
        if (colMatch == null) {
            colMatch = new LinkedList();
            colMatches[match] = colMatch;
        }
        
        colMatch.add(pfl);
    }
    
    public Censor getCensor() {
        return new MatchArrayCensor(matches);
    }
    
    public void prepare() {
        for (int i = 0; i < colMatches.length; i++) {
            final Collection matchListener = colMatches[i];
            if (matchListener != null) {
                final PositionFoundListener[] matchList =
                    new PositionFoundListener[matchListener.size()];
                matches[i] = matchList;
                
                int j = 0;
                for (Iterator it = matchListener.iterator(); it.hasNext();) {
                    matchList[j++] = (PositionFoundListener) it.next();
                }
                colMatches[i] = null;
            }
        }
    }
    
}

--- NEW FILE: MatchArrayCensor.java ---
/*
 * $Id: MatchArrayCensor.java,v 1.1 2004/05/19 07:33:40 kurti Exp $
 * 
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is OAV.
 *
 * The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
 * Portions created by the Initial Developer are Copyright (C) 2001-2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK *****
 */ 
package org.openantivirus.engine.censor.matcharray;

import java.io.*;

import org.openantivirus.engine.censor.*;
import org.openantivirus.engine.vfs.*;

/**
 * Pattern matching by array
 *
 * @author  Kurt Huwig
 * @version $Revision: 1.1 $
 */
public class MatchArrayCensor implements Censor {
    private static final int BUFFER_SIZE = 32768;

    private final PositionFoundListener[][] matchArray;

    private int match;
    
    public MatchArrayCensor(PositionFoundListener[][] matchArray) {
        this.matchArray = matchArray;
    }
    
    public int censor(VfsEntry entry) throws MalwareFoundException, ScanException {
        try {
            final InputStream is = new FileInputStream(entry.getFile());

            try {
                scanStream(entry, is);
            } finally {
                is.close();
            }
            
            return NOTHING_FOUND;
            
        } catch (IOException ioe) {
            throw new ScanException(ioe);
        }
    }

    protected void scanStream(VfsEntry entry, InputStream is)
    throws IOException, MalwareFoundException {
        byte[] abBuffer = new byte[3 * BUFFER_SIZE];
        
        int iLength = fillBuffer(is, abBuffer, 0, abBuffer.length);
        
        if (iLength == -1) {
            return;
        }
        
        match = abBuffer[0] & 0xff;
        
        if (iLength < abBuffer.length) {
            update(entry, 1L, abBuffer, 0, iLength, 0, 0);
            
        } else  {
            update(entry, 1L, abBuffer, 0, 2 * BUFFER_SIZE, 0, BUFFER_SIZE);
            
            long fileOffset = 2 * BUFFER_SIZE;
            int iBufferPos = 2 * BUFFER_SIZE;
            int iReadAheadPos = 0;
            do {
                iLength = fillBuffer(is,
                                     abBuffer,
                                     iReadAheadPos,
                                     BUFFER_SIZE);
                
                update(entry,
                       fileOffset,
                       abBuffer,
                       iBufferPos,
                       BUFFER_SIZE,
                       BUFFER_SIZE,
                       iLength != -1 ? iLength : 0);
                
                iBufferPos = iReadAheadPos;
                iReadAheadPos += BUFFER_SIZE;
                iReadAheadPos %= 3 * BUFFER_SIZE;
                fileOffset += BUFFER_SIZE;
                
            } while (iLength == BUFFER_SIZE);
            
            if (iLength != -1) {
                update(entry,
                       fileOffset,
                       abBuffer,
                       iBufferPos,
                       iLength,
                       BUFFER_SIZE,
                       0);
            }
        }
    }
    
    /**
     * scans the next block of the stream for viruses; blocks are expected to
     * appear in the correct order
     */
    protected void update(VfsEntry entry,
                          long fileOffset,
                          byte[] ab,
                          int iOffset,
                          int iLength,
                          int iPrefix,
                          int iSuffix) throws MalwareFoundException {
        for (int i = iOffset; i < iOffset + iLength; i++) {
            match &= 0xff;
            match <<= 8;
            match |= ab[i] & 0xff;
            
            final PositionFoundListener[] matchListener = matchArray[match];
            if (matchListener != null) {
                final int iPosition = i - 1;
                final PositionFoundEvent pfe = new PositionFoundEvent(
                        entry,
                        fileOffset + iPosition,
                        ab,
                        iPosition,
                        2,
                        iPosition - iOffset + iPrefix,
                        iOffset + iLength - iPosition + iSuffix);
                
                for (int j = 0; j < matchListener.length; j++) {
                    matchListener[j].positionFound(pfe);
                }
            }
        }
    }
    
    /**
     * fills the buffer up to the end unless the end of data is reached, or
     * an IOException occurs
     */
    protected int fillBuffer(InputStream stream,
                             byte[] buffer,
                             int offset,
                             int length) throws IOException {
        int iRead = 0;
        do {
            int iLength = stream.read(buffer, offset + iRead, length - iRead);
            if (iLength == -1) {
                return iRead == 0 ? -1 : iRead;
            }
            iRead += iLength;
        } while (iRead < length);
        return iRead;
    }
}



-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click