ReadProcessMemory/C++的探索[通俗易懂]

ReadProcessMemory/C++的探索[通俗易懂]ReadProcessMemory函数msdn说明:BOOLWINAPIReadProcessMemory(_In_   HANDLEhProcess,_In_   LPCVOIDlpBaseAddress,_Out_  LPVOIDlpBuffer,_In_   SIZE_TnSize,_Out_  SIZE_T*lpNumberOfByte

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

ReadProcessMemory 函数msdn说明:

BOOL WINAPI ReadProcessMemory(
  _In_   HANDLE hProcess,
  _In_   LPCVOID lpBaseAddress,
  _Out_  LPVOID lpBuffer,
  _In_   SIZE_T nSize,
  _Out_  SIZE_T *lpNumberOfBytesRead
);

Parameters

hProcess [in]

A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.

进程句柄

lpBaseAddress [in]

A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails.

读取内存的基址(关键,因为不是随便取一个就能读出来的)

lpBuffer [out]

A pointer to a buffer that receives the contents from the address space of the specified process.

读出内容后输出的缓冲区的头地址

nSize [in]

The number of bytes to be read from the specified process.

需要读取内存的大小

lpNumberOfBytesRead [out]

A pointer to a variable that receives the number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.

实际读取内存的大小

Return value

If the function succeeds, the return value is nonzero.

如果成功,返回非0。

If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.

如果失败,返回0,错误可通过GetLastError获得

The function fails if the requested read operation crosses into an area of the process that is inaccessible.

重点:当操作进入了进程不可读取的部分时会失败,大多数人犯的错误。

Remarks

ReadProcessMemory copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call the function.

函数需要进程的PROCESS_VM_READ 权限

The entire area to be read must be accessible, and if it is not accessible, the function fails.

关于探索旅程的废话说一点:

开始按实验报告上的要求基址填了0x,其它查了下msdn函数原型简单写出了程序,运行一下,结果就悲剧的读取失败。

下面是错误的代码:

STARTUPINFO si;	PROCESS_INFORMATION pi;	HANDLE hProcess=NULL;	ZeroMemory( &si, sizeof(si) );	si.cb = sizeof(si);	ZeroMemory( &pi, sizeof(pi) );	if(!CreateProcess(L".\\memoryinfo_child2.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))	{		printf( "CreateProcess2 failed (%d)\n", GetLastError() );	}	WaitForSingleObject( pi.hProcess, 1000 );	byte *readtemp=new byte[256*16];	DWORD dwNumberOfBytesRead;	hProcess = OpenProcess(PROCESS_ALL_ACCESS,		FALSE, pi.dwProcessId );	if(hProcess !=NULL)	{		int i=0x00000000;		if(!ReadProcessMemory(hProcess,(LPCVOID)i,readtemp,0x10,&dwNumberOfBytesRead)){			i++;		}		printf("readsuccess:");		for(int i=0;i<dwNumberOfBytesRead;i++){			printf("\n");			printf("%X",readtemp[i]);		}		printf("\n");	}	CloseHandle( pi.hProcess );	CloseHandle( pi.hThread );

然后查了各种博客,讲得大同小异,有的说权限不对,有的说地址不对,然后我看到可以用GetLastError(菜鸟一枚,勿喷)获取错误代码,我用了后发现代码是5,然后用IDE工具中的错误查看器查出错误是:

仅完成部分的 ReadProcessMemory 或 WriteProcessMemory 请求。没啥帮助,不过 至少学会GetLastError(菜鸟一枚,勿喷),,,

对于基址不对,有人说得用CE工具查看(表示CE是神马东东),然后百度了下,原来CE的全称是ChartEngine,大神一般用来游戏作弊,没想到今日居然用来做作业。。。怒下。

居然支持中文版,感动,,,

用ChartEngine查看了子进程的内存,果然基址至少20000以上,还且经常会变。基址换了之后,真的读取成功了,感动得泪流满面。

后来由于基址在程序运行前会变化,所有用了while语句,直到成功时才跳出循环,苦逼,,,这么简单的东西搞了半天,主要基础没打好,,,,

下面是正确的代码:

STARTUPINFO si;	PROCESS_INFORMATION pi;	HANDLE hProcess=NULL;	ZeroMemory( &si, sizeof(si) );	si.cb = sizeof(si);	ZeroMemory( &pi, sizeof(pi) );	if(!CreateProcess(L".\\memoryinfo_child2.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))	{		printf( "CreateProcess2 failed (%d)\n", GetLastError() );	}	WaitForSingleObject( pi.hProcess, 1000 );	byte *readtemp=new byte[256*16];	DWORD dwNumberOfBytesRead;	hProcess = OpenProcess(PROCESS_ALL_ACCESS,		FALSE, pi.dwProcessId );	if(hProcess !=NULL)	{		int i=0x00020000;		while(!ReadProcessMemory(hProcess,(LPCVOID)i,readtemp,0x10,&dwNumberOfBytesRead)){			i++;		}		printf("readsuccess:");		for(int i=0;i<dwNumberOfBytesRead;i++){			printf("\n");			printf("%X",readtemp[i]);		}		printf("\n");	}	CloseHandle( pi.hProcess );	CloseHandle( pi.hThread );

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185838.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 对PS2遥控手柄与stm32单片机通信的理解(结合平衡小车之家的说明和程序)

    对PS2遥控手柄与stm32单片机通信的理解(结合平衡小车之家的说明和程序)为了更好地应用PS2遥控手柄,我想尽可能理解一下它与stm32单片机间通信控制的过程,首先看了平衡小车之家给的PS2遥控手柄使用说明,讲解的内容比较简洁,光凭这个说明不能很轻易地理解配套的程序逻辑,接下来结合平衡小车之家的程序内容对照说明解释一下我的理解。因是个人理解并非官方说明,如有误请帮助指出改正,非常感谢!一、自己看一遍说明在看程序之前要先看一下说明里的介绍,大致了解一下。说明及源码:…

    2022年5月2日
    48
  • file_get_contents(“php://input”)[通俗易懂]

    file_get_contents(“php://input”)

    2022年2月10日
    52
  • fsync操作

    fsync操作/*update需要刷磁盘的操作*/#0os_file_fsync_posix(file=20)at/data/mysql-boost-5.7.32/mysql-5.7.32/storage/innobase/os/os0file.cc:3081#10x000000000198c562inos_file_flush_func(file=20)at/data/mysql-boost-5.7.32/mysql-5.7.32/storage/innobase/os/os0file.c

    2022年5月31日
    47
  • java解析XML为对象「建议收藏」

    java解析XML为对象「建议收藏」详解Java解析XML的四种方法http://developer.51cto.com 2009-03-3113:12 cnlw1985 javaeye 我要评论()XML现在已经成为一种通用的数据交换格式,平台的无关性使得很多场合都需要用到XML。本文将详细介绍用Java解析XML的四种方法。
     
    XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。对于XML本身的语法知识与技术细节,需要阅读相关的技术文献

    2022年5月4日
    39
  • Arduino教程 RFID-RC522读IC卡门禁原理及破解防御[通俗易懂]

    【文章特色:1、提出IC卡破解原理和简单有效的防御方法2、网上其他文章对于硬件如何接线说得模糊不清】1、序言2、加载RC522库文件3、模块引脚接线4、程序代码5、运行结果先说下简单门禁系统的原理:(1)IC卡激活:门禁卡管理员将卡片放到读卡器、这时软件读取到IC卡的UID序列号信息(相当于身份证号码),将这个UID录入数据库激活IC卡。(2)刷卡

    2022年4月17日
    288
  • SORT 多目标跟踪算法笔记[通俗易懂]

    SORT 多目标跟踪算法笔记[通俗易懂]sort是一种简单的在线实时多目标跟踪算法。文章要点为:以IoU作为前后帧间目标关系度量指标;利用卡尔曼滤波器预测当前位置;通过匈牙利算法关联检测框到目标;应用试探期甄别虚检;使用FasterR-CNN,证明检测好跟踪可以很简单。技术方案所提方法以检测作为关键组件,传播目标状态到未来帧中,将当前检测与现有目标相关联,并管理跟踪目标的生命周期。Detection为从…

    2025年8月14日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号