Skip to content

Instantly share code, notes, and snippets.

@vvb2060
Created July 19, 2022 17:12
Show Gist options
  • Save vvb2060/a3d40084cd9273b65a15f8a351b4eb0e to your computer and use it in GitHub Desktop.
Save vvb2060/a3d40084cd9273b65a15f8a351b4eb0e to your computer and use it in GitHub Desktop.
monitor app process start
#include <unistd.h>
#include <string>
#include <cinttypes>
#include <android/log.h>
#include <sys/system_properties.h>
using namespace std;
extern "C" {
struct logger_entry {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry) */
int32_t pid; /* generating process's pid */
uint32_t tid; /* generating process's tid */
uint32_t sec; /* seconds since Epoch */
uint32_t nsec; /* nanoseconds */
uint32_t lid; /* log id of the payload, bottom 4 bits currently */
uint32_t uid; /* generating process's uid */
};
#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
struct log_msg {
union [[gnu::aligned(4)]] {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
struct logger_entry entry;
};
};
[[gnu::weak]] struct logger_list *android_logger_list_alloc(int mode, unsigned int tail, pid_t pid);
[[gnu::weak]] void android_logger_list_free(struct logger_list *list);
[[gnu::weak]] int android_logger_list_read(struct logger_list *list, struct log_msg *log_msg);
[[gnu::weak]] struct logger *android_logger_open(struct logger_list *list, log_id_t id);
typedef struct [[gnu::packed]] {
int32_t tag; // Little Endian Order
} android_event_header_t;
typedef struct [[gnu::packed]] {
int8_t type; // EVENT_TYPE_INT
int32_t data; // Little Endian Order
} android_event_int_t;
typedef struct [[gnu::packed]] {
int8_t type; // EVENT_TYPE_STRING;
int32_t length; // Little Endian Order
char data[];
} android_event_string_t;
typedef struct [[gnu::packed]] {
int8_t type; // EVENT_TYPE_LIST
int8_t element_count;
} android_event_list_t;
// 30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
typedef struct [[gnu::packed]] {
android_event_header_t tag;
android_event_list_t list;
android_event_int_t user;
android_event_int_t pid;
android_event_int_t uid;
android_event_string_t process_name;
// android_event_string_t type;
// android_event_string_t component;
} android_event_am_proc_start;
}
void ProcessBuffer(struct logger_entry *buf) {
auto *eventData = reinterpret_cast<const unsigned char *>(buf) + buf->hdr_size;
auto *event_header = reinterpret_cast<const android_event_header_t *>(eventData);
if (event_header->tag != 30014) return;
auto *am_proc_start = reinterpret_cast<const android_event_am_proc_start *>(eventData);
printf("user=%" PRId32" pid=%" PRId32" uid=%" PRId32" proc=%.*s\n",
am_proc_start->user.data, am_proc_start->pid.data, am_proc_start->uid.data,
am_proc_start->process_name.length, am_proc_start->process_name.data);
}
[[noreturn]] void Run() {
while (true) {
bool first;
__system_property_set("persist.log.tag", "");
unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{
android_logger_list_alloc(0, 1, 0), &android_logger_list_free};
auto *logger = android_logger_open(logger_list.get(), LOG_ID_EVENTS);
if (logger != nullptr) [[likely]] {
first = true;
} else {
continue;
}
struct log_msg msg{};
while (true) {
if (android_logger_list_read(logger_list.get(), &msg) <= 0) [[unlikely]] {
break;
}
if (first) [[unlikely]] {
first = false;
continue;
}
ProcessBuffer(&msg.entry);
}
sleep(1);
}
}
int main(int argc, char *argv[]) {
Run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment