2017-03-19 1 views
3

특정 프로그램의 메모리를 PID로 검사하는 프로그램이 있습니다. Windows XP와 Windows 7에서는 잘 작동하지만 갑자기 Windows 10에서는 작동하지 않습니다.Windows 10에서 notepad.exe 메모리 검사가 작동하지 않습니다.

프로세스 권한을 사용할 수 있습니다. 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가 출력되지 NOTEPAD.EXE 메모리 덤프 입력 않을 때. Windows 10에서 내 프로그램이 잘 작동하도록하는 유용한 솔루션이 있습니까? 미리 감사드립니다.

+0

내 프로그램은 Windows 10에서 다른 프로세스의 메모리를 검사 할 수 있습니다. 왜 notepad.exe의 메모리를 검사 할 수 없는지 궁금합니다. – xersi

+2

[최소한의 완전하고 검증 가능한 예] (https://stackoverflow.com/help/mcve)를 보여주십시오. –

+0

http://www.cplusplus.com/forum/general/202725/에서 얻을 수 있습니다. 헬리오스 솔루션을 사용하십시오. notepad.exe 프로세스에서 프로그램이 메모리 덤프를 생성하지 않는다는 것을 알 수 있습니다. – xersi

답변

2

샘플 프로그램은 32 비트 프로세스 용으로 설계되었습니다. 64 비트에 비해 너무 큰 프로세스 메모리 파일을 만들려고합니다. 파일을 쓰려는 시도를 주석 처리하는 경우 for 루프를 수정하여 더 큰 프로세스 공간에서 반복하고 64 비트를 컴파일하면 작동합니다. 다음과 같이 변경하십시오.

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