如何获得一个函数的大小

soft_biao 2007-12-01 01:17:27
VC中有什么办法可以获得一个函数的大小呢,就象汇编一样
szieofproc = $-procname
望达人解决~~
...全文
1141 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
jues 2011-09-02
  • 打赏
  • 举报
回复
网上找了一遍,结果不太理想.回复了一下学习的汇编,用C写了一个计算函数的大小函数,给大家用

注:不是网上说的通过两个函数地址比较来获取大小.

刚刚写好的,欢迎留言指出.

地址:http://blog.sina.com.cn/s/blog_69eef8440100wrsz.html
raojl 2007-12-03
  • 打赏
  • 举报
回复
#include<stdio.h>
void why_here(void) /*这个函数没有任何地方调用过*/
{
printf("why u here ?!\n");
_exit(0);
}
int main(int argc,char * argv[])
{
int buff[1];
buff[2]=(int)why_here;
return 0;
}
-----------------------
看看这个缓冲注入,你就知道怎么搞,关键要知道程序贞是怎么回事!
soft_biao 2007-12-02
  • 打赏
  • 举报
回复
呵呵,我的作用不是你说的那样
另外如果函数代码很短且固定的话把函数的机器指令放在数据区是个不错的选择,可是如果函数代码多而且要不断修改的话这个方法就显得很麻烦了
zenny_chen 2007-12-02
  • 打赏
  • 举报
回复
一般来说,用C/C++等高级语言写的代码一般都不会去随随便便地覆盖。而用汇编写的代码倒是有可能。而且一般代码覆盖总是在操作系统启动前执行。而在用户模式中想要用一个函数来完全覆盖掉另一个函数是不理智的。而要获得函数的大小就是为了做这个事情吧。:)

不过还有一种可能就是将函数相应的机器指令放在数据区:

unsigned char funcBytes[] = { 0x00, 0x80, 0xaa ...};

然后可以调用它:(*(void(*)(void))funcBytes)();

然后funcBytes可以被其它数据替换掉。



soft_biao 2007-12-02
  • 打赏
  • 举报
回复
szieofproc DWORD $ - procname 一样不行
我昨天在该函数之后定义了一个空函数,用函数名地址相减,还没发现出什么问题,拿出来给大家分享吧

volatile _declspec( naked ) void func(void)
{
//code
//……
}
volatile _declspec( naked ) void funcEnd(void){}

…………

funclen = (ULONG)funcEnd - (ULONG)func; //函数长度

编译选项:
Debug设置
C/C++ -- Optimizations : Minimize Size //可不改
C/C++ -- General -- Debug info: None
Link -- Link incrementally 钩取消

Release设置
C/C++ -- Optimizations : Minimize Size
gernal_dn 2007-12-02
  • 打赏
  • 举报
回复
如果你能确保不被优化,有个很简单的方法:编译出来,然后反查代码。
soft_biao 2007-12-02
  • 打赏
  • 举报
回复
就是函数的代码只有几条指令而且一般不需要修改啊,结贴了,分不多,一人一点吧,呵呵
JobSeeker 2007-12-02
  • 打赏
  • 举报
回复
"函数代码很短且固定的话把函数的机器指令放在数据区是个不错的选择"
此话从何说起?
xiaoQ008 2007-12-02
  • 打赏
  • 举报
回复
没有
别最那无聊的工作
zenny_chen 2007-12-01
  • 打赏
  • 举报
回复
嗯。楼主说得不错。 虽然在C99标准中没有找到关于volatile修饰函数的具体例子,也没有提到修饰函数的情况,但是在C99标准支持得相当好的VisualDSP++中的确表现出来了。
以下是我的测试代码:

#include <stdio.h>


volatile void Hello(void)
{
printf("Hello, world!\n");
}


int main(void)
{
Hello();

return 0;
}



当我把编译器以速度100%的参数进行优化后,Hello函数中的代码内容与优化之前没有任何改变。确实够绝的。
不过我刚才提到的#pragma never_inline这个开关不像volatile那么绝。它只是将该函数不优化为内联,但是函数里面的东西将会被优化。

不过,不管怎么说,只要函数不内联,那么还是可以有机会在运行时获得函数代码大小的。不过VisualDSP++没有提供编译时的获得函数大小的保留字。
JobSeeker 2007-12-01
  • 打赏
  • 举报
回复
volatile来修饰普通函数?第一次听说过。c++应该不支持。
“szieofproc = $ - procname ”这个应该改成
“szieofproc DWORD $ - procname ”吧?
soft_biao 2007-12-01
  • 打赏
  • 举报
回复
to Kenmark:
那是在汇编中用的代码,C里面我不知道如何实现

to zenny_chen:
你在函数前加上volatile和_declspec( naked ),编译之后用ida之类的软件反汇编看下就知道了,volatile关键字可以让你的函数不被编译器优化,declspec(naked)可以不产生代码来保存ESI,EDI,EBX,EBP寄存器,所以你函数里是什么内容编译出来就是什么的了

