在不使用任何工具等的情况下查找某些API函数调用的堆栈用法?

时间:2012-02-09 18:18:53

标签: c

如何从提供给您的API确定函数调用的堆栈使用情况?您不知道该函数是什么样的,并且您只能访问API。例如,

    int main() {
      // call some API function  
      some_func_called();

      // rest of your main
    }

我唯一能想到的是在调用函数之前用已知模式填充堆栈内存,然后检查堆栈以查看函数返回后已知模式的字节数已更改。还有其他想法吗? (这是一个面试问题)

2 个答案:

答案 0 :(得分:2)

这样的事情,未经过全面测试,可能会遇到限制问题。只有当堆栈指针因PUSHING而减少时才有效,所以这不能在所有硬件上移植......

#include <stdlib.h>
#include <string.h>

#define STK_CNT 65536

size_t STK_fill()
{
    volatile size_t i, cnt = 0;

    volatile u_int32_t fill[STK_CNT];

    for(i = 0; i < STK_CNT; i++)
    {
        fill[i] = 0xDEADBEEFUL;
    }

    return cnt;
}

size_t STK_find()
{
    volatile size_t i, cnt = 0;

    volatile u_int32_t fill[STK_CNT];

    for(i = 0; i < STK_CNT; i++)
    {
        if(fill[i] == 0xDEADBEEFUL)
        {
            cnt++;
        }else{
            break;
        }
    }

    return ((STK_CNT - cnt) * 4);
}

void victim(char *po_str, const char *pi_str)
{
    char str[1024];

    strcpy(str, "stk_TEST_");
    strcat(str, pi_str);
    strcat(str, "_stk_TEST");

    strcpy(po_str, str);
}

int main()
{
    int  temp;
    int  used;
    char str[4096] = {0};

    temp = (int)STK_fill();
    victim(str, "STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK");
    used = (int)STK_find();

    printf("VICTIM function used %d bytes of stack\n", used);

    return 0;
}

答案 1 :(得分:0)

我认为你的方法是最可靠的方法。

另一种选择可能是使用现代操作系统倾向于根据需要增加堆栈(即向其提交内存)这一事实。请参阅Will the stack of a C program ever shrink?也许,调用此函数后,您可以询问操作系统有关提交给堆栈的内存量。当然,这是特定于操作系统的,可能是特定于体系结构的,总的来说可能比第一种方法更加繁琐。