展开中的状态是什么意思?

逆向工程 x86 微信
2021-06-13 18:39:13

我在看UnwindMapEntry这是它的声明:

//
// UnwindMapEntry - Description of each state transition for unwinding
//  the stack (i.e. calling destructors).
//
// The unwind map is an array, indexed by current state.  Each entry specifies
// the state to go to during unwind, and the action required to get there.
// Note that states are represented by a signed integer, and that the 'blank'
// state is -1 so that the array remains 0-based (because by definition there
// is never any unwind action to be performed from state -1).  It is also
// assumed that state indices will be dense, i.e. that there will be no gaps of
// unused state indices in a function.
//

typedef const struct _s_UnwindMapEntry {
    __ehstate_t toState;                    // State this action takes us to
#if _EH_RELATIVE_FUNCINFO
    int         action;                     // Image relative offset of funclet
#else
    void        (__cdecl * action)(void);   // Funclet to call to effect state change
#endif
} UnwindMapEntry;

对不起,如果这对您来说很明显,但是 toState 是什么意思?通过阅读上面的描述,我并不清楚。

还有一个 tryblockmaprntry 的结构,它也以某种方式涉及:

//
// HandlerMapEntry - associates a handler list (sequence of catches) with a
//  range of eh-states.
//
typedef const struct _s_TryBlockMapEntry {
    __ehstate_t     tryLow;             // Lowest state index of try
    __ehstate_t     tryHigh;            // Highest state index of try
    __ehstate_t     catchHigh;          // Highest state index of any associated catch
    //....

什么catchHigh- 总是这样tryHigh + 1吗?

好的 似乎catchHigh是在继续 catch 块内的状态 - 因为你也可以在那里有异常。但我仍然没有看到它的目的 - 就像这个领域有什么不同一样。

1个回答

所述__ehstate_t类型定义为INTtoState是数组中需要展开的下一个处理程序的索引。

Action是为了达到下一个状态(toState的值而需要完成的操作这一直发生到toState达到 -1,这是结束展开过程的“空白”状态。

每次进入 try 块或以其他方式创建一个对象时,如果在调用其析构函数的程序之前抛出异常,则必须在展开过程中销毁该对象时,状态都会增加 1。

例子:

说有一个函数 int F1(){}

在函数开始时,当前作用域状态为 -1,因为如果发生异常,则不会采取任何措施。

在 F1 开始之后的某个地方创建了一个 ClassA 类型的对象。这将调用构造函数ClassA::ClassA()此时如果抛出异常,则有一个ClassA对象需要在catch调用block之前删除对象的初始化将状态增加到 0。

现在出现一个try块 - 现在状态为 1。如果这里抛出异常,处理程序将不得不离开try块 (state->0) 并调用ClassA::~ClassA()之前创建的对象 (state->-1)。如果执行到达try的末尾并且没有发生异常,则状态递减(再次状态-> 0)。

tryLow是处理程序在调用catch之前必须达到的目标最外层状态在我们的示例中,当进入try块(状态 = 1)时,tryLow值将为 -1。处理程序必须进入状态 -1,即离开try调用ClassA::~ClassA(),然后才调用catch块。

出于逆向工程的目的,OpenRCE 上有一篇很棒的帖子:

http://www.openrce.org/articles/full_view/21