随着MODULEENTRY32和MODULEINFO,什么是扫描在一个单独的进程特定的INT值的步骤是什么?

问题描述 投票:1回答:1

我已经列举了流程模块,并有MODULEINFO。从我有一个基本地址,模块的大小和入口点。如果我有一个单独的进程与int x = 4定义的整数main(),我可以扫描该整数的地址使用的是什么我有MODULEINFO?会不会x栈,这是从模块EXE独立上存在?

我试图使与基址和SizeOfImage成员一环,铸造基地址为byte*,再加入1个字节,然后将其投射到int*搜索一个特定的值,但是我回来的每一个值是“0 ”。我相信我的方法是(非常)不正确。

如果有可能扫描int值任何人都可以点我在大方向上这样做呢?

c++ winapi
1个回答
3
投票

是 - 局部变量(非静态的,反正)被分配在栈上。看到自己的价值,你需要写东西调试器的顺序,如同时它的运行(以及含有感兴趣的变量功能被激活)暂停程序,走栈找到该值。

既然你显然使用的是Windows,函数,你可能会想看看包括:

你可能也想看看dbghlp API,可能与这些开始:

还有很多更没有考虑,但是这可能足以至少得到一点开始的。我以前发布的an answer that demonstrates StackWalk64, and some of the Sym* stuff

下面是一些代码使用调试器,将生成一个子进程,然后登录其产生的调试事件的梗概:

#include <windows.h>
#include <stdio.h>
#include "child_process.h"

void dispatch_child_event(DEBUG_EVENT const &event, child_process const &child) { 
    char *file_name;
    char buffer[512];

    switch ( event.dwDebugEventCode ) {
    case LOAD_DLL_DEBUG_EVENT:
        file_name = child.get_string(event.u.LoadDll.lpImageName);
        if ( event.u.LoadDll.fUnicode)
            printf("Loading %S\n", (wchar_t *)file_name);
        else
            printf("Loading %s\n", file_name);            

        break;

    case EXCEPTION_DEBUG_EVENT:
        switch (event.u.Exception.ExceptionRecord.ExceptionCode) 
        { 
            case EXCEPTION_ACCESS_VIOLATION: 
            {                
                if ( event.u.Exception.dwFirstChance)
                    break;
                EXCEPTION_RECORD const &r = event.u.Exception.ExceptionRecord;
                printf("Access Violation %x at %0#p\n",
                        r.ExceptionCode,
                        r.ExceptionAddress);
                break;
            }

            case EXCEPTION_BREAKPOINT: 
                printf("Breakpoint reached\n");
                break;

            case EXCEPTION_DATATYPE_MISALIGNMENT: 
                if ( !event.u.Exception.dwFirstChance)
                    printf("Misaligned data exception.\n");
                break;

            case EXCEPTION_SINGLE_STEP: 
                printf("Single Step...\n");
                break;

            case DBG_CONTROL_C: 
                if ( !event.u.Exception.dwFirstChance)
                    printf("Control+C pressed\n");
                break;    
            break;
        }

    case CREATE_THREAD_DEBUG_EVENT:
        printf("Client created a thread\n");
        break;

    case CREATE_PROCESS_DEBUG_EVENT:
        printf("Create-Process\n");
        break;

    case EXIT_THREAD_DEBUG_EVENT:
        printf("Thread exited.\n");
        break;

    case UNLOAD_DLL_DEBUG_EVENT:
        printf("DLL being unloaded\n");
        break;

    case OUTPUT_DEBUG_STRING_EVENT: {
        OUTPUT_DEBUG_STRING_INFO const &d = event.u.DebugString;
        char *string = child.get_debug_string(d.lpDebugStringData,
                                        d.nDebugStringLength);
        if ( d.fUnicode) 
            printf("Debug string: %S\n", string);
        else
            printf("Debug string: %s\n", string);
        break;
    }
    }
}

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

    DEBUG_EVENT event;

    if ( argc < 2 ) {
        fprintf(stderr, "Usage: Trace [executable|PID]");
        return EXIT_FAILURE;
    }

    child_process child(argv[1]);

    do { 
        WaitForDebugEvent(&event, INFINITE);

        dispatch_child_event(event, child);

        ContinueDebugEvent( event.dwProcessId,
                            event.dwThreadId,
                            DBG_CONTINUE );

    } while ( event.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);

    return 0;
}

