“地铁偷拍门事件”真正的加害者隐藏在幕后
她作为一个新闻系的研究生明知对方没有偷拍的事实情况下,伪装成“受害者”的身份,打着“维权”的旗号,刻意制造冲突,利用网友的同情心,引导舆论攻击无辜的农民大叔,在农民大叔和儿子的要求下,该女子一边哭一边道歉,也得到了他们一家人的谅解。真的是被这操作恶心坏了,恶心的我赶紧去应用市场下载了某拍摄软件分析了一波,这些软件才是真正的偷拍!
学习目录
1. 某软件的分析
2. 某软件的复现
1. 某软件的分析
像应用市场上下载的某些app,名义上说着用于什么场景,实际上大都扮演着吞噬用户的个人信息的角色,这些软件就像早期的那些病毒软件,勒索,偷拍,恶意获取用户的个人信息,他们的操作也非常简单,对于安卓的四大组件玩的非常的溜,熟练工净整这些歪门邪道,真是可恶至极。应用市场上找了一款app很简单,看看他是怎么做的,后台可以开启摄像机,屏幕之前可以打游戏还能录别人的。 既然它需要开启摄像头直接搜索getSystemService("camera")或者 cameraManager.openCamera这些api急速定位到他的位置,和开始预想的差不多,就是通通过前台还有后台服务来进行摄像机的隐藏,让其不可见。代码简单看看记录下
private void getRunningServices() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mServices = am.getRunningServices(Integer.MAX_VALUE);
List<ActivityManager.RunningServiceInfo> list = mServices;
if (list != null && !list.isEmpty()) {
for (ActivityManager.RunningServiceInfo service : list) {
Log.i("RunningServices", service.service.toString());
Log.i("RunningServices", "PID: " + service.pid + ", UID: " + service.uid);
Log.i("RunningServices", service.process + ", Foreground: " + service.foreground);
}
}
}
public void stackTrace(){
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement element : stackTrace) {
}
}
String b10;
Set physicalCameraIds;
d9.m mVar;
j0 j0Var;
if (this.f18118z.get()) {
return;
}
this.f18118z.set(true);
synchronized (this.f18100g) {
d9.d dVar = this.f18110q;
if (dVar != null && (mVar = dVar.f11438a) != null && (j0Var = mVar.J) != null) {
j0Var.f(this.G);
}
this.A.set(false);
this.f18117y.set(false);
y8.d dVar2 = y8.d.f18541a;
y8.d.g(this.f18095b).unregisterAvailabilityCallback(this.D);
if (this.f18098e != null) {
return;
}
m();
Object systemService = this.f18095b.getSystemService("camera");
a6.e.i(systemService, "null cannot be cast to non-null type android.hardware.camera2.CameraManager");
CameraManager cameraManager = (CameraManager) systemService;
try {
b10 = this.f18094a.b();
} catch (Exception e9) {
this.f18096c.postDelayed(new v1.n(3, this, e9, z10), 1500L);
}
if (!this.f18101h.tryAcquire(3000L, TimeUnit.MILLISECONDS)) {
gb.c.f12939a.d("Camera onError openCamera tryAcquire", new Object[0]);
j.i(this, "Tried acquiring timeout", false, 6);
this.f18118z.set(false);
a((r12 & 1) != 0 ? false : false, (r12 & 2) != 0, (r12 & 4) != 0 ? false : false, false, (r12 & 16) != 0 ? false : false);
return;
}
if (Build.VERSION.SDK_INT >= 28) {
if (y8.d.f18545e) {
List list = y8.d.f18543c;
if (list == null) {
list = w9.j.f18148s;
}
if (!list.contains(b10)) {
Iterator it = list.iterator();
while (true) {
if (!it.hasNext()) {
break;
}
String str = (String) it.next();
physicalCameraIds = y8.d.c(y8.d.f18541a, this.f18095b, str).getPhysicalCameraIds();
if (physicalCameraIds.contains(b10)) {
b10 = str;
break;
}
}
}
}
h0.h hVar = this.f18106m;
a6.e.h(hVar);
cameraManager.openCamera(b10, hVar, this.N);
} else {
cameraManager.openCamera(b10, this.N, this.f18105l);
}
this.F = 0;
public final boolean A(CaptureRequest.Builder builder, CaptureRequest.Builder builder2, boolean z10) {
boolean z11;
CaptureRequest.Key key;
Integer num;
Integer num2;
b9.e eVar = this.f18094a;
int s10 = eVar.s(z10);
Integer num3 = (Integer) builder.get(CaptureRequest.CONTROL_AF_MODE);
if (num3 == null || s10 != num3.intValue()) {
builder.set(CaptureRequest.CONTROL_AF_MODE, Integer.valueOf(s10));
if (builder2 != null) {
builder2.set(CaptureRequest.CONTROL_AF_MODE, Integer.valueOf(s10));
}
z11 = true;
} else {
z11 = false;
}
if (s10 != 0) {
if (s10 == 1 && ((num2 = (Integer) builder.get(CaptureRequest.CONTROL_AF_TRIGGER)) == null || 1 != num2.intValue())) {
builder.set(CaptureRequest.CONTROL_AF_TRIGGER, 1);
if (builder2 == null) {
return true;
}
key = CaptureRequest.CONTROL_AF_TRIGGER;
num = 1;
builder2.set(key, num);
return true;
}
return z11;
}
Float f10 = (Float) y8.d.c(y8.d.f18541a, this.f18095b, eVar.b()).get(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE);
if (f10 != 0 && !a6.e.d(f10, (Float) builder.get(CaptureRequest.LENS_FOCUS_DISTANCE))) {
builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, f10);
if (builder2 == null) {
return true;
}
key = CaptureRequest.LENS_FOCUS_DISTANCE;
num = f10;
builder2.set(key, num);
return true;
}
return z11;
}
2.复现
创建前台服务或者后台服务,来防止app划到后台被系统kill掉,通过点击按钮打开摄像机,将保存的视频存在本地。
创建服务
public class VideoRecorderService extends Service {
private static final String TAG = "VideoRecorderService";
private static final String CHANNEL_ID = "VideoRecorderServiceServiceChannel";
private static final int NOTIFICATION_ID = 1;
private CameraDevice mCameraDevice;
private MediaRecorder mMediaRecorder;
private CameraCaptureSession mCaptureSession;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e("yyff", "onBind");
return null;
}
@Override
public void onCreate() {
super.onCreate();
startBackgroundThread();
Log.e("yyff", "onCreate");
// 创建通知
createNotificationChannel();
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Background Video Recorder")
.setContentText("Recording video in the background")
.setSmallIcon(R.mipmap.ic_launcher)
.build();
// 开启前台服务
startForeground(NOTIFICATION_ID, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startRecording();
Log.e("yyff", "onStartCommand");
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
stopRecording();
stopBackgroundThread();
super.onDestroy();
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("BackgroundVideoRecorderThread");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
打开相机开始录制并将录制的视频保存在本地
private void startRecording() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if (cameraManager == null) {
return;
}
Log.e("yyff", "startRecording");
String cameraId = null;
try {
for (String id : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
cameraId = id;
break;
}
}
if (cameraId == null) {
return;
}
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] videoSizes = map.getOutputSizes(MediaRecorder.class);
Size videoSize = videoSizes[0];
// 设置 MediaRecorder
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
mMediaRecorder.setVideoEncodingBitRate(5000000);
mMediaRecorder.setVideoFrameRate(30);
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
"background_video.mp4");
mMediaRecorder.setOutputFile(outputFile.getAbsolutePath());
mMediaRecorder.prepare();
// 打开相机
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
Log.e("yyff", "onOpened");
startCameraCaptureSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
Log.e("yyff", "onDisconnected");
cameraDevice.close();
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
cameraDevice.close();
}
}, mBackgroundHandler);
} catch (CameraAccessException | IOException e) {
e.printStackTrace();
}
启动MediaRecorder来进行录制并设置了相机的参数为自动对焦以持续捕捉预览数据
private void startCameraCaptureSession() {
try {
Surface recorderSurface = mMediaRecorder.getSurface();
final CaptureRequest.Builder requestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
requestBuilder.addTarget(recorderSurface);
mCameraDevice.createCaptureSession(Arrays.asList(recorderSurface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
mCaptureSession = cameraCaptureSession;
try {
requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
mCaptureSession.setRepeatingRequest(requestBuilder.build(), null, mBackgroundHandler);
mMediaRecorder.start();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
进行了还原和拼凑,一个后台运行的app诞生了。经过测试确实是可以后台运行还可以录像,以上代码仅供学习参考,未经过他人允许,偷窥、偷拍、窃听、散布他人隐私的,处五日以下拘留或者五百元以下罚款;情节较重的,处五日以上十日以下拘留,可以并处五百元以下罚款。
在拍摄过程中,未经他人允许,不能把路人的具体模样拍到视频里。如果必须要出镜,在未征得他人同意的情况下,要将被拍摄者可识别的标记去掉,如脸部及其他标志化信息。同时要注意不能跟拍、偷拍、尾随别人去拍摄,这涉嫌侵犯他人隐私权和生活安宁权。
我的公众号二维码 喜欢的可以关注下 不定期分享干货 安卓和ios逆向 移动安全 以及二进制算法还原
[培训]《安卓高级研修班(网课)》月薪三万计划,掌
握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
最后于 2023-6-16 11:15
被涿州飞神编辑
,原因: 增加公众号二维码