package fuzion24.device.vulnerability.vulnerabilities.framework.media;

import android.content.Context;
import android.os.Build;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import fuzion24.device.vulnerability.util.CPUArch;
import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;
import fuzion24.device.vulnerability.vulnerabilities.helper.BinaryAssets;
import fuzion24.device.vulnerability.vulnerabilities.helper.KMPMatch;
import fuzion24.device.vulnerability.vulnerabilities.helper.SystemUtils;

/**
 * Created by fuzion24 on 11/16/15.
 */


/*
https://android.googlesource.com/platform/external/tremolo/+/3830d0b585ada64ee75dea6da267505b19c622fd%5E%21/#F1
https://android.googlesource.com/platform/frameworks/av/+/c6a2815eadfce62702d58b3fa3887f24c49e1864%5E%21/#F0

2|shell@flounder_lte:/ $ grep -F "b/23881715" /system/lib/libstagefright.so
1|shell@flounder_lte:/ $ grep -F "b/23881715" /system/lib64/libstagefright.so
*/



public class CVE_2015_6608 implements VulnerabilityTest {

    @Override
    public String getCVEorID() {
        return "CVE-2015-6608";
    }

    @Override
    public boolean isVulnerable(Context context) throws Exception {
        /*
            The patch includes logging messages for when the vulnerable code paths are hit.
            We can simply look for the inclusion of the strings in the libraries to determine
            whether or not the device has a patched libstagefright.so
         */

        File stagefrightlib = new File("/system/lib/libstagefright.so");
        File stagefrightlib64 = new File("/system/lib64/libstagefright.so");

        if(!stagefrightlib.exists() || !stagefrightlib.isFile()){
            throw new Exception("Stagefright doesn't exist or is not a file");
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream((int)stagefrightlib.length());
        BinaryAssets.copy(new FileInputStream(stagefrightlib), baos);

        byte[] libstagefrightSO = baos.toByteArray();

        KMPMatch binMatcher = new KMPMatch();
        int indexOf = binMatcher.indexOf(libstagefrightSO, "b/23680780".getBytes());

        boolean libstagefrightVulnerableToBug23680780 = indexOf == -1;
        indexOf = binMatcher.indexOf(libstagefrightSO, "b/23881715".getBytes());
        boolean libstagefrightvulnerableToBug23881715 = indexOf == -1;
        indexOf = binMatcher.indexOf(libstagefrightSO, "b/23876444".getBytes());
        boolean libstagerightVulnerableToBug23876444 = indexOf == -1;


        return  libstagefrightVulnerableToBug23680780 ||
                (libstagefrightvulnerableToBug23881715 && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) ||  // The vulnerable code doesn't exist on 5.x
                libstagerightVulnerableToBug23876444;

    }

    @Override
    public List<CPUArch> getSupportedArchitectures() {
        List<CPUArch> supportedArchs = new ArrayList<CPUArch>();
        supportedArchs.add(CPUArch.ARM7);
        supportedArchs.add(CPUArch.ARM8);
        supportedArchs.add(CPUArch.X86);
        return null;
    }
}

@@ -2117,16 +2117,26 @@
 Match();
+%0A%0A        
 %0A       
@@ -2213,17 +2213,16 @@
 tes());%0A
-%0A
         
@@ -2588,16 +2588,200 @@
 == -1;%0A%0A
+        //Only affects L and M%0A        if(Build.VERSION.SDK_INT != Build.VERSION_CODES.M && Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP)%7B%0A            return false;%0A        %7D%0A
 %0A       
@@ -2846,17 +2846,16 @@
         
-(
 libstage
@@ -2888,112 +2888,10 @@
 715 
-&& Build.VERSION.SDK_INT %3C Build.VERSION_CODES.LOLLIPOP) %7C%7C  // The vulnerable code doesn't exist on 5.x
+%7C%7C
 %0A   
@@ -3227,12 +3227,22 @@
 urn 
-null
+supportedArchs
 ;%0A  

Return proper CPU archiecture + check Android version(s)