undump.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. $pid = null;
  3. $hexdump = false;
  4. foreach ($argv as $index => $arg) {
  5. if ($arg === "-p" && isset($argv[$index + 1])) {
  6. $pid = intval($argv[$index + 1]);
  7. } elseif ($arg === "--hexdump") {
  8. $hexdump = true;
  9. }
  10. }
  11. $bpf_prog = <<<EOT
  12. #include <uapi/linux/ptrace.h>
  13. #include <net/sock.h>
  14. #include <bcc/proto.h>
  15. #include <linux/aio.h>
  16. #include <linux/socket.h>
  17. #include <linux/net.h>
  18. #include <linux/fs.h>
  19. #include <linux/mount.h>
  20. #include <linux/module.h>
  21. #include <net/sock.h>
  22. #include <net/af_unix.h>
  23. #define MAX_PKT 512
  24. struct recv_data_t {
  25. u32 recv_len;
  26. u8 pkt[MAX_PKT];
  27. };
  28. BPF_PERCPU_ARRAY(unix_data, struct recv_data_t, 1);
  29. BPF_PERF_OUTPUT(unix_recv_events);
  30. int trace_unix_stream_read_actor(struct pt_regs *ctx)
  31. {
  32. u32 zero = 0;
  33. int ret = PT_REGS_RC(ctx);
  34. u64 pid_tgid = bpf_get_current_pid_tgid();
  35. u32 pid = pid_tgid >> 32;
  36. u32 tid = pid_tgid;
  37. FILTER_PID
  38. struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM1(ctx);
  39. struct recv_data_t *data = unix_data.lookup(&zero);
  40. if (!data)
  41. return 0;
  42. unsigned int data_len = skb->len;
  43. if (data_len > MAX_PKT)
  44. return 0;
  45. void *iodata = (void *)skb->data;
  46. data->recv_len = data_len;
  47. bpf_probe_read(data->pkt, data_len, iodata);
  48. unix_recv_events.perf_submit(ctx, data, data_len + sizeof(u32));
  49. return 0;
  50. }
  51. EOT;
  52. if ($pid !== null) {
  53. $filter = "if (pid != $pid) { return 0; }";
  54. $bpf_prog = str_replace("FILTER_PID", $filter, $bpf_prog);
  55. } else {
  56. $bpf_prog = str_replace("FILTER_PID", "", $bpf_prog);
  57. }
  58. // initialize BPF
  59. $b = new Bpf(["text" => $bpf_prog]);
  60. $b->attach_kprobe("unix_stream_read_actor", "trace_unix_stream_read_actor");
  61. echo $pid ? "Tracing PID $pid UNIX socket packets ... Hit Ctrl-C to end\n"
  62. : "Tracing UNIX socket packets ... Hit Ctrl-C to end\n";
  63. function print_recv_pkg($cpu,$data,$size){
  64. $recv_len = unpack("L", substr($data, 0, 4))[1];
  65. $pkt = substr($data, 4, $recv_len);
  66. global $pid;
  67. global $hexdump;
  68. if ($pid) {
  69. echo "PID \033[1;31m$pid\033[0m ";
  70. }
  71. echo "Recv \033[1;31m$recv_len\033[0m bytes\n";
  72. if ($hexdump) {
  73. echo chunk_split(bin2hex($pkt), 32, "\n");
  74. } else {
  75. echo " ";
  76. for ($i = 0; $i < $recv_len; $i++) {
  77. printf("%02x ", ord($pkt[$i]));
  78. if (($i + 1) % 16 == 0) echo "\n ";
  79. }
  80. echo "\n";
  81. }
  82. }
  83. $b->unix_recv_events->open_perf_buffer("print_recv_pkg");
  84. while (true) {
  85. try {
  86. $b->perf_buffer_poll();
  87. } catch (Exception $e) {
  88. exit();
  89. }
  90. }