#!/bin/bash

OPT=$1
INSTALL_PATH=/lib/modules/FusionOS/innersafer

version=`uname -r | awk -F . '{print $1}'`
patchlevel=`uname -r | awk -F . '{print $2}'`
sublevel=`uname -r | awk -F . '{print $3}'`
VERSION=`uname -r`
ARCH=`uname -m`
DEX=0x

KALLSYMSMAP=/proc/kallsyms
SYSMAP=/boot/System.map-$VERSION

sym_stext=`grep -w _stext $KALLSYMSMAP | awk '{print $1}'`
sys_stext=`grep -w _stext $SYSMAP | awk '{print $1}'`
offset=$(($DEX$sym_stext-$DEX$sys_stext))
offset=`printf "0x%x" $offset`

calculate_address() 
{
   local address=$1
   if [ "$offset" != "0x0" ] && [ $address ]; then
      printf "%#x\n" $(($DEX$address+$offset))
   else
      if [ $address ]; then
         printf "%#x\n" $DEX$address
      fi
   fi
}

measure_disk()
{
	/usr/local/xsectcsec/tsb/measuredisk
	echo -n ""
}

start_platform()
{
        if [ ! -d /usr/local/xsectcsec/log ];then
           mkdir -p /usr/local/xsectcsec/log
        fi

        if [ -f /usr/local/xsectcsec/log/tsb.log ];then
           date=`date +%Y%m%d%H%M`
           name="/usr/local/xsectcsec/log/tsb.log_$date"
           mv /usr/local/xsectcsec/log/tsb.log $name
        fi
		
        POINT=`grep -w security_hook_heads $KALLSYMSMAP | awk '{print $1}'`  
        if [ ! $POINT ]; then
	       POINT=`grep -w security_hook_heads $SYSMAP | awk '{print $1}'`
           if [ $POINT ]; then
	          hook_address=$(calculate_address $POINT)
           fi	
        else
	        hook_address=$DEX$POINT
        fi

	    if [ ! $POINT ]; then
           POINT=`grep -w security_ops $KALLSYMSMAP | awk '{print $1}'`
           if [ ! $POINT ]; then
	          POINT=`grep -w security_ops $SYSMAP | awk '{print $1}'`
	          if [ $POINT ]; then
	             hook_address=$(calculate_address $POINT)
	          fi	
	       else
	           hook_address=$DEX$POINT
	       fi
        fi
		
        #init_mm_addr
        POINT=`grep -w init_mm $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
           init_mm_addr=$DEX$POINT
        else
           POINT=`grep -w init_mm $SYSMAP | awk '{print $1}'`
           init_mm_addr=$(calculate_address $POINT)
        fi
		
        #syscall
        POINT=`grep -w sys_call_table $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
           syscall=$DEX$POINT
        else
           POINT=`grep -w sys_call_table $SYSMAP | awk '{print $1}'`
           syscall=$(calculate_address $POINT)
        fi
		
        #mount_lock
        POINT=`grep -w vfsmount_lock $KALLSYMSMAP | awk '{print $1}'`
        if [ ! $POINT ]; then
	       POINT=`grep -w vfsmount_lock $SYSMAP | awk '{print $1}'`
           if [ $POINT ]; then
	          mount_lock=$(calculate_address $POINT)
	       fi
	    else
	       mount_lock=$DEX$POINT
	    fi
	
        if [ ! $POINT ]; then
           POINT=`grep -w mount_lock $KALLSYMSMAP | awk '{print $1}'`
	       if [ ! $POINT ]; then
	          POINT=`grep -w mount_lock $SYSMAP | awk '{print $1}'`
              if [ $POINT ]; then
                 mount_lock=$(calculate_address $POINT)
              fi	
           else
              mount_lock=$DEX$POINT	   
	       fi
        fi

        modprobe platform syscall_table=$syscall mountlock=$mount_lock hook_security_address=$hook_address init_mm_address=$init_mm_addr
        if [ ! -e /dev/xsectcsec ];then
            sleep 1
        fi
        chmod 600 /dev/xsectcsec
}

start_operation()
{
        modprobe file_capture
}

start_smeasure()
{
	POINT=`grep -w kallsyms_lookup_name $KALLSYMSMAP | awk '{print $1}'`
	if [ $POINT ]; then
           lookup_name=$DEX$POINT
	else
           POINT=`grep -w kallsyms_lookup_name $SYSMAP | awk '{print $1}'`
           lookup_name=$(calculate_address $POINT)
	fi

	POINT=`grep -w __flush_dcache_area $KALLSYMSMAP | awk '{print $1}'`
	if [ ! $POINT ]; then
	    POINT=`grep -w __flush_dcache_area $SYSMAP | awk '{print $1}'`
	    if [ $POINT ]; then
	       f_d_a=$(calculate_address $POINT)
	    fi
	else
	    f_d_a=$DEX$POINT
	fi

        if [ ! $POINT ]; then
	   POINT=`grep -w clflush_cache_range $KALLSYMSMAP | awk '{print $1}'`
	   if [ ! $POINT ]; then
	      POINT=`grep -w clflush_cache_range $SYSMAP | awk '{print $1}'`
	      if [ $POINT ]; then
	         f_d_a=$(calculate_address $POINT)
	      fi
	   else
	      f_d_a=$DEX$POINT
	   fi
	fi

	if [ ! $f_d_a ];then
	   modprobe xsectcsmeasure  k_kallsyms_lookup_name=$lookup_name
	else
	   modprobe xsectcsmeasure k_flush_area=$f_d_a k_kallsyms_lookup_name=$lookup_name
	fi
}

