예제 #1
0
void TestThreadList()
{
  using ThreadListIterCat =
    std::iterator_traits<hadesmem::ThreadList::iterator>::iterator_category;
  HADESMEM_DETAIL_STATIC_ASSERT(
    std::is_base_of<std::input_iterator_tag, ThreadListIterCat>::value);
  using ThreadListConstIterCat = std::iterator_traits<
    hadesmem::ThreadList::const_iterator>::iterator_category;
  HADESMEM_DETAIL_STATIC_ASSERT(
    std::is_base_of<std::input_iterator_tag, ThreadListConstIterCat>::value);

  {
    hadesmem::detail::SmartHandle wait_thread_1(
      ::CreateThread(nullptr, 0, &SleepWrapper, nullptr, 0, nullptr));
    hadesmem::detail::SmartHandle wait_thread_2(
      ::CreateThread(nullptr, 0, &SleepWrapper, nullptr, 0, nullptr));
  }

  hadesmem::ThreadList const thread_list_1(::GetCurrentProcessId());
  hadesmem::ThreadList thread_list_2(thread_list_1);
  hadesmem::ThreadList thread_list_3(std::move(thread_list_2));
  thread_list_2 = std::move(thread_list_3);
  BOOST_TEST(std::begin(thread_list_2) != std::end(thread_list_2));

  auto iter = std::begin(thread_list_1);
  BOOST_TEST(iter != std::end(thread_list_1));
  BOOST_TEST(++iter != std::end(thread_list_1));
  BOOST_TEST_NE(iter->GetId(), 0U);
  DWORD const second_id = iter->GetId();
  BOOST_TEST(++iter != std::end(thread_list_1));
  DWORD const third_id = iter->GetId();
  BOOST_TEST_NE(second_id, third_id);
}
예제 #2
0
파일: read.hpp 프로젝트: lvous/hadesmem
void ReadStringEx(Process const& process,
                  PVOID address,
                  OutputIterator data,
                  std::size_t chunk_len,
                  void* upper_bound)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsCharType<T>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_base_of<
    std::output_iterator_tag,
    typename std::iterator_traits<OutputIterator>::iterator_category>::value);

  HADESMEM_DETAIL_ASSERT(chunk_len != 0);

  for (;;)
  {
    detail::ProtectGuard protect_guard{
      process, address, detail::ProtectGuardType::kRead};

    MEMORY_BASIC_INFORMATION const mbi = detail::Query(process, address);
    PVOID const region_next_real =
      static_cast<PBYTE>(mbi.BaseAddress) + mbi.RegionSize;
    void* const region_next = upper_bound
                                ? (std::min)(upper_bound, region_next_real)
                                : region_next_real;

    T* cur = static_cast<T*>(address);
    while (cur + 1 <= region_next)
    {
      std::size_t const len_to_end = reinterpret_cast<DWORD_PTR>(region_next) -
                                     reinterpret_cast<DWORD_PTR>(cur);
      std::size_t const buf_len_bytes =
        (std::min)(chunk_len * sizeof(T), len_to_end);
      std::size_t const buf_len = buf_len_bytes / sizeof(T);

      std::vector<T> buf(buf_len);
      detail::ReadUnchecked(process, cur, buf.data(), buf.size() * sizeof(T));

      auto const iter = std::find(std::begin(buf), std::end(buf), T());
      std::copy(std::begin(buf), iter, data);

      if (iter != std::end(buf) || region_next == upper_bound)
      {
        protect_guard.Restore();
        return;
      }

      cur += buf_len;
    }

    address = region_next;

    protect_guard.Restore();

    if (upper_bound && cur >= upper_bound)
    {
      return;
    }
  }
}
예제 #3
0
파일: read.hpp 프로젝트: lvous/hadesmem
inline std::vector<T, Alloc>
  ReadVector(Process const& process, PVOID address, std::size_t count)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_default_constructible<T>::value);

  HADESMEM_DETAIL_ASSERT(count ? address != nullptr : true);

  return ReadVectorEx<T, Alloc>(process, address, count, ReadFlags::kNone);
}
예제 #4
0
파일: patch_dr.hpp 프로젝트: geota/hadesmem
 explicit PatchDr(Process const& process,
                  TargetFuncT target,
                  DetourFuncT detour)
   : PatchVeh{process, target, detour}
 {
   HADESMEM_DETAIL_STATIC_ASSERT(detail::IsFunction<TargetFuncT>::value ||
                                 std::is_pointer<TargetFuncT>::value);
   HADESMEM_DETAIL_STATIC_ASSERT(detail::IsFunction<DetourFuncT>::value ||
                                 std::is_pointer<DetourFuncT>::value);
 }
