我最近开始学习装配,以便进行逆向工程。我正在阅读Practical Reverse Engineering并在其中看到了以下汇编代码:

loop_start:
  mov eax, [edi+4]
  mov eax, [eax+ebx*4]
  test eax, eax
  ... //They also did the dots here
  jz short loc_7F627F
loc_7F627F:
  inc ebx
  cmp ebx, [edi]
  jl short loop_start


然后他们告诉该信息应该给我们这个主意,将其反编译为该主意(我正在将所有点精确地放置在它们做的地方):

typedef struct _Foo
{
  DWORD size;
  DWORD array[...];} FOO, *PFOO;

  PFOO bar= ...;

  for(i= ...; i < bar->size; i++)
  {
    if(bar->array[i] != 0){
    ...
  }
}


但是因为jz short loc_7F627F仅在eax的内容为零的情况下才会跳转,所以...不应该在jz之后而不是在jz之前吗?否则,这意味着我要测试eax的内容(是否为零),然后执行一些未知的操作,然后在该内容为零时跳转(前提是...中没有其他指令会影响ZF标志) ,似乎与他们编写的C代码不匹配。

最佳答案

这部分:

loc_7F627F:
inc ebx
cmp ebx, [edi]
jl short loop_start


转换为:

for(i= ?; i < bar->size; i++){
    //do something
    }
}


这部分

mov eax, [edi+4]
mov eax, [eax+ebx*4]
test eax, eax
... //They also did the dots here
jz short loc_7F627F


(不)翻译为:

if(bar->array[i] != 0){
  ...
}


你是对的。
...仅在array[i] <> 0时执行,因此Assembly语句中的...应该在jz skip_to_next_loop_iteration之后,而不是之前。

通常,在loc_7F627F之后也应该无条件跳转到...;但是,在这种情况下,第一个...之后的代码可以直接进入for循环。

08-17 05:30