繁体   English   中英

使用MODULEENTRY32和MODULEINFO,在单独的进程中扫描特定INT值的步骤是什么?

[英]With MODULEENTRY32 and MODULEINFO, what are the steps to scan for a specific INT value in a separate process?

我列举了一个流程模块,并有一个MODULEINFO 从那里我有一个基地址,模块的大小和入口点。 如果我有一个单独的进程,在main()定义了一个整数int x = 4 ,我可以使用MODULEINFO内容扫描该整数的地址吗? 不会在堆栈上存在x ,它与模块exe分开吗?

我尝试使用基地址和SizeOfImage成员创建循环,将基地址转换为byte* ,然后添加1个字节然后将其转换为int*以搜索特定值,但是我得到的每个值都是“0”。 我相信我的方法(严重)不正确。

如果有可能扫描一个int值,任何人都可以指出我这样做的大方向吗?

是 - 在堆栈上分配局部变量(无论如何)。 要查看它们的值,您需要按调试器的顺序编写一些内容,例如在程序运行时暂停程序(并且包含感兴趣的变量的函数处于活动状态),然后遍历堆栈以查找值。

由于您显然使用的是Windows,因此您可能希望查看的功能包括:

您可能还想查看dbghlp API ,可能从以下开始:

还有更多需要考虑的因素,但这可能足以至少得到一些启动。 我之前发布了一个演示StackWalk64的答案,以及一些Sym *的东西

下面是一些代码,其中包含一个将生成子进程的调试器的骨架,然后记录它生成的调试事件:

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

这还不足以做你想做的一切,但至少它应该给你一个大方向的开始。

哦,一个免责声明:很久以前我写了大部分代码。 如果我今天要写的话,我肯定会有不同的部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM