知道一个进程的ID/HANDLE/FileName,怎么取得它在内存中的映像文件地址?!

fi9 2002-12-24 02:05:42
知道一个进程的ID/HANDLE/FileName,怎么取得它在内存中的映像文件地址?!像
IMAGE_NT_HEADERTF等。
我知道ReadProcessMomey API是可以,但是它里面有个参数BaseAddress(基址),应该
就是映像文件的首地址吧?!可是我连它的首址都取不到,那我更加不能用
ReadProcessMomey来取得它了!
请问:怎么取得它的映像地址呢?!
...全文
93 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
fi9 2003-01-03
  • 打赏
  • 举报
回复
结帖!!!!!
RomanticProgrammer 2003-01-01
  • 打赏
  • 举报
回复
:)
fi9 2002-12-31
  • 打赏
  • 举报
回复
对不起,这两天忙着去把一个游戏修改器反汇编来研,所以没有上着来,
也谢谢各位的帮忙!
经过努力终于被做出来了,大家也来分享一下,因为,我没有发现哪位的回答比较正确,所以,也给大家来研究一下:
// 其实不是很难,真的,就一个参数问题,呵呵
#define PROCESS_BASE_ADDRESS //用户级程序基地址
DWORD dwP[0x200]; // 读进来的buffer
// Get Process's Handle with read/write VM
hProcessID = OpenProcess(
PROCESS_VM_READ | PROCESS_VM_WRITE, // 注意啊!就是用这两个参数
false,
dwProcessID); // 进程的ID
ReadProcessMemory(hProcessID, 0x400000, dwM, sizeof(dwM), NULL);

// 呵呵^_&,就这么地简单!!!
// 知道这些你也可以做个游戏修改器了,哈哈!
// 不过,还有一些进程是读不出来的,或者说不是读不出来吧,而是还不
// 知道它的基址,像kernal32.dll这样一些系统级的进程还不清楚它地基址
// 上面的代码只支持用户级的应用程序
大大怪老张 2002-12-31
  • 打赏
  • 举报
回复
记得01年有一期《电脑爱好者》里有提到过这个api的使用
iec 2002-12-30
  • 打赏
  • 举报
回复
xx
fi9 2002-12-28
  • 打赏
  • 举报
回复
?!
再UP一下!
bcb_fans 2002-12-27
  • 打赏
  • 举报
回复
我在VC版回复了......
RomanticProgrammer 2002-12-27
  • 打赏
  • 举报
回复
我想你还是没有理解Win32的虚拟内存技术.
"我的问题就是找出一般用户应用程序(用户模式区)的基址,可是,我还是不是很明白,它说到用户程序的地址为(0x00400000~0x7fffffff),是不是每个应用程序都有这么一块内存呢?!还是所有的应用程序共享这块内存?!
"
当然每个进程都有0x00400000~0x7fffffff地址,Win32的虚拟内存和保护模式下的dos内存是不一样的.在dos下,每个程序只占内存地址的一部分,比如0x004000~0x008fff.但是Win32 的虚拟内存是每个程序独有自己的4G内存空间.当然它是通过虚拟内存技术来实现的,因为我们知道现在的计算机没有4G的内存的.一个程序的0x00400000~0x7fffffff和另外一个程序的0x00400000~0x7fffffff的部分在实际上对应的实际内存是不一样的,这些都是有操作系统来管理和实现的,其中设计到Windows页管理等待技术,你不需要关心.你只需要知道每个程序都有4g的内存空间(地址)就行了,而且每个程序的地址和另外一个程序的地址是完全无关的.你在这4G的内存空间的内存访问完全不会影响另外一个程序(当然只是原理上).
RomanticProgrammer 2002-12-27
  • 打赏
  • 举报
