Advertisement
wanam

xposed_logcat.cpp

Jun 7th, 2015
355
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.98 KB | None | 0 0
  1. /**
  2.  * This file includes the Xposed service, which is especially used to work around SELinux restrictions.
  3.  */
  4.  
  5. #define LOG_TAG "Xposed"
  6. #define CAP_SYSLOG 34
  7. #define AID_LOG 1007
  8.  
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13.  
  14. #include "xposed.h"
  15. #include "xposed_logcat.h"
  16.  
  17.  
  18. namespace xposed {
  19. namespace logcat {
  20.  
  21. ////////////////////////////////////////////////////////////
  22. // Declarations
  23. ////////////////////////////////////////////////////////////
  24.  
  25. char marker[50];
  26.  
  27.  
  28. ////////////////////////////////////////////////////////////
  29. // Functions
  30. ////////////////////////////////////////////////////////////
  31.  
  32. static void execLogcat() {
  33.     // Execute a logcat command that will keep running in the background
  34.     execl("/system/bin/logcat", "logcat",
  35.         "-v", "time",            // include timestamps in the log
  36.         "-s",                    // be silent by default, except for the following tags
  37.         "XposedStartupMarker:D", // marks the beginning of the current log
  38.         "Xposed:I",              // Xposed framework and default logging
  39.         "appproc:I",             // app_process
  40.         "XposedInstaller:I",     // Xposed Installer
  41.         "art:F",                 // ART crashes
  42.         "libc:F",                // Native crashes
  43.         "DEBUG:I",               // Native crashes
  44.         (char*) 0);
  45.  
  46.     // We only get here in case of errors
  47.     ALOGE("Could not execute logcat: %s", strerror(errno));
  48.     exit(EXIT_FAILURE);
  49. }
  50.  
  51. #ifndef dprintf
  52. static inline int dprintf(int fd, const char *format, ...) {
  53.     char* message;
  54.     va_list args;
  55.     va_start(args, format);
  56.     int size = vasprintf(&message, format, args);
  57.     if (size > 0) {
  58.         write(fd, message, size);
  59.         free(message);
  60.     }
  61.     va_end(args);
  62.     return size;
  63. }
  64. #endif
  65.  
  66. static void runDaemon(int pipefd) {
  67.     xposed::setProcessName("xposed_logcat");
  68.  
  69.     umask(0);
  70.     int logfile = open(XPOSEDLOG, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  71.     if (logfile < 0) {
  72.         ALOGE("Could not open %s: %s", XPOSEDLOG, strerror(errno));
  73.         exit(EXIT_FAILURE);
  74.     }
  75.  
  76.     FILE* pipe = fdopen(pipefd, "r");
  77.     if (pipe == NULL) {
  78.         ALOGE("fdopen failed for pipe file descriptor %d: %s", pipefd, strerror(errno));
  79.         exit(EXIT_FAILURE);
  80.     }
  81.  
  82.     char buf[512];
  83.     bool foundMarker = false;
  84.     long totalSize = 0;
  85.     while (fgets(buf, sizeof(buf), pipe) != NULL) {
  86.         if (buf[0] == '-')
  87.             continue; // beginning of <logbuffer type>
  88.  
  89.         if (!foundMarker) {
  90.             if (strstr(buf, "XposedStartupMarker") != NULL && strstr(buf, marker) != NULL) {
  91.                 foundMarker = true;
  92.             }
  93.             continue;
  94.         }
  95.  
  96.         int len = strlen(buf);
  97.         write(logfile, buf, len);
  98.  
  99.         totalSize += len;
  100.         if (totalSize > XPOSEDLOG_MAX_SIZE) {
  101.             dprintf(logfile, "\nReached maximum log size (%'d kB), further lines won't be logged.\n", XPOSEDLOG_MAX_SIZE / 1024);
  102.             exit(EXIT_FAILURE);
  103.         }
  104.     }
  105.  
  106.     ALOGE("Broken pipe to logcat: %s", strerror(ferror(pipe)));
  107.     close(logfile);
  108.     exit(EXIT_FAILURE);
  109. }
  110.  
  111. void start() {
  112.     sprintf(marker, "Current time: %d, PID: %d", (int) time(NULL), getpid());
  113.     ALOG(LOG_DEBUG, "XposedStartupMarker", marker, NULL);
  114.  
  115.     // Fork to create a daemon
  116.     pid_t pid;
  117.     if ((pid = fork()) < 0) {
  118.         ALOGE("Fork for Xposed logcat daemon failed: %s", strerror(errno));
  119.         return;
  120.     } else if (pid != 0) {
  121.         return;
  122.     }
  123.  
  124.     setgid(AID_LOG);
  125.  
  126.     xposed::dropCapabilities(CAP_SYSLOG);
  127.  
  128. #if XPOSED_WITH_SELINUX
  129.     if (xposed->isSELinuxEnabled) {
  130.         if (setcon(ctx_app) != 0) {
  131.             ALOGE("Could not switch to %s context", ctx_app);
  132.             exit(EXIT_FAILURE);
  133.         }
  134.     }
  135. #endif  // XPOSED_WITH_SELINUX
  136.  
  137.     int err = rename(XPOSEDLOG, XPOSEDLOG_OLD);
  138.     if (err < 0 && errno != ENOENT) {
  139.         ALOGE("%s while renaming log file %s -> %s", strerror(errno), XPOSEDLOG, XPOSEDLOG_OLD);
  140.     }
  141.  
  142.     int pipeFds[2];
  143.     if (pipe(pipeFds) < 0) {
  144.         ALOGE("Could not allocate pipe for logcat output: %s", strerror(errno));
  145.         exit(EXIT_FAILURE);
  146.     }
  147.  
  148.     if ((pid = fork()) < 0) {
  149.         ALOGE("Fork for logcat execution failed: %s", strerror(errno));
  150.         exit(EXIT_FAILURE);
  151.     } else if (pid == 0) {
  152.         close(pipeFds[1]);
  153.         runDaemon(pipeFds[0]);
  154.     } else {
  155.         close(pipeFds[0]);
  156.         if (dup2(pipeFds[1], STDOUT_FILENO) == -1) {
  157.             ALOGE("Could not redirect stdout: %s", strerror(errno));
  158.             exit(EXIT_FAILURE);
  159.         }
  160.         if (dup2(pipeFds[1], STDERR_FILENO) == -1) {
  161.             ALOGE("Could not redirect stdout: %s", strerror(errno));
  162.             exit(EXIT_FAILURE);
  163.         }
  164.         execLogcat();
  165.     }
  166.  
  167.     // Should never reach this point
  168.     exit(EXIT_FAILURE);
  169. }
  170.  
  171. }  // namespace logcat
  172. }  // namespace xposed
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement