A shell that runs x86_64 assembly
c
x86-64
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mmap_parse.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include "mmap_parse.h"
  2. int child_mmap_get(pid_t child_pid, child_mmap_l *maps)
  3. {
  4. char procfs_path[PATH_MAX+1];
  5. int ret, maps_fd;
  6. if(child_pid == -1)
  7. {
  8. errno = EINVAL;
  9. return -1;
  10. }
  11. ret = snprintf(procfs_path, PATH_MAX, "/proc/%d/maps", child_pid);
  12. if(ret < 0) { return -1; }
  13. procfs_path[ret] = '\0';
  14. if((maps_fd = open(procfs_path, O_RDONLY)) < 0)
  15. {
  16. return -1;
  17. }
  18. if(child_mmap_get_fd(maps_fd, maps) < 0)
  19. {
  20. ret = -1;
  21. }
  22. else
  23. {
  24. ret = 0;
  25. }
  26. close(maps_fd);
  27. return ret;
  28. err:
  29. ret = errno;
  30. close(maps_fd);
  31. errno = ret;
  32. return -1;
  33. }
  34. int child_mmap_get_fd(int maps_fd, child_mmap_l *maps)
  35. {
  36. const int RDBUF_SZ = 4095;
  37. char rdbuf[RDBUF_SZ+1];
  38. char *line, *endline;
  39. int ret;
  40. size_t curmap;
  41. void *tmp;
  42. curmap = 0;
  43. do
  44. {
  45. ret = read(maps_fd, rdbuf, RDBUF_SZ);
  46. if(ret < 0) { goto err; }
  47. else if(ret == 0) { break; }
  48. rdbuf[ret] = '\0';
  49. line = endline = rdbuf;
  50. while(*endline)
  51. {
  52. if(*endline == '\n')
  53. {
  54. if(maps->size <= curmap)
  55. {
  56. if(_child_mmap_alloc(curmap, maps) < 0)
  57. {
  58. goto err;
  59. }
  60. }
  61. *endline = '\0';
  62. ret = child_mmap_parseline(line, &maps->maps[curmap]);
  63. if(ret < 0) { goto err; }
  64. line = endline + 1;
  65. curmap++;
  66. }
  67. endline++;
  68. }
  69. }while(1);
  70. close(maps_fd);
  71. if(curmap < maps->size)
  72. {
  73. dprintf(2, "debug realloc : %d %d\n", curmap, maps->size);
  74. tmp = realloc(maps->maps, sizeof(child_mmap_t) * curmap);
  75. if(!tmp)
  76. {
  77. perror("err");
  78. goto err;
  79. }
  80. maps->maps = tmp;
  81. maps->size = curmap;
  82. }
  83. return 0;
  84. err:
  85. ret = errno;
  86. close(maps_fd);
  87. errno = ret;
  88. return -1;
  89. }
  90. int child_mmap_parseline(char *line, child_mmap_t *maps)
  91. {
  92. char *ptr, *orig, *endptr;
  93. unsigned long long parsed;
  94. int errno_bck, cperm;
  95. size_t i;
  96. int major;
  97. void **addr_ptr[2] = {&maps->start, &maps->stop};
  98. const char addr_sep[2] = "- ";
  99. const char perms[3] = "rwx";
  100. const int perms_val[3] = {PROT_READ, PROT_WRITE, PROT_EXEC};
  101. #define parsefield(line, sep, base, mapfield) {\
  102. unsigned long long p; char *endptr;\
  103. errno = 0;\
  104. p = strtoull(*line, &endptr, base);\
  105. if(errno || *endptr != sep) {\
  106. dprintf(2, "*line : '%s' %s\n", *line, #mapfield);\
  107. if(errno != ERANGE) { errno=EINVAL; }\
  108. goto err_inval;\
  109. }\
  110. *mapfield=(typeof(*mapfield))p;\
  111. *line = endptr+1;\
  112. }
  113. ptr = orig = line;
  114. parsefield(&line, '-', 16, &maps->start);
  115. parsefield(&line, ' ', 16, &maps->stop);
  116. cperm = 1;
  117. maps->perm = 0;
  118. for(i=0; i<3; i++)
  119. {
  120. if(*line == perms[i])
  121. {
  122. maps->perm |= perms_val[i];
  123. }
  124. else if (*line != '-')
  125. {
  126. goto err_inval;
  127. }
  128. line++;
  129. cperm <<= 1;
  130. }
  131. switch(*line)
  132. {
  133. case 'p':
  134. maps->perm |= MAP_PRIVATE;
  135. break;
  136. case 's':
  137. maps->perm |= MAP_SHARED;
  138. break;
  139. default:
  140. goto err_inval;
  141. }
  142. line++;
  143. parsefield(&line, ' ', 16, &maps->offset);
  144. parsefield(&line, ':', 10, &major);
  145. parsefield(&line, ' ', 10, &maps->device);
  146. maps->device |= major << 8; // WARNING : hardcoded major shift
  147. //parsefield(&line, ' ', 10, &maps->inode);
  148. errno = 0;
  149. parsed = strtoull(line, &endptr, 10);
  150. if(errno || (*endptr != ' ' && *endptr != '\0'))
  151. {
  152. if(errno != ERANGE) { errno = EINVAL; }
  153. goto err_inval;
  154. }
  155. maps->inode = parsed;
  156. line = endptr;
  157. while(*line==' ') { line++; }
  158. maps->pathname = strndup(line, PATH_MAX * 8);
  159. return 0;
  160. err_inval:
  161. errno_bck = errno;
  162. dprintf(2, "Invalid procfs/[pid]/maps content '%s'", orig);
  163. err:
  164. return -1;
  165. }
  166. int _child_mmap_alloc(size_t curmap, child_mmap_l *maps)
  167. {
  168. void *tmp;
  169. maps->size++;
  170. if(curmap == 0)
  171. {
  172. tmp = malloc(sizeof(child_mmap_t));
  173. }
  174. else
  175. {
  176. tmp = realloc(maps->maps,
  177. sizeof(child_mmap_t) * maps->size);
  178. }
  179. if(!tmp)
  180. {
  181. perror("Unable to allocate maps description");
  182. return -1;
  183. }
  184. maps->maps = tmp;
  185. return 0;
  186. }