Skip to content

Instantly share code, notes, and snippets.

@jrziviani
Created Aug 12, 2018
Embed
What would you like to do?
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include <regex>
#include <tuple>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
struct base
{
int width;
int height;
int mines;
int unused;
};
using namespace std;
using range = tuple<uint64_t, uint64_t>;
range find_heap(const string &pid)
{
regex heap_regex(".*\\[heap\\].*");
regex heap_addr("^([0-9a-fA-F]+)-([0-9a-fA-F]+)");
string path = "/proc/" + pid + "/maps";
fstream file(path, file.in);
smatch addr;
if (!file.is_open())
return {0UL, 0UL};
for (string line; getline(file, line); ) {
if (regex_search(line, heap_regex)) {
regex_search(line, addr, heap_addr);
return {stoul("0x" + addr.str(1), 0, 16),
stoul("0x" + addr.str(2), 0, 16)};
}
}
return {0UL, 0UL};
}
uint64_t search_memory(int fd, range addr, base expected)
{
base frame;
uint64_t start = get<0>(addr);
while (start < get<1>(addr)) {
pread(fd, &frame, sizeof(frame), static_cast<off_t>(start + 0x20));
if (frame.width == expected.width &&
frame.height == expected.height &&
frame.mines == expected.mines) {
return start;
}
start += 8;
}
return 0;
}
int main(int argc, char *argv[])
{
uint64_t location;
uint64_t has_mine_p;
int32_t has_mine;
int32_t mine_pos;
if (argc != 5) {
cerr << "run: " << argv[0] << " <pid> <width> <height> <mines>\n";
return 2;
}
auto addresses = find_heap(string(argv[1]));
if (get<0>(addresses) == 0ULL) {
cerr << "cannot parse the mem map correctly.\n";
return 1;
}
string mem_path("/proc/" + string(argv[1]) + "/mem");
int fd = open(mem_path.c_str(), O_RDONLY);
if (fd < 0) {
cerr << "cannot open " << mem_path << ".\n";
return 3;
}
base frame = {stoi(argv[2]), stoi(argv[3]), stoi(argv[4])};
auto address = search_memory(fd, addresses, frame);
if (address == 0) {
cerr << "cannot find the board in memory.\n";
return 4;
}
pread(fd, &location, sizeof(uint64_t), static_cast<off_t>(address + 0x30));
pread(fd, &mine_pos, sizeof(int32_t), static_cast<off_t>(address + 0x3c));
for (int i = 0; i < frame.height; ++i) {
for (int j = 0; j < frame.width; ++j) {
auto index = 8 * (mine_pos * j + i);
pread(fd, &has_mine_p, sizeof(uint64_t),
static_cast<off_t>((location + index)));
pread(fd, &has_mine, sizeof(int32_t),
static_cast<off_t>(has_mine_p + 0x20));
cout << has_mine << " ";
}
cout << endl;
}
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment