本文共 2980 字,大约阅读时间需要 9 分钟。
#include#include int main(void){ char buff[8] = {0}; char *p = "012345678912345"; strcpy(buff,p); printf("%s\n",buff); return 0;}
这是缓冲区溢出原理演示的基本C程序;
p所指向的字符串长度大于buff的长度,拷贝时发生缓冲区溢出;程序崩溃;
如果p指向字符串的长度不超过,就不会溢出;
对于Win32来说,使用Windows提供的Win32字符串函数,字符串拷贝使用lstrcpy;
#include#include int main(void){ char buff[8] = {0}; char *p = "0123456789"; lstrcpy(buff,p); printf("%s\n",buff); return 0;}
一样的,长度超过,运行程序,崩溃;
如果使用安全版的字符串拷贝函数,strncpy(buff,p,sizeof(buff));
就不会溢出;
下面来作一个Win32窗口版本溢出程序;单击鼠标左键执行拷贝并输出;
/* buffer over demo,by bobo,2020-01-19 */#includeLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("buffer over demo") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName,TEXT ("buffer over demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc ; PAINTSTRUCT ps ; char buff[8] = {0}; char *p = "012345678912345"; switch (message) { case WM_CREATE: return 0 ; case WM_LBUTTONDOWN : hdc = GetDC(hwnd); lstrcpy(buff,p); TextOut(hdc, 100, 100, buff, 15); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
buff长度8,p指向内容长度15;
按理程序应该崩溃;但是Win32窗口程序真的没崩溃;还输出了15个长度的字符串;
啥情况?
以上是Win10,VC++6;
此程序仅演示缓冲区溢出最基本原理;
如果真能干这事的人,其目的并不是引起程序崩溃,而是通过覆盖程序返回地址等手段,改变程序的执行流程;
转载地址:http://jouy.baihongyu.com/