2017-03-19 10 views
3

のために動作しません、私はPIDで特定のプログラムのメモリをスキャンするプログラムを持っています。これは、Windows XPとWindows 7のために非常にうまく動作しますが、突然、それは私も、プロセスの特権を有効にしているWindowsの10スキャンをnotepad.exeメモリは、Windows 10

では動作しません。 Windows 10のnotepad.exeのメモリを調べることができない理由は何ですか?これはSYSTEMプロセスでもありません。ここ

は基本的に同じことの例である:

#include <Windows.h> 
#include <iostream> 
#include <iomanip> 
#include <exception> 
#include <cstdint> 
#include <vector> 
#include <sstream> 
#include <fstream> 

template <typename T> 
void print_hex(std::ostream &stream, T x, int width = 8){ 
    stream << std::hex << std::setw(width) << std::setfill('0') << x << std::dec; 
} 

template <typename T> 
void print_address(std::ostream &stream, T x){ 
    if (x < 0x100) 
     print_hex(stream, x, 2); 
    else if (x < 0x10000) 
     print_hex(stream, x, 4); 
    else if (x < 0x100000000ULL) 
     print_hex(stream, x, 8); 
    else 
     print_hex(stream, x, 16); 
} 

class DebugProcess{ 
    DWORD pid; 
public: 
    DebugProcess(DWORD pid): pid(pid){ 
     if (!DebugActiveProcess(pid)){ 
      auto error = GetLastError(); 
      std::cerr << "DebugActiveProcess() failed with error " << error << " (0x"; 
      print_hex(std::cerr, error); 
      std::cerr << ")\n"; 
      throw std::exception(); 
     } 
    } 
    ~DebugProcess(){ 
     if (!DebugActiveProcessStop(this->pid)){ 
      auto error = GetLastError(); 
      std::cerr << "DebugActiveProcessStop() failed with error " << error << " (0x"; 
      print_hex(std::cerr, error); 
      std::cerr << ")\n"; 
     } 
    } 
}; 

bool is_handle_valid(HANDLE handle){ 
    return handle && handle != INVALID_HANDLE_VALUE; 
} 

class AutoHandle{ 
    HANDLE handle; 
public: 
    AutoHandle(HANDLE handle): handle(handle){} 
    ~AutoHandle(){ 
     if (is_handle_valid(this->handle)) 
      CloseHandle(this->handle); 
    } 
}; 

template <typename T> 
void zero_struct(T &mem){ 
    memset(&mem, 0, sizeof(mem)); 
} 

struct memory_region{ 
    std::uint64_t start, 
     size; 
    MEMORY_BASIC_INFORMATION info; 
}; 

void dump_process_memory(DWORD pid){ 
    DebugProcess dp(pid); 

    auto proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid); 
    if (!is_handle_valid(proc)){ 
     auto error = GetLastError(); 
     std::cerr << "OpenProcess() failed with error " << error << " (0x"; 
     print_hex(std::cerr, error); 
     std::cerr << ")\n"; 
     return; 
    } 
    AutoHandle autoproc(proc); 

    std::vector<memory_region> regions; 
    for (std::uint64_t address = 0; address < 0x10000000ULL;){ 
     MEMORY_BASIC_INFORMATION mbi; 
     zero_struct(mbi); 
     auto bytes = VirtualQueryEx(proc, (LPCVOID)address, &mbi, sizeof(mbi)); 
     if (!bytes){ 
      address += 4096; 
      continue; 
     } 
     if (mbi.State == MEM_COMMIT && (mbi.Protect & PAGE_GUARD) != PAGE_GUARD) 
      regions.push_back(memory_region{ (std::uint64_t)mbi.BaseAddress, mbi.RegionSize, mbi }); 

     address += mbi.RegionSize; 
    } 

    if (regions.size()){ 
     std::cout << "Flat size: " << regions.back().start + regions.back().size << std::endl; 
     std::uint64_t sum = 0; 
     for (auto &region : regions) 
      sum += region.size; 
     std::cout << "Packed size: " << sum << std::endl; 
    } 

    std::ofstream file("dump.bin", std::ios::binary); 
    std::uint64_t current_size = 0; 
    for (auto &region : regions){ 
     std::vector<char> buffer(region.size); 
     size_t read; 
     if (!ReadProcessMemory(proc, (LPCVOID)region.start, &buffer[0], buffer.size(), &read)){ 
      auto error = GetLastError(); 
      if (error != ERROR_PARTIAL_COPY){ 
       std::cerr << "ReadProcessMemory() failed with error " << error << " (0x"; 
       print_hex(std::cerr, error); 
       std::cerr << ")\n"; 
       return; 
      } 
     } 

     if (read < region.size){ 
#if 1 
      std::cerr << "Warning: region starting at 0x"; 
      print_address(std::cerr, region.start); 
      std::cerr << " has size " << region.size << ", but only " << read 
       << " bytes could be read by ReadProcessMemory().\n"; 
#endif 
      memset(&buffer[read], 0, buffer.size() - read); 
     } 

     file.seekp(region.start); 

     file.write(&buffer[0], buffer.size()); 
    } 
} 

