我有一个问题,就像这个问题一样。现代的编译器不使用ebp处理局部变量和参数,它们只是计算并向esp添加硬编码偏移量。示例:

sub     esp, 5Eh  
...     
mov     [esp+5Eh+var_1], 123h
mov     [esp+5Eh+var_2], 456h
call    some_func            ; var_1 and var_2 point to actual addresses
cmp     eax, 0               ; esp changed (stdcall), var_1 and var_2 point to wrong addresses

...

;  creation of a "fake" variable example:
;  var_3 = -8h
;  var_4 = -12h 
mov     [esp+5Eh+var_3], 78h  ; var_3 at: esp + 5Eh -8h
pop     eax                   ; esp = esp + 4  
mov     [esp+5Eh+var_4], 89h  ; var_4 at: esp + 4  + 5eh -12h = esp + 5Eh -8h = var_3
; desireable fix:
mov     [esp+62h+var_3], 89h 


这会导致大量开销:IDA创建“伪”局部变量(即,一个和一个相同地址的多个名称),您不能随时随地自由检查变量,必须创建其他注释,等等。所以我想知道是否有任何方法可以解决该问题?

PS。我正在使用IDA Pro Free。告诉我是否只有IDA Pro(完整版)才有可能。

#1 楼

IDA生成的变量名不是“ fake”。它们与如果基于ebp的功能将被标记的标签完全相同。您描述的问题仅在调试时才是真正的问题,因为这是您只能检查所指向的值的时间。我不知道让IDA显示您想要的任何内置方法。当您将鼠标悬停在操作数上时,IDA只会获取寄存器的当前值并加上偏移量。如果esp更改了,那么它将显示给您错误的地址,这就是您在示例中看到的地址。要求写一个IDC脚本来检查eip,并在计算最终目标地址之前调整esp值的差异。在给定地址获取堆栈偏移的IDC函数是GetSpd()。该算法将如下所示:


计算您感兴趣的操作数的目标地址(即esp + 5Eh + var_1-> 0x10000000)
获取堆栈指针包含您感兴趣的操作数的行的SPD(即5Eh)
获得eip的SPD(即6Eh)
计算两个SPD的差并加(或减)从您在步骤1中计算出的目标地址开始的金额(即0x10000000 +(6Eh-5Eh)= 0x10000010)

评论


非常感谢您的回答,现在我知道IDA Pro中没有针对该问题的工具,因此我应该编写自己的脚本。广告。 (“假”)变量-我更新了我的文章,以便更清楚我的意思。广告。您的算法-这不是那么简单,因为GetSpd()忽略了stdcall函数完成的esp更改。我认为我将采用的方法是编写一个脚本,该脚本将在跟踪所有变量地址的同时运行一个函数,并进行一些访问表示调整(帖子中显示的修复),并最终在注释中写入地址。

– Krzysztof Bracha
2014年5月3日22:37

嗨,看看您的更新,您标记为理想的修复正是我的IDA版本所做的。我想知道这是免费还是付费的区别。我使用IDA 6.2。没错,脚本比我说的要复杂。 :-)我发现堆栈指针增量通常非常准确,但是在最新版本中也可能有所改进。

–bad_decoy
2014年5月3日在22:53

啊,抱歉,创建主题时我没有发布它。我认为这不是免费vs付费的区别,只是免费版本是5.0,自那时以来,hex-rays做了很多改进。再次感谢您,一个可以运行该功能的脚本应该很有用,但是我可能不得不冒着未来的风险,总有一天会购买最新版本的IDA。

– Krzysztof Bracha
2014年5月4日在8:24



#2 楼

将光标置于给定功能的内部,按Alt + P编辑功能属性。在“编辑功能”窗口中,取消选中基于BP的框架,然后按OK。

评论


感谢您的答复,但从未对其进行过检查。

– Krzysztof Bracha
2014年4月30日13:57

这应该是正确的答案。

–alexandernst
17年12月14日在23:10