确定被调用的宿主问题

YFLK 2012-05-30 05:32:04
加精
有过程Sub1、Sub2、Sub3、.....,均要调用另外一个S_Sub。
我的问题是如何在S_Sub中确定是那会函数调用了它?当然可以通过在S_Sub中确定返回地址的方法判断调用宿主,也可以用形参实参传递标志的方法或设公用标志变量,但我不想用这些方法。
各位还有方法吗?
...全文
2203 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
YFLK 2012-06-19
  • 打赏
  • 举报
回复
经大家参与讨论。本贴所列问题的解决之路只能是通过栈分析方法。当然也可采用传参和设置标识(前提是Sub1、sub2....和Subs必需采用同样的设计规则,统一规划方可)。
谢谢各位的帮助!
YFLK 2012-06-19
  • 打赏
  • 举报
回复
能用IDA的人不多,特别是你不能因为你的DLL使用了IDA而要求用户用IDA
YFLK 2012-06-18
  • 打赏
  • 举报
回复
to tomsoft
后期的分析可以借助很多工具来达到这样的效果,但是设计者如何将这些工具动态连接到自己的程序中?好象不可能,也不现实。
在自己的DLL中能用你的方法确定调用者?有现成的代码吗?期待中......
「已注销」 2012-06-18
  • 打赏
  • 举报
回复
[Quote=引用 59 楼 yflk 的回复:]

to tomsoft
后期的分析可以借助很多工具来达到这样的效果,但是设计者如何将这些工具动态连接到自己的程序中?好象不可能,也不现实。
在自己的DLL中能用你的方法确定调用者?有现成的代码吗?期待中......
[/Quote]
IDA这样的工具不需要一定在后期分析时采用,工具在于灵活应用;IDA可以对已经运行的DLL或其他常驻系统的程序进行分析;IDA最大的有别于程序设定断定的好处是不需要对程序进行任何修改,也不需要连接什么特定的库 ---- 个人观点是尽量少对程序进行修改:现在很多程序都会使用第三方库;尤其是诸如int 3这样和系统相关的更要谨慎使用
「已注销」 2012-06-16
  • 打赏
  • 举报
回复
补充一下,如果需要生成如上符号表请使用Debug模式,针对Release (商业代码)IDA也可以生成调用、被调用关系。但没有符号表;IDA不仅仅可以帮助分析C/C++,其他一些语言也可以,包括程序流程图绘制 ---- 当然是针对目标代码;
「已注销」 2012-06-16
  • 打赏
  • 举报
回复
为什么都是些很奇怪的方法呢?程序员的任务不是把问题复杂化而是解决问题,忽然看到居然某个大神用汇编,已经被惊倒了 ---- 会汇编很了不起,今天给你换个其他平台玩玩:修改程序已经是比较糟糕的主意了,不就要看这个函数被那些函数调用了,用得着这么麻烦:

是不是这个效果?我想知道_getdrive被谁调用了。使用现成工具IDA就可以了
biololo 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]

狗尾续貂一下。(^_^)
C/C++ code
#include <stdio.h>
void whocallme();
void fun1() {
whocallme();
}
void fun2() {
whocallme();
}
void fun3() {
fun1();
}
void whocallme() {
int *_esp,i;
__……
[/Quote]
43楼,这段代码我在VC++ 2008 下执行,无论开不开Debug都得不到预期的结果。主要是以下两句

if ((int)fun1<=_esp[i+2] && _esp[i+2]<(int)fun2) printf("fun1 callme\n");
if ((int)fun2<=_esp[i+2] && _esp[i+2]<(int)fun3) printf("fun2 callme\n");

这两句if的条件判断始终为false,所以后面的printf语句始终不能执行到。
我想43楼在看完前面提到的那篇blog没有很好的理解其中的意思,
因为
(int)fun1

指的是代码段地址,

_esp[i+2]

中存储的是栈地址。
同时,在那篇博客中的代码已经明确表示:只能通过返回地址获得主调函数的栈地址,但是不加debug信息,很难通过栈数据反过来获得代码段数据,而且你也无法仅仅只通过地址而获得函数的名称,因为名称信息在编译的时候已经被翻译成段地址了。

我不知道在开debug时,运行时信息是怎么样的,但一定会丰富,不过可能不同编译器编译出的RTL会不一样,也许没有一个通用的解决方案。

总的来说,我觉得这个问题其实是由于楼主程序结构设计不合理造成的。如果你一定要在被调函数中知道主调函数是谁,其实就是需要一个外部状态来决定函数的执行行为。
YFLK 2012-06-14
  • 打赏
  • 举报
回复
to 54楼Sender是控件的触发事件产生的,其中确实有主调函数的相关信息。可是Sub1调用Sub_S是最原始的过程调用,已知的可利用信息只有在堆栈中找。
haitao 2012-06-13
  • 打赏
  • 举报
回复
delphi的事件都有一个sender参数,就是事件触发时的被操作者(按钮、列表。。。。)
可以参考借鉴一下,只是接口都需要修改了
YFLK 2012-06-11
  • 打赏
  • 举报
回复
to 50楼,对于模块设计来说,当然越简单也就越可靠越好。可是在很多情况下简单并不能解决问题。比如插件模块用你说的方法就不行。因为Sub1、Sub2不是你自己设计的。这就是为什么在主楼说明中将这种方法排除在外的原因。
xiying12571 2012-06-10
  • 打赏
  • 举报
回复
这些方法还不错
stl_market 2012-06-08
  • 打赏
  • 举报
回复
好方法,值 得学习
Clonne 2012-06-08
  • 打赏
  • 举报
回复
我否定楼上所有的做法,我觉得越简单越好,直接使用一个静态变量,在调用S_Sub之前设置静态变量的值,在S_Sub中判断静态变量的值就知道了。如果不需要并发那这个方法是最佳的。
IKEA66 2012-06-08
  • 打赏
  • 举报
回复
虽不懂,但可以学习中
失散糖 2012-06-08
  • 打赏
  • 举报
回复
虽不懂,但觉厉
tanshikao 2012-06-07
  • 打赏
  • 举报
回复
都是好方法,值 得学习
YFLK 2012-06-06
  • 打赏
  • 举报
回复
现在打开了,谢谢!我看看
金卯刀 2012-06-06
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 的回复:]

33楼的连接打不开。麻烦核实一下好吗?
[/Quote]
是可以打开的
YFLK 2012-06-06
  • 打赏
  • 举报
回复
33楼的连接打不开。麻烦核实一下好吗?
摸石头不过河 2012-06-06
  • 打赏
  • 举报
回复
谢谢链接
加载更多回复(26)

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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