
/******************************************************************************
**
**  Copyright (C) 2001  - the shmoo group -
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  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.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/******************************************************************************
**
**    The Shmoo Group (TSG)
**
**    File:      filter_executable.c
**    Author:    Brian Wotring
**
**    Date:      March 14, 2002.
**    Project:   osiris
**
******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include <sys/stat.h>

#include "utilities.h"
#include "scan_record.h"
#include "filter.h"

osi_bool filter_executable( const char *file_path, FILTER_CONTEXT *context )
{
    int length              = 0;
    long lvalue             = 0;
    osi_uint16 svalue       = 0;

    unsigned char number[6] = "\0";
    unsigned char elf[5]    = "\177ELF";

    if( ( file_path != NULL ) &&
        ( context != NULL ) &&
        ( context->filter_argument != NULL ) )
    {
        /* open file if it isn't already open. */

        if( context->file_handle == NULL )
        {
            context->file_handle = osi_fopen( file_path, "r", 0 );
        }
    
        else
        {
            fseek( context->file_handle, 0, SEEK_SET );
        }

        if( context->file_handle != NULL )
        {
            length = fread( number, 1, 6, context->file_handle );
        
            if( length != 6 )
                return FALSE;
        
            if( memcmp( elf, number, 4 ) == 0 )
                return TRUE;
        
        #if   defined( SYSTEM_DARWIN ) || defined( SYSTEM_OPENBSD )
        
            memcpy( &lvalue, number, 4 );
        
            if( lvalue == 000000407 )
                return TRUE;
        
            if( lvalue == 4277009102 )
                return TRUE;
        
        #if defined( PLATFORM_INTEL )
        
            if( ( lvalue & 0377777777 ) == 041400407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400413 )
                return TRUE;
        
        #endif
        
            if( ( lvalue & 0377777777 ) == 041600413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041600410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041600407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042000413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042000410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042200407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042200410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042200413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042400407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042400410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042400413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042600407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042600410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 042600413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043000407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043000410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043000413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043400407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043400410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043400413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043600407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043600410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 043600413 )
                return TRUE;
        
        #elif defined( SYSTEM_FREEBSD )
        
            memcpy( &lvalue, number, 4 );
        
            if( ( lvalue & 0377777777 ) == 041400407 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400410 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400413 )
                return TRUE;
        
            if( ( lvalue & 0377777777 ) == 041400314 )
                return TRUE;
        
        #elif defined( SYSTEM_BSDOS ) && defined( PLATFORM_INTEL )
        
            if( number[0] == 204  || number[0] == 263 )
                return TRUE;
        
            if( number[0] == 264 || number[0] == 267 )
                return TRUE;
        
        #elif defined( SYSTEM_LINUX )
        
            memcpy( &svalue, number, 2 );
        
            if( svalue == 0x00640107 )
                return TRUE;
        
            if( svalue == 0x00640108 )
                return TRUE;
        
            if( svalue == 0x0064010b )
                return TRUE;
        
            if( svalue == 0x006400cc )
                return TRUE;
        
            if( number[0] == '\01' && number[1] == '\03' )
            {
                if( number[2] == '\020' && number[3] == '\04' )
                    return TRUE;
        
                if( number[2] == '\040' && number[3] == '\04' )
                    return TRUE;
                }
        
        #elif defined( SYSTEM_SOLARIS ) || defined( SYSTEM_SUNOS )
        
            memcpy( &lvalue, number, 4 );
        
            if( ( lvalue & 077777777 ) == 0600413 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0600410 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0600407 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0400413 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0400410 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0400407 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0200413 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0200410 )
                return TRUE;
        
            if( ( lvalue & 077777777 ) == 0200407 )
                return TRUE;
        
        #endif
        
        }
    }

    return FALSE;
}
