MemoryAccessor 1
A command-line front-end for exploring virtual memory of a linux process by accessing /proc/PID/mem file.
Loading...
Searching...
No Matches
console.h
Go to the documentation of this file.
1// MemoryAccessor - A tool for accessing /proc/PID/mem
2// Copyright (C) 2024 zloymish
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
24
25#ifndef MEMORYACCESSOR_SRC_CONSOLE_H_
26#define MEMORYACCESSOR_SRC_CONSOLE_H_
27
28#include <array>
29#include <cstdint>
30#include <exception>
31#include <memory>
32#include <string>
33#include <vector>
34
35#include "hexviewer.h"
36#include "memoryaccessor.h"
37#include "processapi.h"
38#include "segmentinfo.h"
39
40class Console;
41
49struct Command {
50 using CommandFuncP = void (Console::*)(
51 const Command &parent, const std::vector<std::string>
52 &);
53
54 std::string name;
55 CommandFuncP func{nullptr};
56 std::vector<std::array<std::string, 2>>
59};
60
69class Console {
70public:
71 constexpr static int kCommandsNumber{
72 9};
73
74 explicit Console(MemoryAccessor *memory_accessor, HexViewer *hex_viewer,
75 ProcessApi *process_api) noexcept(false);
76
83 Console(const Console &origin) = delete;
84
91 Console(Console &&origin) = delete;
92
99 Console &operator=(const Console &origin) = delete;
100
107 Console &operator=(Console &&origin) = delete;
108
109 ~Console() noexcept;
110
117 void SetBufferSize(const size_t &buffer_size) { buffer_size_ = buffer_size; }
118
119 void PrintNameVer() const noexcept;
120 void Start() noexcept;
121 void ReadStdin() noexcept;
122 void HandleCommand(const std::string &line) noexcept;
123
124 const std::string kProjectName{"MemoryAccessor"};
125 const std::string kProjectVersion{"v1.0"};
126 const std::string kProjectDescription{
127 "A command-line front-end for exploring virtual memory of a linux "
128 "process "
129 "by accessing /proc/PID/mem file."};
130 const std::string kConsolePrefix{
131 "(MemAcc)"};
132
137
139 {"help", &Console::CommandHelp, {{"help", "Show help"}}},
140 {"name",
141 &Console::CommandName,
142 {{"name name [pid_num]", "Search for PID by name and set PID if only 1 "
143 "PID found, or set PID number"},
144 {"",
145 "pid_num of found PIDs if pid_num is specified (starting from 0)."}}},
146 {"pid",
147 &Console::CommandPid,
148 {{"pid PID", "Set PID and parse /proc/PID/maps."}}},
149 {"maps",
150 &Console::CommandMaps,
151 {{"maps", "List memory segments found by parsing /proc/PID/maps."}}},
152 {"view",
153 &Console::CommandView,
154 {{"view SEGMENT", "Print data of memory segment, where SEGMENT is its "
155 "\"maps\" number, or first"},
156 {"", "with matching name."},
157 {"-h", "show hex (if no -r specified)"},
158 {"-r", "print raw data"},
159 {"-f file", "output to file"}}},
160 {"read",
161 &Console::CommandRead,
162 {{"read address amount", "Read amount bytes starting from address."},
163 {"-h", "show hex (if no -r specified)"},
164 {"-r", "print raw data"},
165 {"-f file", "output to file"}}},
166 {"write",
167 &Console::CommandWrite,
168 {{"write address amount string",
169 "Write amount bytes of string to memory starting from address."},
170 {"or", ""},
171 {"write address amount -f file",
172 "Write amount bytes from file to memory starting from address."}}},
173 {"diff",
174 &Console::CommandDiff,
175 {{"diff length [replacement]",
176 "Find difference in memory states by length and replace to string, if "
177 "specified."}}},
178 {"await",
179 &Console::CommandAwait,
180 {{"await process_name", "Wait for the process with matching name."},
181 {"await -p pid", "Wait for the process with PID."}}},
182 };
183private:
190 enum class Error0Arg {
191 kPidNotSet,
192 kPidNotSetUnexpectably,
193 kErrCheckingPid,
194 kPrintErrCheckingProcess,
195 kPrintErrOpenMaps,
196 kPrintErrParseMaps,
197 kPrintErrOpenMem,
198 kPrintSegNotExist,
199 kPrintSegNoAccess,
200 };
201
209 class WrapperException : public std::exception {
210 public:
217 WrapperException(uint8_t _return_code) : return_code(_return_code) {}
218
219 uint8_t return_code;
220 private:
227 virtual const char *what() const noexcept override {
228 return "Wrapper exception";
229 }
230 };
231
232 int SetSigint(void (*handler)(int)) const noexcept;
233
234 void PrintDescription(const Command &command, uint32_t left = 2,
235 uint32_t middle = 0) const noexcept;
236 void ShowUsage(const Command &command) const noexcept;
237 void PrintError0Arg(const Error0Arg &error) const noexcept;
238 void PrintFileNotOpened(const std::string &path) const noexcept;
239 void PrintFileFail(const std::string &path) const noexcept;
240
241 void PrintSegment(const SegmentInfo &segmentInfo) const noexcept;
242 void
243 PrintSegments(const std::vector<SegmentInfo> &segment_infos) const noexcept;
244
245 std::vector<std::string> ParseCmdline(std::string line) const noexcept;
246
247 uint8_t ParseAddress(const std::string &s, size_t &result) const noexcept;
248 uint8_t StoiWrapper(const std::string &s, int &result,
249 const std::string &name) const noexcept;
250 uint8_t StoullWrapper(const std::string &s, uint64_t &result,
251 const std::string &name) const noexcept;
252 uint8_t ParseMapsWrapper() const noexcept;
253 uint8_t CheckPidWrapper() const noexcept;
254 uint8_t CheckSegNumWrapper(const size_t &num) const noexcept;
255 uint8_t ReadSegWrapper(char *dst, const size_t &num, size_t start = 0,
256 size_t amount = SIZE_MAX) const noexcept;
257 uint8_t WriteSegWrapper(char *src, const size_t &num, size_t start = 0,
258 size_t amount = SIZE_MAX) const noexcept;
259 uint8_t ReadWrapper(char *dst, size_t address, size_t amount,
260 size_t &done_amount) const noexcept;
261 uint8_t WriteWrapper(char *src, size_t address, size_t amount,
262 size_t &done_amount) const noexcept;
263
264 std::array<std::unique_ptr<char[]>, 2>
265 FindDifferencesOfLen(const char *old_str, const char *new_str, size_t str_len,
266 size_t &done, const size_t &len) const noexcept;
267 uint8_t DiffReadSeg(std::unique_ptr<char[]> &mem_dump,
268 const size_t &num) noexcept;
269 void DiffCompare(const char *old_dump, const char *new_dump,
270 const size_t &o_offs, const size_t &n_offs, size_t amount,
271 size_t start_addr, const size_t &length,
272 const std::string &replacement) noexcept;
273 uint8_t DiffOldNext(size_t &i, const size_t &old_segments_amount,
274 std::vector<std::unique_ptr<char[]>>::iterator &it,
275 std::vector<std::unique_ptr<char[]>> &full_dump) noexcept;
276 uint8_t DiffNewNext(size_t &j,
277 std::vector<std::unique_ptr<char[]>>::iterator &it,
278 std::unique_ptr<char[]> &mem_dump,
279 std::vector<std::unique_ptr<char[]>> &full_dump) noexcept;
280
281 void CommandHelp(const Command &parent,
282 const std::vector<std::string> &args) noexcept;
283 void CommandName(const Command &parent,
284 const std::vector<std::string> &args) noexcept;
285 void CommandPid(const Command &parent,
286 const std::vector<std::string> &args) noexcept;
287 void CommandMaps(const Command &parent,
288 const std::vector<std::string> &args) noexcept;
289 void CommandView(const Command &parent,
290 const std::vector<std::string> &args) noexcept;
291 void CommandRead(const Command &parent,
292 const std::vector<std::string> &args) noexcept;
293 void CommandWrite(const Command &parent,
294 const std::vector<std::string> &args) noexcept;
295 void CommandDiff(const Command &parent,
296 const std::vector<std::string> &args) noexcept;
297 void CommandAwait(const Command &parent,
298 const std::vector<std::string> &args) noexcept;
299
300 static bool one_instance_created_;
302 const std::string kCheckSudoStr{
303 "Check if you're running with \"sudo\"."};
307
308 size_t buffer_size_{
309 0x1000};
310
311 bool seg_not_exist_msg_enabled_{
312 true};
313 bool seg_no_access_msg_enabled_{
314 true};
315};
316
317#endif // MEMORYACCESSOR_SRC_CONSOLE_H_
A class to perform CLI.
Definition console.h:69
void SetBufferSize(const size_t &buffer_size)
Set buffer size of an instance.
Definition console.h:117
Console & operator=(const Console &origin)=delete
Copy-assignment operator (deleted).
const std::string kProjectDescription
Project description.
Definition console.h:126
Console(Console &&origin)=delete
Move constructor (deleted).
HexViewer * hex_viewer_
A pointer to a HexViewer class instance.
Definition console.h:135
Console(const Console &origin)=delete
Copy constructor (deleted).
const std::string kProjectName
Name of the project.
Definition console.h:124
Console & operator=(Console &&origin)=delete
Move-assignment operator (deleted).
void Start() noexcept
Start the console.
Definition console.cc:321
MemoryAccessor * memory_accessor_
A pointer to a MemoryAccessor class instance.
Definition console.h:134
void ReadStdin() noexcept
Read and process input from stdin.
Definition console.cc:341
static constexpr int kCommandsNumber
Number of the commands available.
Definition console.h:71
void HandleCommand(const std::string &line) noexcept
Handle line with command.
Definition console.cc:367
const Command kCommands[kCommandsNumber]
Definitions of commands.
Definition console.h:138
ProcessApi * process_api_
A pointer to a ProcessApi class instance.
Definition console.h:136
const std::string kProjectVersion
Project version.
Definition console.h:125
const std::string kConsolePrefix
Prefix shown in console input.
Definition console.h:130
Console(MemoryAccessor *memory_accessor, HexViewer *hex_viewer, ProcessApi *process_api) noexcept(false)
Constructor.
Definition console.cc:276
~Console() noexcept
Destructor.
Definition console.cc:292
void PrintNameVer() const noexcept
Print project name and version.
Definition console.cc:310
A class for printing data in a readable format.
Definition hexviewer.h:37
A class to perform the main operations with memory.
Definition memoryaccessor.h:50
A class with functionality to work with system processes.
Definition processapi.h:41
HexViewer header.
MemoryAccessor header.
ProcessApi header.
SegmentInfo header.
A struct that represents command in Console.
Definition console.h:49
std::vector< std::array< std::string, 2 > > description
Definition console.h:57
void(Console::*)( const Command &parent, const std::vector< std::string > &) CommandFuncP
Type of pointer to command function.
Definition console.h:50
std::string name
Command name.
Definition console.h:54
CommandFuncP func
Pointer.
Definition console.h:55