Porting Across UNIX and Win32 by Abdul Sakib Mondal Example 1: #ifdef WIN32 VOID ServiceStart (DWORD argc, LPTSTR *argv) #endif #ifdef UNIX int main(int argc,char *argv[]) #endif { /**Main work is done here**/ } Listing One /***************CODE FOR SUN OS**********************************/ /* The kvm routines are used to read certain information from the kernel */ kvm_t *mptr; /* Pointer to kmem */ struct proc *process; /* Pointer to proc structure */ struct user *user; /* Pointer to user structure */ struct file ofile; /* File structure of an object */ struct file *fileptr; /* Pointer to above structure */ struct ucred credits; /* Process credentials */ /*Open /dev/kmem */ if (!(mptr = kvm_open((char *)0, (char *)0, (char *)0,O_RDONLY, (char *)0 ))) exit (-1); /*read process-structure of the process with pid what->proc_nr*/ process = kvm_getproc(mptr, what->proc_nr); /* read the credentials of the process */ if(kvm_read(mptr, process->p_cred, (char *)&credits, sizeof (credits)) != sizeof (credits)){ exit(-1); } /*you can verify for effective and real uids and gids, and user groups of the process using members cr_uid, cr_gid, cr_ruid, cr_rgid, cr_groups[] of credits */ /*Given a file/socket descriptor (what->sock_nr), if you want to determine properties of the corresponding object, you need to read the ofile structure of the object, but for this you have to first read user structure from the kernel */ if((user = kvm_getu(mptr, process)) == NULL){ exit(-1); } /*Now, read the ofile structure */ if (what->sock_nr < NOFILE_IN_U) {/* if the file structure is in the user-area */ if(kvm_read(mptr, user->u_ofile_arr[what->sock_nr], (char *) &ofile, sizeof (struct file)) != sizeof (struct file)){ exit(-1); } } else/* if the file structure is not in the user-area */{ if (kvm_read(mptr, (user->u_ofile + ((what->sock_nr - NOFILE_IN_U) * sizeof (struct file *))),(char *) &fileptr, sizeof (struct file *)) != sizeof (struct file *)){ exit(-1); } if (kvm_read(mptr, fileptr, (char *) &ofile, sizeof (struct file)) != sizeof (struct file)){ exit(-1); } } /* Now we can use the structure to extract further details of the object (example type of the object, permissions, group owner etc. if the object is file, port, domain, protocol etc. if the object is socket etc.)*/ /******************CODE FOR LINUX***********************************/ * Unlike SUN OS where, task structures are maintained as linked list* * Linux keeps an array of entires for task structures. Additional * * information (such as files opened etc.) are available through a * * pointer in the entry. * *********************************************************************/ #define __KERNEL__ #define TASK 0x001d61f4 #ifdef OLDLNUX #define FD0 ((char *)&ts.files->fd[0] - (char *)&ts) #define AD(fd) (task_addr +FD0+4*(fd)) #else #define FILES ((char *)&ts.files - (char *)&ts) #define FD0 ((char *)&fs.fd[0] - (char *)&fs) #define AD(fd) (readvalz(task_addr +FILES)+FD0+4*(fd)) #endif int kfd; /* File Pointer to /dev/kmem */ int task_addr; struct task_struct ts; /*task structure*/ struct files_struct fs; /*file system structure*/ struct file ofile; /*File structure of an object */ struct file *fileptr; /*Pointer to above structure */ struct uid_credit{ /*process credential*/ unsigned short uid,euid,suid,fsuid; unsigned short gid,egid,sgid,fsgid; }credits; int procgrps[NGROUPS]; /*process groups*/ /******************************************************************* * read an entry from the array in symbol table * ********************************************************************/ int readval(int ad){ int val,r; if (lseek(kfd,ad,SEEK_SET)<0){ perror("lseek"); exit(1); } if((r=read(kfd,&val,4))!=4){ if (r<0) perror("read"); else fprintf(stderr,"Error reading ..\n"); exit(1); } return val; } /******************************************************************* * read value at specified location, error if value is 0 * ********************************************************************/ int readvalz(int ad){ int r=readval(ad); if(r==0) fprintf(stderr,"Error reading ..\n"); return r; } /******************************************************************** * to read the additional information, we require the id of the * * process corresponding to this entry * *********************************************************************/ void readtask(int ad){ int r; if (lseek(kfd,ad,SEEK_SET)<0) perror("lseek"), exit(1); if((r=read(kfd,&ts,sizeof(struct task_struct)))!=sizeof(struct task_struct)){ if (r<0) perror("read"); else fprintf(stderr,"Error reading ..\n"); exit(1); } } /******************************************************************* * find the task structure of specified process * ********************************************************************/ void findtask(int pid){ int kadr; for(kadr=TASK;;kadr+=4){ /*TASK is starting address for symbol table: differs from installation to * installation. Its value can be found from /boot/System.map */ if (kadr>=TASK+4*NR_TASKS){ /*NR_TASK indicates number of tasks*/ fprintf(stderr,"Proc not found ..\n"); } task_addr=readval(kadr); readtask(task_addr); if (ts.pid==pid) break; } } /******************************************************************* * read process credentials * ********************************************************************/ void readcred(struct uid_credit *credits){ int r; int ad= task_addr +(char *)&ts.uid-(char *)&ts; if (lseek(kfd,ad,SEEK_SET)<0) perror("lseek"), exit(1); if((r=read(kfd,credits,sizeof(struct uid_credit)))!= sizeof(struct uid_credit)){ if (r<0) perror("read"); else fprintf(stderr,"Error reading ..\n"); exit(1); } } /******************************************************************* * read process user groups * ********************************************************************/ void readgroups(int *procgrps){ int r; int ad= task_addr +(char *)&ts.groups[0]-(char *)&ts; if (lseek(kfd,ad,SEEK_SET)<0) perror("lseek"), exit(1); if((r=read(kfd,procgrps,NGROUPS*sizeof(int)))!=NGROUPS*sizeof(int)){ if (r<0) perror("read"); else fprintf(stderr,"Error reading ..\n"); exit(1); } } /******************************************************************* * read file structure for a given kernel object * ********************************************************************/ void readfile(int sock_nr, struct file *fileptr){ int r; int ad=AD(sock_nr); if (lseek(kfd,ad,SEEK_SET)<0) perror("lseek"), exit(1); if((r=read(kfd,(char *)fileptr,sizeof(struct files_struct) ))!=sizeof(struct files_struct)){ if (r<0) perror("read"); else fprintf(stderr,"Error reading ..\n"); exit(1); } } kfd=open("/dev/kmem",O_RDONLY); if (kfd<0) { perror("open"); exit(1);} /* read the task structure first */ findtask(what->proc_nr); /* read the credentials of the process */ readcred(&credits); /* read the user groups of the process*/ readgroups(procgrps); /*you can verify for effective and real uids and gids, and user groups of the process using members uid, gid, euid, egid of credits and procgrps */ /* read the ofile structure for the give descriptor (what-> sock_nr) */ readfile(what->sock_nr,&ofile); /* Now we can use the structure to extract further details of the object (example type of the object, permissions, group owner etc. if the object is file, port, domain, protocol etc. if the object is socket etc.)*/ 4