回复
我想你还是没有理解Win32的虚拟内存技术.
"我的问题就是找出一般用户应用程序(用户模式区)的基址,可是,我还是不是很明白,它说到用户程序的地址为(0x00400000~0x7fffffff),是不是每个应用程序都有这么一块内存呢?!还是所有的应用程序共享这块内存?!
"
当然每个进程都有0x00400000~0x7fffffff地址,Win32的虚拟内存和保护模式下的dos内存是不一样的.在dos下,每个程序只占内存地址的一部分,比如0x004000~0x008fff.但是Win32 的虚拟内存是每个程序独有自己的4G内存空间.当然它是通过虚拟内存技术来实现的,因为我们知道现在的计算机没有4G的内存的.一个程序的0x00400000~0x7fffffff和另外一个程序的0x00400000~0x7fffffff的部分在实际上对应的实际内存是不一样的,这些都是有操作系统来管理和实现的,其中设计到Windows页管理等待技术,你不需要关心.你只需要知道每个程序都有4g的内存空间(地址)就行了,而且每个程序的地址和另外一个程序的地址是完全无关的.你在这4G的内存空间的内存访问完全不会影响另外一个程序(当然只是原理上).
fi9 2002-12-27
  • 打赏
  • 举报
回复
谢过!
昨晚在暖和的被窝里看了一个晚上的书(《Windows系统编程》),上面说到系统内存分了几个区:NULL指针分配模式区、MSDOS/16位WINDOWS应用程序兼容区(win2k无此区)、用户模式区、64K禁止进入模式区(win98无此区)、共享内存映射模式文件区(win2k无此区)、内核模式区。
我的问题就是找出一般用户应用程序(用户模式区)的基址,可是,我还是不是很明白,它说到用户程序的地址为(0x00400000~0x7fffffff),是不是每个应用程序都有这么一块内存呢?!还是所有的应用程序共享这块内存?!
可是,还是没有找到哪种方法可以读取其个应用程序的内存!
还请各位多多指教!
fi9 2002-12-27
  • 打赏
  • 举报
回复
都谢过啦!

TO BCB_FANS(四大名捕之追杀令):
我再去试试看!不过不知道用这种方法能够以PE结构读得出其它进程在内存中的内容来吗?!就像IMAGE_NT_HEADERS, IMAGE_SECTION_HEADER等?!

TO RomanticProgrammer(兰企鹅||南极俺最帅):
已经大部分明白了,可是,不知道这个(虚拟内存)与文件映射有什么关系、有什么不同?!

也希望哪位知道或者有什么见解的帮忙一下^_&
RomanticProgrammer 2002-12-26
  • 打赏
  • 举报
回复
我知道了.第二个参数是一个你遂意设定的地址值.
我们两对这个参数的理解有误.
在Win32中每个进程拥有4G的虚拟地址空间.这个参数只是你要都数据的开始地址.当然是0到4G的任意一个值,只要该进程从你指定的位置到size的位置的虚拟内存已经Allocate并且又都的权限.你就可以用ReadProcessMemory去读它.
如果你没有读的权限,就要用
VirtualProtectEx (lpDbgProcess->hProcess, PMAAddress,PMASize, PAGE_READONLY, &Protect);
把你知道的虚拟内存区域的保护属性改成可读,然后就可以读了.
当然.高端的2G属性操作系统,所以你没有权限读的.
RomanticProgrammer 2002-12-26
  • 打赏
  • 举报
回复
I am sorry!我误解了这个函数的参数,向你表示道歉.我大错特错.正在考虑.
fi9 2002-12-26
  • 打赏
  • 举报
回复
TO RomanticProgrammer(兰企鹅||南极俺最帅):

你的意思是:第二个参数(PMAAdress)是传出来的值?!
可是,我看到帮助里说是传进去的?!
像:
StartAddress = 0x400000;
VirtualQueryEx(MyProcessHandle, StartAddress, pimb,
sizeof(MEMORY_BASIC_INFORMATION));
可是,读到内容是去到StartAddress(0x400000)地址上的内容的?!

能出给出个简单的例子吗?!
现在知道进程句柄:MyProcessHandle
怎么取得进程的基址?!
谢谢!
RomanticProgrammer 2002-12-26
  • 打赏
  • 举报
回复
看看SDK帮助这几个函数的说明. :)
RomanticProgrammer 2002-12-26
  • 打赏
  • 举报
