Esempio n. 1
0
SimpleProcStat getProcStat(const std::string& pid) {
  SimpleProcStat stat;
  std::string content;
  if (readFile(getProcAttr("stat", pid), content).ok()) {
    auto detail_start = content.find_last_of(")");
    // Start parsing stats from ") <MODE>..."
    auto details = osquery::split(content.substr(detail_start + 2), " ");
    stat.state = details.at(0);
    stat.parent = details.at(1);
    stat.group = details.at(2);
    stat.user_time = details.at(11);
    stat.system_time = details.at(12);
    stat.nice = details.at(16);
    stat.start_time = TEXT(AS_LITERAL(BIGINT_LITERAL, details.at(19)) / 100);
  }

  if (readFile(getProcAttr("status", pid), content).ok()) {
    for (const auto& line : osquery::split(content, "\n")) {
      // Status lines are formatted: Key: Value....\n.
      auto detail = osquery::split(line, ":", 1);
      if (detail.size() != 2) {
        continue;
      }

      // There are specific fields from each detail.
      if (detail.at(0) == "Name") {
        stat.name = detail.at(1);
      } else if (detail.at(0) == "VmRSS") {
        detail[1].erase(detail.at(1).end() - 3, detail.at(1).end());
        // Memory is reported in kB.
        stat.resident_size = detail.at(1) + "000";
      } else if (detail.at(0) == "VmSize") {
        detail[1].erase(detail.at(1).end() - 3, detail.at(1).end());
        // Memory is reported in kB.
        stat.phys_footprint = detail.at(1) + "000";
      } else if (detail.at(0) == "Gid") {
        // Format is: R E - -
        auto gid_detail = osquery::split(detail.at(1), "\t");
        if (gid_detail.size() == 4) {
          stat.real_gid = gid_detail.at(0);
          stat.effective_gid = gid_detail.at(1);
        }
      } else if (detail.at(0) == "Uid") {
        auto uid_detail = osquery::split(detail.at(1), "\t");
        if (uid_detail.size() == 4) {
          stat.real_uid = uid_detail.at(0);
          stat.effective_uid = uid_detail.at(1);
        }
      }
    }
  }

  return stat;
}
Esempio n. 2
0
inline std::string readProcLink(const std::string& attr, const std::string& pid) {
  // The exe is a symlink to the binary on-disk.
  auto attr_path = getProcAttr(attr, pid);

  std::string result;
  char link_path[PATH_MAX] = {0};
  auto bytes = readlink(attr_path.c_str(), link_path, sizeof(link_path) - 1);
  if (bytes >= 0) {
    result = std::string(link_path);
  }

  return result;
}
Esempio n. 3
0
inline std::string readProcCMDLine(const std::string& pid) {
  auto attr = getProcAttr("cmdline", pid);

  std::string content;
  readFile(attr, content);
  // Remove \0 delimiters.
  std::replace_if(content.begin(),
                  content.end(),
                  [](const char& c) { return c == 0; },
                  ' ');
  // Remove trailing delimiter.
  boost::algorithm::trim(content);
  return content;
}
Esempio n. 4
0
void genProcessMap(const std::string& pid, QueryData& results) {
  auto map = getProcAttr("maps", pid);

  std::string content;
  readFile(map, content);
  for (auto& line : osquery::split(content, "\n")) {
    auto fields = osquery::split(line, " ");
    // If can't read address, not sure.
    if (fields.size() < 5) {
      continue;
    }

    Row r;
    r["pid"] = pid;
    if (!fields[0].empty()) {
      auto addresses = osquery::split(fields[0], "-");
      if (addresses.size() >= 2) {
        r["start"] = "0x" + addresses[0];
        r["end"] = "0x" + addresses[1];
      } else {
        // Problem with the address format.
        continue;
      }
    }

    r["permissions"] = fields[1];
    try {
      auto offset = std::stoll(fields[2], nullptr, 16);
      r["offset"] = (offset != 0) ? BIGINT(offset) : r["start"];

    } catch (const std::exception& e) {
      // Value was out of range or could not be interpreted as a hex long long.
      r["offset"] = "-1";
    }
    r["device"] = fields[3];
    r["inode"] = fields[4];

    // Path name must be trimmed.
    if (fields.size() > 5) {
      boost::trim(fields[5]);
      r["path"] = fields[5];
    }

    // BSS with name in pathname.
    r["pseudo"] = (fields[4] == "0" && !r["path"].empty()) ? "1" : "0";
    results.push_back(std::move(r));
  }
}
Esempio n. 5
0
void genProcessEnvironment(const std::string& pid, QueryData& results) {
  auto attr = getProcAttr("environ", pid);

  std::string content;
  readFile(attr, content);
  const char* variable = content.c_str();

  // Stop at the end of nul-delimited string content.
  while (*variable > 0) {
    auto buf = std::string(variable);
    size_t idx = buf.find_first_of("=");

    Row r;
    r["pid"] = pid;
    r["key"] = buf.substr(0, idx);
    r["value"] = buf.substr(idx + 1);
    results.push_back(r);
    variable += buf.size() + 1;
  }
}
Esempio n. 6
0
void genProcessMap(const std::string& pid, QueryData& results) {
  auto map = getProcAttr("maps", pid);

  std::string content;
  readFile(map, content);
  for (auto& line : osquery::split(content, "\n")) {
    auto fields = osquery::split(line, " ");

    Row r;
    r["pid"] = pid;

    // If can't read address, not sure.
    if (fields.size() < 5) {
      continue;
    }

    if (fields[0].size() > 0) {
      auto addresses = osquery::split(fields[0], "-");
      r["start"] = "0x" + addresses[0];
      r["end"] = "0x" + addresses[1];
    }

    r["permissions"] = fields[1];
    r["offset"] = BIGINT(std::stoll(fields[2], nullptr, 16));
    r["device"] = fields[3];
    r["inode"] = fields[4];

    // Path name must be trimmed.
    if (fields.size() > 5) {
      boost::trim(fields[5]);
      r["path"] = fields[5];
    }

    // BSS with name in pathname.
    r["pseudo"] = (fields[4] == "0" && r["path"].size() > 0) ? "1" : "0";
    results.push_back(r);
  }
}