int main(int argc, char **argv) 
{ 
    DWORD pid; 
    std::cout << "Enter PID : "; 
    std::cin >> pid; 

    try{ 
     dump_process_memory(pid); 
    }catch (std::exception &){ 
     std::cerr << "Exception caught.\n"; 
    } 

    std::cin.ignore();  
    std::cin.get();  
    return 0; 
} 

例では、そのPIDが入力されると、プログラムは、メモ帳のための出力メモリダンプはありません。 私のプログラムをWindows 10でうまく動作させるための有益な解決策はありますか?前もって感謝します。

+0

私のプログラムでは、他のプロセスのメモリをWindows 10でもうまく調べることができます。なぜnotepad.exeのメモリをスキャンできないのでしょうか? – xersi

+2

は(https://stackoverflow.com/help/mcve)[最小の、完全な、検証例]表示します。 –

+0

あなたはhttp://www.cplusplus.com/forum/general/202725/から1を得ることができます。ヘリオス溶液を使用してください。 notepad.exeプロセスでは、プログラムがメモリダンプを生成しないことがわかります。 – xersi

答えて

2

サンプルプログラムは、32ビットプロセス用に設計されています。 64ビットでは大きすぎるプロセスメモリのファイルを作成しようとします。あなたは、ファイルを書き込むための試みをコメントアウトした場合、はるかに大きなプロセス空間を反復し、それが動作する64ビットをコンパイルするforループを修正。次のように変更してください。

for(std::uint64_t address = 0;;) // remove exit condition 
{ 
    MEMORY_BASIC_INFORMATION mbi; 
    zero_struct(mbi); 
    auto bytes = VirtualQueryEx(proc, (LPCVOID)address, &mbi, sizeof(mbi)); 
    if (!bytes){ 
     break; // break loop when address exceeds maximum supported 
    } 
    if (mbi.State == MEM_COMMIT && (mbi.Protect & PAGE_GUARD) != PAGE_GUARD) 
     regions.push_back(memory_region{ (std::uint64_t)mbi.BaseAddress, mbi.RegionSize, mbi }); 

    address += mbi.RegionSize; 

} 

コメントの書き込み。再評価が必要です。

//std::ofstream file("dump.bin", std::ios::binary); 

    ... 

    //file.seekp(region.start); 
    //file.write(&buffer[0], buffer.size()); 

メモ帳の出力。フラットサイズ(書き込もうとしたファイルのサイズ)は140TBです。

Flat size: 140728080994304 
Packed size: 106180608 
Warning: region starting at 0x00007df600fe8000 has size 552960, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f5d23000 has size 6721536, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f638e000 has size 3747840, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f672d000 has size 77824, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6748000 has size 147456, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6777000 has size 786432, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f683a000 has size 16384, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f683f000 has size 774144, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6902000 has size 4096, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6906000 has size 163840, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f692f000 has size 8192, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6938000 has size 331776, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f698c000 has size 32768, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f699a000 has size 319488, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f69ea000 has size 4096, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f69ee000 has size 32768, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f69fe000 has size 8192, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6a35000 has size 4096, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6a8e000 has size 77824, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6aad000 has size 32768, but only 0 bytes could be read by ReadProcessMemory(). 
Warning: region starting at 0x00007ff5f6ac7000 has size 20480, but only 0 bytes could be read by ReadProcessMemory(). 
+0

私はこの問題を解決する方法を見つけ、Windows 10でプログラムを正常に動作させるために使用しました。32ビットプログラムが64ビットプログラムで動作しないという情報のビットは貴重です。あなたはこの質問に答えるためにいくつかの点を得る。 – xersi