예제 #5
0
파일: read.hpp 프로젝트: lvous/hadesmem
inline void ReadVector(Process const& process,
                       PVOID address,
                       std::size_t count,
                       OutputIterator out)
{
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_base_of<
    std::output_iterator_tag,
    typename std::iterator_traits<OutputIterator>::iterator_category>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_default_constructible<T>::value);

  HADESMEM_DETAIL_ASSERT(count ? address != nullptr : true);

  return ReadVectorEx<T>(process, address, count, out, ReadFlags::kNone);
}
예제 #6
0
  void GetCallbacks(OutputIterator callbacks) const
  {
    using OutputIteratorCategory =
      typename std::iterator_traits<OutputIterator>::iterator_category;
    HADESMEM_DETAIL_STATIC_ASSERT(
      std::is_base_of<std::output_iterator_tag, OutputIteratorCategory>::value);

    auto const image_base = GetRuntimeBase(*process_, *pe_file_);
    auto callbacks_raw = reinterpret_cast<PIMAGE_TLS_CALLBACK*>(
      RvaToVa(*process_,
              *pe_file_,
              static_cast<DWORD>(GetAddressOfCallBacks() - image_base)));
    if (!callbacks_raw)
    {
      HADESMEM_DETAIL_THROW_EXCEPTION(
        Error{} << ErrorString{"TLS callbacks are invalid."});
    }

    for (auto callback = Read<PIMAGE_TLS_CALLBACK>(*process_, callbacks_raw);
         callback;
         callback = Read<PIMAGE_TLS_CALLBACK>(*process_, ++callbacks_raw))
    {
      auto const callback_offset =
        reinterpret_cast<ULONGLONG>(callback) - image_base;
      *callbacks = reinterpret_cast<PIMAGE_TLS_CALLBACK>(
        static_cast<ULONG_PTR>(callback_offset));
      ++callbacks;
    }
  }
