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 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* Copyright Yann Weber <asmsh@yannweb.net>
  2. This file is part of asmsh.
  3. asmsh is free software: you can redistribute it and/or modify it under the
  4. terms of the GNU General Public License as published by the Free Software
  5. Foundation, either version 3 of the License, or any later version.
  6. asmsh is distributed in the hope that it will be useful, but WITHOUT ANY
  7. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  9. details.
  10. You should have received a copy of the GNU General Public License along
  11. with asmsh. If not, see <https://www.gnu.org/licenses/>.
  12. */
  13. #include "mmap_parse.h"
  14. void child_mmap_init(child_mmap_l *maps)
  15. {
  16. bzero(maps, sizeof(*maps));
  17. }
  18. int child_mmap_get(pid_t child_pid, child_mmap_l *maps)
  19. {
  20. char procfs_path[PATH_MAX+1];
  21. int ret, maps_fd;
  22. if(child_pid == -1)
  23. {
  24. errno = EINVAL;
  25. return -1;
  26. }
  27. ret = snprintf(procfs_path, PATH_MAX, "/proc/%d/maps", child_pid);
  28. if(ret < 0) { return -1; }
  29. procfs_path[ret] = '\0';
  30. if((maps_fd = open(procfs_path, O_RDONLY)) < 0)
  31. {
  32. return -1;
  33. }
  34. if(child_mmap_get_fd(maps_fd, maps) < 0)
  35. {
  36. ret = -1;
  37. }
  38. else
  39. {
  40. ret = 0;
  41. }
  42. close(maps_fd);
  43. return ret;
  44. err:
  45. ret = errno;
  46. close(maps_fd);
  47. errno = ret;
  48. return -1;
  49. }
  50. int child_mmap_get_fd(int maps_fd, child_mmap_l *maps)
  51. {
  52. const int RDBUF_SZ = 4095;
  53. char rdbuf[RDBUF_SZ+1];
  54. char *line, *endline;
  55. int ret;
  56. size_t curmap;
  57. void *tmp;
  58. curmap = 0;
  59. do
  60. {
  61. ret = read(maps_fd, rdbuf, RDBUF_SZ);
  62. if(ret < 0) { goto err; }
  63. else if(ret == 0) { break; }
  64. rdbuf[ret] = '\0';
  65. line = endline = rdbuf;
  66. while(*endline)
  67. {
  68. if(*endline == '\n')
  69. {
  70. if(maps->size <= curmap)
  71. {
  72. if(_child_mmap_alloc(curmap, maps) < 0)
  73. {
  74. goto err;
  75. }
  76. }
  77. *endline = '\0';
  78. ret = child_mmap_parseline(line, &maps->maps[curmap]);
  79. if(ret < 0) { goto err; }
  80. line = endline + 1;
  81. curmap++;
  82. }
  83. endline++;
  84. }
  85. }while(1);
  86. close(maps_fd);
  87. if(curmap < maps->size)
  88. {
  89. dprintf(2, "debug realloc : %d %d\n", curmap, maps->size);
  90. tmp = realloc(maps->maps, sizeof(child_mmap_t) * curmap);
  91. if(!tmp)
  92. {
  93. perror("err");
  94. goto err;
  95. }
  96. maps->maps = tmp;
  97. maps->size = curmap;
  98. }
  99. return 0;
  100. err:
  101. ret = errno;
  102. close(maps_fd);
  103. errno = ret;
  104. return -1;
  105. }
  106. int child_mmap_parseline(char *line, child_mmap_t *maps)
  107. {
  108. char *ptr, *orig, *endptr;
  109. unsigned long long parsed;
  110. int errno_bck, cperm;
  111. size_t i;
  112. int major;
  113. void **addr_ptr[2] = {&maps->start, &maps->stop};
  114. const char addr_sep[2] = "- ";
  115. const char perms[3] = "rwx";
  116. const int perms_val[3] = {PROT_READ, PROT_WRITE, PROT_EXEC};
  117. #define parsefield(line, sep, base, mapfield) {\
  118. unsigned long long p; char *endptr;\
  119. errno = 0;\
  120. p = strtoull(*line, &endptr, base);\
  121. if(errno || *endptr != sep) {\
  122. dprintf(2, "*line : '%s' %s\n", *line, #mapfield);\
  123. if(errno != ERANGE) { errno=EINVAL; }\
  124. goto err_inval;\
  125. }\
  126. *mapfield=(typeof(*mapfield))p;\
  127. *line = endptr+1;\
  128. }
  129. ptr = orig = line;
  130. parsefield(&line, '-', 16, &maps->start);
  131. parsefield(&line, ' ', 16, &maps->stop);
  132. cperm = 1;
  133. maps->perm = 0;
  134. for(i=0; i<3; i++)
  135. {
  136. if(*line == perms[i])
  137. {
  138. maps->perm |= perms_val[i];
  139. }
  140. else if (*line != '-')
  141. {
  142. goto err_inval;
  143. }
  144. line++;
  145. cperm <<= 1;
  146. }
  147. switch(*line)
  148. {
  149. case 'p':
  150. maps->perm |= MAP_PRIVATE;
  151. break;
  152. case 's':
  153. maps->perm |= MAP_SHARED;
  154. break;
  155. default:
  156. goto err_inval;
  157. }
  158. line++;
  159. parsefield(&line, ' ', 16, &maps->offset);
  160. parsefield(&line, ':', 10, &major);
  161. parsefield(&line, ' ', 10, &maps->device);
  162. maps->device |= major << 8; // WARNING : hardcoded major shift
  163. //parsefield(&line, ' ', 10, &maps->inode);
  164. errno = 0;
  165. parsed = strtoull(line, &endptr, 10);
  166. if(errno || (*endptr != ' ' && *endptr != '\0'))
  167. {
  168. if(errno != ERANGE) { errno = EINVAL; }
  169. goto err_inval;
  170. }
  171. maps->inode = parsed;
  172. line = endptr;
  173. while(*line==' ') { line++; }
  174. maps->pathname = strndup(line, PATH_MAX * 8);
  175. return 0;
  176. err_inval:
  177. errno_bck = errno;
  178. dprintf(2, "Invalid procfs/[pid]/maps content '%s'", orig);
  179. err:
  180. return -1;
  181. }
  182. int _child_mmap_alloc(size_t curmap, child_mmap_l *maps)
  183. {
  184. void *tmp;
  185. maps->size++;
  186. if(curmap == 0)
  187. {
  188. tmp = malloc(sizeof(child_mmap_t));
  189. }
  190. else
  191. {
  192. tmp = realloc(maps->maps,
  193. sizeof(child_mmap_t) * maps->size);
  194. }
  195. if(!tmp)
  196. {
  197. perror("Unable to allocate maps description");
  198. return -1;
  199. }
  200. maps->maps = tmp;
  201. return 0;
  202. }