OllyDBG 之旅 (五)

00401431  |.  8D35 9C334000 lea     esi, dword ptr [40339C]
00401437  |.  0FB60D EC3340>movzx   ecx, byte ptr [4033EC]
0040143E  |.  33FF          xor     edi, edi
00401440  |>  8BC1          mov     eax, ecx
00401442  |.  8B1E          mov     ebx, dword ptr [esi]
00401444  |.  F7E3          mul     ebx
00401446  |.  03F8          add     edi, eax
00401448  |.  49            dec     ecx                                                              让ECX寄存器自减一,
00401449  |.  83F9 00       cmp     ecx, 0
0040144C  |.^ 75 F2         jnz     short 00401440
0040144E  |.  893D 9C334000 mov     dword ptr [40339C], edi
00401454  |.  61            popad

lea     esi, dword ptr [40339C]
   lea 目的地址传送指令. 将  40339C 这个值放到 esi 寄存器

movzx   ecx, byte ptr [4033EC]  
MOVZX指令将他的源操作数0扩展为他的目标操作数的长度(即不保留最高位的符号属性),然后将结果复制到目标操作数中。 
            movzx   eax,   bx      
    等价于  
            xor   eax,eax  
            mov   ax,bx   
  前者目标码代码较小,后者   速度更快(在主流CPU)    


0040143E  |.  33FF          xor     edi, edi                                           将 edi 清零
00401440  |>  8BC1          mov     eax, ecx                                      将 ecx 的值赋值到 eax  (ecx 现在等于 3) <======     0040144C  |.^ 75 F2         jnz     short 00401440
00401442  |.  8B1E          mov     ebx, dword ptr [esi]                      将 esi 所指向的地址的值赋给 ebx ,  这里是dword,即四个字节,将 卷标的前四个字节的值赋给 ebx 
00401444  |.  F7E3          mul     ebx
00401446  |.  03F8          add     edi, eax
00401448  |.  49            dec     ecx                                                              让ECX寄存器自减一,
00401449  |.  83F9 00       cmp     ecx, 0
0040144C  |.^ 75 F2         jnz     short 00401440                                <==== 这里做了一个循环
0040144E  |.  893D 9C334000 mov     dword ptr [40339C], edi
00401454  |.  61            popad

mul
MUL,将AL,AX或EAX与源操作数相乘。
如果源操作数是8位的,则与AL相乘,积存储在AX中
如果源操作数是16位的,则与AX相乘,积存储在DX:AX中
如果源操作数是32位的,则与EAX相乘,积存储在EDX:EAX中   EDX 为高位
    你例句的操作数为10000h,已经不是16位了,故它因该是存储在一个32位寄存器中。
    依照以上第三条,与EAX相乘,最大情况为2的15次方乘以2的15次方=2的16次方,EDX:EAX满足条件存储,而10000h就更不用说了

POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.


esi = 40339c
ecx = 3
edi = 0

第一次循环
:again
eax = ecx (3)
ebx = 'ABCD'
eax = eax * ebx   (3 * 0x44434241) = CCC9C6C3   (32位相乘高位在 EDX, 低位在 EAX)
edi = edi + eax   (0 + CCC9C6C3) = CCC9C6C3
ecx--
if ecx != 0  then goto again

第二次循环
:again
eax = ecx (2)
ebx = 'ABCD'
eax = eax * ebx   (2 * 0x44434241) = 88868482 (32位相乘高位在 EDX, 低位在EAX)
edi = edi + eax   (CCC9C6C3 + 88868482) = 155504B45 (此处溢出,edi只取得 55504B45)
ecx--
if ecx != 0 then goto again

第三次循环
:again
eax = ecx (1)
ebx = 'ABCD'
eax = eax * ebx (1* 0x44434241) = 0x44434241  (32位相乘高位在 EDX, 低位在EAX)
edi = edi + eax (0x55504B45 + 0x44434241) = 99938D86
ecx--

经过三次循环
经过计算的值放在 edi

经过
0040144E  |.  893D 9C334000 mov     dword ptr [40339C], edi

edi 的值放在 40339C 这个内存地址

0040339C  86 8D 93 99 45 46 47 48 49 4A 00 00 00 00 00 00  啀摍EFGHIJ......
004033AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ...............

经过推算,不难将它转成C++代码

#include <iostream>
#include <windows.h>
#include <memory.h>
using namespace std;

int main()
{
 int nDriveType = ::GetDriveType(NULL);

 char szBuf[11] = {0};
    ::GetVolumeInformation(NULL, szBuf, 11, NULL, NULL, NULL, NULL, NULL);

 UINT nResult = 0;
 for( int i=3; i>0; i-- )
 {
  UINT nValue = 0;
  memcpy(&nValue, szBuf, 4);

  nValue *= i;
  nResult += nValue;
 }

 nResult ^= 0x797A7553;

 std::cout << nResult << std::endl;

 return 0;
}
 

你可能感兴趣的:(OllyDBG 之旅 (五))