小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

vim+xxd=強(qiáng)大的十六進(jìn)制編輯器

 曉理曉章 2021-05-13
在linux下用vim打開jpg文件,使用%!xxd進(jìn)行16進(jìn)制顯示時,文件頭顯示為"3f3f 
3f3f 0011 0804"文件尾端顯示為 "3f3f 
0a";而同樣的操作在windows下,就顯示為"ffd8 ffc0 0011 0804"和 "ffd9 
0a",這才是正確的jpeg文件頭和文件尾標(biāo)志。
很蹊蹺 !
初時,我以為是jpeg在windows和linux下是不同的文件頭,后來把jpg后綴去掉,就一個純文件,現(xiàn)象依舊。考慮可能不是操作系統(tǒng)的差異了。
重新使用ghex打開jpeg數(shù)據(jù)查看,發(fā)現(xiàn)顯示正常,為"ffd8 ffc0 0011 
0804"和 "ffd9 0a",正確。
估計應(yīng)該是vim的問題了。
3f的ascii碼是?,那表示vim對文件頭、尾沒有正常解析,是不是和vim解析文件時用的編碼格式有關(guān)系呢?
打開.vimrc配置項,屏蔽掉下面這句話:
set fileencodings=utf-8,gb2312,gbk,gb18030,ucs-bom
再用vim打開jpeg文件,顯示"ffd8 ffc0 0011 0804"和 "ffd9 0a", 
顯示正確。
原來,為了支持識別和顯示中文,我規(guī)定了vim的fileencodings, 
當(dāng)vim打開文件時,會使用規(guī)定的編碼格式對數(shù)據(jù)進(jìn)行解析,可惜jpeg的文件頭FFD8、尾FFD9 
不是任何一個中文的編碼,vim找不到對應(yīng)的中文字,就顯示為??,即:3f3f。
至此,困惑全部打開。




通常來說文件分為文本和二進(jìn)制文件兩大類,文本文件的編輯很容易,Windows下的notepad、UltraEdit都很好用,二進(jìn)制文件的編輯在Windows下也有很多工具,UltraEdit也不錯,但是Linux下呢?今天終于發(fā)現(xiàn)了一個好方法,但是最終出處找不到了。

首先創(chuàng)建一個二進(jìn)制文件:

Ruby代碼 復(fù)制代碼  收藏代碼
  1. [oracle@logserver tmp]$ echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz" > test.bin   
  2. [oracle@logserver tmp]$ cat test.bin    
  3. ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz   
  4. [oracle@logserver tmp]$  
  1. [oracle@logserver tmp]$ echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz" > test.bin
  2. [oracle@logserver tmp]$ cat test.bin
  3. ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
  4. [oracle@logserver tmp]$
 
注意echo 一定要跟上 -n 選項,否則會被自動加上一個換行行,再用vim打開 test.bin
Ruby代碼 復(fù)制代碼  收藏代碼
  1. [oracle@logserver tmp]$ vim -b test.bin  
[oracle@logserver tmp]$ vim -b test.bin
   vim 的 -b 選項是告訴 vim 打開的是一個二進(jìn)制文件,不指定的話,會在后面加上 0x0a ,即一個換行符。

在命令模式下鍵入:

Ruby代碼 復(fù)制代碼  收藏代碼
  1. :%!xxd  
:%!xxd
   

 

如果 vim 后面沒有加 -b 選項就會出現(xiàn)可惡的 0x0a:
如果有 -b 選項就不會有這種情況:
然后進(jìn)入編輯模式改,改就是了,我將A、B對應(yīng)的41、42改成61、62,將a、b對應(yīng)的61、62改成41、42。
回到命令模式輸入:
Ruby代碼 復(fù)制代碼  收藏代碼
  1. :%!xxd -r  
:%!xxd -r
 
 
此時可以發(fā)現(xiàn)AB和ab的位置互換了。
最后在命令模式中輸入 :wq 保存退出即可。


-----------------------------------------------------------------------------------------------------------


