获取可执行文件中的函数位置

时间:2015-12-02 09:50:14

标签: c assembly

我需要可执行文件中代码段的位置(begin和ebn地址)。我试图使用两个虚函数:

void begin_address(){}
void f(){
    ...
}
void end_address(){}

...

printf("Function length: %td\n", (intptr_t)end_address - (intptr_t)begin_address);

问题是,-O4使用gcc进行优化时,我得到了一个负长度。似乎这不适用于优化。

我将f编译为程序集,并尝试了以下内容:

__asm__(
"func_begin:"
"movq $10, %rax;"
"movq $20, %rbx;"
"addq %rbx, %rax;"
"func_end:"
);

extern unsigned char* func_begin;
extern unsigned char* func_end;

int main(){
    printf("Function begin and end address: %p\t%p\n", func_begin, func_end);
    printf("Function length: %td\n", (intptr_t)func_end - (intptr_t)func_begin);
}

问题在于,即使没有优化,我也会得到一些奇怪的输出:

Function begin and end address: 0x480000000ac0c748  0xf5158b48e5894855
Function length: -5974716185612615411

如何在可执行文件中获取函数的位置?我的第二个问题是,const char*是否安全,是否提及此地址。如果存在差异,我对32位和64位解决方案感兴趣。

3 个答案:

答案 0 :(得分:1)

如果要查看函数在二进制文件中占用的字节数,可以使用objdump反汇编二进制文件以查看函数的第一个ip和最后一个ip。或者你可以打印$ ebp - $ esp如果你想知道一个函数在堆栈上使用了多少空间。

答案 1 :(得分:0)

如果您有可行的选择,请告诉gcc使用-O0编译所需的部分:

#include <stdio.h>
#include <stdint.h>

void __attribute__((optimize("O0"))) func_begin(){}
void __attribute__((optimize("O0"))) f(){
    return;
}
void __attribute__((optimize("O0"))) func_end(){}

int main()
{
    printf("Function begin and end address: %p\t%p\n", func_begin, func_end);
    printf("Function length: %td\n", (uintptr_t)func_end - (uintptr_t)func_begin);
}

我不确定__attribute__((optimize("O0")))是否需要f()

答案 2 :(得分:0)

我不了解GCC,但对于某些Microsoft编译器或某些版本的Visual Studio,如果您在调试模式下构建,它会为函数条目创建一个跳转表,然后跳转到实际函数。在发布模式下,它通常不使用跳转表。

我认为大多数链接器都有一个地图输出选项,至少会显示功能的偏移量。

您可以使用可以搜索的asm指令:

        movel   $12345678,eax     ;search for this instruction

这适用于Microsoft C / C ++ 4.1,VS2005和VS2010发布版本:

#include <stdio.h>

void swap(char **a, char **b){
    char *temp = *a;
    *a = *b;
    *b = temp;
}

void sortLine(char *a[], int size){
    int i, j;
    for (i = 0; i < size; i++){
        for (j = i + 1; j < size; j++){
            if(memcmp(a[i], a[j], 80) > 0){
                swap(&a[i], &a[j]);
            }
        }
    }
}

int main(int argc, char **argv)
{
void (*pswap)(char **a, char **b) = swap;
void (*psortLine)(char *a[], int size) = sortLine;
char *pfun1 = (void *) pswap;
char *pfun2 = (void *) psortLine;

    printf("%p %p %x\n", pfun1, pfun2, pfun2-pfun1);

    return(0);
}