如何在 Win32 中定位进程的全局和堆栈区域? [英] How can I locate a process' global and stack areas in Win32?

查看:26
本文介绍了如何在 Win32 中定位进程的全局和堆栈区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何定位 Win32 进程的哪些内存区域包含每个线程的全局数据和堆栈数据?

How can I locate which areas of memory of a Win32 process contain the global data and the stack data for each thread?

推荐答案

没有(我知道的)API 可以做到这一点.但是,如果您在此过程中有一个 DLL,那么您将在 DllMain 当每个线程被创建时.当您收到这些通知时,您可以记录该线程的线程 ID 和堆栈对象的地址,因为您将在新线程上被调用.因此,将线程 id 和堆栈地址存储在您当时创建的某个表中.尽量不要在DllMain中做很多工作,只需要记录堆栈位置并返回即可.

There is no API (that I know of) to do this. But If you have a DLL in the process, then you will get DLL_PROCESS_ATTACH/DLL_THREAD_ATTACH notifications in DllMain when each thread is created. You can record the thread ID and the address of a stack object for that thread when you get these notifications, because you will get called on the new thread. So store the thread id and stack address in some table that you create at that time. Don't try to do a lot of work in DllMain, just record the stack location and return.

然后您可以使用 VirtualQueryget 将每个线程堆栈上的变量地址转换为虚拟分配范围,这应该为您提供堆栈的基址(请记住,堆栈从高地址增长到低地址).堆栈的默认分配大小为 1Mb,但可以由链接器开关或线程创建者覆盖,但堆栈必须是连续的.因此,您从 VirtualQuery 返回的将是 那个时间点的完整堆栈

You can then use VirtualQuery to get turn the address of a variable on each thread stack into a virtual allocation range, that should give you the base address of the stack (remember that stacks grow from high addresses to low addresses). The default allocation size for a stack is 1Mb, but that can be overridden by a linker switch or by the thread creator, but a stack must be contiguous. So what you get back from VirtualQuery will be the full stack at that point in time

至于堆位置 - 堆可以有多个位置,但一般来说,如果您想假设一个连续的堆位置,请使用 HeapAlloc 获取堆对象的地址,然后VirtualQuery 确定用于堆的那部分.

As for the heap location - there can be multiple locations for the heap, but in general if you want to assume a single contigous heap location then use HeapAlloc to get the address of a heap object and then VirtualQuery to determine the range of pages for that section of the heap.

或者,您可以在 hModule 上为 EXE 和每个 DLL 使用 VirtualQuery.然后您可以假设任何可读写且不是堆栈或模块的东西都是堆的一部分.请注意,这在大多数进程中都是正确的,但在某些进程中可能并非如此,因为应用程序可以直接调用 VirtualAllocCreateFileMapping,从而导致有效的数据指针不是来自堆栈或堆.使用 EnumProcessModules 获取模块列表加载到进程中.

Alternatively You can use VirtualQuery on the hModule for the EXE and for each DLL. and then you can assume that anything that is read-write and isn't a stack or a module is part of the heap. Note that this will be true in most processes, but may not be true in some because an application can call VirtualAlloc or CreateFileMapping directly, resulting in valid data pointers that are not from either stack or heap. Use EnumProcessModules to get the the list of modules loaded into a process.

VirtualQuery 基本上采用一个随机地址,并返回该地址所属的页面集合的基地址,以及页面保护.因此,最好从分配的类型"的特定指针出发.

VirtualQuery basically takes a random address, and returns the base address of the collection of pages that that address belongs to, as well as the page protections. So it's good for going from a specific pointer which 'type' of allocation.

这篇关于如何在 Win32 中定位进程的全局和堆栈区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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