4个高难度又很有用的嵌入ASM进行堆栈回朔展开搜索问题:1。在某函数fc中判断fc是被fc2直接调用的3。在某函数fc中判断此时距main有几层

universee 2007-10-08 10:56:24
几个高难度又很有用的嵌入ASM进行堆栈回朔展开搜索问题:

1。在某函数fc中判断fc是被fc2直接调用的,
2。在某函数fc中判断调用链中有fc2。并判断是在第几层调用中。
3。在某函数fc中判断此时“距离”main有几层,就是说main是调用了多少层函数进入了fc的。
4。在某函数fc中,不用本函数名称,取得此函数的地址。

这几个问题都涉及堆栈回朔展开搜索,要取机器码的call偏移量,用ebp比较多。

int fc(int a,int b)
{

int c;
if(main直接调用我)
{
c=a*b+a;
}
else if(fc3调用了fc2再调用我)
{
c=a*b;
}

else if(fc2调用我)
{
c=a*b+b;
}
int n=(main调用了N个函数才调用到我,取此N值)
printf("距离main的层数:%d\r\n",n);
return c;
}
int fc2(int a)
{
return fc(a,a+2);
}

int fc3(int a)
{
return fc2(a,a-1);
}
main()
{
fc(1,2);
fc2(5);
fc3(10);
}



----------------------
int fc(int a,int b)
{
int c=a+b;
if(我已经递归了8次了)//要用堆栈展开做递归计数。
{ return c; }
return fc(c,a);
}


...全文
186 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
universee 2007-10-11
  • 打赏
  • 举报
回复
CSDN的高手呢?现身吧
mLee79 2007-10-08
  • 打赏
  • 举报
回复
这种严重依赖编译器策略的东东有屁意思...
3可以这样, 其他的也差不多 :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef _MSC_VER
#define GET_STACK_FRAME( __ebp__ ) do { __asm { mov __ebp__ , ebp } } while(0)
#else
#define GET_STACK_FRAME( __ebp__ ) __asm__ ("movl %%ebp , %0":"=m"(__ebp__) )
#endif
void* getNextFrame( void* xFrame , void** nextFrame )
{
if( nextFrame )
*nextFrame = ((void**)xFrame)[0];
return ((void**)xFrame)[1];
}

void* startUpCode = NULL;

void foobar()
{
int depth = 0;
void *xFrame , *xReturnAddress;
GET_STACK_FRAME( xFrame );
for( ;( xReturnAddress = getNextFrame( xFrame , &xFrame ) ) != startUpCode ; ++depth )
;
printf( "%d\n" , depth );
}

void dummyCaller()
{
if( rand()&15 )
dummyCaller();
else
foobar();
}

int main()
{
void* xMainFrame;

srand( time(NULL) );

GET_STACK_FRAME( xMainFrame );
startUpCode = getNextFrame( xMainFrame , NULL );

foobar();
dummyCaller();

return 0;
}



universee 2007-10-08
  • 打赏
  • 举报
回复
都是这类的代码
__asm
{
mov eax,ss:[ebp+4];
mov ebpj4,eax;
sub eax,4;
mov eax,cs:[eax];
mov thisaddr,eax
}
universee 2007-10-08
  • 打赏
  • 举报
回复
一个星期后公布答案
universee 2007-10-08
  • 打赏
  • 举报
回复


int fc(int a,int b)
{

int c;
if(main直接调用我)
{
c=a*b+a;
}
else if(fc3调用了fc2再调用我)
{
c=a*b;
}

else if(fc2调用我)
{
c=a*b+b;
}
int n=(main调用了N个函数才调用到我,取此N值)
printf("距离main的层数:%d\r\n",n);
return c;
}
int fc2(int a)
{
return fc(a,a+2);
}

int fc3(int a)
{
return fc2(a,a-1);
}
main()
{
fc(1,2);
fc2(5);
fc3(10);
}



----------------------
int fc(int a,int b)
{
int c=a+b;
if(我已经递归了8次了)//要用堆栈展开做递归计数。
{ return c; }
return fc(c,a);
}

universee 2007-10-08
  • 打赏
  • 举报
回复
rational对编译器的依赖比这还强呢,对版本都有要求,因为它要分析obj文件,呵呵

不要光想着通用化,往往真正有用的是特化
universee 2007-10-08
  • 打赏
  • 举报
回复


int fc()
{
...
if(直接调用我的是fc2)
{
让fc2本身也返回;
}
else
{
...
}

}

int fc()
{
...
if(某种情况)
{
返回n层
}

else if(某种情况2)
{
返回直到是另一函数fck的环境
...
}

}
mLee79 2007-10-08
  • 打赏
  • 举报
回复
自动生成代码时序图,profile 等等想得到的功能显然分析 mapfile 更方便的多...
现在很多的实现都是用 mapfile 来实现, 简单而有效, 当然没必要使用这种严重依赖编译器的东东干活 ...
universee 2007-10-08
  • 打赏
  • 举报
回复
有时感觉ASM就已经是动态语言了,还有机器语言也是
universee 2007-10-08
  • 打赏
  • 举报
回复
即使没有栈帧,堆栈回朔,还可以用代码段回朔技术,不过如果给优化成了不带push的jmp,那可无能为力了,
不过这些很多情况下是在代码白盒测试阶段给程序员用的,所以还不用怎么担心这个问题

不要轻易说任何一种技术没用,特别对于这么底层的技术。
自动生成代码时序图只是一个最简单的例子,其他高端功能多的是,想不到用途时不要说没用,RATIONAL里非常广泛的在用这些技术,都是在关键的地方。

huzhangyou 2007-10-08
  • 打赏
  • 举报
回复
大师的帖子要顶
mLee79 2007-10-08
  • 打赏
  • 举报
回复
要实现这些东西有必要搞这么复杂么, 要求生成 .map , 然后 writeprocmem 就是, 简单直接 ...
universee 2007-10-08
  • 打赏
  • 举报
回复
3可以这样, 其他的也差不多 :
---------------------------------------

嗯,第3个问题已经解决啦,继续吧,

还有,第3个问题还有一种解法,是用代码段回朔的方案,

这几个问题不是差不多,其他的有些是必须涉及代码段回朔的,单纯堆栈回朔很难做到
universee 2007-10-08
  • 打赏
  • 举报
回复
不要总是考虑通用性。
强大的功能往往都是有针对性的,同时也正是因为了有针对性所以强大。
有针对性的定制软件就可以把价格抬的高高的。

这几个问题不仅涉及堆栈回朔,还涉及代码段回朔,
要问有什么用,不要你想不到用处就说没有用,它的用处大去了,其能力简直是可怕的。rational的软件里大量用了这些技术,它还有更变态的呢,竟然截获OBJ的连接生成过程往里边注入代码,(这连编译器兼容性都没了,但正是这种专门化针对性的东西才可以卖大价钱,通用的大路货没人要)。

这些技术可以实现很多的高端功能,比如自动生成代码时序图等等,(可不是hack gcc然后生成的啊),这在当前rational不支持VS2005的情况下可是很有用的啊,而且可以做得比rational 还好,我可以选择那些函数(包括成员函数)参与代码时序生成。

64,654

社区成员

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

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