Làm cách nào để tìm kiếm một chuỗi byte ở chế độ hexl?


7

Có thể tìm kiếm một chuỗi byte trong hexl-modevà có thể làm nổi bật nó?

Ví dụ, trong tệp dưới đây tôi muốn tìm kiếm chuỗi byte f9beb4d9. isearchkhông hoạt động vì nó tìm kiếm bản trình bày trong bộ đệm và không phải tệp gốc.

00000000: f9be b4d9 1d01 0000 0100 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 3ba3 edfd  ............;...
00000030: 7a7b 12b2 7ac7 2c3e 6776 8f61 7fc8 1bc3  z{..z.,>gv.a....
00000040: 888a 5132 3a9f b8aa 4b1e 5e4a 29ab 5f49  ..Q2:...K.^J)._I
00000050: ffff 001d 1dac 2b7c 0101 0000 0001 0000  ......+|........
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Vui lòng làm rõ ý của bạn bằng cách "tìm kiếm một chuỗi byte" bằng một ví dụ.
Stefan

@Stefan Tôi nghĩ "tìm kiếm một chuỗi byte" phải được thay thế bằng "tìm kiếm cho một chuỗi byte". OP nên sửa điều đó. Nếu phiên bản được sửa là đúng, thì "tìm kiếm chuỗi byte" trong bộ đệm hexl có nghĩa là gì. Người ta phải tính đến việc bộ đệm hexl thực sự đại diện cho chuỗi byte của bộ đệm ban đầu. Người dùng không cần biết hexl hoạt động như thế nào và có sự khác biệt nhỏ giữa chuỗi byte trong bộ đệm hexl và chuỗi byte trong chuỗi gốc.
Tobias

1
Câu hỏi chính là làm thế nào anh ta có ý định xác định trình tự anh ta đang tìm kiếm.
Stefan

Tôi hy vọng câu hỏi là rõ ràng bây giờ.
gdkrmr

@Stefan, điểm thưởng nếu bạn có thể tìm kiếm cả biểu diễn chuỗi và hex :-) Tôi chỉ quan tâm đến biểu diễn hex của byte.
gdkrmr

Câu trả lời:


2

Nếu bạn sử dụng nhexl-mode(có sẵn từ kho lưu trữ GNU ELPA lân cận của bạn), thì bạn có thể làm C-s f9beb4d9và nó sẽ tìm kiếm chuỗi 4 byte có mã f9 be b4 d9(tất nhiên cũng như văn bản 8 byte f9beb4d9và cả byte tại địa chỉ có f9beb4d9trong đại diện hex của họ).


cảm ơn vì điều này, nó hoạt động, nhưng hiệu suất trong các tệp lớn là khủng khiếp.
gdkrmr

1
@gdkrmr: Một phần động lực của tôi để phát triển chế độ nhexl là tránh các vấn đề về hiệu suất ở chế độ hexl trong các tệp lớn. Nhưng tôi không hoàn toàn ngạc nhiên khi bạn gặp vấn đề về hiệu suất, thành thật mà nói. Vui lòng báo cáo cho họ bằng cách M-x report-emacs-bugcung cấp càng nhiều chi tiết càng tốt (một URL cho một tệp lớn mẫu cũng có thể hữu ích, vì hiệu suất có thể bị ảnh hưởng đáng kể bởi nội dung của tệp).
Stefan

1
Xin chào Stefan, tôi chỉ tìm kiếm nhị phân và dịch địa chỉ vào các vị trí của bộ đệm hexl. Có vẻ như điều đó không có vấn đề về hiệu suất. Có lẽ đó là một thay thế cho hexl hoặc nhexl? Tôi đã sửa một vấn đề trong kho git: github.com/TobiasZawada/hexl-isearch .
Tobias

2

Mã lisp sau đây đặt một mục "Chế độ tìm kiếm Hexl" vào menu "Hexl".

Mục menu đó (de-) kích hoạt chế độ nhỏ hexl-isearch-mode. Nếu bạn kích hoạt chế độ isearchtìm kiếm đó trong dữ liệu nhị phân thay vì bộ đệm hexl.

Chuỗi tìm kiếm được đọc với read. Vì vậy, tất cả các chuỗi thoát cho chuỗi lisp làm việc. Để làm ví dụ, bạn có thể tìm kiếm \x0a\x0dhoặc \^M\ntìm kiếm kết thúc dòng dos.

