C - Định dạng% x


78

Tôi có một câu hỏi nhỏ. Tôi biết rằng mã định dạng% x có thể được sử dụng để đọc các giá trị từ ngăn xếp trong một cuộc tấn công chuỗi định dạng.

Tôi tìm thấy mã sau:

08 có nghĩa là gì? Chính xác thì nó đang làm gì? Cảm ơn :)


1
Chiều rộng trường gồm 8 ký tự, các số ngắn hơn được bắt đầu bằng các số 0 ở đầu để khớp với chiều rộng trường, ví dụ: 000007achoặc 0005ceef.
Hristo Iliev

2
Chức năng này đang nói về? Bạn nói "đọc các giá trị", nhưng tất cả các câu trả lời dường như giả định printf()đang được sử dụng.
thư giãn

1
@unwind điểm tốt. tất cả chúng ta đều viết cho printf.
Grijesh Chauhan

1
Tôi thật ngốc. Có, tôi đã đề cập đến việc sử dụng mã này trong hàm printf.
Matthew

Câu trả lời:


138

Phá vỡ:

  • 8 nói rằng bạn muốn hiển thị 8 chữ số
  • 0mà bạn muốn đặt tiền tố bằng 0's thay vì chỉ có khoảng trắng
  • x mà bạn muốn in trong hệ thập lục phân viết thường.

Ví dụ nhanh (cảm ơn Grijesh Chauhan):

Đầu ra:

Cũng có thể xem http://www.cplusplus.com/reference/cstdio/printf/ để tham khảo.


9
Thêm một ví dụ hy vọng bạn thích. NẾU không, bạn có thể hoàn nguyên về phiên bản của mình
Grijesh Chauhan 27/02

1
@Matthew bạn cũng nên thử với %-8xvà vốn X. và quan sát hiệu ứng
Grijesh Chauhan

1
Mặc dù 80cả hai đều là số (và do đó các phần giống hệt nhau của ngữ pháp bằng tiếng Anh) nhưng chúng là các phần khác nhau của ngữ pháp định dạng printf. 0là một "lá cờ" và 8là một tham số để "width" (có thể <ε (no input)>, <d (any number greater than 0)>hoặc * (a literal asterisk)). Chắc chắn đây là một API không trực quan! Nhưng bạn có thể nói gì ... đó là tất cả những thứ C kiểu cũ, nơi bộ nhớ là thứ cao cấp đến mức bạn muốn lưu càng nhiều ký tự trong một chương trình càng tốt - Tôi đồng ý với quyết định của họ vì những hạn chế mà họ phải đối mặt!
Ari Sweedler

1
Tôi nghĩ đó là một câu hỏi thú vị để suy ngẫm. Bạn sẽ thiết kế lại printfcú pháp như thế nào? Tôi thích sử dụng %làm ký tự thoát, nó rất độc đáo và thích hợp để định dạng chuỗi. Tôi nghĩ rằng các bổ ngữ nên được thêm vào thay vì thêm vào trước - theo cách đó bạn có thể đọc nó từ trái sang phải. Một cái gì đó như %<specifier>[%f<flags>][%-w<width>.<precision>]%, thay vì %[flags][width][.precision][length]specifier. Tôi chọn một %giữa từng lĩnh vực, cũng như một đến gần (vì vậy bạn vẫn có thể làm %x%x- `% x %% x%) và cho phép một specifier đa char
Ari Sweedler

5

%08x có nghĩa là mỗi số phải được in rộng ít nhất 8 ký tự với việc điền vào tất cả các chữ số còn thiếu bằng các số không, ví dụ: đối với đầu ra '1' sẽ là 00000001


2

Điều đó chỉ định số lượng chữ số bạn muốn nó hiển thị.

giá trị số nguyên hoặc * chỉ định độ rộng trường tối thiểu. Kết quả được đệm bằng các ký tự khoảng trắng (theo mặc định), nếu được yêu cầu, ở bên trái khi căn phải hoặc ở bên phải nếu căn trái. Trong trường hợp khi * được sử dụng, chiều rộng được chỉ định bởi một đối số bổ sung kiểu int. Nếu giá trị của đối số là âm, nó dẫn đến - cờ được chỉ định và độ rộng trường dương.



2

Cuộc tấn công chuỗi định dạng trên printf mà bạn đã đề cập không dành riêng cho định dạng "% x" - trong bất kỳ trường hợp nào printf có nhiều tham số định dạng hơn các biến đã truyền, nó sẽ đọc các giá trị từ ngăn xếp không thuộc về nó. Bạn sẽ gặp vấn đề tương tự với% d chẳng hạn. % x hữu ích khi bạn muốn xem các giá trị đó dưới dạng hex.

Như đã giải thích trong các câu trả lời trước,% 08x sẽ tạo ra một số hex gồm 8 chữ số, được đệm bởi các số không đứng trước.

Sử dụng định dạng trong ví dụ mã của bạn trong printf, không có tham số bổ sung:

Sẽ tìm nạp 4 tham số từ ngăn xếp và hiển thị chúng dưới dạng số hex có đệm 8 chữ số.

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.