content: /*----------------------------------------------------------------------------+
   *|                                                                           |
   *|                          Android's Hooker                                 |
   *|                                                                           |
   *+---------------------------------------------------------------------------+
   *| Copyright (C) 2011 Georges Bossert and Dimitri Kirchner                   |
   *| 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 3 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, see <http://www.gnu.org/licenses/>.      |
   *+---------------------------------------------------------------------------+
   *| @url      : http://www.amossys.fr                                         |
   *| @contact  : android-hooker@amossys.fr                                     |
   *| @sponsors : Amossys, http://www.amossys.fr                                |
   *+---------------------------------------------------------------------------+
   */
   
  package com.amossys.hooker.hookers;
  
  import java.util.HashMap;
  import java.util.Map;
  
  import com.amossys.hooker.SubstrateMain;
  import com.amossys.hooker.exceptions.HookerInitializationException;
  
  /**
   * @author Georges Bossert
   * 
   */
  public class NetworkHooker extends Hooker {
  
    public static final String NAME = "Network";
  
    public NetworkHooker() {
      super(NetworkHooker.NAME);
    }
  
  
    @Override
    public void attach() {
      attachOnIOBridgeClass();
      attachOnAbstractHttpClientClass();
      attachOnHttpGetClass();
      attachOnUrlClass();
      // attachOnUrlConnectionClass();
      attachOnIOExceptionClass();
      attachOnSocketClass();
      attachOnProxyClass();
      attachOnServerSocketClass();
      attachOnSSLCertificateSocketFactoryClass();
      attachOnSSLParametersClass();
      attachOnSSLContextClass();
      attachOnHttpURLConnection();
      attachOnHttpsURLConnection();
      attachOnWebviewClass();
      attachOnWebSettingsClass();
    }
  
  
  	private void attachOnHttpsURLConnection() {
  		final String className = "javax.net.ssl.HttpsURLConnection";
  
  		Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
  		methodsToHook.put("getDefaultHostnameVerifier", 0);
  		methodsToHook.put("getDefaultSSLSocketFactory", 0);
  		methodsToHook.put("getHostnameVerifier", 0);
  		methodsToHook.put("getLocalPrincipal", 0);
  		methodsToHook.put("getSSLSocketFactory", 0);
  		methodsToHook.put("setDefaultHostnameVerifier", 0);
  		methodsToHook.put("setDefaultSSLSocketFactory", 0);
  		methodsToHook.put("setHostnameVerifier", 0);
  		methodsToHook.put("setSSLSocketFactory", 0);
  
  		try {
  			hookMethods(null, className, methodsToHook);
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods sucessful").toString());
  
  		} catch (HookerInitializationException e) {
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods has failed").toString(), e);
  		}
  	}
    
    /**
     * 
     */
    private void attachOnHttpURLConnection() {
      final String className = "java.net.HttpURLConnection";
  
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("HttpURLConnection", 0);
      methodsToHook.put("getErrorStream", 0);
      methodsToHook.put("getFollowRedirects", 0);
      methodsToHook.put("getHeaderFieldDate", 0);
      methodsToHook.put("getInstanceFollowRedirects", 0);
      methodsToHook.put("getPermission", 0);
      methodsToHook.put("setChunkedStreamingMode", 0);
      methodsToHook.put("setFixedLengthStreamingMode", 0);
      methodsToHook.put("setFollowRedirects", 0);
      methodsToHook.put("setInstanceFollowRedirects", 0);
      methodsToHook.put("setRequestMethod", 0);
      methodsToHook.put("setDoOutput", 0);
      
  
      try {
        hookMethods(null, className, methodsToHook);
        SubstrateMain.log(new StringBuilder("hooking ").append(className)
            .append(" methods sucessful").toString());
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log(
            new StringBuilder("hooking ").append(className).append(" methods has failed").toString(),
            e);
      }
  
    }
  
  
    /**
     * Attach on SSLContext class
     */
    private void attachOnSSLContextClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("getInstance", 0);
      methodsToHook.put("init", 0);
      methodsToHook.put("createSSLEngine", 0);
      methodsToHook.put("getDefault", 0);
  
      try {
        hookMethods(null, "javax.net.ssl.SSLContext", methodsToHook);
        SubstrateMain.log("hooking javax.net.ssl.SSLContext methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking javax.net.ssl.SSLContext methods has failed", e);
      }
  
    }
  
    /**
     * Attach on SSLParameters class
     */
    private void attachOnSSLParametersClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("SSLParameters", 0);
      methodsToHook.put("setCipherSuites", 0);
      methodsToHook.put("setNeedClientAuth", 0);
      methodsToHook.put("setProtocols", 0);
      methodsToHook.put("setWantClientAuth", 0);
  
      try {
        hookMethods(null, "javax.net.ssl.SSLParameters", methodsToHook);
        SubstrateMain.log("hooking javax.net.ssl.SSLParameters methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking javax.net.ssl.SSLParameters methods has failed", e);
      }
  
    }
  
    /**
     * Attach on SSLCertificateSocketFactory class
     */
    private void attachOnSSLCertificateSocketFactoryClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("SSLCertificateSocketFactory", 0);
      methodsToHook.put("getDefault", 0);
      methodsToHook.put("createSocket", 0);
      methodsToHook.put("getHttpSocketFactory", 0);
      methodsToHook.put("getNpnSelectedProtocol", 0);
      methodsToHook.put("setHostname", 0);
      methodsToHook.put("setKeyManager", 0);
      methodsToHook.put("setNpnProtocols", 0);
      methodsToHook.put("setTrustManagers", 0);
      methodsToHook.put("setUseSessionTickets", 0);
  
      try {
        hookMethods(null, "android.net.SSLCertificateSocketFactory", methodsToHook);
        SubstrateMain.log("hooking android.net.SSLCertificateSocketFactory methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking android.net.SSLCertificateSocketFactory methods has failed", e);
      }
  
    }
  
    /**
     * Attach on ServerSocket class
     */
    private void attachOnServerSocketClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("ServerSocket", 0);
      methodsToHook.put("accept", 0);
      methodsToHook.put("bind", 0);
  
      try {
        hookMethods(null, "java.net.ServerSocket", methodsToHook);
        SubstrateMain.log("hooking java.net.ServerSocket methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking java.net.ServerSocket methods has failed", e);
      }
  
    }
  
    /**
     * Attach on Proxy class
     */
    private void attachOnProxyClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("Proxy", 0);
  
      try {
        hookMethods(null, "java.net.Proxy", methodsToHook);
        SubstrateMain.log("hooking java.net.Proxy methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking java.net.Proxy methods has failed", e);
      }
  
    }
  
    /**
     * Attach on Socket class
     */
    private void attachOnSocketClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("Socket", 2);
      methodsToHook.put("bind", 2);
      methodsToHook.put("close", 1);
      methodsToHook.put("connect", 2);
      methodsToHook.put("getInetAddress", 1);
      methodsToHook.put("getInputStream", 1);
      methodsToHook.put("getLocalAddress", 1);
      methodsToHook.put("getLocalPort", 1);
      methodsToHook.put("getLocalSocketAddress", 1);
      methodsToHook.put("getOutputStream", 1);
      methodsToHook.put("getPort", 1);
      methodsToHook.put("sendUrgentData", 2);
      methodsToHook.put("getPort", 1);
      methodsToHook.put("setReuseAddress", 1);
      methodsToHook.put("setSocketImplFactory", 1);
      methodsToHook.put("setTcpNoDelay", 1);
      methodsToHook.put("shutdownInput", 1);
      methodsToHook.put("shutdownOutput", 1);
  
      try {
        hookMethods(null, "java.net.Socket", methodsToHook);
        SubstrateMain.log("hooking java.net.Socket methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking java.net.Socket methods has failed", e);
      }
  
    }
  
    /**
     * Attach on HttpGet class
     */
    private void attachOnHttpGetClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("HttpGet", 2);
      methodsToHook.put("getMethod", 1);
      methodsToHook.put("getURI", 1);
  
      try {
        hookMethods(null, "org.apache.http.client.methods.HttpGet", methodsToHook);
        SubstrateMain.log("hooking org.apache.http.client.methods.HttpGet methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking org.apache.http.client.methods.HttpGet methods has failed", e);
      }
  
    }
  
    /**
     * Attach on AbstractHttpClient class
     */
    private void attachOnAbstractHttpClientClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("execute", 2);
      methodsToHook.put("getAuthSchemes", 1);
      methodsToHook.put("getCookiesStore", 1);
      methodsToHook.put("getCredentialProvider", 1);
      methodsToHook.put("getParams", 1);
      methodsToHook.put("setParams", 2);
  
      try {
        hookMethods(null, "org.apache.http.impl.client.AbstractHttpClient", methodsToHook);
        SubstrateMain.log("hooking org.apache.http.impl.client.AbstractHttpClient methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log(
            "hooking org.apache.http.impl.client.AbstractHttpClient methods has failed", e);
      }
  
    }
  
    @SuppressWarnings("unused")
    private void attachOnUrlConnectionClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("addRequestProperty", 0);
      methodsToHook.put("connect", 1);
      methodsToHook.put("getContent", 1);
      methodsToHook.put("getContentEncoding", 1);
      methodsToHook.put("getContentType", 0);
      methodsToHook.put("getContentLength", 0);
      methodsToHook.put("getInputStream", 1);
      methodsToHook.put("getOutputStream", 1);
      methodsToHook.put("getURL", 0);
      methodsToHook.put("setRequestProperty", 1);
  
      try {
        hookMethods(null, "java.net.HttpURLConnection", methodsToHook);
        SubstrateMain.log("hooking java.net.HttpURLConnection methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking java.net.HttpURLConnection methods has failed", e);
      }
    }
  
    private void attachOnUrlClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("URL", 0);
      methodsToHook.put("getAuthority", 0);
      methodsToHook.put("getContent", 0);
      methodsToHook.put("getDefaultPort", 0);
      methodsToHook.put("getFile", 0);
      methodsToHook.put("getHost", 0);
      methodsToHook.put("getPath", 0);
      methodsToHook.put("getPort", 0);
      methodsToHook.put("getProtocol", 0);
      methodsToHook.put("getQuery", 0);
      methodsToHook.put("openConnection", 1);
      methodsToHook.put("openStream", 1);
      methodsToHook.put("toURI", 0);
  
      try {
        hookMethods(null, "java.net.URL", methodsToHook);
        SubstrateMain.log("hooking 	java.net.URL methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking 	java.net.URL methods has failed", e);
      }
    }
  
    private void attachOnIOExceptionClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      methodsToHook.put("IOException", 0);
  
      try {
        hookMethods(null, "java.io.IOException", methodsToHook);
        SubstrateMain.log("hooking 	java.io.IOException methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking 	java.io.IOException methods has failed", e);
      }
    }
  
    /**
     * Attach on IOBridge class
     */
    private void attachOnIOBridgeClass() {
      Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
      // methodsToHook.put("open", 1); This is in common with filesystem operation.
      methodsToHook.put("recvfrom", 1);
      // methodsToHook.put("read", 1);
  
      // methodsToHook.put("write", 2);
      methodsToHook.put("sendto", 2);
  
      methodsToHook.put("getSocketLocalAddress", 1);
      methodsToHook.put("getSocketLocalPort", 1);
  
      methodsToHook.put("closeSocket", 1);
      methodsToHook.put("connectErrno", 1);
      methodsToHook.put("connect", 2);
      methodsToHook.put("bind", 1);
  
      try {
        hookMethods(null, "libcore.io.IoBridge", methodsToHook);
        SubstrateMain.log("libcore.io.IoBridge methods sucessful");
  
      } catch (HookerInitializationException e) {
        SubstrateMain.log("hooking libcore.io.IoBridge methods has failed", e);
      }
  
    }
    
  	private void attachOnWebviewClass() {
  		final String className = "android.webkit.WebView";
  
  		Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
  		methodsToHook.put("addJavascriptInterface", 2);
  		methodsToHook.put("capturePicture", 2);
  		methodsToHook.put("clearSslPreferences", 1);
  		methodsToHook.put("evaluateJavascript", 2);
  		methodsToHook.put("findAddress", 0);
  		methodsToHook.put("getCertificate", 0);
  		methodsToHook.put("getSettings", 0);
  		
  		methodsToHook.put("isPrivateBrowsingEnabled", 0);
  		methodsToHook.put("loadData", 2);
  		methodsToHook.put("loadDataWithBaseURL", 2);
  		methodsToHook.put("loadUrl", 2);
  		methodsToHook.put("postUrl", 0);
  		methodsToHook.put("removeJavascriptInterface", 2);
  		methodsToHook.put("restoreState", 1);
  		methodsToHook.put("savePassword", 1);
  		methodsToHook.put("saveState", 1);
  		methodsToHook.put("setCertificate", 2);
  		methodsToHook.put("setHttpAuthUsernamePassword", 2);
  		methodsToHook.put("setWebContentsDebuggingEnabled", 2);
  		
  		try {
  			hookMethods(null, className, methodsToHook);
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods sucessful").toString());
  
  		} catch (HookerInitializationException e) {
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods has failed").toString(), e);
  		}
  	}
  	
  	private void attachOnWebSettingsClass() {
  		final String className = "android.webkit.WebSettings";
  
  		Map<String, Integer> methodsToHook = new HashMap<String, Integer>();
  
  		methodsToHook.put("setAllowContentAccess", 2);
  		methodsToHook.put("setAllowFileAccess", 2);
  		methodsToHook.put("setDatabaseEnabled", 2);
  		methodsToHook.put("setDatabasePath", 2);
  		methodsToHook.put("setJavaScriptEnabled", 2);
  		methodsToHook.put("setSavePassword", 2);
  		
  		try {
  			hookMethods(null, className, methodsToHook);
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods sucessful").toString());
  
  		} catch (HookerInitializationException e) {
  			SubstrateMain.log(new StringBuilder("hooking ").append(className)
  					.append(" methods has failed").toString(), e);
  		}
  	}
  
  }
  