“这样,你在定义好一个函数后,再定义个哑函数,将哑函数的首地址减去上面那个函数的首地址即可。 ”
这个的关键就在于两个函数紧挨着,这和JobSeeker 提到的方法很类似,看来是没有什么简单的方法了。。哎
zenny_chen 2007-12-01
  • 打赏
  • 举报
回复
Kenmark所言极是。

当编译器对你代码优化后,函数会发生各种有意思的变化。所以在我的《双核协作完成搜索β》中——http://download.csdn.net/user/zenny_chen,为了使我的函数不被编译器优化(变成内联),我使用了#pragma never_inline。不过这个编译开关可能VC没有,或者是用其它的表示。

所以,一般来说,编译器不会提供这样的编译程序保留关键字(如sizeof)来提供获取一个C/C++函数的代码长度。如果真的想取的话,首先,应当保证函数不被内联或是被其它形式地破坏;然后,函数调用时不应该出现像VC那样的函数跳转表;最后还要编译环境还要提供编译选项开关,使得能够将两个函数紧挨着存放在存储器中。这样,你在定义好一个函数后,再定义个哑函数,将哑函数的首地址减去上面那个函数的首地址即可。

我啃 2007-12-01
  • 打赏
  • 举报
回复
“我要对PE文件进行操作,所以这个对我来说有用”
哈哈,哈哈,哈哈哈,同仁
编译器针对性是可能的但是 不是保证的
首先向你肯定:

procname proc
;code
……
procname endp
szieofproc = $ - procname

用于VC是不可能的
其次,即使编译器支持(恕我无知我不知道类似的编译器扩展)也是非标准的

此外,标准不完全保证程序编译后的样子,一般编译器添加的东西会令其面目全非,函数部分尤其恶心
soft_biao 2007-12-01
  • 打赏
  • 举报
回复
to Kenmark:
我要取得的这个函数大小是不会被优化的,函数前加了volatile和_declspec( naked ),编译器会保留函数的原始内容,所以这点不担心

to sinux_1983:
就是这个函数代码的总大小

to visame:
按以下方法使用,编译出来后szieofproc的值就是函数的大小
procname proc
;code
……
procname endp
szieofproc = $ - procname

to thecorr:
我要对PE文件进行操作,所以这个对我来说有用
thecorr 2007-12-01
  • 打赏
  • 举报
回复
sizeof(function)
有什么实际意义啊?
visame 2007-12-01
  • 打赏
  • 举报
回复
Copy过来的,
If you're using GCC, the easiest thing to do is to put the
function in question in its own section using
__attribute__((section "whatever")). Then you can put labels
at the start and end of section "whatever". Or you can define
a global symbol having the value of the size of the section
(which even more directly answers the original question).

Of course you could also put all functions in individual
sections using -ffunction-sections.
visame 2007-12-01
  • 打赏
  • 举报
回复
找到一个,GCC下的。应该和JobSeeker的思路类似。
If you're using GCC, probably you do not need to
copy anything, just locate your function to the initialized
data section:

/* Write unlock sequence */

static void unlock(void) __attribute__((section(".data")));
static void unlock(void)
{
FLASHMEM[KEYLOC1] = KEY1;
FLASHMEM[KEYLOC2] = KEY2;
}

This is the Flash unlock routine from an embedded
system.
***************************************************************
但是,查找过程中我发现更多的人质疑“函数的大小”这样一个概念。
质疑1:
In C types and objects, and only types and objects, have size.
A function is neither of these.

质疑2:
You haven't really defined what is included in "the size" of
a function.
If the function has uninitialized static variables,
then do you include the size of the automatic-initialized-to-zero
region used? If the function has initialized static variables,
then do you include the size of the initialization block (which
might be in a completely different code segment and might happen
to merge initializations of multiple variables from different
functions)? On architectures that are not stack-oriented, do you
include the size of the caller save area? Does "the size" of
the function include any temporary non-heap (e.g., stack) required
for it to execute?

If an optimizer detects common code between the function and
a different function, it could merge the two paths together
as long as it had some method of determining when to split apart
again (and if the code was the tail end of the code, that might
just be the "return from subroutine" code.) When code overlaps like
that, which of the functions do you count the size against?

我目前还没有明确找到“function size和size of a function”的定义。
楼主的szieofproc = $-procname在汇编下真的通过了吗?汇编中是怎样定义函数大小的?
sinux_1983 2007-12-01
  • 打赏
  • 举报
回复
什么叫“函数的大小”?
我啃 2007-12-01
  • 打赏
  • 举报
回复
不是有需求就有必要,编译优化后的机器代码不向你保证任何东西,只是貌似和你的代码运行效果等价而已,很有可能一个函数被撕裂,或者分割成片段与虚拟机互动,此刻你还以为有可能获得C++层面抽象概念的函数吗?
加载更多回复(9)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