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