Ada语言嵌套子程序之间参数传递的逆向分析

Ada语言提供了嵌套子程序(Nested Subprograms),这是Ada中实现代码模块化和信息隐藏的重要设施,它允许在主程序或另一个子程序内部定义和调用函数(Function)或过程(Procedure),这些内部子程序能访问外部(包围)作用域的变量,形成强大的作用域规则。

with Ada.Text_IO; use Ada.Text_IO;

procedure try_nested_proc_main is
   procedure Outer_Procedure;
   procedure Outer_Procedure is
      X : Integer;

      procedure Inner_Procedure (Y : Integer);
      procedure Inner_Procedure (Y : Integer) is
      begin
         Put_Line ("Inner_Procedure: X = " & X'Image & ", Y = " & Y'Image);
      end Inner_Procedure;

   begin
      Put_Line ("Outer_Procedure start");
      X := 5;
      Inner_Procedure (10);
      Put_Line ("Outer_Procedure end");
   end Outer_Procedure;
begin
   Outer_Procedure;
end try_nested_proc_main; 

对于这类程序被编译后的可执行文件,目前手头的IDA不能识别其中嵌套子程序之间的参数传递。请看以下由IDA生成的一段伪代码(与上述Ada示例程序无关):

int __cdecl page_s_duplicate__cmd_duplicate_l1_l5__index_point_selected_0(unsigned __int8 a1, unsigned __int8 a2)
{
  int v2; // ecx
  int v3; // ebx
  int v4; // esi

  v3 = v2;
  v4 = 1;
  context__read_var_value(a1, 603, v2 - 656, 0, 0);
  if ( *(_BYTE *)(v3 - 655) != 2 )
  {
    if ( mmi_application_types__t_data_formatD4(*(_BYTE *)(v3 - 656)) )
      __gnat_rcheck_02("page_s_duplicate.adb", 1097);
    return a2 - 15 + 5 * *(_DWORD *)(v3 - 652) - 5;
  }
  return v4;
}
// A870F7: variable 'v2' is possibly undefined

以下是上述伪代码中最初两行赋值语句对应的汇编代码:

.text:00A870F7 mov     ebx, ecx ;v3 = v2;
.text:00A870F9 mov     esi, 1 ;v4 = 1;

IDA也注明了v2就是ecx。

以下是调用上述函数的汇编代码:

.text:00A87AA2 push    eax
.text:00A87AA3 push    ebx
.text:00A87AA4 lea     ecx, [ebp+var_18]
.text:00A87AA7 call    _page_s_duplicate__cmd_duplicate_l1_l5__index_point_selected_0

由此可见,ecx的值来源于变量var_18的地址。var_18是调用者函数中的局部变量。

但是,IDA没有处理“lea     ecx, [ebp+var_18]”。

根据上下文分析,传递到函数中的var_18的地址都被再次计算(例如,v2 – 656)后再作为指针使用。

经过计算后的地址,是另一个具有结构类型的变量var_2A8及其分量的地址。

因此,把原来的伪代码修改为以下C代码:

static integer32 page_s_duplicate__cmd_duplicate_l1_l5__index_point_selected_0_A870EC
(
  unsigned8 arg_0,
  unsigned8 arg_4,
  mmi_application_types__data_format_t* var_2A8 //增加
)
{
  //int v2; // ecx
  //int v3; // ebx
  integer32 v4; // esi

  //v3 = v2;
  v4 = 1;
  context__read_var_value_47A817(
    arg_0, 
    603,
    var_2A8,//&v2 - 656, 0x18+656=0x2A8
    0, 
    0);
  //if ( *(unsigned8 *)(v3 - 655) != 2 )
  if (var_2A8->_1 != 2)
  {
    if ( mmi_application_types__t_data_formatD4_450149(var_2A8->_0)) //(v3 - 656)._0) )
      __gnat_rcheck_02_C386A8("page_s_duplicate.adb", 1097);
    //return arg_4 - 15 + 5 * *(unsigned32 *)(v3 - 652) - 5;
    return arg_4 - 15 + 5 * var_2A8->formatD4._4 - 5;
  }
  return v4;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值