In Android 5.1.1, all processes can be listed (ps
command) through an App (tested on AVD).
An Android application can be used as a background services that log (in logcat) all the processes that have a PPID the same as adbd process (recursively):
fun adbMonitor(){
try {
val process = Runtime.getRuntime().exec("/system/bin/ps")
val reader = BufferedReader(
InputStreamReader(process.inputStream)
)
var read: Int
val buffer = CharArray(4096)
val output = StringBuffer()
while (reader.read(buffer).also { read = it } > 0) {
output.append(buffer, 0, read)
}
reader.close()
process.waitFor()
val processes = output.toString().split("\n")
var pidADBD = ""
for (proc in processes){
val splitted = proc.split("\\s+".toRegex())
if (proc.isEmpty())
break
if (splitted[splitted.size -1] == "/sbin/adbd" ) {
pidADBD = splitted[1]
}
}
for (child in childProcesses(output.toString(), pidADBD)) {
Log.d("ADBD", Calendar.getInstance().getTime().toString() + " " + child)
}
} catch (e: IOException) {
throw RuntimeException(e)
} catch (e: InterruptedException) {
throw RuntimeException(e)
}
}
fun childProcesses(processList : String, pid : String) : List<String> {
var adbdChilds: List<String> = listOf<String>()
val processes = processList.split("\n")
for (proc in processes){
val splitted = proc.split("\\s+".toRegex())
if (proc.isEmpty())
continue
if (splitted[2] == pid ) {
Log.d("ADBD", splitted[splitted.size -1])
adbdChilds += childProcesses(processList, splitted[1])
}
}
return adbdChilds
}
Starting the service:
private fun startService() {
if (isServiceStarted) return
isServiceStarted = true
setServiceState(this, ServiceState.STARTED)
// we need this lock so our service gets not affected by Doze Mode
wakeLock =
(getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Monitoring::lock").apply {
acquire()
}
}
// we're starting a loop in a coroutine
GlobalScope.launch(Dispatchers.IO) {
while (isServiceStarted) {
launch(Dispatchers.IO) {
adbMonitor()
}
delay(100)
}
Log.d("Monitoring","End of the loop for the service")
}
}
And in the MainActivity:
Intent(this, Monitoring::class.java).also {
it.action = Actions.START.toString()
startService(it)
}
Example of logs in logcat:
07-15 23:05:48.653 13697-13778/com.example.audit D/ADBD: logcat
07-15 23:05:48.750 13697-13844/com.example.audit D/ADBD: /system/bin/sh
07-15 23:05:48.823 13697-13851/com.example.audit D/ADBD: /system/bin/sh
07-15 23:05:49.268 13697-13770/com.example.audit D/ADBD: dumpsys
07-15 23:05:49.293 13697-13770/com.example.audit D/ADBD: /system/bin/sh
07-15 23:05:49.301 13697-13770/com.example.audit D/ADBD: /data/local/tmp/perfd/transport
07-15 23:05:49.317 13697-13770/com.example.audit D/ADBD: /system/bin/sh
07-15 23:05:49.326 13697-13770/com.example.audit D/ADBD: top
07-15 23:05:49.769 13697-13723/com.example.audit D/ADBD: /data/local/tmp/perfd/transport
07-15 23:05:50.058 13697-13724/com.example.audit D/ADBD: /system/bin/sh
07-15 23:05:50.526 13697-13794/com.example.audit D/ADBD: /system/bin/sh
Note that not all the commands will be logged as there is a delay of 100 milliseconds.
If needed, all the source code of the app can be provided.