运行时进程内存补丁恢复状态 [英] Runtime process memory patching for restoring state

查看:219
本文介绍了运行时进程内存补丁恢复状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找存储过程内存的方法,稍后在某些条件下恢复。

I'm looking for a method for storing the process memory, and restore it later at certain conditions.

...

其实我已经阅读了关于它的问题...这似乎是一个很大的挑战!

Actually I've read questions about it... It seems a big challenge!

所以,让我们分析一下: ,但是许多进程是无状态的(向集中式服务器请求它们的状态)。进程使用网络连接和共享内存与其他进程进行通信。

So, let's analyse: The application is a distributed one, but many processes are stateless (request their state to a centralized server). Processes uses network connections and shared memory for communicating with other processes.

中央服务器应通过转储其进程内存来保存其状态,稍后在某些条件下应该恢复它。 (1)

The central server shall save its state by dumping its process memory, which should be restored later a certain conditions. (1)

我知道 ReadProcessMemory WriteProcessMemory 函数,它允许进程读取自己并覆盖已分配的内存,不是吗?
所以,我需要的是我开始读/写的地址,以及读/写的字节数。那么... 什么地址?我读过的许多代码都使用 VirtualAlloc ,但我不知道这是否对我有用。

I known about ReadProcessMemory and WriteProcessMemory functions, which allow the process to read itself and overwrite already allocated memory, isn't it? So, which I need is address where I start to read/write, and the number of bytes to read/write. So... what addresses? Many code I've read uses the address returned by VirtualAlloc, but I don't known whether this could be useful to me.

我假设进程可执行段不改变,所以他们不需要红色/书面。
在还原时,我还可以假设当主线程读取内存时,所有进程线程都处于相同的执行位置。

I assume that the process executable segments are not changing, so they do not need red/written. At restore time, I could also assume that all process threads are in the same execution position when the memory was read by the main thread.

堆栈内存和堆内存,这是我感兴趣的内存段。

It remains the stack memory, and the heap memory, which are the memory segments what I'm interested in.

可能吗?

(1)问为什么我要这么做是完全合法的。原因是...复杂,像往常一样。然而,说应用具有非常复杂的状态,这需要太复杂的状态保存算法。另一个选择(分析的主题)是实现一个记录器/重放机制,能够重现每一个已经导致修改状态的事件。

(1) It is perfectly legal to ask why I'm trying to do this. The reason is... complicated, as usual. However, say that the application has a very complicated state, that requires a too complex state saving algorithm. The another alternative (which is in subject of analysis) is the implementation of a logger/replay mechanism able to reproduce every event which has contributed to the modified state.

在我看来, malloc &公司钩子。所以我可以跟踪进程分配的内存。但实际上我注意到了 _CrtMemState 结构,但我不知道它是否对我有用。

It came to my mind the malloc & co. hook. So I can track the memory allocated by the process. But actually I noticed the _CrtMemState structure, but I don't known whether it could be useful to me.

推荐答案

ReadProcessMemory用于读取另一个过程。在进程内部,这是不必要的 - 你可以在同一个进程内引用一个指针来读取内存。

ReadProcessMemory is for reading the memory of another process. Inside of a process, it's unnecessary -- you can just dereference a pointer to read memory within the same process.

为了找到进程中的内存块,使用 VirtualQuery 。每个块将被标记一个状态,类型,大小等等。这里是一些代码我写几年前走的块列表为指定的进程(使用 VirtualQueryEx )。你使用 VirtualQuery 几乎相同的方式,除了你不必指定一个进程,因为它总是在运行它的进程。

To find the blocks of memory in a process, you can use VirtualQuery. Each block will be tagged with a state, type, size, etc. Here's some code I wrote years ago to walk the block list for a specified process (using VirtualQueryEx). You use VirtualQuery pretty much the same way, except that you don't have to specify a process, since it always walks the process in which its running.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

unsigned long usage;

void show_modules(HANDLE process) {

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for ( p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        printf("%#10.10x (%6uK)\t", info.BaseAddress, info.RegionSize/1024);

        switch (info.State) {
        case MEM_COMMIT:
            printf("Committed");
            break;
        case MEM_RESERVE:
            printf("Reserved");
            break;
        case MEM_FREE:
            printf("Free");
            break;
        }
        printf("\t");
        switch (info.Type) {
        case MEM_IMAGE:
            printf("Code Module");
            break;
        case MEM_MAPPED:
            printf("Mapped     ");
            break;
        case MEM_PRIVATE:
            printf("Private    ");
        }
        printf("\t");

        if ((info.State == MEM_COMMIT) && (info.Type == MEM_PRIVATE))
            usage +=info.RegionSize;

        int guard = 0, nocache = 0;

        if ( info.AllocationProtect & PAGE_NOCACHE)
            nocache = 1;
        if ( info.AllocationProtect & PAGE_GUARD )
            guard = 1;

        info.AllocationProtect &= ~(PAGE_GUARD | PAGE_NOCACHE);

        switch (info.AllocationProtect) {
        case PAGE_READONLY:
            printf("Read Only");
            break;
        case PAGE_READWRITE:
            printf("Read/Write");
            break;
        case PAGE_WRITECOPY:
            printf("Copy on Write");
            break;
        case PAGE_EXECUTE:
            printf("Execute only");
            break;
        case PAGE_EXECUTE_READ:
            printf("Execute/Read");
            break;
        case PAGE_EXECUTE_READWRITE:
            printf("Execute/Read/Write");
            break;
        case PAGE_EXECUTE_WRITECOPY:
            printf("COW Executable");
            break;
        }

        if (guard)
            printf("\tguard page");
        if (nocache)
            printf("\tnon-cachable");
        printf("\n");
    }
}

int main(int argc, char **argv) {

    int pid;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <process ID>", argv[0]);
        return 1;
    }

    sscanf(argv[1], "%i", &pid);

    HANDLE process = OpenProcess( 
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 
        false,
        pid);

    show_modules(process);
    printf("Total memory used: %luKB\n", usage/1024);
    return 0;
}        

这篇关于运行时进程内存补丁恢复状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