使用以下child_process头:

#ifndef CHILD_PROCESS_H_INC_
#define CHILD_PROCESS_H_INC_

#include <windows.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <io.h>

#include "syserror.h"

struct no_spawn {
    no_spawn() { system_error("Spawning Program"); }
};

class child_process {
    HANDLE process_;
    HANDLE thread_;

    mutable char buffer[FILENAME_MAX];

public:
    child_process(char const *filename);

    char *get_string(void *string_name, DWORD num = 0) const;
    char *get_debug_string(void *string, DWORD num) const;   

    HANDLE process() { return process_; }
    HANDLE thread() { return thread_; }

    ~child_process() { CloseHandle(process()); }
};

#endif

这个类的实现如下:

#include "child_process.h"

static BOOL find_image(char const *name, char *buffer) {
    // Try to find an image file named by the user.
    // First search for the exact file name in the current
    // directory.  If that's not found, look for same base name
    // with ".com", ".exe" and ".bat" appended, in that order.
    // If we can't find it in the current directory, repeat
    // the entire process on directories specified in the
    // PATH environment variable.
    //
#define elements(array) (sizeof(array)/sizeof(array[0]))

    static char *extensions[] = {".com", ".exe", ".bat", ".cmd"};
    int i;
    char temp[FILENAME_MAX];

    if (-1 != _access(name, 0)) {
        strcpy(buffer, name);
        return TRUE;
    }

    for (i=0; i<elements(extensions); i++) {
        strcpy(temp, name);
        strcat(temp, extensions[i]);
        if ( -1 != _access(temp, 0)) {
            strcpy(buffer, temp);
            return TRUE;
        }
    }

    _searchenv(name, "PATH", buffer);
    if ( buffer[0] != '\0')
        return TRUE;

    for ( i=0; i<elements(extensions); i++) {
        strcpy(temp, name);
        strcat(temp, extensions[i]);
        _searchenv(temp, "PATH", buffer);
        if ( buffer[0] != '\0')
            return TRUE;
    }

    return FALSE;
}

child_process::child_process(char const *filename) {
    if (isdigit(filename[0])) {
        DWORD id = atoi(filename);
        process_ = OpenProcess(PROCESS_ALL_ACCESS, false, atoi(filename));
        DebugActiveProcess(id);
    }
    else {
        char buf[FILENAME_MAX];

        PROCESS_INFORMATION pi = {0};
        STARTUPINFO si = {0};
        si.cb = sizeof(si);

        if (!find_image(filename, buf))
            throw no_spawn();

        BOOL new_process_ = CreateProcess(buf, NULL, NULL, NULL, FALSE,
            DEBUG_ONLY_THIS_PROCESS,
            NULL, NULL,
            &si, &pi);

        if (!new_process_)
            throw no_spawn();

        CloseHandle(pi.hThread);
        process_ = pi.hProcess;
        thread_ = pi.hThread;
    }
}

char *child_process::get_string(void *string_name, DWORD num) const {
// string_name is a pointer to a pointer to a string, with the pointer and the 
// string itself located in another process_.  We use Readprocess_Memory to read 
// the first pointer, then the string itself into our process_ address space.  
// We then return a pointer (in our address space) to the string we read in.
//
    char *ptr;
    SIZE_T bytes_read;

    if ( 0 == num )
        num = sizeof(buffer);

    if ( string_name == NULL ) 
        return NULL;

    ReadProcessMemory(process_,
        string_name, 
        &ptr, 
        sizeof(ptr),
        &bytes_read);

    if (NULL == ptr ) 
        return NULL;

    ReadProcessMemory(process_,
        ptr,
        buffer,
        num,
        &bytes_read);

    return buffer;
}

char *child_process::get_debug_string(void *string, DWORD num) const {

    static char buffer[FILENAME_MAX];
    SIZE_T bytes_read;

    if ( string == NULL ) 
        return NULL;

    ReadProcessMemory(process_,
        string, 
        buffer, 
        num,
        &bytes_read);
    return buffer;
}

这还不够,做你想做的一切还没有,但至少应该给你在大方向上是一个开始。

哦,一个声明:我写的大多数代码相当长一段时间以前。有部分我一定会做不同,如果我是今天写。

© www.soinside.com 2019 - 2024. All rights reserved.