/**
 * Diagnostic: only LOG exit-related calls, do not block.
 */
"use strict";
function log(msg) { send("[TNG-diag] " + msg); }
function findExport(mod, name) {
  try {
    var m = Process.findModuleByName(mod);
    if (m) { var a = m.findExportByName(name); if (a) return a; }
  } catch (e) {}
  try { return Module.getGlobalExportByName(name); } catch (e2) { return null; }
}
function bt(ctx) {
  try {
    return Thread.backtrace(ctx, Backtracer.FUZZY).map(DebugSymbol.fromAddress).slice(0, 8).join(" <- ");
  } catch (e) { return "?"; }
}

["_exit", "exit", "abort", "quick_exit"].forEach(function (n) {
  var a = findExport("libc.so", n);
  if (!a) return;
  Interceptor.attach(a, {
    onEnter: function (args) {
      log("CALL " + n + "(" + args[0] + ") " + bt(this.context));
    }
  });
  log("watch " + n + " @ " + a);
});

["kill", "tgkill", "raise"].forEach(function (n) {
  var a = findExport("libc.so", n);
  if (!a) return;
  Interceptor.attach(a, {
    onEnter: function (args) {
      log("CALL " + n + "(" + args[0] + "," + args[1] + ") " + bt(this.context));
    }
  });
});

var sys = findExport("libc.so", "syscall");
if (sys) {
  Interceptor.attach(sys, {
    onEnter: function (args) {
      var nr = args[0].toInt32();
      if (nr === 93 || nr === 94 || nr === 129 || nr === 131) {
        log("CALL syscall(" + nr + ") " + bt(this.context));
      }
    }
  });
}

// count mprotect EXEC
var mp = findExport("libc.so", "mprotect");
if (mp) {
  Interceptor.attach(mp, {
    onEnter: function (args) {
      if (args[2].toInt32() & 4) {
        log("mprotect EXEC " + args[0] + " len=" + args[1]);
      }
    }
  });
}

log("diag ready pid=" + Process.id);
setTimeout(function () {
  var n = 0;
  Process.enumerateRanges("r-x").forEach(function (r) {
    var file = r.file ? r.file.path : "anon";
    if (file.indexOf("/system") === 0 || file.indexOf("/apex") === 0) return;
    n++;
    log("RX " + file + " " + r.base + " +" + r.size);
  });
  log("app RX ranges=" + n);
}, 800);
