書名: C和C++安全編碼(原書第2版)作者名: (美)Robert C.Seacord本章字數: 542字更新時間: 2020-10-30 17:56:50
3.9 longjmp()函數
C標準定義了setjmp()宏、longjmp()函數,以及jmp_buf類型,它們可以用來繞過正常的函數調用和返回規則。
setjmp()宏為稍后將會調用的longjmp()函數保存其調用環境。longjmp()則恢復最后一次由setjmp()宏保存的調用環境。例3.13展示了longjmp()是如何將程序控制權返回到setjmp()調用點的。
例3.13 longjmp()函數使用示例
01 #include <setjmp.h> 02 jmp_buf buf; 03 void g(int n); 04 void h(int n); 05 int n = 6; 06 07 void f(void) { 08 setjmp(buf); 09 g(n); 10 } 11 12 void g(int n) { 13 h(n); 14 } 15 16 void h(int n){ 17 longjmp(buf, 2); 18 }
例3.14展示了Linux中jmp_buf數據結構的實現及其相關定義。jmp_buf結構(第11~15行)包含3個域。調用環境存儲于__jmp_buf(于第1行聲明)中。__jmp_buf類型是一個包含了6個元素的整數數組。#define語句指明每個數組元素中保存的值。例如,基址指針(Base Pointer,BP)存儲于__jmp_buf[3]中,而程序計數器(Program Counter,PC)則存儲于__jmp_buf[5]中。
例3.14 jmp_buf結構的Linux實現
01 typedef int __jmp_buf[6]; 02 03 #define JB_BX 0 04 #define JB_SI 1 05 #define JB_DI 2 06 #define JB_BP 3 07 #define JB_SP 4 08 #define JB_PC 5 09 define JB_SIZE 24 10 11 typedef struct __jmp_buf_tag { 12 __jmp_buf __jmpbuf; 13 int __mask_was_saved; 14 __sigset_t __saved_mask; 15 } jmp_buf[1];
例3.15展示了Linux上為longjmp()產生的匯編指令。第2行的movl指令恢復BP,第3行的movl指令恢復棧指針(SP),第4行則將程序控制權轉移到保存的PC。
例3.15 在Linux上為longjmp()生成的匯編指令
1 movl i, %eax /* 返回 i */ 2 movl env.__jmpbuf[JB_BP], %ebp 3 movl env.__jmpbuf[JB_SP], %esp 4 jmp (env.__jmpbuf[JB_PC])
可以通過將jmp_buf緩沖區中PC的值覆寫為外殼代碼的起始地址的方法來利用longjmp()函數。任意內存寫或者直接針對jmp_buf結構的緩沖區溢出都能達到這個目的。
推薦閱讀
- Data Visualization with D3 4.x Cookbook(Second Edition)
- Boost C++ Application Development Cookbook(Second Edition)
- Docker進階與實戰
- Python自動化運維快速入門(第2版)
- 數據結構簡明教程(第2版)微課版
- 信息安全技術
- Julia Cookbook
- Mastering KnockoutJS
- AutoCAD VBA參數化繪圖程序開發與實戰編碼
- The HTML and CSS Workshop
- Spring Boot Cookbook
- Spring核心技術和案例實戰
- 大數據分析與應用實戰:統計機器學習之數據導向編程
- Visual C#.NET Web應用程序設計
- Learning Python Data Visualization