linux查看静态库函数c++程序某个函数的反汇编会显示函数名吗

hipercomer 的BLOG
用户名:hipercomer
文章数:64
评论数:124
访问量:192534
注册日期:
阅读量:5863
阅读量:12276
阅读量:364678
阅读量:1059873
51CTO推荐博文
C/C++~Boost, Qt, lam-mpi~
&&&&&& STLmaplam-mpi
EnumWindowsCqsort
unixsignalsys/signal.h
void (*signal)(int signo,void (*func)(int)))(int);
&&& C++late-binding
Shape *pSh;
scanf(&%d&,&choice);
if(choice)
pSh= new Rectangle();
pSh= new Square();
pSh-&display();
(1)SquareRectange
(2)RectangleShape
(3)displayShape
choicechoice
&&&& _____&&&&&&&&&&&&&&&& &&&&_) )
&& \/,---&&&&&&&&&&&&&&&& &&&&&&\ \
&& ( )c~c~~@~@&&&&&&&&&&& )- - &&\ \
&&& C&& &/&&&&&&&&&&&&&&& \&&& |&/
&&&& \_O/ - &&&&&&&&& _`*-'_/ /
&& ,- &o&-.&&&&&&&&&&&&& / ____ _/
& /&& \/&& \&&&&&&&&&&& / /\& _)_)
&/ /|& | |\ \&&&&&&&&& / /& )&& |
&\ \|& | |/ /&&&&&&&&& \ \ /&&& |
& \_\& | |_/&&&&&&& &&&&\ \_&&& |
& /_/`___|_\&&&&&&&&&&& /_/\____|
&&& |& | |&&&&&&&&&&&&&&&&& \& \|
&&& |& | |&&&&&&&&&&&&&&&&&& `. )
&&& |& | |&&&&&&&&&&&&&&&&&& / /
&&& |__|_|_&&&&&&&&&&&&&&&& /_/|
&&& (____)_)&&&&&&&&&&&&&&& |\_\_
switch-case
&&&&&&&&#include&stdio.h&&#define&UNIXEVN&&#if&defined(UNIXENV)&&#include&sys/time.h&&&#endif&&#define&N&1000000&&#define&COE&1000000&&float&add(float&a,float&b){return&a+b;}&&float&minus(float&a,float&b){return&a-b;}&&float&multiply(float&a,float&b){return&a*b;}&&float&divide(float&a,float&b){return&a/b;}&&typedef&float&(*pf)(float,float);&&void&switch_impl(float&a,float&b,char&op)&&{&&&&&&&&float&result=0.0;&&&&&&&&switch(op)&&&&&&&&{&&&&&&&&&&&&&&&case&'+':&&&&&&&&&&&&&&&&&&&&&&result=add(a,b);&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&case&'-':&&&&&&&&&&&&&&&&&&&&&&result=minus(a,b);&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&case&'*':&&&&&&&&&&&&&&&&&&&&&&result=multiply(a,b);&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&case&'/':&&&&&&&&&&&&&&&&&&&&&&result=divide(a,b);&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&}&&}&&void&switch_fp_impl(float&a,float&b,pf&p)&&{&&&&&&&&float&result=0.0;&&&&&&&&result=p(a,b);&&}&&int&conversion(struct&timeval&tmp_time)&&{&&&&&&&&return&tmp_time.tv_sec*COE+tmp_time.tv_&&}&&int&main()&&{&&&&&&&&int&i=0;&&#if&defined(UNIXENV)&&&&&&&&struct&timeval&start_point,end_&&&&&&&&&&&gettimeofday(&start_point,NULL);&&#endif&&&&&&&&for(i=0;i&N;i++)&&&&&&&&{&&&&&&&&&&&&&&&switch_impl(12.32,54.14,'-');&&&&&&&&}&&#if&defined(UNIXENV)&&&&&&&&gettimeofday(&end_point,NULL);&&&&&&&&printf(&check&point&1:%d\n&,conversion(end_point)-conversion(start_point));&&&&&&&&&&&&&&&gettimeofday(&start_point,NULL);&&#endif&&&&&&&&for(i=0;i&N;i++)&&&&&&&&{&&&&&&&&&&&&&&&switch_fp_impl(12.32,54.14,minus);&&&&&&&&}&&#if&defined(UNIXENV)&&&&&&&&gettimeofday(&end_point,NULL);&&&&&&&&printf(&check&point&2:%d\n&,conversion(end_point)-conversion(start_point));&&#endif&&&&&&&&return&0;&&}&
[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22588&&check&point&2:19407&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22656&&check&point&2:19399&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22559&&check&point&2:19380&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22181&&check&point&2:19667&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22226&&check&point&2:19813&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:22141&&check&point&2:19893&&[lichao@sg01&replaceswitch]$&./replaceswitch&&check&point&1:21640&&check&point&2:19745&
unixwindows#define UNIXENV
int *pa=&a;
int (*pFunction)(float,char,char)=NULL;
int (MyClass::*pMemberFunction)(float,char,char)=NULL;
int (MyClass::*pConstMemberFunction)(float,char,char) const=NULL;
_stdcall,_fastcall,_pascal,_cdecl_cdecl
int func1(float f,int a,int b){return f*a/b;}
int func2(float f,int a,int b){return f*a*b}
pFunction=func1;
pFunction=&func2;
pFunction(10.0,&a&,&b&);
(*pFunction)(10.0,&a&,&b&);
&&&&& int func1(float f,char a,char b)
&&&&&&&&&&&& return f*a*b;
&&&&& int func2(float f,char a,char b) const
return f*a/b;
pMemberFunction= &mc.func1;& //
pConstMemberFunction = &mc.func2;
(mc.*pMemberFunction)(10.0,&a&,&b&);
(mc.*pConstMemberFunction)(10.0,&a&,&b&);
&&&&&&&&#include&stdio.h&&&float&func1(float&f,char&a,char&b)&&{&&&&&&&&printf(&func1\n&);&&&&&&&&return&f*a/b;&&}&&float&&func2(float&f,char&a,char&b)&&{&&&&&&&&printf(&func2\n&);&&&&&&&&return&f*a*b;&&}&&class&MyClass&&{&&public:&&&&&&&&MyClass(float&f)&&&&&&&&{&&&&&&&&&&&&&&&factor=f;&&&&&&&&}&&&&&&&&float&func1(float&f,char&a,char&b)&&&&&&&&{&&&&&&&&&&&&&&&printf(&MyClass::func1\n&);&&&&&&&&&&&&&&&return&f*a/b*&&&&&&&&&&&&&}&&&&&&&&float&func2(float&f,char&a,char&b)&const&&&&&&&&{&&&&&&&&&&&&&&&printf(&MyClass::func2\n&);&&&&&&&&&&&&&&&return&f*a*b*&&&&&&&&}&&private:&&&&&&&&float&&&};&&int&main(int&argc,char&*argv[])&&{&&&&&&&&&&&&&&&float&(*pFunction)(float,char,char)=NULL;&&&&&&&&float&(MyClass::*pMemberFunction)(float,char,char)=NULL;&&&&&&&&float&(MyClass::*pConstMemberFunction)(float,char,char)const=NULL;&&&&&&&&&&&&&&&float&f=10.0;&&&&&&&&char&a='a',b='b';&&&&&&&&float&&&&&&&&&pFunction=func1;&&&&&&&&printf(&pointer&pFunction's&address&is:%x\n&,pFunction);&&&&&&&&result=(*pFunction)(f,a,b);&&&&&&&&&&printf(&result=%f\n&,result);&&&&&&&&&&&&&&&pFunction=&func2;&&&&&&&&printf(&pointer&pFunction's&address&is:%x\n&,pFunction);&&&&&&&&result=pFunction(f,a,b);&&&&&&&&&&printf(&result=%f\n&,result);&&&&&&&&if(func1!=pFunction)&&&&&&&&&&&&&&&printf(&not&equal.\n&);&&&&&&&&&&&&&&&pMemberFunction=&MyClass::func1;&&&&&&&&MyClass&mc1(0.2);&&&&&&&&printf(&pointer&pMemberFunction's&address&is:%x\n&,pMemberFunction);&&&&&&&&result=(mc1.*pMemberFunction)(f,a,b);&&&&&&&&&&printf(&result=%f\n&,result);&&&&&&&&pConstMemberFunction=&MyClass::func2;&&&&&&&&MyClass&mc2(2);&&&&&&&&printf(&pointer&pConstMemberFunction's&address&is:%x\n&,pConstMemberFunction);&&&&&&&&result=(mc2.*pConstMemberFunction)(f,a,b);&&&&&&&&&&printf(&result=%f\n&,result);&&&&&&&&&&&return&0;&&}&
pointer&pFunction's&address&is:400882&&func1&&result=9.897959&&pointer&pFunction's&address&is:400830&&func2&&result=&&not&equal.&&pointer&pMemberFunction's&address&is:400952&&MyClass::func1&&result=1.979592&&pointer&pConstMemberFunction's&address&is:4008f2&&MyClass::func2&&result=000&
&&&&&&&&#include&iostream&&&class&MyClass&&{&&public:&&&&&&&&static&float&plus(float&a,float&b)&&&&&&&&{&&&&&&&&&&&&&&&return&a+b;&&&&&&&&}&&&&&&};&&int&main()&&{&&&&&&&&float&result,a=10.0,b=10.0;&&&&&&&&float&(*p)(float,float);&&&&&&&&p=&MyClass::&&&&&&&&result=p(a,b);&&&&&&&&printf(&result=%f\n&,result);&&&&&&&&return&0;&&}&
result=20.000000&
由于字数比较多,一篇发不完,和函数指针相关的更精彩的内容请看下一篇博文哈~本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)
16:53:25 11:52:24 08:27:14 10:17:06 17:16:15 09:47:33新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
稍有积蓄, 积分 280, 距离下一级还需 220 积分
论坛徽章:0
原始函数:
int& &getx(int& &x,int& &y)&&
&&return& &x+y;&&
使用GDB查看 该函数的汇编代码
(gdb) disassemble getx
Dump of assembler code for function getx:
0x &getx+0&:& & push& &%ebp
0x &getx+1&:& & mov& & %esp,%ebp
0x &getx+3&:& & mov& & 0xc(%ebp),%eax
0x &getx+6&:& & add& & 0x8(%ebp),%eax
0x &getx+9&:& & leave&&
0x0804847a &getx+10&:& &ret& &
End of assembler dump.
请问不使用汇编机器码对照表的情况下,怎么才能直接在GDB中直接查看到这个函数的机器码?或者如何从原始的二进制文件或是运行时内存中查看到机器码呢?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
小富即安, 积分 4912, 距离下一级还需 88 积分
论坛徽章:0
原帖由 shineyear 于
14:20 发表
原始函数:
int& &getx(int& &x,int& &y)&&
&&return& &x+y;&&
使用GDB查看 该函数的汇编代码
(gdb) disassemble getx
Dump of assembler code for function getx:
0x &get ...
看反汇编还是用objdump出来,用gdb设断点,然后打印寄存器的值。
论坛徽章:3
有汇编码对照多好,为什么不要呢?
稍有积蓄, 积分 280, 距离下一级还需 220 积分
论坛徽章:0
原帖由 zx_wing 于
14:47 发表
看反汇编还是用objdump出来,用gdb设断点,然后打印寄存器的值。
objdump 没用过,能讲的详细一些吗?谢谢
论坛徽章:3
man odpdump
objdump -D a.out看看
稍有积蓄, 积分 280, 距离下一级还需 220 积分
论坛徽章:0
哦,已经可以了,我使用的是 objdump --disassemble --show-raw-insn filename 这样可以把汇编和机器码一起打印,并带有函数名,可以很方便的找到对应函数的机器码,谢谢各位!http://6882059.linqq.netc++反汇编与逆向分析技术揭秘电子书|C++反汇编与逆向分析技术揭秘epub格式【完整清晰版】-东坡下载
东坡下载:内容最丰富最安全的下载站!
→ C++反汇编与逆向分析技术揭秘 epub格式【完整清晰版】
有读者看完C++反汇编与逆向分析技术揭秘之后这样建议到:读者看这本书时,有什么C++概念不清楚参考C++经典书,比如《C++程序设计语言》。另外,关于这本书的评价,有人这样说:书中代码与谭浩强的《C语言程序设计》有的一拼――此时小编要说的是在本节内容中小编为为大家整理带来的是一份epub格式完整清晰版C++反汇编与逆向分析技术揭秘,以下是关于该电子书的相关介绍,希望对大家有所帮助!c++反汇编与逆向分析技术揭秘电子书目录前言第一部分 准备工作第1章 熟悉工作环境和相关工具 / 21.1 调试工具Microsoft Visual C++ 6.0和OllyDBG / 21.2 反汇编静态分析工具IDA / 51.3 反汇编引擎的工作原理 / 111.4 本章小结 / 16第二部分 C++反汇编揭秘第2章 基本数据类型的表现形式 / 182.1 整数类型 / 182.1.1 无符号整数 / 182.1.2 有符号整数 / 182.2 浮点数类型 / 202.2.1 浮点数的编码方式 / 212.2.2 基本的浮点数指令 / 232.3 字符和字符串 / 262.3.1 字符的编码 / 272.3.2 字符串的存储方式 / 282.4 布尔类型 / 292.5 地址、指针和引用 / 292.5.1 指针和地址的区别 / 302.5.2 各类型指针的工作方式 / 312.5.3 引用 / 342.6 常量 / 352.6.1 常量的定义 / 362.6.2 #define和const的区别 / 372.7 本章小结 / 38第3章 认识启动函数,找到用户入口 / 403.1 程序的真正入口 / 403.2 了解VC++ 6.0的启动函数 / 403.3 main函数的识别 / 443.4 本章小结 / 46第4章 观察各种表达式的求值过程 / 474.1 算术运算和赋值 / 474.1.1 各种算术运算的工作形式 / 474.1.2 算术结果溢出 / 824.1.3 自增和自减 / 834.2 关系运算和逻辑运算 / 854.2.1 关系运算和条件跳转的对应 / 854.2.2 表达式短路 / 864.2.3 条件表达式 / 884.3 位运算 / 924.4 编译器使用的优化技巧 / 944.4.1 流水线优化规则 / 974.4.2 分支优化规则 / 1014.4.3 高速缓存(cache)优化规则 / 1014.5 一次算法逆向之旅 / 1024.6 本章小结 / 109第5章 流程控制语句的识别 / 1105.1 if语句 / 1105.2 if…else…语句 / 1125.3 用if构成的多分支流程 / 1155.4 switch的真相 / 1195.5 难以构成跳转表的switch / 1285.6 降低判定树的高度 / 1335.7 do/while/for的比较 / 1375.8 编译器对循环结构的优化 / 1435.9 本章小结 / 148第6章 函数的工作原理 / 1496.1 栈帧的形成和关闭 / 1496.2 各种调用方式的考察 / 1526.3 使用ebp或esp寻址 / 1556.4 函数的参数 / 1586.5 函数的返回值 / 1606.6 回顾 / 1636.7 本章小结 / 165第7章 变量在内存中的位置和访问方式 / 1667.1 全局变量和局部变量的区别 / 1667.2 局部静态变量的工作方式 / 1697.3 堆变量 / 1737.4 本章小结 / 177第8章 数组和指针的寻址 / 1788.1 数组在函数内 / 1788.2 数组作为参数 / 1818.3 数组作为返回值 / 1858.4 下标寻址和指针寻址 / 1898.5 多维数组 / 1938.6 存放指针类型数据的数组 / 1998.7 指向数组的指针变量 / 2018.8 函数指针 / 2048.9 本章小结 / 206第9章 结构体和类 / 2079.1 对象的内存布局 / 2079.2 this指针 / 2129.3 静态数据成员 / 2179.4 对象作为函数参数 / 2199.5 对象作为返回值 / 2269.6 本章小结 / 231第10章 关于构造函数和析构函数 / 23310.1 构造函数的出现时机 / 23310.2 每个对象都有默认的构造函数吗 / 24310.3 析构函数的出现时机 / 24510.4 本章小结 / 254第11章 关于虚函数 / 25611.1 虚函数的机制 / 25611.2 虚函数的识别 / 26111.3 本章小结 / 268第12章 从内存角度看继承和多重继承 / 26912.1 识别类和类之间的关系 / 27012.2 多重继承 / 29212.3 虚基类 / 29812.4 菱形继承 / 29912.5 本章小结 / 307第13章 异常处理 / 30813.1 异常处理的相关知识 / 30813.2 异常类型为基本数据类型的处理流程 / 31413.3 异常类型为对象的处理流程 / 32313.4 识别异常处理 / 32913.5 本章小结 / 341第三部分 逆向分析技术应用第14章 PEiD的工作原理分析 / 34414.1 开发环境的识别 / 34414.2 开发环境的伪造 / 35314.3 本章小结 / 356第15章 “熊猫烧香”病毒逆向分析 / 35715.1 调试环境配置 / 35715.2 病毒程序初步分析 / 35815.3 “熊猫烧香”的启动过程分析 / 36015.4 “熊猫烧香”的自我保护分析 / 36615.5 “熊猫烧香”的感染过程分析 / 36915.6 本章小结 / 379第16章 调试器OllyDBG的工作原理分析 / 38016.1 INT3断点 / 38016.2 内存断点 / 38516.3 硬件断点 / 39016.4 异常处理机制 / 39616.5 加载调试程序 / 40216.6 本章小结 / 406第17章 反汇编代码的重建与编译 / 40717.1 重建反汇编代码 / 40717.2 编译重建后的反汇编代码 / 41017.3 本章小结 / 411参考文献 / 412c++反汇编与逆向分析技术揭秘作者简介钱林松,资深安全技术专家、软件开发工程师和架构师,从事计算机安全和软件开发工作12年,实践经验极其丰富。尤其精通软件逆向分析技术,对C/C++技术和Windows的底层机制也有非常深入的研究。武汉科锐软件技术有限公司创始人,教学经验丰富,多年来,为国内计算机安全领域培养和输送了大量的人才。活跃于看雪论坛,有较高的知名度和影响力。c++反汇编与逆向分析技术揭秘电子书内容截图
安卓官方手机版
IOS官方手机版
C++反汇编与逆向分析技术揭秘截图
C++反汇编与逆向分析技术揭秘 epub格式【完整清晰版】
本类最新软件
本类软件推荐
2.0M / 06-11 / pdf高清电子版【03x502图集】
13.9M / 06-11 / pdf扫描版【清晰版】
2.4M / 06-11 / pdf超清免费版【无水印图集】
1.8M / 06-11 / pdf免费版【jgj3102013】
1.1M / 06-11 / pdf格式免费版【00d1017图集】
本类软件排行
装机必备软件
素材字体高考学习
请简要描述您遇到的错误,我们将尽快予以修正。
轮坛转帖HTML方式
轮坛转帖UBB方式16917人阅读
C++对象模型(17)
Linux(15)
调试实践(8)
&&&&&&&& 上一篇文章《》没想到能得到那么多人的喜爱,因为那篇文章是以32位的C++普通函数(非类成员函数)为例子写的,因此只是一个特殊的例子。本文将函数调用时的参数传递方法进行一下总结。总结将为C++普通函数、类成员函数;32位和64位进行总结。
&&&&&&& 建议还是读一下,这样本文的结论将非常容易理解,将非常好的为CoreDump分析开一个好头。而且,它也是32位C++ 普通函数的调用的比较好的例子,毕竟从汇编的角度,将参数如何传递的进行了比较好的说明。
1. 32位程序普通函数
普通函数的意思是非class member function
void func2(int a, int b)
int main()
main函数的汇编:
%esp, %ebp
$2222, 4(%esp)
$1111, (%esp)
func2(int, int)
1111是第一个参数,放到了esp指向的地址。2222是第二个参数,放到了高地址。因次我们可以知道,在函数func2中,通过ebp+8可以访问到第一个参数1111,通过ebp+12可以访问到第二个参数2222。
func2(int, int):
&&&&&&& pushl&& %ebp
&&&&&&& movl&&& %esp, %ebp
&&&&&&& addl&&& $1, 8(%ebp)
&&&&&&& addl&&& $2, 12(%ebp)
&&&&&&& popl&&& %ebp
&&&&&&& ret
下面我们使用gdb通过ebp打印一下传入的参数:
anzhsoft@ubuntu:~/linuxDebugging/parameter$ gdb a.out
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type &show copying&
and &show warranty& for details.
This GDB was configured as &i686-pc-linux-gnu&...
(gdb) b func2
Breakpoint 1 at 0x8048597: file m32noclass.cpp, line 6.
Starting program: /home/anzhsoft/linuxDebugging/parameter/a.out
Breakpoint 1, func2 (a=1111, b=2222) at m32noclass.cpp:6
warning: Source file is more recent than executable.
(gdb) p *(int*)($ebp+8)
(gdb) p *(int*)($ebp+12)
1. 参数通过栈查传递,底地址传递从左边开始的第一个参数
2. 使用gdb可以很方便打印传入参数
(gdb) p *(int*)($ebp+8)
(gdb) p *(int*)($ebp+12)
其实32位的程序也可以使用寄存器传递参数。请看下一节。
2. 32位普通函数-通过寄存器传递参数
可以使用GCC的扩展功能__attribute__使得参数传递可以使用寄存器。
修改第一节的函数:
#define STACKCALL __attribute__((regparm(3)))
void STACKCALL func4(int a, int b, int c, int d)
int main()
& func4(, );
& return 0;
__attribute__((regparm(3)))意思是使用寄存器
anzhsoft@ubuntu:~/linuxDebugging/parameter$ gdb a.out
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.& Type &show copying&
and &show warranty& for details.
This GDB was configured as &i686-pc-linux-gnu&...
(gdb) b main
Breakpoint 1 at 0x80485bb: file m32noclass.cpp, line 14.
Starting program: /home/anzhsoft/linuxDebugging/parameter/a.out
Breakpoint 1, main () at m32noclass.cpp:14
14&& && func4(, );
func4 (a=1111, b=2222, c=3333, d=4444) at m32noclass.cpp:6
6&& && a++;
eax&&&&&&&&&&& 0x457&& &1111
ecx&&&&&&&&&&& 0xd05&& &3333
edx&&&&&&&&&&& 0x8ae&& &2222
ebx&&&&&&&&&&& 0xb3eff4&& &
esp&&&&&&&&&&& 0xbf8e9580&& &0xbf8e9580
ebp&&&&&&&&&&& 0xbf8e958c&& &0xbf8e958c
esi&&&&&&&&&&& 0x0&& &0
edi&&&&&&&&&&& 0x0&& &0
eip&&&&&&&&&&& 0x80485a3&& &0x80485a3 &func4(int, int, int, int)+15&
eflags&&&&&&&& 0x282&& &[ SF IF ]
cs&&&&&&&&&&&& 0x73&& &115
ss&&&&&&&&&&&& 0x7b&& &123
ds&&&&&&&&&&&& 0x7b&& &123
es&&&&&&&&&&&& 0x7b&& &123
fs&&&&&&&&&&&& 0x0&& &0
gs&&&&&&&&&&&& 0x33&& &51
(gdb) p *(int*)($ebp+8)
可以看到,前三个参数分别通过eax/edx/ecx传递,第四个参数通过栈传递。这种传递方式被称为fastcall
3. 32位 class member function 参数传递方式
我们通过宏USINGSTACK强制使用栈来传递参数。
#define USINGSTACK __attribute__((regparm(0)))
class Test
Test():number(3333){}
void USINGSTACK func2(int a, int b)
int main(int argc, char* argv[])
tInst.func2();
通过gdb来打印传入的参数:
anzhsoft@ubuntu:~/linuxDebugging/parameter$ gdb a.out
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type &show copying&
and &show warranty& for details.
This GDB was configured as &i686-pc-linux-gnu&...
(gdb) b main
Breakpoint 1 at 0x804859d: file m32class.cpp, line 18.
Starting program: /home/anzhsoft/linuxDebugging/parameter/a.out
Breakpoint 1, main (argc=1, argv=0xbf98a454) at m32class.cpp:18
tInst.func2();
Test::func2 (this=0xbf98a39c, a=1111, b=2222) at m32class.cpp:9
(gdb) p *(int*)($ebp+12)
(gdb) p *(int*)($ebp+16)
(gdb) p *this
$3 = {number = 3333}
可以看到,class成员函数的第一个参数是对象的指针。通过这种方式,成员函数可以和非成员函数以类似的方式进行调用。
4. x86-64 class member function 的参数传递
在x86-64中,整形和指针型参数的参数从左到右依次保存到rdi,rsi,rdx,rcx,r8,r9中。浮点型参数会保存到xmm0,xmm1……。多余的参数会保持到栈上。
下面这个例子将传递九个参数。可以通过它来验证一下各个寄存器的使用情况:
class Test
Test():number(5555){}
void func9(int a, int b, int c, int d,char*str, long e, long f, float h, double i)
int main(int argc, char* argv[])
tInst.func9(, , &hello, world!&, , 8.888, 9.999);
下面通过gdb验证各个寄存器的使用情况:
khawk-dev-zhanga12:~/study/c++callstack # gdb a.out
GNU gdb (GDB) SUSE (7.0-0.4.16)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type &show copying&
and &show warranty& for details.
This GDB was configured as &x86_64-suse-linux&.
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&...
Reading symbols from /root/study/c++callstack/a.out...done.
(gdb) b main
Breakpoint 1 at 0x40071b: file m64class.cpp, line 19.
Starting program: /root/study/c++callstack/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffe188) at m64class.cpp:19
tInst.func9(, , &hello, world!&, , 8.888, 9.999);
Test::func9 (this=0x7fffffffe0a0, a=1111, b=2222, c=3333, d=4444, str=0x400918 &hello, world!&, e=6666, f=7777, h=8., i=9.0006)
at m64class.cpp:8
(gdb) info reg
0x7fffffffe0a0
0x7fffffffe070
0x7fffffffe070
0x7fffffffe070
0x7fffffffe070
0xffffffffffffffff
0x7ffff733d890
0x7fffffffe180
0x4007ff 0x4007ff &Test::func9(int, int, int, int, char*, long, long, float, double)+35&
[ IM DM ZM OM UM PM ]
(gdb) p *this
$1 = {number = 5555}
(gdb) p *(char*)$r9@13
$2 = &hello, world!&
(gdb) p *(int*)($rbp+16)
(gdb) p *(int*)($rbp+24)
(gdb) p *(int*)$rdi
r9存储的是指针型char *str的字符串。因为寄存器只能存储6个整形、指针型参数,注意,Test 对象的指针占用了一个。因此
参数e和f只能通过栈传递。注意每个地址空间占8个字节。因此rbp+2*8存储的是e,rbp+3*8存储的是f。
float h是通过xmm0,double i是通过xmm1传递的。这类寄存器的size大小是128bits,当然128个bits可以不填满。GDB将这些寄存器看成下面这些数据的联合:
v4_float[4];
v2_double[2];
v16_int8[16];
int16_t v8_int16[8];
int32_t v4_int32[4];
int64_t v2_int64[2];
int128_t unit128;
}xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7;
打印方式如下:
(gdb) p $xmm0.v4_float[0]
(gdb) p $xmm1.v2_double[0]
$8 = 9.0006
在x86-64中,整形和指针型参数的参数从左到右依次保存到rdi,rsi,rdx,rcx,r8,r9中。浮点型参数会保存到xmm0,xmm1……。多余的参数会保持到栈上。
& 1)默认的传递方法不使用寄存器,使用ebp+8可以访问第一个参数,ebp+16可以访问第二个参数。。。
& 2) 可以使用GCC扩展__attribute__将参数放到寄存器上,依次使用的寄存器是eax/edx/ecx
& 3)对于class 的member function,调用时第一个参数为this(对象指针)地址。因此函数的第一个参数使用ebp+16才可以访问到。
& 4)ebp存储的是上层的bp的地址。ebp+4存储的是函数返回时的地址指令。
& 1)默认的传递方法是使用寄存器。当然也可以强制使用栈,方式:函数声明时使用
__attribute__((regparm(0)))& 2)整形和指针型参数的参数从左到右依次保存到rdi,rsi,rdx,rcx,r8,r9中。浮点型参数会保存到xmm0,xmm1……。多余的参数会保持到栈上。
& 3)xmm0……是比较特殊的寄存器,访问内容时需要注意。
尊重原创,转载请注明出处: anzhsoft http://blog.csdn.net/anzhsoft/article/details/
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1550468次
积分:14262
积分:14262
排名:第629名
原创:105篇
评论:703条
鉴于很多网站转载本博客的文章而大部分都没有标明出处,本博客声明如下:
本博客所有文章都为原创,未经允许,不得转载;未经允许,不得进行商业发布或者其他的盈利性活动。如发现侵权,将依法追究其责任。
文章:26篇
阅读:446039
阅读:51825
文章:11篇
阅读:137202
阅读:315928
阅读:151074
(1)(1)(1)(2)(1)(9)(5)(4)(8)(2)(4)(5)(5)(2)(4)(14)(11)(17)(10)}

我要回帖

更多关于 查看dll函数名 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信