117 void SetBufferSize(const
size_t &buffer_size) { buffer_size_ = buffer_size; }
120 void Start() noexcept;
127 "A command-line front-end for exploring virtual memory of a linux "
129 "by accessing /proc/PID/mem file."};
139 {
"help", &Console::CommandHelp, {{
"help",
"Show help"}}},
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"},
145 "pid_num of found PIDs if pid_num is specified (starting from 0)."}}},
147 &Console::CommandPid,
148 {{
"pid PID",
"Set PID and parse /proc/PID/maps."}}},
150 &Console::CommandMaps,
151 {{
"maps",
"List memory segments found by parsing /proc/PID/maps."}}},
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"}}},
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"}}},
167 &Console::CommandWrite,
168 {{
"write address amount string",
169 "Write amount bytes of string to memory starting from address."},
171 {
"write address amount -f file",
172 "Write amount bytes from file to memory starting from address."}}},
174 &Console::CommandDiff,
175 {{
"diff length [replacement]",
176 "Find difference in memory states by length and replace to string, if "
179 &Console::CommandAwait,
180 {{
"await process_name",
"Wait for the process with matching name."},
181 {
"await -p pid",
"Wait for the process with PID."}}},
190 enum class Error0Arg {
192 kPidNotSetUnexpectably,
194 kPrintErrCheckingProcess,
209 class WrapperException :
public std::exception {
217 WrapperException(uint8_t _return_code) : return_code(_return_code) {}
227 virtual const char *what() const noexcept
override {
228 return "Wrapper exception";
232 int SetSigint(
void (*handler)(
int))
const noexcept;
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;
241 void PrintSegment(const SegmentInfo &segmentInfo) const noexcept;
243 PrintSegments(const std::vector<SegmentInfo> &segment_infos) const noexcept;
245 std::vector<std::
string> ParseCmdline(std::
string line) const noexcept;
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;
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;
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;
300 static
bool one_instance_created_;
302 const std::
string kCheckSudoStr{
303 "Check if you're running with \"sudo\"."};
311 bool seg_not_exist_msg_enabled_{
313 bool seg_no_access_msg_enabled_{