/*----------------------------------------------------------------------------+ *| | *| 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; /** * Hooker for MediaRecorder. * Attach on Android Camera API (PackageManager.hasSystemFeature is captured by PackageManager hooker). * Attach on MediaRecorder class (for microphone for example). * @author Dimitri Kirchner * */ public class MediaRecorderHooker extends Hooker { public static final String NAME = "MediaRecorder"; public MediaRecorderHooker() { super(MediaRecorderHooker.NAME); } @Override public void attach() { attachOnCameraClass(); attachOnAudioRecordClass(); attachOnAudioManagerClass(); //We cannot hook the class MediaRecorder, since it is deeply related to JNI. //attachOnMediaRecorderClass(); } /** * Attach on Camera class */ private void attachOnCameraClass() { final String className = "android.hardware.Camera"; Map<String, Integer> methodsToHook = new HashMap<String, Integer>(); methodsToHook.put("open", 2); methodsToHook.put("getParameters", 1); methodsToHook.put("setParameters", 2); methodsToHook.put("startPreview", 1); methodsToHook.put("takePicture", 2); methodsToHook.put("release", 0); methodsToHook.put("enableShutterSound", 2); methodsToHook.put("getCameraInfo", 1); methodsToHook.put("getNumberOfCameras", 1); methodsToHook.put("lock", 2); methodsToHook.put("reconnect", 2); methodsToHook.put("setFaceDetectionListener", 2); methodsToHook.put("startFaceDetection", 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 attachOnAudioRecordClass() { final String className = "android.media.AudioRecord"; Map<String, Integer> methodsToHook = new HashMap<String, Integer>(); methodsToHook.put("getAudioFormat", 0); methodsToHook.put("getAudioSessionId", 0); methodsToHook.put("getAudioSource", 0); methodsToHook.put("getChannelConfiguration", 0); methodsToHook.put("getChannelCount", 0); methodsToHook.put("getRecordingState", 0); methodsToHook.put("getState", 0); methodsToHook.put("read", 1); methodsToHook.put("release", 0); methodsToHook.put("setNotificationMarkerPosition", 1); methodsToHook.put("setPositionNotificationPeriod", 1); methodsToHook.put("setRecordPositionUpdateListener", 1); methodsToHook.put("startRecording", 2); methodsToHook.put("stop", 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 attachOnAudioManagerClass() { final String className = "android.media.AudioManager"; Map<String, Integer> methodsToHook = new HashMap<String, Integer>(); methodsToHook.put("getParameters", 0); methodsToHook.put("getProperty", 0); methodsToHook.put("isMicrophoneMute", 0); methodsToHook.put("isSpeakerphoneOn", 0); methodsToHook.put("registerMediaButtonEventReceiver", 0); methodsToHook.put("registerRemoteControlClient", 0); methodsToHook.put("registerRemoteController", 0); methodsToHook.put("setParameters", 1); methodsToHook.put("setRingerMode", 0); methodsToHook.put("setSpeakerphoneOn", 2); methodsToHook.put("setRouting", 2); methodsToHook.put("setStreamMute", 1); methodsToHook.put("setStreamSolo", 1); methodsToHook.put("setStreamVolume", 1); 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 MediaRecorder class */ @SuppressWarnings("unused") private void attachOnMediaRecorderClass() { Map<String, Integer> methodsToHook = new HashMap<String, Integer>(); methodsToHook.put("setOutputFile", 2); methodsToHook.put("prepare", 1); methodsToHook.put("reset", 2); methodsToHook.put("setLocation", 2); //From 4.0.1 r1 methodsToHook.put("setAudioChannels", 2); //From 2.3 // methodsToHook.put("setCamera", 2); //This is native method. // methodsToHook.put("setAudioSource", 2); //native // methodsToHook.put("setOutputFormat", 1); //native // methodsToHook.put("start", 2); //native // methodsToHook.put("stop", 0); //native try { hookMethods(null, "android.media.MediaRecorder", methodsToHook); SubstrateMain.log("hooking android.media.MediaRecorder methods sucessful"); } catch (HookerInitializationException e) { SubstrateMain.log("hooking android.media.MediaRecorder methods has failed", e); } } }