こういう知識があってもいい思ったこと (バイナリ編)

## はじめに

- 発端
    - https://qiita.com/atm-snag/items/dc7e168ec7e08182ba64#%E7%99%BA%E7%AB%AF
- 言わないこと
    - OS，実行可能ファイル他フォーマット

## 実行可能ファイル

 - 実行可能ファイルは，機械語が束ねられている
     - ex. `objdump --disassemble=main a.out`
     - ```as
       401106:       55                      push   %rbp
       401107:       48 89 e5                mov    %rsp,%rbp
       40110a:       b8 01 00 00 00          mov    $0x1,%eax
       40110f:       5d                      pop    %rbp
       401110:       c3                      ret
       ```
 - 実行可能ファイルにそのまま書いてある
     - ex. `od --endian=big -x a.out`
     - ```
       0010400 f30f 1efa eb8a 5548 89e5 b801 0000 005d
       0010420 c300 0000 4883 ec08 4883 c408 c300 0000
       ```
 - データも書いてある
     - ex. `od --endian=big -x -c rodata_str`
     - ```
       0020000    0100    0200    4865    6c6c    6f2c    2077    6f72    6c64
               001  \0 002  \0   H   e   l   l   o   ,       w   o   r   l   d
       0020020    2100    0000    011b    033b    2800    0000    0400    0000
                 !  \0  \0  \0 001 033 003   ;   (  \0  \0  \0 004  \0  \0  \0
       ```

<details><summary>詳細</summary>

<div>

```shell-session
$ cat docker-compose.yml
services:
  app:
    image: amd64/gcc:13.1.0
    working_dir:  /usr/src/myapp
    volumes:
      - $PWD:/usr/src/myapp
$ cat main.c
int main() {
    return 1;
}
$ cat Makefile
SRC = main.c
EXE = a.out
PREFIX = docker compose run --rm app

default: run

clean:
	$(RM) $(RMF) $(EXE)

run: build
	$(PREFIX) ./$(EXE)

build: $(EXE)

$(EXE): $(SRC)
	$(PREFIX) gcc -g $< -o $@

disassemble: $(EXE)
	$(PREFIX) objdump --disassemble=main $(EXE)

objdump: $(EXE)
	$(PREFIX) od --endian=big -x $(EXE)
$ make disassemble
docker compose run --rm app  objdump --disassemble=main a.out
[+] Building 0.0s (0/0)
[+] Building 0.0s (0/0)

a.out:     file format elf64-x86-64


Disassembly of section .init:

Disassembly of section .text:

0000000000401106 <main>:
  401106:       55                      push   %rbp
  401107:       48 89 e5                mov    %rsp,%rbp
  40110a:       b8 01 00 00 00          mov    $0x1,%eax
  40110f:       5d                      pop    %rbp
  401110:       c3                      ret

Disassembly of section .fini:
$ make objdump|grep -A1 -E '55.?48.?89'
0010320 f30f 1efa 803d 352f 0000 0075 1355 4889
0010340 e5e8 7aff ffff c605 232f 0000 015d c390
--
0010400 f30f 1efa eb8a 5548 89e5 b801 0000 005d
0010420 c300 0000 4883 ec08 4883 c408 c300 0000
$ cat hello.c
int main() {
    printf("Hello, world!\n");
}
$ cat Makefile.hello
SRC = rodata_str.c
EXE = rodata_str
PREFIX = docker compose run --rm app 

default: run

clean:
	$(RM) $(RMF) $(EXE)

run: build
	$(PREFIX) ./$(EXE)

build: $(EXE)

rodata_str: rodata_str.c
	$(PREFIX) gcc -g $< -o $@

disassemble: $(EXE)
	$(PREFIX) objdump --disassemble=main $(EXE)

rodata: $(EXE)
	$(PREFIX) objdump -s -j .rodata $(EXE)

objdump: $(EXE)
	$(PREFIX) od --endian=big -x -c $(EXE) | grep -A3 -E '6c.?6c'
$ make -f Makefile.hello disassemble
docker compose run --rm app  objdump --disassemble=main rodata_str
[+] Building 0.0s (0/0)
[+] Building 0.0s (0/0)

rodata_str:     file format elf64-x86-64


Disassembly of section .init:

Disassembly of section .plt:

Disassembly of section .text:

0000000000401126 <main>:
  401126:       55                      push   %rbp
  401127:       48 89 e5                mov    %rsp,%rbp
  40112a:       bf 04 20 40 00          mov    $0x402004,%edi
  40112f:       e8 fc fe ff ff          call   401030 <puts@plt>
  401134:       b8 00 00 00 00          mov    $0x0,%eax
  401139:       5d                      pop    %rbp
  40113a:       c3                      ret

Disassembly of section .fini:
$ make -f Makefile.hello rodata
docker compose run --rm app  objdump -s -j .rodata rodata_str
[+] Building 0.0s (0/0)
[+] Building 0.0s (0/0)

rodata_str:     file format elf64-x86-64

Contents of section .rodata:
 402000 01000200 48656c6c 6f2c2077 6f726c64  ....Hello, world
 402010 2100                                 !.                           !.
$ make -f Makefile.hello objdump
docker compose run --rm app  od --endian=big -x -c rodata_str | grep -A3 -E '6c.?6c'
0020000    0100    0200    4865    6c6c    6f2c    2077    6f72    6c64
        001  \0 002  \0   H   e   l   l   o   ,       w   o   r   l   d
0020020    2100    0000    011b    033b    2800    0000    0400    0000
          !  \0  \0  \0 001 033 003   ;   (  \0  \0  \0 004  \0  \0  \0
```
</div>
</details>

## Refs

- [機械語を「直打ち」して Hello, World! - Qiita](https://qiita.com/reika727/items/23bd5367e13114f6705c)
- [od コマンド – ファイルをバイナリで表示する | Linuxコマンド.NET](https://linuxcommand.net/od/#8)
- [objdumpを触ってみた - 雑なメモ書き](https://hiroyukim.hatenablog.com/entry/2019/03/20/181825)
- [ELF入門 - 情弱ログ](https://sugawarayusuke.hatenablog.com/entry/2017/04/09/213133)
- [バイナリレベルでの調査に使用するLinuxコマンドメモ - Qiita](https://qiita.com/rsooo/items/bb91071685f447ce29db)