From db12e4afc31a8399eefb61f6121512bbc01dc5e8 Mon Sep 17 00:00:00 2001 From: firmianay Date: Fri, 29 Dec 2017 00:17:22 +0800 Subject: [PATCH] update 1.3_linux_basic.md --- doc/1.3_linux_basic.md | 95 ++++++++++++++++++++++++++++++++++ doc/4.2_Linux_terminal_tips.md | 2 + 2 files changed, 97 insertions(+) diff --git a/doc/1.3_linux_basic.md b/doc/1.3_linux_basic.md index 1de6fd3..25f3ff1 100644 --- a/doc/1.3_linux_basic.md +++ b/doc/1.3_linux_basic.md @@ -11,6 +11,7 @@ - [文件描述符](#文件描述符) - [核心转储](#核心转储) - [调用约定](#调用约定) +- [环境变量](#环境变量) ## 常用基础命令 @@ -394,3 +395,97 @@ Cannot access memory at address 0x4141413d **x86-32 函数调用约定**:参数通过栈进行传递。最后一个参数第一个被放入栈中,直到所有的参数都放置完毕,然后执行 call 指令。这也是 Linux 上 C 语言函数的方式。 **x86-64 函数调用约定**:x86-64 下通过寄存器传递参数,这样做比通过栈有更高的效率。它避免了内存中参数的存取和额外的指令。根据参数类型的不同,会使用寄存器或传参方式。如果参数的类型是 MEMORY,则在栈上传递参数。如果类型是 INTEGER,则顺序使用 `rdi`、`rsi`、`rdx`、`rcx`、`r8` 和 `r9`。所以如果有多于 6 个的 INTEGER 参数,则后面的参数在栈上传递。 + + +## 环境变量 +#### 分类 +- 按照生命周期划分 + - 永久环境变量:修改相关配置文件,永久生效。 + - 临时环境变量:使用 `export` 命令,在当前终端下生效,关闭终端后失效。 +- 按照作用域划分 + - 系统环境变量:对该系统中所有用户生效。 + - 用户环境变量:对特定用户生效。 + +#### 设置方法 +1. 在文件 `/etc/profile` 中添加变量,这种方法对所有用户永久生效。如: +``` +# Set our default path +PATH="/usr/local/sbin:/usr/local/bin:/usr/bin" +export PATH +``` +添加后执行命令 `source /etc/profile` 使其生效。 + +2. 在文件 `~/.bash_profile` 中添加变量,这种方法对当前用户永久生效。其余同上。 +3. 直接运行命令 `export` 定义变量,这种方法只对当前终端临时生效。 + +#### 常用变量 +使用命令 `echo` 打印变量: +``` +$ echo $PATH +/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl +$ echo $HOME +/home/firmy +$ echo $LOGNAME +firmy +$ echo $HOSTNAME +firmy-pc +$ echo $SHELL +/bin/bash +$ echo $LANG +en_US.UTF-8 +``` +使用命令 `env` 可以打印出所有环境变量: +``` +$ env +``` +使用命令 `set` 可以打印处所有本地定义的 shell 变量: +``` +$ set +``` +使用命令 `unset` 可以清楚环境变量: +``` +$ unset $变量名 +``` + +#### LD_PRELOAD +该环境变量可以定义在程序运行前优先加载的动态链接库。在 pwn 题目中,我们可能需要一个特定的 libc,这时就可以定义该变量: +``` +$ LD_PRELOAD=/path/to/libc.so ./binary +``` +一个例子: +``` +$ ldd /bin/true + linux-vdso.so.1 => (0x00007fff9a9fe000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1c083d9000) + /lib64/ld-linux-x86-64.so.2 (0x0000557bcce6c000) +$ LD_PRELOAD=~/libc.so.6 ldd /bin/true + linux-vdso.so.1 => (0x00007ffee55e9000) + /home/firmy/libc.so.6 (0x00007f4a28cfc000) + /lib64/ld-linux-x86-64.so.2 (0x000055f33bc50000) +``` + +注意,这种方法得根据实际情况来用,大概就是使用的发行版要相同(`interpreter` 相同),上面的例子中两个 libc 是这样的: +``` +$ file /lib/x86_64-linux-gnu/libc-2.23.so +/lib/x86_64-linux-gnu/libc-2.23.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped +$ file ~/libc.so.6 +/home/firmy/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped +``` +都是 `interpreter /lib64/ld-linux-x86-64.so.2`,所以可以替换。 + +而下面的例子是在 Arch Linux 上使用一个 Ubuntu 的 libc,就会出错: +``` +$ ldd /bin/true + linux-vdso.so.1 (0x00007ffc969df000) + libc.so.6 => /usr/lib/libc.so.6 (0x00007f7ddde17000) + /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f7dde3d7000) +$ LD_PRELOAD=~/libc.so.6 ldd /bin/true +Illegal instruction (core dumped) +``` +``` +$ file /usr/lib/libc-2.26.so +/usr/lib/libc-2.26.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /usr/lib/ld-linux-x86-64.so.2, BuildID[sha1]=458fd9997a454786f071cfe2beb234542c1e871f, for GNU/Linux 3.2.0, not stripped +$ file ~/libc.so.6 +/home/firmy/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped +``` +一个在 `interpreter /usr/lib/ld-linux-x86-64.so.2`,而另一个在 `interpreter /lib64/ld-linux-x86-64.so.2`。 diff --git a/doc/4.2_Linux_terminal_tips.md b/doc/4.2_Linux_terminal_tips.md index 26c9d11..25655b7 100644 --- a/doc/4.2_Linux_terminal_tips.md +++ b/doc/4.2_Linux_terminal_tips.md @@ -8,6 +8,7 @@ - [nohup 和 &](#nohup-和-) - [cat -](#cat--) + ## 通配符 - `*`:匹配任意字符 - `ls test*` @@ -284,6 +285,7 @@ $ bg 1 $ fg 1 ``` + ## cat - 通常使用 cat 时后面都会跟一个文件名,但如果没有,或者只有一个 `-`,则表示从标准输入读取数据,它会保持标准输入开启,如: ```