vim可以很方便地編輯二進(jìn)制文件,個人認(rèn)為它比emacs的二進(jìn)制編輯方式更好用。vim中二進(jìn)制文件的編輯是先通過外部程序xxd來把文件dump成其二進(jìn)制的文本形式,然后就可以按通常的編輯方式對文件進(jìn)行編輯,編輯完成后再用xxd 轉(zhuǎn)化為原來的形式即可。

可分如下幾步進(jìn)行:

(1) 首先以二進(jìn)制方式編輯這個文件: vim -b datafile

(2) 現(xiàn)在用 xxd 把這個文件轉(zhuǎn)換成十六進(jìn)制: :%!xxd

文本看起來像這樣:

0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49 ....9..;..tt.+NI
0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30 K,.`.....b..4^.0
0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9 7;'1.".....i.59.

現(xiàn)在你可以隨心所欲地閱讀和編輯這些文本了。 Vim 把這些信息當(dāng)作普通文本來對待。修改了十六進(jìn)制部分并不導(dǎo)致可顯示字符部分的改變,反之亦然。

(3) 最后,用下面的命令把它轉(zhuǎn)換回來: :%!xxd -r

只有十六進(jìn)制部分的修改才會被采用。右邊可顯示文本部分的修改忽略不計。

xxd是linux的一個命令,vim可以通過”!”來調(diào)用外部命令,其功能就是進(jìn)行十六進(jìn)制的dump或者反之。

VIM 編輯二進(jìn)制文件 (vim手冊載錄)

*23.4* 二進(jìn)制文件

你可以用 Vim 來編輯二進(jìn)制文件。Vim 本非為此而設(shè)計的,因而有若干局限。但你能讀取一個文件,改動一個字符,然后把它存盤。結(jié)果是你的文件就只有那一個字符給改了,其它的就跟原來那個一模一樣。

要保證 Vim 別把它那些聰明的竅門用錯地方,啟動 Vim 時加上 ”-b” 參數(shù):

vim -b datafile

這個參數(shù)設(shè)定了 'binary' 選項。其作用是排除所有的意外副作用。例如,'textwidth' 設(shè)為零,免得文本行給擅自排版了。并且,文件一律以 Unix 文件格式讀取。

二進(jìn)制模式可以用來修改某程序的消息報文。小心別插入或刪除任何字符,那會讓程序運(yùn)行出問題。用 “R” 命令進(jìn)入替換模式。

文件里的很多字符都是不可顯示的。用 Hex 格式來顯示它們的值:

:set display=uhex

另外,也可以用命令 “ga” 來顯示光標(biāo)下的字符值。當(dāng)光標(biāo)位于一個 <Esc> 字符上時,該命令的輸出看起來就像這樣:

 <^[>  27, Hex 1b,  Octal 033 

文件中也許沒那么多換行符。你可以關(guān)閉 'wrap' 選項來獲得總覽的效果:

        :set nowrap

字節(jié)位置

要發(fā)現(xiàn)你在文件中的當(dāng)前字節(jié)位置,請用這個命令:

g CTRL-G

其輸出十分冗長:

    Col 9-16 of 9-16; Line 277 of 330; Word 1806 of 2058; Byte 10580 of 12206 

最后兩個數(shù)字就是文件中的當(dāng)前字節(jié)位置和文件字節(jié)總數(shù)。這已經(jīng)考慮了 'fileformat' 選項導(dǎo)致?lián)Q行符字節(jié)不同的影響。

要移到文件中某個指定的字節(jié),請用 “go” 命令。例如,要移到字節(jié) 2345:

2345go

使用 XXD

一個真正的二進(jìn)制編輯器用兩種方式來顯示文本: 二進(jìn)制和十六進(jìn)制格式。你可以在 Vim 里通過轉(zhuǎn)換程序 “xxd” 來達(dá)到這效果。該程序是隨 Vim 一起發(fā)布的。

首先以二進(jìn)制方式編輯這個文件:

 vim -b datafile

現(xiàn)在用 xxd 把這個文件轉(zhuǎn)換成十六進(jìn)制:

        :%!xxd

文本看起來像這樣:

        0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49  ....9..;..tt.+NI 
        0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30  K,.`.....b..4^.0 
        0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9  7;'1.".....i.59. 

