syscall.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * syscall.c
  3. *
  4. * System call "stealing" sample.
  5. *
  6. * Disables page protection at a processor level by
  7. * changing the 16th bit in the cr0 register (could be Intel specific)
  8. *
  9. * Based on example by Peter Jay Salzman and
  10. * https://bbs.archlinux.org/viewtopic.php?id=139406
  11. */
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/syscalls.h>
  15. #include <linux/delay.h>
  16. #include <asm/paravirt.h>
  17. #include <linux/moduleparam.h> /* which will have params */
  18. #include <linux/unistd.h> /* The list of system calls */
  19. /*
  20. * For the current (process) structure, we need
  21. * this to know who the current user is.
  22. */
  23. #include <linux/sched.h>
  24. #include <linux/uaccess.h>
  25. unsigned long **sys_call_table;
  26. unsigned long original_cr0;
  27. /*
  28. * UID we want to spy on - will be filled from the
  29. * command line
  30. */
  31. static int uid;
  32. module_param(uid, int, 0644);
  33. /*
  34. * A pointer to the original system call. The reason
  35. * we keep this, rather than call the original function
  36. * (sys_open), is because somebody else might have
  37. * replaced the system call before us. Note that this
  38. * is not 100% safe, because if another module
  39. * replaced sys_open before us, then when we're inserted
  40. * we'll call the function in that module - and it
  41. * might be removed before we are.
  42. *
  43. * Another reason for this is that we can't get sys_open.
  44. * It's a static variable, so it is not exported.
  45. */
  46. asmlinkage int (*original_call) (const char *, int, int);
  47. /*
  48. * The function we'll replace sys_open (the function
  49. * called when you call the open system call) with. To
  50. * find the exact prototype, with the number and type
  51. * of arguments, we find the original function first
  52. * (it's at fs/open.c).
  53. *
  54. * In theory, this means that we're tied to the
  55. * current version of the kernel. In practice, the
  56. * system calls almost never change (it would wreck havoc
  57. * and require programs to be recompiled, since the system
  58. * calls are the interface between the kernel and the
  59. * processes).
  60. */
  61. asmlinkage int our_sys_open(const char *filename, int flags, int mode)
  62. {
  63. int i = 0;
  64. char ch;
  65. /*
  66. * Report the file, if relevant
  67. */
  68. pr_info("Opened file by %d: ", uid);
  69. do {
  70. get_user(ch, filename + i);
  71. i++;
  72. pr_info("%c", ch);
  73. } while (ch != 0);
  74. pr_info("\n");
  75. /*
  76. * Call the original sys_open - otherwise, we lose
  77. * the ability to open files
  78. */
  79. return original_call(filename, flags, mode);
  80. }
  81. static unsigned long **aquire_sys_call_table(void)
  82. {
  83. unsigned long int offset = PAGE_OFFSET;
  84. unsigned long **sct;
  85. while (offset < ULLONG_MAX) {
  86. sct = (unsigned long **)offset;
  87. if (sct[__NR_close] == (unsigned long *) ksys_close)
  88. return sct;
  89. offset += sizeof(void *);
  90. }
  91. return NULL;
  92. }
  93. static int __init syscall_start(void)
  94. {
  95. if(!(sys_call_table = aquire_sys_call_table()))
  96. return -1;
  97. original_cr0 = read_cr0();
  98. write_cr0(original_cr0 & ~0x00010000);
  99. /* keep track of the original open function */
  100. original_call = (void*)sys_call_table[__NR_open];
  101. /* use our open function instead */
  102. sys_call_table[__NR_open] = (unsigned long *)our_sys_open;
  103. write_cr0(original_cr0);
  104. pr_info("Spying on UID:%d\n", uid);
  105. return 0;
  106. }
  107. static void __exit syscall_end(void)
  108. {
  109. if(!sys_call_table) {
  110. return;
  111. }
  112. /*
  113. * Return the system call back to normal
  114. */
  115. if (sys_call_table[__NR_open] != (unsigned long *)our_sys_open) {
  116. pr_alert("Somebody else also played with the ");
  117. pr_alert("open system call\n");
  118. pr_alert("The system may be left in ");
  119. pr_alert("an unstable state.\n");
  120. }
  121. write_cr0(original_cr0 & ~0x00010000);
  122. sys_call_table[__NR_open] = (unsigned long *)original_call;
  123. write_cr0(original_cr0);
  124. msleep(2000);
  125. }
  126. module_init(syscall_start);
  127. module_exit(syscall_end);
  128. MODULE_LICENSE("GPL");