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.1KB

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