現(xiàn)在你可以隨心所欲地閱讀和編輯這些文本了。 Vim 把這些信息當(dāng)作普通文本來對待。修改了十六進(jìn)制部分并不導(dǎo)致可顯示字符部分的改變,反之亦然。

最后,用下面的命令把它轉(zhuǎn)換回來:

:%!xxd -r

只有十六進(jìn)制部分的修改才會被采用。右邊可顯示文本部分的修改忽略不計。



--------------------------------------------------------------------------------------------------------

xxd使用手冊

目錄:

★ 命令行參數(shù)簡介
★ xxd使用中的注意事項
★ xxd使用舉例
. 從偏移0x10開始顯示,也就是缺省情況下的第一行不顯示
. 顯示倒數(shù)0x30個字節(jié)(缺省情況下倒數(shù)3行)
. 顯示120字節(jié),連續(xù)顯示,每行20字節(jié)
. 顯示120字節(jié),每行12字節(jié)
. 顯示0x6c偏移開始的12個字節(jié)
. 創(chuàng)建一個65537字節(jié)大小的文件,除了最后一個字節(jié)是'A',其余都是0x00
. 使用autoskip選項
. 創(chuàng)建只包含一個'A'字節(jié)的文件
. 復(fù)制輸入文件到輸出文件,且給輸出文件前部增加100字節(jié)的0x00
. 二進(jìn)制文件打補(bǔ)丁
. Read single characters from a serial line

★ 命令行參數(shù)簡介

xxd -h
xxd [options] [infile [outfile]]
xxd -r [options] [infile [outfile]]

xxd可以創(chuàng)建給定文件或標(biāo)準(zhǔn)輸入的hexdump,也可以還原一個hexdump成以前的二進(jìn)
制文件。如果沒有指定文件或指定文件名為-,則采用標(biāo)準(zhǔn)輸入。如果沒有指定輸出
文件或指定文件名為-,則采用標(biāo)準(zhǔn)輸出。

-a
toggle autoskip: A single '*' replaces nul-lines. Default off.

-b
采用2進(jìn)制顯示,而不是默認(rèn)的16進(jìn)制

xxd -l 32 -b scz.sh
0000000: 00100011 00100001 00100000 00101111 01100010 01101001 #! /bi
0000006: 01101110 00101111 01110011 01101000 00001010 00100011 n/sh.#
000000c: 00001010 00100011 00100000 11001000 10100001 11010110 .# ...
0000012: 11110111 11001001 11101000 10110001 10111000 10111010 ......
0000018: 11000101 00001010 00100011 00100000 01100011 01100001 ..# ca
000001e: 01110100 00100000 t

-c cols
默認(rèn)16,-i指定時采用12,-p指定時采用30,-b指定時采用6,最大256
-c8、-c 8、-c 010是等價的,其他選項類似。

xxd -c 8 -l 32 -g 1 scz.sh
0000000: 23 21 20 2f 62 69 6e 2f #! /bin/
0000008: 73 68 0a 23 0a 23 20 c8 sh.#.# .
0000010: a1 d6 f7 c9 e8 b1 b8 ba ........
0000018: c5 0a 23 20 63 61 74 20 ..# cat

-E
不用ASCII顯示,而采用EBCDIC編碼,不影響16進(jìn)制顯示

xxd -E -l 32 -g 1 scz.sh
0000000: 23 21 20 2f 62 69 6e 2f 73 68 0a 23 0a 23 20 c8 ......>........H
0000010: a1 d6 f7 c9 e8 b1 b8 ba c5 0a 23 20 63 61 74 20 .O7IY...E..../..

-g bytes
比較下面三種顯示方式,缺省bytes為2,指定-b時采用1。

