/*----------------------------------------------------------------------------+
*| |
*| 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);
}
}
}