Advertisement
xosski

Ect/vmap debugging/read/write

Jan 9th, 2025
8
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <linux/proc_fs.h>
  5. #include <linux/uaccess.h>
  6. #include <linux/slab.h>
  7. #include <linux/vmalloc.h>
  8. #include <linux/mm.h>
  9. #include <linux/kprobes.h>
  10. #include <linux/mutex.h>
  11.  
  12. #define PROC_FILENAME_ECT "ect_region_dump"
  13. #define PROC_FILENAME_FVMAP "fvmap_region_dump"
  14.  
  15. static void *v_addr_ect = NULL;
  16. static unsigned int data_size_ect = 0;
  17.  
  18. static void *v_addr_fvmap = NULL;
  19. static unsigned int data_size_fvmap = 0;
  20.  
  21. static DEFINE_MUTEX(ect_lock);
  22. static DEFINE_MUTEX(fvmap_lock);
  23.  
  24. static unsigned long ect_phys_addr = 0x90000000; // Default ECT physical address
  25. static unsigned int ect_region_size = 0xc4000; // Default ECT region size
  26.  
  27. module_param(ect_phys_addr, ulong, 0444);
  28. MODULE_PARM_DESC(ect_phys_addr, "Physical address of the ECT region");
  29. module_param(ect_region_size, uint, 0444);
  30. MODULE_PARM_DESC(ect_region_size, "Size of the ECT region");
  31.  
  32. // Function to map physical memory to virtual memory
  33. static void *map_physical_memory(unsigned long phys_addr, unsigned int size) {
  34. int i;
  35. unsigned int num_pages = size >> PAGE_SHIFT;
  36. pgprot_t prot = pgprot_writecombine(PAGE_KERNEL);
  37. struct page **pages = NULL;
  38. void *v_addr = NULL;
  39.  
  40. if (!phys_addr || size == 0) {
  41. pr_err("[henr1kas] Invalid physical address or size\n");
  42. return NULL;
  43. }
  44.  
  45. pages = kmalloc_array(num_pages, sizeof(struct page *), GFP_ATOMIC);
  46. if (!pages) {
  47. pr_err("[henr1kas] Failed to allocate memory for page array\n");
  48. return NULL;
  49. }
  50.  
  51. for (i = 0; i < num_pages; i++) {
  52. pages[i] = phys_to_page(phys_addr);
  53. phys_addr += PAGE_SIZE;
  54. }
  55.  
  56. v_addr = vmap(pages, num_pages, VM_MAP, prot);
  57. kfree(pages);
  58.  
  59. if (!v_addr)
  60. pr_err("[henr1kas] Failed to map physical memory to virtual address\n");
  61.  
  62. return v_addr;
  63. }
  64.  
  65. // Generic /proc read function
  66. static ssize_t proc_read_generic(struct file *file, char __user *user_buf, size_t count, loff_t *ppos, void *v_addr, unsigned int data_size, struct mutex *lock) {
  67. ssize_t ret;
  68.  
  69. if (mutex_lock_interruptible(lock))
  70. return -ERESTARTSYS;
  71.  
  72. if (!v_addr || data_size == 0) {
  73. mutex_unlock(lock);
  74. return -ENODATA;
  75. }
  76.  
  77. if (*ppos >= data_size) {
  78. mutex_unlock(lock);
  79. return 0; // EOF
  80. }
  81.  
  82. if (count > (data_size - *ppos))
  83. count = data_size - *ppos;
  84.  
  85. if (copy_to_user(user_buf, (char *)v_addr + *ppos, count)) {
  86. pr_err("[henr1kas] Failed to copy data to user space\n");
  87. mutex_unlock(lock);
  88. return -EFAULT;
  89. }
  90.  
  91. *ppos += count;
  92. ret = count;
  93.  
  94. mutex_unlock(lock);
  95. return ret;
  96. }
  97.  
  98. // /proc read functions
  99. static ssize_t proc_read_ect(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) {
  100. return proc_read_generic(file, user_buf, count, ppos, v_addr_ect, data_size_ect, &ect_lock);
  101. }
  102.  
  103. static ssize_t proc_read_fvmap(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) {
  104. return proc_read_generic(file, user_buf, count, ppos, v_addr_fvmap, data_size_fvmap, &fvmap_lock);
  105. }
  106.  
  107. // /proc file operations
  108. static const struct proc_ops proc_fops_ect = {
  109. .proc_read = proc_read_ect,
  110. };
  111.  
  112. static const struct proc_ops proc_fops_fvmap = {
  113. .proc_read = proc_read_fvmap,
  114. };
  115.  
  116. // Resolve FVMAP base dynamically using kprobes
  117. static void *get_fvmap_base(void) {
  118. struct kprobe kp = { .symbol_name = "get_fvmap_base" };
  119. void *(*func)(void) = NULL;
  120. void *fvmap_base = NULL;
  121.  
  122. if (register_kprobe(&kp) < 0) {
  123. pr_err("[henr1kas] Failed to register kprobe for get_fvmap_base\n");
  124. return NULL;
  125. }
  126.  
  127. func = (void *(*)(void))kp.addr;
  128. if (func)
  129. fvmap_base = func();
  130. else
  131. pr_err("[henr1kas] Failed to resolve get_fvmap_base address\n");
  132.  
  133. unregister_kprobe(&kp);
  134. return fvmap_base;
  135. }
  136.  
  137. // Module initialization
  138. static int __init henr1kas_init(void) {
  139. struct proc_dir_entry *entry;
  140.  
  141. pr_info("[henr1kas] Kernel module loaded\n");
  142.  
  143. // Map ECT region
  144. v_addr_ect = map_physical_memory(ect_phys_addr, ect_region_size);
  145. if (!v_addr_ect)
  146. return -ENOMEM;
  147.  
  148. data_size_ect = *(unsigned int *)(v_addr_ect + 8);
  149.  
  150. entry = proc_create(PROC_FILENAME_ECT, 0444, NULL, &proc_fops_ect);
  151. if (!entry) {
  152. pr_err("[henr1kas] Failed to create /proc/%s\n", PROC_FILENAME_ECT);
  153. kvfree(v_addr_ect);
  154. return -ENOMEM;
  155. }
  156.  
  157. pr_info("[henr1kas] /proc/%s created, exporting %u bytes\n", PROC_FILENAME_ECT, data_size_ect);
  158.  
  159. // Resolve FVMAP base
  160. v_addr_fvmap = get_fvmap_base();
  161. if (!v_addr_fvmap) {
  162. pr_err("[henr1kas] Failed to resolve FVMAP base\n");
  163. remove_proc_entry(PROC_FILENAME_ECT, NULL);
  164. kvfree(v_addr_ect);
  165. return -ENOMEM;
  166. }
  167.  
  168. data_size_fvmap = 8192;
  169.  
  170. entry = proc_create(PROC_FILENAME_FVMAP, 0444, NULL, &proc_fops_fvmap);
  171. if (!entry) {
  172. pr_err("[henr1kas] Failed to create /proc/%s\n", PROC_FILENAME_FVMAP);
  173. kvfree(v_addr_ect);
  174. kvfree(v_addr_fvmap);
  175. remove_proc_entry(PROC_FILENAME_ECT, NULL);
  176. return -ENOMEM;
  177. }
  178.  
  179. pr_info("[henr1kas] /proc/%s created, exporting %u bytes\n", PROC_FILENAME_FVMAP, data_size_fvmap);
  180.  
  181. return 0;
  182. }
  183.  
  184. // Module cleanup
  185. static void __exit henr1kas_exit(void) {
  186. remove_proc_entry(PROC_FILENAME_ECT, NULL);
  187. remove_proc_entry(PROC_FILENAME_FVMAP, NULL);
  188.  
  189. if (v_addr_ect)
  190. kvfree(v_addr_ect);
  191.  
  192. if (v_addr_fvmap)
  193. kvfree(v_addr_fvmap);
  194.  
  195. pr_info("[henr1kas] Kernel module unloaded\n");
  196. }
  197.  
  198. module_init(henr1kas_init);
  199. module_exit(henr1kas_exit);
  200.  
  201. MODULE_LICENSE("GPL");
  202. MODULE_AUTHOR("henr1kas");
  203. MODULE_DESCRIPTION("Improved ECT and FVMAP memory dumping module");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement