AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 760684
Accepted
Ole Tange
Ole Tange
Asked: 2023-11-05 20:38:40 +0800 CST2023-11-05 20:38:40 +0800 CST 2023-11-05 20:38:40 +0800 CST

为什么“H”/72/0x48 是可执行文件中第二个最常见的字节?

  • 772

我跑了这个:

cat /usr/bin/* |
  perl -ne 'map {$a{$_}++} split//; END{print map { "$a{$_}\t$_\n" } keys %a}' |
  grep --text . | sort -n | plotpipe --log y {1}

并得到这个:

字节值出现的次数

(即使使用对数 y 轴,它看起来仍然是指数的!顶部和底部之间的距离超过 100 倍)

看一下数字:

:
31919597        ^H
32983719        ^B
33943030        ^O
39130281        \213
39893389        $
52237360        \211
53229196        ^A
76884442        \377
100776756       H
746405320       ^@

^@ (NUL) 是可执行文件中最常见的字节,这并不奇怪。\377 (255) 和 ^A (1) 对我来说也具有直观意义。

但是,是什么导致“H”(72)成为可执行文件中第二常见的字节——比 255 和 1 更常见呢?

x86
  • 1 1 个回答
  • 7277 Views

1 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-11-06T01:17:05+08:002023-11-06T01:17:05+08:00

    (如果此答案得分为72分,请勿点赞!)

    这将是amd64 机器代码指令的64 位操作数大小前缀。

    您会注意到它只发生在 amd64 可执行文件上。

    如果您 比较/bin/*http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_9.1-1_arm64.deb,http://ftp.debian.org/debian/pool/main/ _ c/coreutils/coreutils_9.1-1_amd64.deb和 http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_9.1-1_i386.deb,你会看到:

    $ for f (coreutils_9.1-1_*.deb) bsdtar xOf $f da\* | bsdtar xO ./bin/\* | xxd -p -c1 | sort | uniq -c | sort -rn | head -n 5 | grep -H --label="${${f:r}##*_}" .
    amd64: 692417 00
    amd64: 145689 ff
    amd64:  81911 48
    amd64:  48006 89
    amd64:  45331 0f
    arm64:1409826 00
    arm64:  70391 ff
    arm64:  67915 03
    arm64:  49380 20
    arm64:  41655 40
    i386: 515346 00
    i386: 171643 ff
    i386:  78361 0e
    i386:  69317 24
    i386:  50497 83
    

    0x48(72,'H')仅位于 amd64 上的前 3 名中。

    ls在我的 amd64 Debian 系统上:

    $ xxd -p -c1 =ls | sort | uniq -c | sort -rn | head -n 5
      39187 00
       7827 ff
       5565 48
       4181 20
       3393 0f
    

    如果我们反汇编该可执行文件中的代码,我们会在指令中发现大量 0x48 字节:

    $ objdump -d =ls | grep -cw 48
    5353
    

    其中大多数都处于第一位置:

    $ objdump -d =ls | grep -wm10 48
        4000:       48 83 ec 08             sub    $0x8,%rsp
        4004:       48 8b 05 ad ff 01 00    mov    0x1ffad(%rip),%rax        # 23fb8 <__gmon_start__@Base>
        400b:       48 85 c0                test   %rax,%rax
        4012:       48 83 c4 08             add    $0x8,%rsp
        44b6:       68 48 00 00 00          push   $0x48
        4751:       48 89 f3                mov    %rsi,%rbx
        4754:       48 83 ec 68             sub    $0x68,%rsp
        4758:       48 8b 3e                mov    (%rsi),%rdi
        475b:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
        4764:       48 89 44 24 58          mov    %rax,0x58(%rsp)
    
    $ objdump -d =ls | grep -Pc '^\s*[\da-f]+:\s+48'
    5113
    

    根据http://ref.x86asm.net/geek.html#x48,0x48 是64 位操作数大小 REX.W操作码前缀,它指定要在 64 位操作数上进行操作,而不是默认值。

    $ objdump -d =ls | pcregrep -o1 -o2 '^\s*[\da-f]+:\s+(48 .. ).*?\t(\S+)' | sort | uniq -c  | sort -rn | head
       1512 48 89 mov
       1040 48 8b mov
        630 48 8d lea
        372 48 85 test
        326 48 83 add
        198 48 39 cmp
        158 48 83 sub
         79 48 01 add
         72 48 83 cmp
         69 48 c7 movq
    

    所有指令均在 64 位操作数上完成。

    • 72

相关问题

  • 为什么 Linux 世界使用术语 i386 而不是 x86?

  • 不同 32 位仿真模式之间的 GNU Linker 区别?

  • x86 Linux 中的物理地址 0 包含什么?

  • 用于大文件的 FreeBSD i386 sendfile

  • 如何缓解 Linux 系统上的 Spectre 和 Meltdown 漏洞?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve