【问题标题】:Assembly Language (Find the following query as mentioned below)汇编语言(找到以下查询,如下所述)
【发布时间】:2018-01-07 21:10:07
【问题描述】:

在以下代码和查询方面需要帮助。

我对下面代码的理解表明它会陷入无限循环。

  1. DemoFunction2 的返回值是多少?
  2. DemoFunction2 的目的是什么?

    //
    
    0:000> uf    010024d0
    
    asmdemo2!DemoFunction2:
    
    010024d0 55                push    ebp
    
    010024d1 8bec              mov     ebp,esp                
    
    010024d3 8b5508            mov     edx,dword ptr [ebp+8] 
    
    010024d6 33c0              xor     eax,eax               
    
    010024d8 b920000000        mov     ecx,20h              
    
    010024dd d1ea              shr     edx,1               
    
    010024df 7301              jnc     asmdemo2!DemoFunction2+0x12 (010024e2)
    
    010024e1 40                inc     eax                   
    
    010024e2 e2f9              loop    asmdemo2!DemoFunction2+0xd (010024dd)
    
    010024e4 5d                pop     ebp
    
    010024e5 c3                ret
    
    
    0:000> r
    eax=80002418    ebx=7ffd7000    ecx=00682295   edx=00000000   esi=80002418 
    edi=00000002
    eip=010024d0   esp=0006fe98    ebp=0006fea8    iopl=0         nv up ei pl zr na 
    pe nc
    cs=001b    ss=0023   ds=0023   es=0023   fs=003b   gs=0000             
    efl=00000246
    
    asmdemo2!DemoFunction2:
    
    010024d0 55              push    ebp
    
    0:000> dps   esp
    
    0006fe98  0100251c asmdemo2!main+0x20
    
    0006fe9c  80002418
    
    0006fea0  00000002 
    
    0006fea4  00000000
    
    0006fea8  0006ff88
    
    0006feac  01002969 asmdemo2!_mainCRTStartup+0x12c
    
    0006feb0  00000002
    
    0006feb4  00682270
    
    0006feb8  006822b8
    
    0006febc  f395c17d
    
    0006fec0  00000000
    
    0006fec4  00000000
    
    0006fec8  7ffd7000
    
    0006fecc  00000000
    
    0006fed0  00000000
    
    0006fed4  00000000
    
    0006fed8  00000094
    
    0006fedc  00000006
    
    0006fee0  00000000
    
    0006fee4  00001771
    
    0006fee8  00000002
    
    0006feec  76726553
    
    0006fef0  20656369
    
    0006fef4  6b636150
    
    0006fef8  00003120
    
    0006fefc  00000000
    
    0006ff00  00000000
    
    0006ff04  00000000
    
    0006ff08  00000000
    
    0006ff0c  00000000
    
    0006ff10  00000000
    
    0006ff14  00000000
    

【问题讨论】:

  • ECX 设置为 32。每次执行循环指令时,ECX 都会减 1。这种情况一直持续到 0。EDX 从传递的第一个参数的值开始。在每次迭代中,值(在 EDX 中)右移 1 位。最右边位的值将被移出并移入进位标志。当进位标志置位时,EAX 加 1,否则 EAX 不变。这样做了 32 次,实际上计算了所有设置为 1 的位。
  • @Harun:LOOP instruction 不是无条件的。它会将 ECX 减 1,然后比较 ECX 是否为 0。如果它不为零,则循环分支回到指定的偏移量,否则 ECX 为 0 和它在循环指令之后进入下一条指令
  • LOOP 指令每次执行都会将 ECX 减一。如果 ECX 中的值变为 0,则循环退出。这就是循环结束的方式 - 当 ECX 达到 0 时。EAX 用作计数器来跟踪设置为 1 的移出位数。
  • 如果我在问题中正确读取了堆栈输出,则 EBP+8 处的值(与推送 EBP 后的 ESP+4 相同) 是 0x80002418。 0x8002418 = 二进制 10000000000000000010010000011000 。有 5 位设置为 1。当此函数退出时,EAX 的值为 5。
  • 循环总是执行 32 次(ECX 最初设置为 0x20=32 十进制)。 SHR 指令在每个循环中执行一次。如果设置了右移位,则进位标志 (CF) 将被设置并且 EAX 加 1 并继续循环。如果 CF 清零(未设置移出的位)EAX 不会递增并且循环继续。

标签: assembly x86 reverse-engineering


【解决方案1】:

不,这不是无限循环。

一开始ecx设置为32。
每次loop instruction 执行时,ecx 减 1。
当 ecx 达到 0 时,循环指令将通过(而不是跳转),之后的指令将被执行(pop+ret)。

显然代码效率低。

一个简单的

popcnt eax,[esp+4]
ret

会更快地执行相同的功能,但它确实有效。

它使用 cdecl 调用约定计算第一个参数中设置的位数。

【讨论】:

    猜你喜欢
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 2016-03-06
    相关资源
    最近更新 更多