ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
linux/system.c
Go to the documentation of this file.
1
7#include <ascii-chat/platform/abstraction.h>
8#include <ascii-chat/platform/internal.h>
9#include <ascii-chat/common.h>
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13
26int get_binary_file_address_offsets(const void *addr, platform_binary_match_t *matches, int max_matches) {
27 int count = 0;
28 uintptr_t addr_int = (uintptr_t)addr;
29
30 FILE *maps = fopen("/proc/self/maps", "r");
31 if (!maps) {
32 return 0;
33 }
34
35 char line[512];
36 while (fgets(line, sizeof(line), maps) && count < max_matches) {
37 uintptr_t start, end, offset;
38 char perms[5], device[10], path[PLATFORM_MAX_PATH_LENGTH];
39 unsigned long inode;
40
41 // Parse: start-end perms offset device inode path
42 // Example: 7f3a2b1c0000-7f3a2b1c1000 r-xp 00000000 08:02 12345678 /usr/lib/libsodium.so.23
43 int parsed = sscanf(line, "%lx-%lx %4s %lx %9s %lu", &start, &end, perms, &offset, device, &inode);
44
45 if (parsed < 6) {
46 continue; // Incomplete line
47 }
48
49 // Skip lines without executable flag
50 if (perms[2] != 'x') {
51 continue;
52 }
53
54 // Extract path more robustly by searching for the last whitespace-separated token
55 // /proc/self/maps format: start-end perms offset device inode [path]
56 // The path is optional and starts after the inode field
57 path[0] = '\0';
58
59 // Find the last whitespace and take everything after it as the path
60 // This is more robust than trying to count fields
61 int line_len = strlen(line);
62 int path_start = -1;
63
64 // Scan from the end backwards to find the last non-whitespace character
65 for (int i = line_len - 1; i >= 0; i--) {
66 if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') {
67 // Found a non-whitespace char, now find the start of this token
68 path_start = i;
69 while (path_start > 0 && line[path_start - 1] != ' ' && line[path_start - 1] != '\t') {
70 path_start--;
71 }
72 break;
73 }
74 }
75
76 if (path_start > 0 && line[path_start - 1] != '\0') {
77 // Extract the path starting from path_start
78 strncpy(path, &line[path_start], PLATFORM_MAX_PATH_LENGTH - 1);
79 path[PLATFORM_MAX_PATH_LENGTH - 1] = '\0';
80 // Remove trailing whitespace
81 int path_len = strlen(path);
82 while (path_len > 0 && (path[path_len - 1] == '\n' || path[path_len - 1] == '\r')) {
83 path[--path_len] = '\0';
84 }
85 }
86
87 // Check if address falls within this segment
88 if (perms[2] == 'x' && path[0] == '/') {
89 if (addr_int >= start && addr_int < end) {
90 strncpy(matches[count].path, path, PLATFORM_MAX_PATH_LENGTH - 1);
91 matches[count].path[PLATFORM_MAX_PATH_LENGTH - 1] = '\0';
92 matches[count].file_offset = (addr_int - start) + offset;
93 count++;
94 }
95 }
96 }
97
98 fclose(maps);
99 return count;
100}
int get_binary_file_address_offsets(const void *addr, platform_binary_match_t *matches, int max_matches)
Get binary that contains address on Linux via /proc/self/maps.
#define PLATFORM_MAX_PATH_LENGTH
Definition system.c:64