xxd -l 32 -g 0 scz.sh
0000000: 2321202f62696e2f73680a230a2320c8 #! /bin/sh.#.# .
0000010: a1d6f7c9e8b1b8bac50a232063617420 ..........# cat

xxd -l 32 -g 1 scz.sh
0000000: 23 21 20 2f 62 69 6e 2f 73 68 0a 23 0a 23 20 c8 #! /bin/sh.#.# .
0000010: a1 d6 f7 c9 e8 b1 b8 ba c5 0a 23 20 63 61 74 20 ..........# cat

xxd -l 32 -g 2 scz.sh
0000000: 2321 202f 6269 6e2f 7368 0a23 0a23 20c8 #! /bin/sh.#.# .
0000010: a1d6 f7c9 e8b1 b8ba c50a 2320 6361 7420 ..........# cat

-h
顯示幫助信息

-i
以C語言數(shù)組形式顯示,如果輸入來自stdin,則有所區(qū)別

unsigned char scz_sh[] = {
0x23, 0x21, 0x20, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x0a, 0x23,
0x0a, 0x23, 0x20, 0xc8, 0xa1, 0xd6, 0xf7, 0xc9, 0xe8, 0xb1, 0xb8, 0xba,
0xc5, 0x0a, 0x23, 0x20, 0x63, 0x61, 0x74, 0x20
};
unsigned int scz_sh_len = 32;

注意區(qū)分下面兩條命令執(zhí)行效果的不同

xxd -l 12 -i < scz.sh
0x23, 0x21, 0x20, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x0a, 0x23

xxd -l 12 -i scz.sh
unsigned char scz_sh[] = {
0x23, 0x21, 0x20, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x0a, 0x23
};
unsigned int scz_sh_len = 12;

-l len
只顯示<len>這么多字節(jié)

-p
以連續(xù)的16進(jìn)制表示顯示,比較下面的不同顯示效果

xxd -u -l 32 scz.sh
0000000: 2321 202F 6269 6E2F 7368 0A23 0A23 20C8 #! /bin/sh.#.# .
0000010: A1D6 F7C9 E8B1 B8BA C50A 2320 6361 7420 ..........# cat

xxd -u -l 32 -p scz.sh
2321202F62696E2F73680A230A2320C8A1D6F7C9E8B1B8BAC50A23206361
7420

-r
reverse operation: convert (or patch) hexdump into binary.
If not writing to stdout, xxd writes into its output file without
truncating it. Use the combination -r -p to read plain hexadecimal
dumps without line number information and without a particular
column layout. Additional Whitespace and line-breaks are allowed
anywhere.

這個選項要用的話,一定要提前測試

-seek offset
When used after -r : revert with <offset> added to file positions
found in hexdump.

-s [+][-]seek
start at <seek> bytes abs. (or rel.) infile offset. + indicates
that the seek is relative to the current stdin file position
(meaningless when not reading from stdin). - indicates that the seek
should be that many characters from the end of the input (or if
combined with + : before the current stdin file position).
Without -s option, xxd starts at the current file position.

-u
采用大寫16進(jìn)制字母顯示,缺省采用小寫16進(jìn)制字母

-v
顯示版本信息

★ xxd使用中的注意事項

xxd -r has some builtin magic while evaluating line number information. If the ouput file
is seekable, then the linenumbers at the start of each hexdump line may be out of order,
lines may be missing, or overlapping. In these cases xxd will lseek(2) to the next position.
If the output file is not seekable, only gaps are allowed, which will be filled by null-
bytes.

xxd -r never generates parse errors. Garbage is silently skipped.

When editing hexdumps, please note that xxd -r skips everything on the input line after
reading enough columns of hexadecimal data (see option -c). This also means, that changes to
the printable ascii (or ebcdic) columns are always ignored. Reverting a plain (or
postscript) style hexdump with xxd -r -p does not depend on the correct number of columns.
Here an thing that looks like a pair of hex-digits is interpreted.

