<linux Assembly> 常用工具

 

1.1 gdb

1) info registers   : 显示所有寄存器的值

 

2 )print : 打印特定寄存器

(gdb) p $edi

 

print/d 显示 10进制

print/t  显示 2进制

print/x 显示 16进制

 

3) x 显示特定内存的位置 值

x/ABC

A : 个数

B : c 字符  d 同上

C : b 字节 ; h 字 ;w ;双字

 

(gdb) x/16cb &mystr

 

4) 从开始点

(gdb) b *_start

1.2 as

命令 as -o xxx.o xxx.s

as -o xxx.o -gstabs xxx.s 为了可以gdb

 

1.3 ld

命令 ld -o main main.o

如果需要系统调用  加上 运行时加载动态库的程序

ld -dynamic-linker /lib/ld-linux.so.2 -o main -lc main.o

 

写道
这里带出点东西

使用原始系统调用好处
创建长度尽可能短的代码,执行最可能快的代码
因为他不需要把外部库链入 (不要加载动态加载程序)

C库 呢 移植 ,可共享,但是我清楚的记得 很多系统调用没有C库接口
或许你可以说他 can not be portable

 

 

 

当然以上所有的等同于 gcc -o main xxx.s

 

1.4 objdump -D main

 

1.5 strace

 

strace -c xxx

 会列出一些 errors

strace -e trace = xxx,xxx

或者 直接 strace -p pid

 

 

 

 二 架子

 

2.1 数据段

.data  .rodata(read only)

2.1.1 标签:

.ascii 文本; .asciz 带空字符结尾的文本 ; .long .int ....

mystr:(相当于指针)

 .ascii "Hello world"

2.1.2 静态符号(数据段)

output:
   .ascii "szx start\n"
output_end:
   .equ len , output_end - output

 

.equ MYNAGE ,22

cmp $MYAGE, %eax

 

2.2 bss段  

 

 

.comm 声明初始化的数据的通用内存区域

.lcomm 声明未初始化的数据的本地内存区域 (不能用在globl命令)

 

.seciont .bss

.lcomm buffer ,10

好处是不会让你编译后的文件包括你开的bss空间. 上图可能只是一个符号

 

 

一般查找PC指针出错的方法是 (如果gdb where 只能看到出错的register 和pc )

 

1  如果有ld 链接文件,那么直接分析文件 比如android 里面就有很多 .map的 链接映射文件 规定了代码段 库等分布

   (这个以后会专门写一篇)

 

如果没有也可以 通过/proc/pidxxx/men 来查看具体的分布

 

2 这时候找到.so 或者数据段的基址 然后去根据 -g 编译出来的文件 反编译汇编 找到PC出错的行 ,一般就可以分析出原因了(以后会补个列子)

 

 

 ==================================

 

linux 系统中 分配给程序运行的虚拟地址从
0x80480000 开始

 

使用 objdump -x 可执行 .可以获得内存布局  (readelf -e 或许更好 ^^)

写道
08048134 l d .interp 00000000 .interp
08048148 l d .note.ABI-tag 00000000 .note.ABI-tag
08048168 l d .note.gnu.build-id 00000000 .note.gnu.build-id
0804818c l d .gnu.hash 00000000 .gnu.hash
080481ac l d .dynsym 00000000 .dynsym
0804820c l d .dynstr 00000000 .dynstr
0804825e l d .gnu.version 00000000 .gnu.version
0804826c l d .gnu.version_r 00000000 .gnu.version_r
0804828c l d .rel.dyn 00000000 .rel.dyn
08048294 l d .rel.plt 00000000 .rel.plt
080482b4 l d .init 00000000 .init
080482e4 l d .plt 00000000 .plt
08048340 l d .text 00000000 .text
080484ec l d .sched.text 00000000 .sched.text
08048500 l d .fini 00000000 .fini
0804851c l d .rodata 00000000 .rodata
08048548 l d .eh_frame 00000000 .eh_frame
08049f0c l d .ctors 00000000 .ctors
08049f18 l d .dtors 00000000 .dtors
08049f24 l d .jcr 00000000 .jcr
08049f28 l d .dynamic 00000000 .dynamic
08049ff0 l d .got 00000000 .got
08049ff4 l d .got.plt 00000000 .got.plt
0804a010 l d .data 00000000 .data
0804a018 l d .bss 00000000 .bss

 

 

 

 其实.init .sched.text 在kernel 中可以看到进常通过gcc 特性用
#define __sched __attribute__((__section__(".sched.text")))
来指定

 

如果你 gdb where 

 

发现都是一排 十六进制地址  没有任何源码信息  不要慌着

 

记得加上-g 编译后 用 objdump -D 翻译成 汇编 ,

 

然后去找这些地址  , 当然你需要知道一些C 风格的汇编 格式(入stack 局部变量保存 等) 

==========================

 

有时候如果你没有nm 或者ldd 来看系统当前连接的动态库, 何不直接vi 可执行文件,然后 /???.so 这样看

屡试不爽哦

 

当然也可以直接  readelf .....

 

http://www.cnblogs.com/napoleon_liu/archive/2011/05/06/2038698.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值