扫描notepad.exe内存不适用于windows 10

wyyhbhjk  于 2023-05-08  发布在  Windows
关注(0)|答案(1)|浏览(147)

我有一个程序,它用PID扫描某个程序的内存。它在Windows XP和Windows 7上运行得非常好,但突然间它不适用于Windows 10。
我甚至启用了进程特权。它无法检查notepad.exe在Windows 10中的内存的原因是什么?它甚至不是一个系统进程。
下面是一个基本上相同的例子:

#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;
}

在本例中,当输入notepad.exe的PID时,程序不输出其内存转储。是否有任何有用的解决方案,使我的程序在Windows 10中正常工作?先谢谢你。

rslzwgfq

rslzwgfq1#

示例程序是为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().

相关问题