xxd -s +seek may be different from xxd -s seek , as lseek(2) is used to "rewind" input. A
'+' makes a difference if the input source is stdin, and if stdin's file position is not at
the start of the file by the time xxd is started and given its input. The following
examples may help to clarify (or further confuse!)...

Rewind stdin before reading; needed because the `cat' has already read to the end of stdin.
% sh -c 'cat > plain_copy; xxd -s 0 > hex_copy' < file

Hexdump from file position 0x480 (=1024+128) onwards. The `+' sign means "relative to the
current position", thus the `128' adds to the 1k where dd left off.
% sh -c 'dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet' < file

Hexdump from file position 0x100 ( = 1024-768) on.
% sh -c 'dd of=plain_snippet bs=1k count=1; xxd -s +-768 > hex_snippet' < file

However, this is a rare situation and the use of `+' is rarely needed. the author prefers
to monitor the effect of xxd with strace(1) or truss(1), whenever -s is used.

★ xxd使用舉例

.. 從偏移0x10開始顯示,也就是缺省情況下的第一行不顯示
xxd -s 0x10 scz.sh

.. 顯示倒數(shù)0x30個字節(jié)(缺省情況下倒數(shù)3行)
xxd -s -0x30 -g 1 scz.sh

.. 顯示120字節(jié),連續(xù)顯示,每行20字節(jié)
xxd -l 120 -p -c 20 scz.sh

.. 顯示120字節(jié),每行12字節(jié)
xxd -l 120 -c 12 -g 1 scz.sh

.. 顯示0x6c偏移開始的12個字節(jié)
xxd -l 12 -c 12 -g 1 -s 0x6c scz.sh

.. 創(chuàng)建一個65537字節(jié)大小的文件,除了最后一個字節(jié)是'A',其余都是0x00
echo 10000: 41 | xxd -r > scz.txt

od -A x -t x1 scz.txt
000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
010000 41
010001

.. 使用autoskip選項

xxd -a scz.txt
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
*
0010000: 41 A

注意,缺省情況下autoskip功能是關(guān)閉的,但od看樣子缺省就是打開的。

.. 創(chuàng)建只包含一個'A'字節(jié)的文件
echo '010000: 41' | xxd -r -s -0x10000 > scz_1

注意對比這些效果
echo '010: 41 42 43 44 45 46' | xxd -r -s 0 > scz_1

echo '010: 41 42 43 44 45 46' | xxd -r -s -0x10 > scz_1
等價于
echo '0: 41 42 43 44 45 46' | xxd -r -s 0 > scz_1

echo '010: 41 42 43 44 45 46' | xxd -r -s -0x12 > scz_1
執(zhí)行的時候報錯,xxd: sorry, cannot seek backwards.

echo '010: 41 42 43 44 45 46' | xxd -r -s 0x10 > scz_1
等價于
echo '020: 41 42 43 44 45 46' | xxd -r -s 0 > scz_1

.. 復(fù)制輸入文件到輸出文件,且給輸出文件前部增加100字節(jié)的0x00
xxd scz_1 | xxd -r -s 100 > scz_2

od -A x -t x1 scz_2
000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
000060 00 00 00 00 41
000065

.. 二進(jìn)制文件打補(bǔ)丁
echo '0: 41 42 43 44 45 46' | xxd -r -s 0 > scz_1
od -A x -t x1 scz_1
echo '4: 47 48' | xxd -r - scz_1
od -A x -t x1 scz_1

.. Use xxd as a filter within an editor such as vim(1) to hexdump a region
marked between `a' and `z'.
:'a,'z!xxd

.. Use xxd as a filter within an editor such as vim(1) to recover a
binary hexdump marked between `a' and `z'.
:'a,'z!xxd -r

.. Use xxd as a filter within an editor such as vim(1) to recover one line
of a hexdump. Move the cursor over the line and type:
!!xxd -r

.. Read single characters from a serial line
xxd -c1 < /dev/term/b &
stty < /dev/term/b -echo -opost -isig -icanon min 1
echo -n foo > /dev/term/b

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多