1. Trang chủ
  2. » Giáo Dục - Đào Tạo

KỸ THUẬT LẬP TRÌNH AN TOÀN LỖI ĐỊNH DẠNG CHUỖI

13 6 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

HỌC VIỆN KỸ THUẬT MẬT MÃ Khoa An tồn thơng tin KỸ THUẬT LẬP TRÌNH AN TỒN LỖI ĐỊNH DẠNG CHUỖI Giảng viên hướng dẫn: Bùi Việt Thắng Sinh viên thực hiện: Vũ Viết Tùng Vũ Trần Hoàng Anh Kim Việt Anh Nguyễn Quang Huy CÁC HÀM NHẬP - XUẤT Scanf() hàm liên quan Cú pháp Tính khơng an tồn Tràn đệm Đối số %c %s dùng cho liệu kiểu char Giải pháp đề xuất Xử lý tràn đệm Xử lý ghi xâu Gets() hàm liên quan Cú pháp Tính khơng an tồn Giải pháp đề xuất Printf() hàm liên quan Cú pháp Tính khơng an tồn Giải pháp đề xuất CÁC THAO TÁC TRÊN XÂU Hàm chép xâu Cú pháp Tính khơng an tồn Giải pháp đề xuất Hàm nối xâu Cú pháp Tính khơng an tồn Giải pháp đề xuất 3 3 5 5 6 7 9 9 10 11 11 12 12 CÁC HÀM NHẬP - XUẤT Scanf() hàm liên quan 1.1 Cú pháp Trong C, hàm scanf(); dùng để lấy liệu vào từ bàn phím quy định thư viện stdio.h C scanf() quy định cú pháp sau: scanf("format string", argument_list); Trong đó: - scanf() lời gọi hàm - format string đối số hàm định dạng xâu chứa tham số định dạng (Các đối số thông dụng đề cập phụ lục) - argument_list biến ghi liệu vào Ví dụ sau cho thấy cách sử dụng scanf chương trình C: #include #include void main(){ char *ten[15]; printf("Nhap vao ten cua ban: "); scanf("%s",ten); printf("ban vua nhap vao | %s | bang scanf(); ",ten); } 1.2 Tính khơng an tồn 1.2.1 Tràn đệm scanf(); gây lỗi tràn đệm sử dụng khơng cách, ví dụ sau cho thấy lỗi xảy nào: #include #include void main() { char ho[2], ten[2], dem[2]; printf("Nhap vao ho cua ban: "); scanf("%s",&ho); printf("Nhap vao ten dem cua ban: "); scanf("%s",&dem); printf("Nhap vao ten cua ban: "); scanf("%s",&ten); } printf("Ho: %s\nDem: %s\nTen: %s.",ho,dem,ten); Khi chạy chương trình, ta gặp lỗi sau: Lỗi ví dụ xảy đầu vào người dùng nhập vào dài mức quy định chương trình Để khắc phục lỗi này, cần kiểm sốt đầu vào từ phía người dùng 1.2.2 Đối số %c %s dùng cho liệu kiểu char Khi sử dụng scanf để nhập liệu dạng xâu, sử dụng hai đối số %s %c cụ thể sau: - %c nhận vào ký tự đơn - %s nhận vào xâu trước dấu cách Việc sử dụng hai đối số gây lỗi, ví dụ thể rõ lỗi sau: #include #include void main() { char ho[2], ten[15], dem[2]; printf("Nhap vao ho cua ban: "); scanf("%c",&ho); printf("Nhap vao ten dem cua ban: "); scanf("%s",&dem); printf("Nhap vao ten cua ban: "); scanf("%s",&ten); } printf("Ho: %s\nDem: %s\nTen: %s.",ho,dem,ten); Khi tiến hành nhập đầu vào, ta có kết sau: Lỗi ví dụ xảy hàm nhập họ, đối số %c scanf nhận vào ký tự đơn nhất, ký tự u bị thừa bị tràn sang lưu vào biến đệm Ở biến tên, đối số %s lưu xâu đơn kết thúc dấu cách nên lưu xâu “anh” sau dấu cách 1.3 Giải pháp đề xuất 1.3.1 Xử lý tràn đệm Lỗi ví dụ xảy đầu vào người dùng nhập vào dài mức quy định chương trình Để khắc phục lỗi này, cần kiểm sốt đầu vào từ phía người dùng hàm fgets() nhắc đến mục “2 Gets() hàm liên quan.” giải vấn đề 1.3.2 Xử lý ghi xâu Ở ví dụ 3, để ghi xâu có nhiều ký tự dấu cách, sử dụng lệnh scanf phải thay đổi đối số %s thành %[^\n] để ghi liệu gặp dấu enter Ví dụ làm sáng tỏ phương pháp này: #include #include void main() { char ho[5], ten[15], dem[7]; printf("Nhap vao ho cua ban: "); scanf("%s",&ho); printf("Nhap vao ten dem cua ban: "); scanf("%s",&dem); fflush(stdin); printf("Nhap vao ten cua ban: "); scanf("%[^\n]",ten); } printf("Ho: %s\nDem: %s\nTen: %s.",ho,dem,ten); Khởi chạy chương trình nhập đầu vào ta kết sau: Ngồi cịn sử dụng lệnh gets() nhắc tới mục để sửa lỗi Gets() hàm liên quan 2.1 Cú pháp Trong C, hàm gets() sử dụng để nhập vào ký tự biến dạng char Cú pháp gets() có cấu trúc sau: gets(char *str) Trong đó: - gets lời gọi lệnh - str biên cần nhập liệu vào Ví dụ cho thấy cách sử dụng gets() C: #include #include void main() { char ho[5], ten[15], dem[7] printf("Nhap vao ho cua ban: "); gets(&ho); printf("Nhap vao ten dem cua ban: "); gets(&dem); printf("Nhap vao ten cua ban: "); gets(&ten); } printf("Ho: %s\nDem: %s\nTen: %s.",ho,dem,ten); Chạy chương trình ta có kết sau: 2.2 Tính khơng an tồn gets() khắc phục số vấn đề scanf(), nhiên việc thiếu kiểm soát đầu vào gây tràn đệm Nhập đầu vào khơng hợp lệ ví dụ gây lỗi này: Tràn đệm khiến giá trị lưu vào biến bị ảnh hưởng 2.3 Giải pháp đề xuất Sử dụng fgets(); để kiểm soát đầu vào Trong C, fgets() quy định cú pháp sau: char *fgets(char *str, int n, FILE *stream) Trong đó: - fgets lời gọi lệnh - str biến lưu liệu - n số nguyên dương quy định độ dài xâu nhập vào - stream luồng nhận liệu (file bàn phím) Ví dụ thể cách fgets() ngăn đầu vào có độ dài không hợp lệ: #include #include void main() { char *ho[5], *ten[5], *dem[5]; printf("Nhap vao ho cua ban: "); fgets(ho,5,stdin); fflush(stdin); printf("Nhap vao ten dem cua ban: "); fgets(dem,5,stdin); fflush(stdin); printf("Nhap vao ten cua ban: "); fgets(ten,5,stdin); fflush(stdin); } printf("Ho: %s\nDem: %s\nTen: %s.",ho,dem,ten); Các đầu vào dài bị cắt bớt Printf() hàm liên quan 3.1 Cú pháp Trong C, lệnh printf() dùng để in liệu Cú pháp printf() quy định thư viện stdio.h sau: int printf(const char *format, ) Trong đó: - printf lời gọi hàm - char *format biến lưu liệu cần in - Ngồi lệnh printf sử dụng để in xâu dấu nháy kép “” 3.2 Tính khơng an tồn printf() sử dụng khơng cách gây lỗi nguy hiểm việc in địa trỏ, tạo điều kiện cho việc thực cơng tràn đệm Ví dụ làm rõ lỗi này: #include #include void main() { char a[10]; gets(&a); printf(a); } Nhập đầu vào %p cho kết địa ô nhớ: 3.3 Giải pháp đề xuất Để tránh lỗi ví dụ 7, nên sử dụng print() với cú pháp đầy đủ bao gồm đối số biến, cụ thể VD sau: #include #include void main() { char a[10]; gets(&a); printf("%s",a); } Khi nhập %p vào chương trình trả kết sau: Lý đối số %s a nằm dấu nháy kép nhập %p printf() in xâu %p thay địa nhớ CÁC THAO TÁC TRÊN XÂU Hàm chép xâu 1.1 Cú pháp Trong C, hàm dùng để chép xâu có cú pháp sau: char *strcpy(char *dest, const char *src) Trong đó: - -+strcpy lời gọi hàm - src biến lưu xâu cần chép - dest biến chép xâu từ src vào Ví dụ sau cho thấy cách strcpy() hoạt động: #include #include #include void main() { char src[15]="abcde"; char dest[15]="a"; printf("\nTruoc cop: \nsrc: %s\ndest: %s",src,dest); strcpy(dest,src); printf("\nSau cop\nsrc: %s\ndest: %s",src,dest); } Khi chương trình chạy xong, giá trị dest gán giống src: 1.2 Tính khơng an tồn Vì strcpy() khơng có kiểm sốt đầu vào nên gây tràn đệm tiến hành xâu hai biến cấp phát nhớ khác Ví dụ 10 sau cho thấy rõ cách lỗi xảy ra: #include #include #include void main() { char src[11]={'v', 'n','h'}; char dest[2]={'a'}; 'u', 'h', 'o', 'a', 'n', 'g', 'a', printf("\nTruoc cop: \nsrc: %s\ndest: %s",src,dest); } strcpy(dest,src); printf("\nSau cop\nsrc: %s\ndest: %s",src,dest); Trước chạy strcpy() giá trị lưu src vuhoanganh Nếu chương trình chạy sau kết thúc giá trị src không đổi, nhiên, tràn đệm nên dest ghi đè lên phần liệu src: 1.3 Giải pháp đề xuất Để khắc phục lỗi dest bị tràn nhớ chép xâu dài từ src, ta sử dụng lệnh strncpy() có cấu trúc sau: char *strncpy(char *dest, const char *src, size_t n) Trong đó: - strncpy lời gọi lệnh dest biến chép xâu src biến chứa xâu cần chép n số nguyên quy định số xâu phép chép tính từ phần tử mảng ký tự src (Cop n-1 ký tự, để dành ô nhớ cho ký hiệu kết thúc) Ví dụ số 11 thể cách hoạt động strncpy(): #include #include #include void main() { char src[11]={'v', 'n','h'}; char dest[5]={'a'}; 'u', 'h', 'o', 'a', 'n', 'g', 'a', 10 printf("\nTruoc cop: \nsrc: %s\ndest: %s",src,dest); strncpy(dest,src,4); printf("\nSau cop\nsrc: %s\ndest: %s",src,dest); } Sau chạy chương trình ta thấy tràn đệm khắc phục: Hàm nối xâu 2.1 Cú pháp Trong C, hàm dùng để nối xâu có cú pháp sau: char *strcat(char *dest, const char *src) Trong đó: - strcat lời gọi hàm - dest biến chứa xâu nối thêm từ src - src biến chứa xâu nối vào dest Ví dụ: #include #include #include void main() { char src[11]={'v', 'n','h'}; 'u', 'h', 'o', 'a', 'n', 'g', 'a', char dest[15]={'a'}; printf("\nTruoc cat: \nsrc: %s\ndest: %s",src,dest); } strcat(dest,src); printf("\nSau cat\nsrc: %s\ndest: %s",src,dest); Khi chạy chương trình, mảng ký tự src nối vào sau dest sau: 11 2.2 Tính khơng an tồn Cũng giống strcpy(), hàm strcat() khơng kiểm sốt số lượng ký hiệu nối vào sau dest, điều dễ dẫn tới lỗi tràn đệm, ví dụ 13 sau thể rõ lỗi ảnh hưởng tới chương trình Ví dụ: #include #include #include void main() { char src[11]={'v', 'n','h'}; char dest[2]={'a'}; 'u', 'h', 'o', 'a', 'n', 'g', 'a', printf("\nTruoc cat: \nsrc: %s\ndest: %s",src,dest); } strcat(dest,src); printf("\nSau cat\nsrc: %s\ndest: %s",src,dest); Khởi chạy chương trình cho thấy việc nối thêm xâu dài khiến tràn đệm làm hỏng liệu lưu src 2.3 Giải pháp đề xuất Để khắc phục lỗi dest bị tràn nhớ nối xâu dài từ src, ta sử dụng lệnh strncat() có cấu trúc sau: char *strncat(char *dest, const char *src, size_t n) Trong đó: - strncat lời gọi lệnh - dest biến nối thêm xâu - src biến chứa xâu mang nối 12 - n số nguyên quy định số xâu phép nối tính từ phần tử mảng ký tự src Ví dụ số 14 thể cách hoạt động strncat(): #include #include #include void main() { char src[11]={'v', 'n','h'}; char dest[6]={'a'}; 'u', 'h', 'o', 'a', 'n', 'g', 'a', printf("\nTruoc cop: \nsrc: %s\ndest: %s",src,dest); } strncat(dest,src,4); printf("\nSau cop\nsrc: %s\ndest: %s",src,dest); Sau chạy chương trình ta thấy tràn đệm khắc phục: 13 ... CÁC HÀM NHẬP - XUẤT Scanf() hàm liên quan 1.1 Cú pháp Trong C, hàm scanf(); dùng để lấy liệu vào từ bàn phím quy định thư viện stdio.h C scanf() quy định cú pháp sau: scanf("format string", argument_list);... scanf() lời gọi hàm - format string đối số hàm định dạng xâu chứa tham số định dạng (Các đối số thông dụng đề cập phụ lục) - argument_list biến ghi liệu vào Ví dụ sau cho thấy cách sử dụng scanf... scanf chương trình C: #include #include void main(){ char *ten[15]; printf("Nhap vao ten cua ban: "); scanf("%s",ten); printf("ban vua nhap vao | %s | bang scanf(); ",ten);

Ngày đăng: 15/11/2022, 21:37

Xem thêm:

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w