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;
}

7609

被折叠的 条评论
为什么被折叠?



