gpt4 book ai didi

c - Memcpy() 适用于越界内存?

转载 作者:行者123 更新时间:2023-12-04 11:23:11 34 4
gpt4 key购买 nike

我一直认为 memcpy() 可以用于恶意目的。我做了几个测试应用程序,看看我是否可以从不同区域“窃取”内存中的数据。到目前为止,我已经测试了三个区域,堆、堆栈和常量(只读)内存。在我的测试中,常量内存是唯一崩溃的内存,引发了 MinGW 的错误。

这是一个例子来说明我最近的测试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void removeTerminatingCharacters( char ** string, const int length )
{
int i = 0;

for ( ; i < length; ++i )
if ( !( *string )[i] )
( *string )[i] = '0';

return;
}

int main()
{
int * naive = malloc( sizeof( int ) );
*naive = 0;

char * stolenData = malloc( 2000 );

memset( stolenData, 0, 2000 );
memcpy( stolenData, naive, 1999 );
removeTerminatingCharacters( &stolenData, 2000 );

printf( "%s\n", stolenData );

free( stolenData );
return 0;
}

输出:

0000-0:0Væ1lDk¦#:00000[æ0`Dk00p,:0-0:0MAIN=Computer0USERNAME=JohnDoe0USERPRO
FILE=C:\Users\JohnDoe0WATCOM=C:\watcom0windir=C:\Windows00?æ1+Ik?000S?000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00??????????????????????????000000 00000000 000000?0?0?
00000000000 0 0 ?0000000000 0000000000 0000 00000???????????????????????0???????
0 00000000000000000000000000000000000000000000000
000000000000000000abcdefghijklmnopqrstuvwxyz000000ABCDEFGHIJKLMNOPQRSTUVWXYZ0000
0000â000000Ü0£0P00000000000è0î0Ä 0000000000¬0000000000¦0000¦00000aßGpSsµtFTOd8fe
ä?:0ú?:0-?:0T?:0)?:0`?:0£?:0-?:0p?:0?:0??:0+?:08?:0T?:0¦?:0µ?:0²?:0¶?:03?:0D?:0R
?:0ä :0- :0+ :0a :0v :0?!:0^!:0q!:0ë!:0ñ!:0+!:0±!:0¤":0P":0g":0ó":0¦":0+":0¦":0?
#:0.#:0B#:0W#:0x#:0ë#:00000ALLUSERSPROFILE=C:\ProgramData0APPDATA=C:\Users\Chris
topher\AppData\Roaming0asl.log=Destination=file0CLASSPATH=.;C:\Program Files (x8
6)\Java\jre6\lib\ext\QTJava.zip0CommonProgramFiles=C:\Program Files (x86)\Common
Files0CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files0CommonProgram
W6432=C:\Program Files\Common Files0COMPUTERNAME=COMPUTER0ComSpec=C:\Windows\sys
tem32\cmd.exe0FPPUILang=en-US0FP_NO_HOST_CHECK=NO0HOMEDRIVE=C:0HOMEPATH=\Users\C
hristopher0HuluDesktopPath=C:\Users\JohnDoe\AppData\Local\HuluDesktop\instan
ces\0.9.13.1\HuluDesktop.exe0LOCALAPPDATA=C:\Users\JohnDoe\AppData\Local0LOG
ONSERVER=\\COMPUTER0NUMBER_OF_PROCESSORS=20OnlineServices=Online Services0OOBEUI
Lang=en-US0OS=Windows_NT0Path=.;F:\CodeBlocks\MinGW\bin;F:\CodeBlocks\MinGW;C:\M
inGW\bin;C:\MinGW;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Pro
gram Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Com
mon Files\Microsoft Shared\Windows Live;C:\Windows\System32\WindowsPowerShell\v1
.0;c:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;c:\Program Files
(x86)\Common F0Uô1m+k

我的代码并不漂亮,但它证明了我的观点。如您所见,数据主要是垃圾值,但有一些从堆中抛出的有趣字符串。

我的主要问题是为什么此操作不会导致内存访问冲突错误?

最佳答案

当您访问未映射的页面时,虚拟内存硬件会捕获内存访问冲突错误。并非每个超出范围的地址都在未映射的页面中。页面通常大小相等。典型的页面大小为 4096 字节。 (页面大小是特定于硬件的:一些芯片具有允许可编程页面大小的内存管理,甚至可以为不同的内存区域混合使用不同的页面大小。)有时只有页面的一部分包含有效数据。不可能只取消映射页面的一个片段,因此包含垃圾的部分也会被映射。此外,像 malloc 这样的内存管理器并不总是将内存返回给操作系统;他们保留免费区域以供重复使用。这些区域是有效内存(映射页面)。此外,在构造指针值时,您可以侥幸地最终越界,并可以“​​降落”在对应于有效对象的内存中。

这就是它在您的 PC 上的工作方式,具有命中虚拟内存操作系统。虚拟内存并非无处不在。在没有虚拟内存的计算机上(现在,小型嵌入式系统),您可以访问内存中的任何位置。但是,访问某些区域可能会产生改变硬件(即 I/O 寄存器)状态的副作用。某些地址范围可能会触发“总线错误”类型的 CPU 异常,因为该范围不存在硬件,因此访问请求超时。除此之外,就有效程序内存而言,它不受越界访问保护。

在 1960 年代早期的交互式系统中使用了没有内存保护的操作系统。当个人微型计算机出现时,这段历史再次重演:由于内存小和 CPU 简单,它们的操作系统又没有内存保护。在这些操作系统上,应用程序经常互相占用内存空间,导致频繁崩溃。 (想象一下,使用您的 memcpy,您不仅可以复制自己的越界区域,例如之前释放的一些 malloc block ,还可以复制来自完全不同的正在运行的程序的区域。)用户有时会发现模式,例如当某些程序以特定顺序加载到内存中时,问题就会减少,或者应用程序之间出现所谓的“冲突”。

关于c - Memcpy() 适用于越界内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23000839/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com