Làm thế nào để một quả bom ngã ba hoạt động?


22
  • CẢNH BÁO KHÔNG ATTEMPT ĐỂ CHẠY NÀY TRÊN MÁY SẢN XUẤT

Khi đọc trang Wikipedia về chủ đề này, tôi thường theo dõi những gì đang diễn ra với đoạn mã sau:

:(){ :|:& };:

trích đoạn mô tả

Bom ngã ba sau đây đã được trình bày như một nghệ thuật vào năm 2002;56 nguồn gốc chính xác của nó là không rõ, nhưng nó tồn tại trên Usenet trước năm 2002. Quả bom được thực hiện bằng cách dán 13 ký tự sau vào một UNIX shell như bash hoặc zsh . Nó hoạt động bằng cách định nghĩa một hàm gọi là ':', nó tự gọi hai lần, một lần ở nền trước và một lần trong nền.

Tuy nhiên, bit cuối cùng không hoàn toàn rõ ràng với tôi. Tôi thấy định nghĩa hàm:

:(){ ... }

Nhưng những gì khác đang xảy ra? Ngoài ra các vỏ khác như ksh, cshtcshcũng chịu chung số phận là có thể xây dựng một cái gì đó tương tự?


2
Điều này xuất hiện khá thường xuyên trên trao đổi ngăn xếp, một câu trả lời hay có ở đây: stackoverflow.com/questions/991142/
Kẻ

@DravSloan - Tôi đã cố gắng tạo một số nội dung đó ở đây, câu hỏi của tôi là một chút được tải theo cách đó 8-).
slm

Bạn có thể muốn thêm nghĩa vụ "Vì tình yêu của Thiên Chúa không chạy cái này trên máy sản xuất, hoặc nếu bạn muốn tiếp tục sử dụng máy bạn chạy nó !!" tin nhắn :)
Drav Sloan

1
@ MartinSchröder - bạn hiểu rằng câu hỏi này là nguyên nhân dẫn đến câu hỏi đó? số 8-). Tôi đã hỏi điều này vào một tối thứ sáu để có một cái gì đó đi và sau đó câu hỏi khác đến trong một hoặc 2 giờ sau đó.
slm

1
@ MartinSchröder - tốt nhất nên để chúng là riêng biệt, chúng hơi khác nhau. Đây là yêu cầu cho một cái nhìn toàn cảnh chi tiết về cách thức hoạt động của bom ngã ba, rằng một người khác đang hỏi chi tiết cụ thể về cơ chế đằng sau cách hệ thống này hoạt động trong một quả bom ngã ba. Tôi biết có vẻ khó hiểu vì chúng có liên quan nhưng chúng khác nhau (IMO - rõ ràng). Tôi thậm chí đã trả lời Q khác và cố gắng thể hiện cơ chế dưới mui xe đang lái xe, và tôi đã không gắn cờ nó là bản sao.
slm

Câu trả lời:


23

Quả bom ngã ba này luôn nhắc nhở tôi về điều mà một giáo viên lập trình AI đã nói trong một trong những bài học đầu tiên tôi tham dự "Để hiểu đệ quy, trước tiên bạn phải hiểu đệ quy".

Tại cốt lõi của nó, quả bom này là một chức năng đệ quy . Về bản chất, bạn tạo một hàm, nó tự gọi nó, nó tự gọi nó, nó tự gọi nó .... cho đến khi tài nguyên hệ thống được tiêu thụ. Trong trường hợp cụ thể này, đệ quy được khuếch đại bằng cách sử dụng đường ống hàm cho chính nó và làm nền cho nó.

Tôi đã thấy điều này được trả lời trên StackOverflow và tôi nghĩ ví dụ đưa ra ở đó minh họa rõ nhất, chỉ vì dễ dàng nhìn thấy những gì nó làm trong nháy mắt (bị đánh cắp từ liên kết ở trên ...)

☃(){ ☃|☃& };☃

Xác định hàm lỗi ☃() { ... }, phần thân gọi chính nó (hàm lỗi), dẫn đầu ra đến chính nó (hàm lỗi) ☃|☃và làm nền cho kết quả &. Sau đó, sau khi hàm được định nghĩa, thực sự gọi hàm bug , ; ☃.

Tôi lưu ý rằng ít nhất trên Arch VM của tôi, nhu cầu làm nền cho quá trình không phải là một yêu cầu để có cùng kết quả cuối cùng, để tiêu thụ tất cả không gian quy trình có sẵn và khiến cho máy chủ lưu trữ b0rked. Trên thực tế bây giờ tôi đã nói rằng dường như đôi khi chấm dứt quá trình chạy trốn và sau khi sàng lọc -bash: fork: Resource temporarily unavailablenó sẽ dừng lại với một Terminated(và journalctlhiển thị việc bán phá giá lõi bash).

Để trả lời câu hỏi của bạn về csh / tcsh, cả hai hàm này đều không hỗ trợ các hàm, bạn chỉ có thể đặt bí danh. Vì vậy, đối với các shell đó, bạn phải viết một kịch bản shell mà gọi chính nó theo cách đệ quy.

zsh dường như chịu chung số phận (với cùng một mã), không đổ lõi và khiến Arch đưa ra Out of memory: Kill process 216 (zsh) score 0 or sacrifice child., nhưng nó vẫn tiếp tục rẽ nhánh. Sau một thời gian, nó sẽ phát biểu Killed process 162 (systemd-logind) ...(và vẫn tiếp tục có một zsh forking).

Arch dường như không có pacmanphiên bản của ksh, vì vậy tôi đã phải thử nó trên debian. ksh đối tượng :như là một tên hàm, nhưng sử dụng một cái gì đó - nói b()thay vào đó dường như có kết quả mong muốn.


Những nhân vật đó là gì? Tôi biết chúng là lỗi nhưng làm thế nào bạn tạo ra chúng?
slm

10
Mặc dù ở kích thước phông chữ nhỏ, nó trông giống như một con bọ bạn sẽ thấy rằng thực tế nó là một người tuyết. Đó sẽ là ký tự unicode U + 2603 có thể được hiển thị trong html bằng cách nhập & # x 2603 mà không có khoảng trắng.
lấy mẫu

2
Rõ ràng trong Linux, một số lượng lớn các ứng dụng liên quan đến Gnome và Firefox hỗ trợ trong Ctrl+Shift+u+<hex>đó hex là mã hex của ký tự unicode mà bạn muốn hiển thị. Có thể tìm thấy danh sách unicode có thể xem tại: fileformat.info/info/unicode/utf8test.htmlm (hầu hết các số lẻ đều nằm trong phần "linh tinh"). Windows nên kiểm tra superuser.com/questions/47420/ , và cá nhân tôi sử dụng công cụ được đề cập trong liên kết unicodeinput.exehoặc cắt và dán qua trình duyệt của tôi. Bạn luôn có thể sử dụng các chuỗi html theo đề xuất của sambler.
Drav Sloan

1
Wiki cũng có một danh sách các ký tự unicode: en.wikipedia.org/wiki/List_of_Unicode_char
character

Tôi thích lỗi người tuyết, cái bạn đang sử dụng ở đây không được hiển thị trên hệ thống của tôi, 🐛 xuất hiện như một hộp có số hex trong đó.
terdon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.