2010-04-23 31 views
13

Cho phép chúng tôi xem xét các chương trình sau đây:sụp đổ chương trình với args dòng cmd

#include <stdlib.h> 

int main(int argc, char **argv){ 
    int a,b; 

    if (argc != 3) 
     return -1; 

    a = atoi(argv[1]); 
    b = atoi(argv[2]); 

    a = b ? a/b : 0; 

    return a; 
} 

Nhiệm vụ là sụp đổ chương trình bằng cách cung cấp đối số trong dòng lệnh.

+1

@Stacker: Không có ý tưởng, có vẻ giống như một số câu hỏi phỏng vấn đã được đặt trước. – Quixotic

+0

tôi đoán là không thể ... – Kasturi

+2

Tôi có nhận được cookie nếu tôi trả lời đúng không? Nếu họ hỏi bạn điều này trong một cuộc phỏng vấn, hy vọng họ không cung cấp cho bạn công việc. Nếu họ làm, chạy. –

Trả lời

18

Vượt qua a làm nền tảng INT_MINb là -1. Sau đó, bạn nhận được một lỗi tràn trên bất kỳ máy bổ sung của hai, mặc dù đó không nhất thiết phải là một vụ tai nạn.

+0

Tôi ngạc nhiên khi thấy vấn đề này trong một cuộc phỏng vấn không dành cho các chuyên gia bảo mật. Nhưng phải thừa nhận rằng, tôi sử dụng Java và Python, đây không phải là vấn đề lớn. – Uri

5

Câu trả lời cho câu hỏi này là: Tùy thuộc.

Một trong những thông tin quan trọng bạn cần biết là cách atoi được triển khai và nếu tuân thủ các tiêu chuẩn. Tiêu chuẩn nói rất ít về chi tiết triển khai và cụ thể hơn về hành vi đầu vào đầu vào. Giả sử cho một phút nó thực sự là tiêu chuẩn tuân thủ và tập trung vào việc thực hiện.

Có một số phương pháp có thể được sử dụng hợp lệ và một trong số chúng là đệ quy. Giả sử cho một giây rằng nó được thực hiện như là một thuật toán đệ quy đầu mà buộc một xây dựng của ngăn xếp. Sau đó tôi có thể khiến chương trình này gặp sự cố bằng cách cung cấp một đối số đủ dài rằng nó buộc atoi để recurse đủ sâu để ngăn tràn tràn và do đó làm hỏng ứng dụng.

2

Bạn có thể làm việc ngược lại thông qua quy trình xóa:

1) Bạn có thể kết thúc bằng một bộ chia bằng 0 không? Không có khả năng. Nếu b là 0, biểu thức cuối cùng là 0 và nếu nó không bằng 0, bạn sẽ không nhận được số chia cho 0.

2) Bạn có thể cung cấp số lượng đối số không chính xác và sự cố khi truy cập mảng không? Không thực sự vì kiểm tra trước đó của argc

3) Nếu đối số của bạn không chuyển thành một số, thì hãy gọi trả về giá trị số. Tôi nghĩ rằng đây là một phần của đặc tả thư viện và do đó không mở để thay đổi thực hiện nhưng tôi có thể sai.

Vì vậy, tôi không thấy cách bạn gặp sự cố tại đây.

Điều duy nhất tôi thích về câu hỏi này là chia cho phần không - nó kiểm tra rằng bạn hiểu toán tử ?: và 0 là sai. Tôi không thích phần atoi mà không cho bạn truy cập vào một tài liệu tham khảo hướng dẫn sử dụng. Tôi phải kiểm tra tài liệu để chắc chắn.

Tiềm năng cho tràn/tràn quá IMHO quá phức tạp. Thật tuyệt vời nếu bạn đang phỏng vấn một kỹ sư bảo mật phần mềm, nhưng tôi sẽ không hỏi một ứng cử viên cấp nhập cảnh hoặc thậm chí chỉ cho một công việc lập trình chuẩn. Nếu bạn đến từ các ngôn ngữ khác (ví dụ: Python), điều này đặc biệt khó khăn.

Cập nhật: Tôi đã thực hiện tìm kiếm trực tuyến về một số tham chiếu và có vẻ như atoi sẽ trả về 0 trên đầu vào kém. Ví dụ, từ MSDN:

Mỗi chức năng trả về giá trị int sản xuất bằng cách giải thích đầu vào nhân vật như một số. Giá trị trả về là 0 cho atoi và _wtoi, nếu không thể chuyển đổi đầu vào thành giá trị của loại đó.

+1

lại: 3) không. Chuyển một cái gì đó đến atoi mà không thể được chuyển đổi thành một int là không cần thiết để trả về một giá trị số. Nó gọi hành vi không xác định. Việc triển khai hoàn toàn miễn phí để làm hỏng chương trình của bạn, ghi đĩa cứng của bạn nếu bạn làm như vậy. – nos

+0

@nos: Đó có phải là trường hợp không? Tôi đã kiểm tra Wikipedia và MSDN và dường như chỉ ra cách khác: "Mỗi hàm trả về giá trị int được tạo ra bằng cách diễn giải các ký tự đầu vào như một số. Giá trị trả về là 0 cho atoi và _wtoi, nếu đầu vào không thể được chuyển đổi thành giá trị kiểu." – Uri

+1

Đó là trường hợp theo tiêu chuẩn C, có. "[1] Các chức năng atof, atoi, atol, và đảo san hô không cần ảnh hưởng đến giá trị của biểu thức số nguyên errno trên một lỗi . Nếu giá trị của kết quả không thể đại diện, hành vi là không xác định." – nos

0

Điểm yếu duy nhất tôi thấy là atoi(). Có lẽ nếu nó được thông qua một chuỗi đủ lớn, nó sẽ có hành vi sai trái theo cách nào đó bên trong nó. Ngoài ra, chia cho 0 được bao phủ như đếm đối số. Điều duy nhất tôi có thể nghĩ là bằng cách nào đó làm tràn bộ đệm hệ điều hành bằng cách gửi spam rác vào các đối số. Không quá khả năng.

0

Tôi không biết hầu hết hệ điều hành truyền dữ liệu argv như thế nào. Nó được phân bổ trên ngăn xếp? Nó vốn có giới hạn về chiều dài?

Bạn có thể chuyển một tham số dòng lệnh thực sự dài và tạo ngăn xếp ngăn xếp không?

Các vấn đề liên quan