Ejemplo n.º 1
0
int main(int argc, char* argv[])
{
  try
  {
    std::cout << "HadesMem Dumper [" << HADESMEM_VERSION_STRING << "]\n";

    TCLAP::CmdLine cmd("PE file format dumper", ' ', HADESMEM_VERSION_STRING);
    TCLAP::ValueArg<DWORD> pid_arg(
      "", "pid", "Target process id", false, 0, "DWORD");
    TCLAP::ValueArg<std::string> name_arg(
      "", "name", "Target process name", false, "", "string");
    TCLAP::MultiArg<std::string> path_arg(
      "", "path", "Target path (file or directory)", false, "string");
    TCLAP::SwitchArg all_arg("", "all", "No target, dump everything");
    std::vector<TCLAP::Arg*> xor_args{&pid_arg, &name_arg, &path_arg, &all_arg};
    cmd.xorAdd(xor_args);
    TCLAP::SwitchArg warned_arg(
      "", "warned", "Dump list of files which cause warnings", cmd);
    TCLAP::ValueArg<std::string> warned_file_arg(
      "",
      "warned-file",
      "Dump warned list to file instead of stdout",
      false,
      "",
      "string",
      cmd);
    TCLAP::SwitchArg warned_file_dynamic_arg(
      "",
      "warned-file-dynamic",
      "Dump warnings to file on the fly rather than at the end",
      cmd);
    TCLAP::SwitchArg quiet_arg(
      "", "quiet", "Only output status messages (no dumping)", cmd);
    TCLAP::SwitchArg memonly_arg("", "memonly", "Only do PE memory dumps", cmd);
    TCLAP::ValueArg<int> warned_type_arg("",
                                         "warned-type",
                                         "Filter warned file using warned type",
                                         false,
                                         -1,
                                         "int",
                                         cmd);
    TCLAP::ValueArg<DWORD> threads_arg(
      "", "threads", "Number of threads", false, 0, "size_t", cmd);
    TCLAP::ValueArg<DWORD> queue_factor_arg(
      "", "queue-factor", "Thread queue factor", false, 0, "size_t", cmd);
    TCLAP::SwitchArg strings_arg("", "strings", "Dump strings", cmd);
    cmd.parse(argc, argv);

    g_quiet = quiet_arg.isSet();

    g_strings = strings_arg.isSet();

    SetWarningsEnabled(warned_arg.getValue());
    SetDynamicWarningsEnabled(warned_file_dynamic_arg.getValue());
    if (warned_file_arg.isSet())
    {
      SetWarnedFilePath(
        hadesmem::detail::MultiByteToWideChar(warned_file_arg.getValue()));
    }

    if (GetDynamicWarningsEnabled() && GetWarnedFilePath().empty())
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(
        hadesmem::Error() << hadesmem::ErrorString(
          "Please specify a file path for dynamic warnings."));
    }

    int const warned_type = warned_type_arg.getValue();
    switch (warned_type)
    {
    case static_cast<int>(WarningType::kSuspicious):
      SetWarnedType(WarningType::kSuspicious);
      break;
    case static_cast<int>(WarningType::kUnsupported):
      SetWarnedType(WarningType::kUnsupported);
      break;
    case static_cast<int>(WarningType::kAll):
      SetWarnedType(WarningType::kAll);
      break;
    default:
      HADESMEM_DETAIL_THROW_EXCEPTION(
        hadesmem::Error() << hadesmem::ErrorString("Unknown warned type."));
      break;
    }

    try
    {
      hadesmem::GetSeDebugPrivilege();

      std::wcout << "\nAcquired SeDebugPrivilege.\n";
    }
    catch (std::exception const& /*e*/)
    {
      std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
    }

    auto const threads = threads_arg.isSet() ? threads_arg.getValue() : 1;
    auto const queue_factor =
      queue_factor_arg.isSet() ? queue_factor_arg.getValue() : 1;
    hadesmem::detail::ThreadPool thread_pool{threads, queue_factor};

    if (pid_arg.isSet())
    {
      DWORD const pid = pid_arg.getValue();

      hadesmem::ProcessList const processes;
      auto iter =
        std::find_if(std::begin(processes),
                     std::end(processes),
                     [pid](hadesmem::ProcessEntry const& process_entry)
                     {
                       return process_entry.GetId() == pid;
                     });
      if (iter != std::end(processes))
      {
        DumpProcessEntry(*iter, memonly_arg.isSet());
      }
      else
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          hadesmem::Error()
          << hadesmem::ErrorString("Failed to find requested process."));
      }
    }
    else if (name_arg.isSet())
    {
      auto const proc_name =
        hadesmem::detail::MultiByteToWideChar(name_arg.getValue());
      auto const proc_entry = hadesmem::GetProcessEntryByName(proc_name, false);
      DumpProcessEntry(proc_entry, memonly_arg.isSet());
    }
    else if (path_arg.isSet())
    {
      // TODO: Use backup semantics flags and try to get backup privilege in
      // order to make directory enumeration find more files.
      auto const path_args = path_arg.getValue();
      for (auto const& path : path_args)
      {
        auto const path_wide = hadesmem::detail::MultiByteToWideChar(path);
        if (hadesmem::detail::IsDirectory(path_wide))
        {
          DumpDir(path_wide, thread_pool);
        }
        else
        {
          DumpFile(path_wide);
        }
      }
    }
    else
    {
      DumpThreads(static_cast<DWORD>(-1));

      DumpProcesses(memonly_arg.isSet());

      std::wcout << "\nFiles:\n";

      // TODO: Enumerate all volumes.
      std::wstring const self_path = hadesmem::detail::GetSelfPath();
      std::wstring const root_path = hadesmem::detail::GetRootPath(self_path);
      DumpDir(root_path, thread_pool);
    }

    thread_pool.WaitForEmpty();

    if (GetWarningsEnabled())
    {
      if (!GetWarnedFilePath().empty() && !GetDynamicWarningsEnabled())
      {
        std::unique_ptr<std::wfstream> warned_file_ptr(
          hadesmem::detail::OpenFile<wchar_t>(GetWarnedFilePath(),
                                              std::ios::out));
        std::wfstream& warned_file = *warned_file_ptr;
        if (!warned_file)
        {
          HADESMEM_DETAIL_THROW_EXCEPTION(
            hadesmem::Error()
            << hadesmem::ErrorString("Failed to open warned file for output."));
        }

        DumpWarned(warned_file);
      }
      else
      {
        DumpWarned(std::wcout);
      }
    }

    return 0;
  }
  catch (...)
  {
    std::cerr << "\nError!\n"
              << boost::current_exception_diagnostic_information() << '\n';

    return 1;
  }
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
  try
  {
    std::cout << "HadesMem Dumper [" << HADESMEM_VERSION_STRING << "]\n";

    TCLAP::CmdLine cmd("PE file format dumper", ' ', HADESMEM_VERSION_STRING);
    TCLAP::ValueArg<DWORD> pid_arg(
      "", "pid", "Target process id", false, 0, "DWORD");
    TCLAP::ValueArg<std::string> name_arg(
      "", "name", "Target process name", false, "", "string");
    TCLAP::ValueArg<std::string> path_arg(
      "", "path", "Target path (file or directory)", false, "", "string");
    TCLAP::SwitchArg all_arg("", "all", "No target, dump everything");
    std::vector<TCLAP::Arg*> xor_args{&pid_arg, &name_arg, &path_arg, &all_arg};
    cmd.xorAdd(xor_args);
    TCLAP::SwitchArg warned_arg(
      "", "warned", "Dump list of files which cause warnings", cmd);
    TCLAP::ValueArg<std::string> warned_file_arg(
      "",
      "warned-file",
      "Dump warned list to file instead of stdout",
      false,
      "",
      "string",
      cmd);
    TCLAP::SwitchArg warned_file_dynamic_arg(
      "",
      "warned-file-dynamic",
      "Dump warnings to file on the fly rather than at the end",
      cmd);
    TCLAP::ValueArg<int> warned_type_arg("",
                                         "warned-type",
                                         "Filter warned file using warned type",
                                         false,
                                         -1,
                                         "int",
                                         cmd);
    cmd.parse(argc, argv);

    SetWarningsEnabled(warned_arg.getValue());
    SetDynamicWarningsEnabled(warned_file_dynamic_arg.getValue());
    if (warned_file_arg.isSet())
    {
      SetWarnedFilePath(
        hadesmem::detail::MultiByteToWideChar(warned_file_arg.getValue()));
    }

    if (GetDynamicWarningsEnabled() && GetWarnedFilePath().empty())
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(
        hadesmem::Error() << hadesmem::ErrorString(
          "Please specify a file path for dynamic warnings."));
    }

    int const warned_type = warned_type_arg.getValue();
    switch (warned_type)
    {
    case static_cast<int>(WarningType::kSuspicious):
      SetWarnedType(WarningType::kSuspicious);
      break;
    case static_cast<int>(WarningType::kUnsupported):
      SetWarnedType(WarningType::kUnsupported);
      break;
    case static_cast<int>(WarningType::kAll):
      SetWarnedType(WarningType::kAll);
      break;
    default:
      HADESMEM_DETAIL_THROW_EXCEPTION(
        hadesmem::Error() << hadesmem::ErrorString("Unknown warned type."));
      break;
    }

    try
    {
      hadesmem::GetSeDebugPrivilege();

      std::wcout << "\nAcquired SeDebugPrivilege.\n";
    }
    catch (std::exception const& /*e*/)
    {
      std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
    }

    if (pid_arg.isSet())
    {
      DWORD const pid = pid_arg.getValue();

      hadesmem::ProcessList const processes;
      auto iter =
        std::find_if(std::begin(processes),
                     std::end(processes),
                     [pid](hadesmem::ProcessEntry const& process_entry)
                     {
          return process_entry.GetId() == pid;
        });
      if (iter != std::end(processes))
      {
        DumpProcessEntry(*iter);
      }
      else
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          hadesmem::Error()
          << hadesmem::ErrorString("Failed to find requested process."));
      }
    }
    else if (name_arg.isSet())
    {
      auto const proc_name =
        hadesmem::detail::MultiByteToWideChar(name_arg.getValue());
      auto const proc_entry = hadesmem::GetProcessEntryByName(proc_name, false);
      DumpProcessEntry(proc_entry);
    }
    else if (path_arg.isSet())
    {
      auto const path =
        hadesmem::detail::MultiByteToWideChar(path_arg.getValue());
      if (hadesmem::detail::IsDirectory(path))
      {
        DumpDir(path);
      }
      else
      {
        DumpFile(path);
      }
    }
    else
    {
      DumpThreads(static_cast<DWORD>(-1));

      DumpProcesses();

      std::wcout << "\nFiles:\n";

      std::wstring const self_path = hadesmem::detail::GetSelfPath();
      std::wstring const root_path = hadesmem::detail::GetRootPath(self_path);
      DumpDir(root_path);
    }

    if (GetWarningsEnabled())
    {
      if (!GetWarnedFilePath().empty() && !GetDynamicWarningsEnabled())
      {
        std::unique_ptr<std::wfstream> warned_file_ptr(
          hadesmem::detail::OpenFile<wchar_t>(GetWarnedFilePath(),
                                              std::ios::out));
        std::wfstream& warned_file = *warned_file_ptr;
        if (!warned_file)
        {
          HADESMEM_DETAIL_THROW_EXCEPTION(
            hadesmem::Error()
            << hadesmem::ErrorString("Failed to open warned file for output."));
        }

        DumpWarned(warned_file);
      }
      else
      {
        DumpWarned(std::wcout);
      }
    }

    return 0;
  }
  catch (...)
  {
    std::cerr << "\nError!\n"
              << boost::current_exception_diagnostic_information() << '\n';

    if (!g_current_file_path.empty())
    {
      std::wcerr << "\nCurrent file: " << g_current_file_path << "\n";
    }

    return 1;
  }
}