예제 #7
0
inline void Write(Process const& process, PVOID address, T const& data)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);

  detail::WriteImpl(process, address, data);
}
예제 #8
0
void WriteImpl(Process const& process, PVOID address, T const& data)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);

  WriteImpl(process, address, std::addressof(data), sizeof(data));
}
예제 #9
0
파일: read.hpp 프로젝트: lvous/hadesmem
inline void ReadVectorEx(Process const& process,
                         PVOID address,
                         std::size_t count,
                         OutputIterator out,
                         std::uint32_t flags)
{
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_base_of<
    std::output_iterator_tag,
    typename std::iterator_traits<OutputIterator>::iterator_category>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_default_constructible<T>::value);

  HADESMEM_DETAIL_ASSERT(count ? address != nullptr : true);

  auto const data = ReadVectorEx<T>(process, address, count, flags);
  std::copy(std::begin(data), std::end(data), out);
}
예제 #10
0
void TestRegionList()
{
  using RegionListIterCat =
    std::iterator_traits<hadesmem::RegionList::iterator>::iterator_category;
  HADESMEM_DETAIL_STATIC_ASSERT(
    std::is_base_of<std::input_iterator_tag, RegionListIterCat>::value);
  using RegionListConstIterCat = std::iterator_traits<
    hadesmem::RegionList::const_iterator>::iterator_category;
  HADESMEM_DETAIL_STATIC_ASSERT(
    std::is_base_of<std::input_iterator_tag, RegionListConstIterCat>::value);

  hadesmem::Process const process(::GetCurrentProcessId());

  hadesmem::RegionList const region_list_1(process);
  hadesmem::RegionList region_list_2(region_list_1);
  hadesmem::RegionList region_list_3(std::move(region_list_2));
  region_list_2 = std::move(region_list_3);
  BOOST_TEST(std::begin(region_list_2) != std::end(region_list_2));

  auto iter = std::begin(region_list_1);
  hadesmem::Region const first_region(process, nullptr);
  BOOST_TEST(iter != std::end(region_list_1));
  BOOST_TEST_EQ(*iter, first_region);
  hadesmem::Region const second_region(
    process,
    static_cast<char const* const>(first_region.GetBase()) +
      first_region.GetSize());
  BOOST_TEST(++iter != std::end(region_list_1));
  BOOST_TEST_EQ(*iter, second_region);
  hadesmem::Region last(process, nullptr);
  do
  {
    hadesmem::Region current = *iter;
    BOOST_TEST(current > last);
    BOOST_TEST(current >= last);
    BOOST_TEST(last < current);
    BOOST_TEST(last <= current);
    last = current;
  } while (++iter != std::end(region_list_1));

  BOOST_TEST_THROWS(
    hadesmem::Region(
      process, static_cast<char const* const>(last.GetBase()) + last.GetSize()),
    hadesmem::Error);
}
예제 #11
0
파일: read.hpp 프로젝트: lvous/hadesmem
inline std::vector<T, Alloc> ReadVectorEx(Process const& process,
                                          PVOID address,
                                          std::size_t count,
                                          std::uint32_t flags)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_default_constructible<T>::value);

  HADESMEM_DETAIL_ASSERT(count ? address != nullptr : true);

  if (!count)
  {
    return {};
  }

  std::vector<T, Alloc> data(count);
  detail::ReadImpl(process, address, data.data(), sizeof(T) * count, flags);
  return data;
}
예제 #12
0
inline void WriteString(Process const& process,
                        PVOID address,
                        std::basic_string<T, Traits, Alloc> const& data)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsCharType<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);

  return Write(process, address, data.c_str(), data.size() + 1);
}
예제 #13
0
inline void
  WriteString(Process const& process, PVOID address, T const* const str)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsCharType<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);
  HADESMEM_DETAIL_ASSERT(str != nullptr);

  WriteString(process, address, std::basic_string<T>(str));
}
예제 #14
0
파일: read.hpp 프로젝트: lvous/hadesmem
inline void Read(Process const& process, PVOID address, OutputIterator out)
{
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_base_of<
    std::output_iterator_tag,
    typename std::iterator_traits<OutputIterator>::iterator_category>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);

  auto const data = detail::ReadImpl<std::array<T, N>>(process, address);
  std::copy(&data[0], &data[0] + N, out);
}
예제 #15
0
inline void WriteVector(Process const& process,
                        PVOID address,
                        std::vector<T, Alloc> const& data)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);
  HADESMEM_DETAIL_ASSERT(!data.empty());

  std::size_t const raw_size = data.size() * sizeof(T);
  detail::WriteImpl(process, address, data.data(), raw_size);
}
예제 #16
0
inline void
  Write(Process const& process, PVOID address, T const* beg, T const* end)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);
  HADESMEM_DETAIL_ASSERT(beg != nullptr);
  HADESMEM_DETAIL_ASSERT(end != nullptr);

  std::size_t const count = static_cast<std::size_t>(std::distance(beg, end));
  Write(process, address, beg, count);
}
예제 #17
0
inline void
  Write(Process const& process, PVOID address, T const* ptr, std::size_t count)
{
  HADESMEM_DETAIL_STATIC_ASSERT(detail::IsTriviallyCopyable<T>::value);

  HADESMEM_DETAIL_ASSERT(address != nullptr);
  HADESMEM_DETAIL_ASSERT(ptr != nullptr);
  HADESMEM_DETAIL_ASSERT(count != 0);

  std::size_t const raw_size =
    static_cast<std::size_t>(std::distance(ptr, ptr + count)) * sizeof(T);
  detail::WriteImpl(process, address, ptr, raw_size);
}
예제 #18
0
inline FARPROC GetProcAddressInternalFromPred(Process const& process,
                                              HMODULE module,
                                              Pred pred)
{
  HADESMEM_DETAIL_STATIC_ASSERT(sizeof(FARPROC) == sizeof(void*));

  PeFile const pe_file{process, module, PeFileType::Image, 0};

  ExportList const exports{process, pe_file};
  auto const iter = std::find_if(std::begin(exports), std::end(exports), pred);
  if (iter != std::end(exports))
  {
    return GetProcAddressFromExport(process, *iter);
  }

  return nullptr;
}
예제 #19
0
파일: toolhelp.hpp 프로젝트: lvous/hadesmem
hadesmem::detail::Optional<Entry>
  Toolhelp32Enum(Func func, HANDLE snap, std::string const& error)
{
  HADESMEM_DETAIL_STATIC_ASSERT(std::is_pod<Entry>::value);

  Entry entry{};
  entry.dwSize = static_cast<DWORD>(sizeof(entry));
  if (!func(snap, &entry))
  {
    DWORD const last_error = ::GetLastError();
    if (last_error == ERROR_NO_MORE_FILES)
    {
      return hadesmem::detail::Optional<Entry>();
    }

    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{error.c_str()}
                                            << ErrorCodeWinLast{last_error});
  }

  return hadesmem::detail::Optional<Entry>(entry);
}