回复
PMAAddress就是通过DWORD VirtualQueryEx( HANDLE hProcess, LPCVOID lpAddress,
PMEMORY_BASIC_INFORMATION lpBuffer, DWORD dwLength);得来得.
它得第二个参数就是PMAAdress得指针.

PMASize是偏移的大小,以byte为单位设为0就表示从PMADDress指定的位置开始,没有便宜.
protect是你要设置的新的保护属性,可以设为下列值之一或者并集.
PAGE_READONLY Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception, and turn off the guard page status. Guard pages thus act as a one-shot access alarm.
The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

PAGE_NOACCESS Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE


fi9 2002-12-26
  • 打赏
  • 举报
回复
TO RomanticProgrammer(兰企鹅||南极俺最帅):

VirtualQueryEx(lpDbgProcess->hProcess, PMAAddress, &mbi,
sizeof (MEMORY_BASIC_INFORMATION));
的第二个参数(PMAAddress)是什么来的呢?!

VirtualProtectEx(lpDbgProcess->hProcess, PMAAddress, PMASize,
PAGE_READONLY, &Protect);
的第三个参数(PMASize)和第五个参数(Protect)又是什么来的?!
fi9 2002-12-26
  • 打赏
  • 举报
回复
首先,谢谢各位!
昨天我已经用这样的方法可以列出所有的在内存中进程:
/*
* 这里只是部分代码而以
*/
PROCESSENTRY32 pProcessEntry = new PROCESSENTRY32;
MODULEENTRY32 pModuleEntry = new MODULEENTRY32;

char cpProcessFileName[MAX_PATH];
char cpModuleFileName[MAX_PATH];

bool bOK = false;

HANDLE hSnapshot = ::CreateToolhelp32Snapshot(
TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS,
dwProcessID);

for (bool bProcess = ::Process32First(hSnapshot, pProcessEntry),
bProcess,
bProcess = ::Process32Next(hSnapshot, pProcessEntry))
{
HANDLE hS = ::CreateToolhelp32Snapshot(
TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS,
pProcessEntry->dwProcessID);

for (bool bModule = ::Module32First(hSnapshot, pModuleEntry),
bModule,
bModule = ::Module32Next(hSnapshot, pModuleEntry))
{
/* 注意:
* in windows 9x
* cpModuleFileName = pModuleEntry-szExePath
* in windows 2000
* cpModuleFileName = pModuleEntry->szModule
*
* use _strupr in VC
* use strupr in BCB
*/
strcpy(cpProcessFileName, strupr(pProcessEntry->szExePath));
strcpy(cpModuleFileName, strupr(pModuleEntry->szExePath));
if (strcmp(cpProcessFileName, cpModuleFileName) == 0)
{
bOK = true;
break;
}
}
if (!bOK)
continue;

fprintf(stdout,
"%-40s Address:%10x\n",
cpModuleFileName, (DWORD)cpModuleFileName->modBaseAddr);

::CloseHandle(hS);
}
::CloseHandle(hSnapshot);

但是,为什么列出的每一个用户级的进程地址都是0x400000呢?!
可是,当前0x400000的地址是当前运行的程序首址,也就是的我的这个程序。
我怎么才能得到真正的进程地址呢?!
RomanticProgrammer 2002-12-24
  • 打赏
  • 举报
回复
用这样类似这样得代码修改页属性:
VirtualProtectEx (lpDbgProcess->hProcess, PMAAddress,PMASize, PAGE_READONLY, &Protect);
然后就可以:
ReadProcessMemory (lpDbgProcess->hProcess, PMAAddress, PMABuffer, PMASize, NULL))
RomanticProgrammer 2002-12-24
  • 打赏
  • 举报
回复
to songtao:
GetThreadContext()是得到线程得环境变量,而不能得到进程得基地址;
//////////////
to FIGLAB (无花果) :
用类似这样得代码得到进程得基地址:
if (!VirtualQueryEx (lpDbgProcess->hProcess, PMAAddress, &mbi, sizeof (MEMORY_BASIC_INFORMATION)) || mbi.State != MEM_COMMIT)
{
//你得错误处理代码!!
}
加载更多回复(2)

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