Mã không hoàn hảo.

  1. Giả sử bạn tìm kiếm một chuỗi ELF\x01chỉ xảy ra ở đầu tệp. Hơn nữa, giả sử có một chuỗi ELf\x00sau này trong nhị phân. Sau đó, khi bạn đến ELF\x0bằng cách gõ Emacs sẽ tìm thấy kết quả khớp sau và nếu bạn tiếp tục gõ ELF\x01Emacs nghĩ rằng không có sự xuất hiện của chuỗi đó vì nó đã đến ELF\x0sau trong tệp hơn ELF\x01. Đó là giá trị để thực hiện một tìm kiếm chồng chéo trong trường hợp như vậy. (Sự cố đó đã được khắc phục trong phiên bản git của gói .)

  2. Chỉ chuỗi byte được chiếu sáng chính xác trong bộ đệm hexl chứ không phải biểu diễn chuỗi ở phía bên tay phải.

  3. Nếu chuỗi tìm kiếm kéo dài hai dòng trong bộ đệm hexl, biểu diễn chuỗi ở cuối dòng và địa chỉ ở đầu dòng cũng được tô sáng. Đó không phải là vì chúng thuộc về trận đấu mà bởi vì chúng nằm trong cách làm nổi bật chuỗi byte.

(require 'hexl)

(defvar-local hexl-isearch-raw-buffer nil
  "Buffer with the dehexlified content of the hexl buffer for hexl-isearch-mode.
This variable is set in the original hexl-mode buffer.")

(defvar-local hexl-isearch-original-buffer nil
  "This variable is set in the buffer with the dehexlified content.
It points to the corresponding hexl buffer.")

(defun hexl-address (position)
  "Return address of hexl buffer POSITION."
  (save-excursion
    (goto-char position)
    (hexl-current-address)))

(defun hexl-isearch-startup ()
  "Prepare hexl buffer for `hexl-isearch'."
  (let ((original-buf (current-buffer)))
    (setq-local hexl-isearch-raw-buffer (generate-new-buffer " hexl"))
    (setq-local isearch-search-fun-function (lambda () #'hexl-isearch-fun))
    (with-current-buffer hexl-isearch-raw-buffer
      (set-buffer-multibyte nil)
      (setq-local hexl-isearch-original-buffer original-buf)
      (insert-buffer-substring original-buf 1 (buffer-size original-buf))
      (dehexlify-buffer))))

(defun hexl-isearch-end ()
  "Cleanup after `hexl-isearch'."
  (let ((isearch-raw-buffer hexl-isearch-raw-buffer))
    (setq-local hexl-isearch-raw-buffer nil)
    (when (buffer-live-p isearch-raw-buffer)
      (kill-buffer isearch-raw-buffer))))

(defun hexl-isearch-fun (string &optional bound noerror count)
  "Search for byte sequence of STRING in hexl buffer.
The arguments BOUND and NOERROR work like in `search-forward'."
  (when bound (setq bound (1+ (hexl-address bound))))
  (setq string (read (concat "\"" string "\"")))
  (let ((point (1+ (hexl-current-address)))
    match-data)
    (with-current-buffer hexl-isearch-raw-buffer
      (goto-char point)
      (setq point (funcall (if isearch-forward #'re-search-forward #'re-search-backward)
               (if isearch-regexp
                   string
                 (regexp-quote string))
               bound noerror count))
      (setq match-data (match-data t nil t)))
    (when point
      (prog1
      (hexl-goto-address (1- point))
    (set-match-data
     (mapcar (lambda (el)
           (if (integerp el)
               (hexl-address-to-marker (1- el))
             el))
         match-data))))))

(define-minor-mode hexl-isearch-mode
  "Search for binary string with isearch in hexl buffer."
  :lighter " hi"
  (if hexl-isearch-mode
      (progn
    (setq-local isearch-search-fun-function #'hexl-isearch-fun)
    (add-hook 'isearch-mode-hook #'hexl-isearch-startup t t)
    (add-hook 'isearch-mode-end-hook #'hexl-isearch-end t t))
    (setq-local isearch-search-fun-function #'isearch-search-fun-default)
    (remove-hook 'isearch-mode-hook #'hexl-isearch-startup t)
    (remove-hook 'isearch-mode-end-hook #'hexl-isearch-end t)))

(easy-menu-add-item hexl-mode-map '(menu-bar Hexl)
            ["Hexl Isearch Mode" (if hexl-isearch-mode (hexl-isearch-mode -1) (hexl-isearch-mode)) :style toggle :selected hexl-isearch-mode] "Go to address")

Các tác phẩm của bạn cũng vậy, và hiệu suất cao hơn nhiều trong các tệp lớn!
gdkrmr
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.