start_dmeasure()
{
        #section#
        POINT=`grep -w _stext $KALLSYMSMAP | awk '{print $1}'`
        stext=$DEX$POINT
        stext=`printf "0x%x" $stext`
        POINT=`grep -w _etext $KALLSYMSMAP | awk '{print $1}'`
        etext=$DEX$POINT
        etext=`printf "0x%x" $etext`

        POINT=`grep -w lookup_symbol_name $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            sname=$DEX$POINT
        else
            POINT=`grep -w lookup_symbol_name $SYSMAP | awk '{print $1}'`    
            sname=$(calculate_address $POINT) 
        fi    
		
        #syscall#
        POINT=`grep -w sys_call_table $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then    
            syscall=$DEX$POINT 
        else
	    POINT=`grep -w sys_call_table $SYSMAP | awk '{print $1}'`
            syscall=$(calculate_address $POINT) 
        fi      
		
        #modules#
        POINT=`grep -w modules $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            modules=$DEX$POINT 
        else
            POINT=`grep -w modules $SYSMAP | awk '{print $1}'`
            modules=$(calculate_address $POINT)
        fi 

        #task#
        POINT=`grep -w tasklist_lock $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            tskllock=$DEX$POINT 
        else
            POINT=`grep -w tasklist_lock $SYSMAP | awk '{print $1}'`
            tskllock=$(calculate_address $POINT)
        fi
		
        #net#
        POINT=`grep -w net_families $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            net_families=$DEX$POINT 
        else
	    POINT=`grep -w net_families $SYSMAP | awk '{print $1}'`
            net_families=$(calculate_address $POINT)
        fi
		
        POINT=`grep -w proto_list $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
	    proto_list=$DEX$POINT 
        else
            POINT=`grep -w proto_list $SYSMAP | awk '{print $1}'`
            proto_list=$(calculate_address $POINT)
        fi    
		
        #filesystems#
        POINT=`grep -w file_systems $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            file_systems=$DEX$POINT 
        else
	    POINT=`grep -w file_systems $SYSMAP | awk '{print $1}'`
            file_systems=$(calculate_address $POINT)
        fi    

        POINT=`grep -w super_blocks $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            super_blocks=$DEX$POINT 
        else
            POINT=`grep -w super_blocks $SYSMAP | awk '{print $1}'`
            super_blocks=$(calculate_address $POINT)
        fi 

        POINT=`grep -w sb_lock $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            sb_lock=$DEX$POINT 
        else
	    POINT=`grep -w sb_lock $SYSMAP | awk '{print $1}'`
            sb_lock=$(calculate_address $POINT)
        fi 


        POINT=`grep -w kallsyms_lookup_name $KALLSYMSMAP | awk '{print $1}'`
        if [ $POINT ]; then
            t_lookup_name=$DEX$POINT
            echo "k_lookup_name:$k_lookup_name"
        else
            POINT=`grep -w kallsyms_lookup_name  $SYSMAP | awk '{print $1}'`
            t_lookup_name=$(calculate_address $POINT)
        fi

		# dmeasure all #
        modprobe xsectcdmeasure \
            start_text=$stext end_text=$etext t_lookup_symbol_name=$sname  t_kallsyms_lookup_name=$t_lookup_name\
            syscall_table=$syscall \
            modules_addr=$modules \
            filesystems=$file_systems superblocks=$super_blocks sblock=$sb_lock \
            netfamilies=$net_families protolist=$proto_list \
            tasklistlock=$tskllock
}



start_fac()
{
	modprobe xsectcfac
}

start_udisk()
{
	modprobe xsectcudisk
}

start_net()
{
	modprobe sbinxsectcnet
}

tsb_start()
{
	if [ ! -f $SYSMAP ];then
		echo "$SYSMAP not exist"
		exit 1
	fi

	measure_disk
	if [ $? -ne 0 ]; then
		echo "measure disk error!!!"
		exit 1
	fi

	start_platform
	if [ $? -ne 0 ]; then
		echo "insmod platform ko error!!!"
		exit 1
	fi
	start_smeasure
	if [ $? -ne 0 ]; then
		echo "insmod xsectcsmeasure ko error!!!"
		exit 1
	fi
    start_dmeasure                                                                                                                                              
    if [ $? -ne 0 ]; then                                                                                             
        echo "insmod xsectcdmeasure ko error!!!"                                                                  
        exit 1                                                                                                    
    fi                                                                                                                

    start_fac                                                                                                         
    if [ $? -ne 0 ]; then                                                                                             
        echo "insmod xsectcfac ko error!!!"                                                                       
        exit 1                                                                                                    
    fi             
}

tsb_stop()
{
    rmmod xsectcfac
    rmmod xsectcdmeasure
	rmmod xsectcsmeasure

	while true
	do
        	refcount=`lsmod | egrep "^platform" | awk '{print $3}'`
        	if [ -z "$refcount" ]; then
                	break
        	fi
        	if [ "$refcount" -ge "1" ]; then
            		echo "platform in use, waiting..."
            		sleep 1
        	else
            		break
        	fi
	done

	rmmod platform
}

menu_start()
{
	case $OPT in

		stop)
			tsb_stop
			;;

		start)
			tsb_start
			;;

		disk)
			measure_disk
			;;

		*)
			echo "usage:"
			echo "$0 start | stop"
			exit 1
			;;
	esac
}

menu_start $1
