uint64_t windows_get_offset(vmi_instance_t vmi, const char* offset_name) { const size_t max_length = 100; windows_instance_t windows = vmi->os_data; if (windows == NULL) { errprint("VMI_ERROR: OS instance not initialized\n"); return 0; } if (strncmp(offset_name, "win_tasks", max_length) == 0) { return windows->tasks_offset; } else if (strncmp(offset_name, "win_pdbase", max_length) == 0) { return windows->pdbase_offset; } else if (strncmp(offset_name, "win_pid", max_length) == 0) { return windows->pid_offset; } else if (strncmp(offset_name, "win_pname", max_length) == 0) { if (windows->pname_offset == 0) { windows->pname_offset = find_pname_offset(vmi, NULL ); if (windows->pname_offset == 0) { dbprint(VMI_DEBUG_MISC, "--failed to find pname_offset\n"); return 0; } } return windows->pname_offset; } else { warnprint("Invalid offset name in windows_get_offset (%s).\n", offset_name); return 0; } }
void linux_read_config_ghashtable_entries(char* key, gpointer value, vmi_instance_t vmi) { linux_instance_t linux_instance = vmi->os_data; if (strncmp(key, "sysmap", CONFIG_STR_LENGTH) == 0) { linux_instance->sysmap = strdup((char *)value); goto _done; } if (strncmp(key, "rekall_profile", CONFIG_STR_LENGTH) == 0) { linux_instance->rekall_profile = strdup((char *)value); goto _done; } if (strncmp(key, "linux_tasks", CONFIG_STR_LENGTH) == 0) { linux_instance->tasks_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "linux_mm", CONFIG_STR_LENGTH) == 0) { linux_instance->mm_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "linux_pid", CONFIG_STR_LENGTH) == 0) { linux_instance->pid_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "linux_name", CONFIG_STR_LENGTH) == 0) { linux_instance->name_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "linux_pgd", CONFIG_STR_LENGTH) == 0) { linux_instance->pgd_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "ostype", CONFIG_STR_LENGTH) == 0 || strncmp(key, "os_type", CONFIG_STR_LENGTH) == 0) { goto _done; } if (strncmp(key, "name", CONFIG_STR_LENGTH) == 0) { goto _done; } if (strncmp(key, "domid", CONFIG_STR_LENGTH) == 0) { goto _done; } if (strncmp(key, "physoffset", CONFIG_STR_LENGTH) == 0) { goto _done; } warnprint("Invalid offset %s given for Linux target\n", key); _done: return; }
unsigned long vmi_get_offset( vmi_instance_t vmi, char *offset_name) { size_t max_length = 100; if (strncmp(offset_name, "win_tasks", max_length) == 0) { return vmi->os.windows_instance.tasks_offset; } else if (strncmp(offset_name, "win_pdbase", max_length) == 0) { return vmi->os.windows_instance.pdbase_offset; } else if (strncmp(offset_name, "win_pid", max_length) == 0) { return vmi->os.windows_instance.pid_offset; } else if (strncmp(offset_name, "win_pname", max_length) == 0) { if (vmi->os.windows_instance.pname_offset == 0) { vmi->os.windows_instance.pname_offset = find_pname_offset(vmi, NULL); if (vmi->os.windows_instance.pname_offset == 0) { dbprint("--failed to find pname_offset\n"); return 0; } } return vmi->os.windows_instance.pname_offset; } else if (strncmp(offset_name, "linux_tasks", max_length) == 0) { return vmi->os.linux_instance.tasks_offset; } else if (strncmp(offset_name, "linux_mm", max_length) == 0) { return vmi->os.linux_instance.mm_offset; } else if (strncmp(offset_name, "linux_pid", max_length) == 0) { return vmi->os.linux_instance.pid_offset; } else if (strncmp(offset_name, "linux_name", max_length) == 0) { return vmi->os.linux_instance.name_offset; } else if (strncmp(offset_name, "linux_pgd", max_length) == 0) { return vmi->os.linux_instance.pgd_offset; } else { warnprint("Invalid offset name in vmi_get_offset (%s).\n", offset_name); return 0; } }
uint64_t linux_get_offset(vmi_instance_t vmi, const char* offset_name) { const size_t max_length = 100; linux_instance_t linux_instance = vmi->os_data; if (linux_instance == NULL) { errprint("VMI_ERROR: OS instance not initialized\n"); return 0; } if (strncmp(offset_name, "linux_tasks", max_length) == 0) { return linux_instance->tasks_offset; } else if (strncmp(offset_name, "linux_mm", max_length) == 0) { return linux_instance->mm_offset; } else if (strncmp(offset_name, "linux_pid", max_length) == 0) { return linux_instance->pid_offset; } else if (strncmp(offset_name, "linux_name", max_length) == 0) { return linux_instance->name_offset; } else if (strncmp(offset_name, "linux_pgd", max_length) == 0) { return linux_instance->pgd_offset; } else { warnprint("Invalid offset name in linux_get_offset (%s).\n", offset_name); return 0; } }
void windows_read_config_ghashtable_entries(char* key, gpointer value, vmi_instance_t vmi) { windows_instance_t windows_instance = vmi->os_data; if (strncmp(key, "win_ntoskrnl", CONFIG_STR_LENGTH) == 0) { windows_instance->ntoskrnl = *(addr_t *)value; goto _done; } if (strncmp(key, "win_ntoskrnl_va", CONFIG_STR_LENGTH) == 0) { windows_instance->ntoskrnl_va = *(addr_t *)value; goto _done; } if (strncmp(key, "win_tasks", CONFIG_STR_LENGTH) == 0) { windows_instance->tasks_offset = *(int *)value; goto _done; } if (strncmp(key, "win_pdbase", CONFIG_STR_LENGTH) == 0) { windows_instance->pdbase_offset = *(int *)value; goto _done; } if (strncmp(key, "win_pid", CONFIG_STR_LENGTH) == 0) { windows_instance->pid_offset = *(int *)value; goto _done; } if (strncmp(key, "win_pname", CONFIG_STR_LENGTH) == 0) { windows_instance->pname_offset = *(int *)value; goto _done; } if (strncmp(key, "win_kdvb", CONFIG_STR_LENGTH) == 0) { windows_instance->kdbg_va = *(addr_t *)value; goto _done; } if (strncmp(key, "win_sysproc", CONFIG_STR_LENGTH) == 0) { windows_instance->sysproc = *(addr_t *)value; goto _done; } if (strncmp(key, "win_kpcr", CONFIG_STR_LENGTH) == 0) { windows_instance->kpcr_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "win_kdbg", CONFIG_STR_LENGTH) == 0) { windows_instance->kdbg_offset = *(addr_t *)value; goto _done; } if (strncmp(key, "ostype", CONFIG_STR_LENGTH) == 0 || strncmp(key, "os_type", CONFIG_STR_LENGTH) == 0) { goto _done; } /* Deprecated way of using Rekall profiles */ if (strncmp(key, "sysmap", CONFIG_STR_LENGTH) == 0) { windows_instance->rekall_profile = g_strdup((char *)value); goto _done; } if (strncmp(key, "rekall_profile", CONFIG_STR_LENGTH) == 0) { windows_instance->rekall_profile = g_strdup((char *)value); goto _done; } if (strncmp(key, "name", CONFIG_STR_LENGTH) == 0) { goto _done; } if (strncmp(key, "domid", CONFIG_STR_LENGTH) == 0) { goto _done; } warnprint("Invalid offset \"%s\" given for Windows target\n", key); _done: return; }
int run_server(int port, dserve_global_p globalptr) { struct sockaddr_in clientaddr; int rc, sd, connsd, next; thread_data_p tdata; struct common_data *common; long tid, maxtid, tcount, i; size_t clientlen; //struct timeval timeout; #ifdef MULTI_THREAD #if _MSC_VER HANDLE thandle; HANDLE thandlearray[MAX_THREADS]; DWORD threads[MAX_THREADS]; #else pthread_t threads[MAX_THREADS]; pthread_attr_t attr; struct timespec tim, tim2; #endif #ifdef USE_OPENSSL SSL_CTX *ctx; SSL *ssl; #endif #endif #if _MSC_VER void* db=NULL; // actual database pointer WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 0),&wsaData) != 0) { errprint(WSASTART_ERR,NULL); exit(ERR_EX_UNAVAILABLE); } db = wg_attach_existing_database("1000"); //db = wg_attach_database(database,100000000); if (!db) { errprint(DB_ATTACH_ERR,NULL); exit(ERR_EX_UNAVAILABLE); } #else signal(SIGPIPE,SIG_IGN); // important for linux TCP/IP handling #endif tdata=&(globalptr->threads_data[0]); #ifdef MULTI_THREAD #if _MSC_VER #else if (THREADPOOL) { // ---------------- run as server with threadpool ----------- infoprint(THREADPOOL_INFO,NULL); // setup nanosleep for 100 microsec tim.tv_sec = 0; tim.tv_nsec = 100000; #ifdef USE_OPENSSL // prepare openssl ctx=init_openssl(globalptr->conf); #endif // prepare threads common=(struct common_data *)malloc(sizeof(struct common_data)); tid=0; tcount=0; maxtid=0; if (pthread_mutex_init(&(common->mutex),NULL) !=0 || pthread_cond_init(&(common->cond),NULL) != 0 || pthread_attr_init(&attr) !=0) { errprint(MUTEX_ERROR,NULL); exit(ERR_EX_UNAVAILABLE); } common->threads = threads; common->queue = (common_task_t *)malloc(sizeof(common_task_t) * QUEUE_SIZE); common->thread_count = 0; common->queue_size = QUEUE_SIZE; common->head = common->tail = common->count = 0; common->shutdown = common->started = 0; pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); //PTHREAD_CREATE_DETACHED); // create threads for(tid=0;tid<MAX_THREADS;tid++) { // init thread data block tdata[tid].isserver=1; tdata[tid].thread_id=tid; tdata[tid].realthread=2; tdata[tid].common=common; tdata[tid].inuse=0; tdata[tid].conn=0; tdata[tid].ip=NULL; tdata[tid].port=0; tdata[tid].method=0; tdata[tid].res=0; tdata[tid].global=globalptr; //fprintf(stderr,"creating thread %d tcount %d \n",(int)tid,(int)tcount); rc=pthread_create(&threads[tid], &attr, handle_http, (void *) &tdata[tid]); if (rc) { errprint(THREAD_CREATE_ERR,strerror(errno)); exit(ERR_EX_UNAVAILABLE); } tcount++; } // sd=open_listener(port); if (sd<0) { errprint(PORT_LISTEN_ERR, strerror(errno)); return -1; } clientlen = sizeof(clientaddr); // loop forever, servicing requests while (1) { connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen); if (connsd<0) { warnprint(CONN_ACCEPT_WARN, strerror(errno)); continue; } if(pthread_mutex_lock(&(common->mutex)) != 0) { errprint(THREADPOOL_LOCK_ERR,NULL); exit(ERR_EX_UNAVAILABLE); } #ifdef USE_OPENSSL ssl = SSL_new(ctx); // get new SSL state with context SSL_set_fd(ssl,connsd); #endif // now we have a connection: add to queue next=common->tail+1; next=(next==common->queue_size) ? 0 : next; do { if(common->count==common->queue_size) { // full? //fprintf(stderr, "queue full\n"); nanosleep(&tim , &tim2); break; //continue; } if(common->shutdown) { warnprint(SHUTDOWN_WARN,NULL); break; } // add to task queue common->queue[common->tail].conn=connsd; #ifdef USE_OPENSSL common->queue[common->tail].ssl=ssl; #endif common->tail=next; common->count+=1; //printf("next %d\n",next); // broadcast if(pthread_cond_signal(&(common->cond)) != 0) { warnprint(COND_SIGNAL_FAIL_WARN,NULL); break; } } while(0); //fprintf(stderr,"starting to unlock \n"); if(pthread_mutex_unlock(&(common->mutex)) != 0) { errprint(THREADPOOL_UNLOCK_ERR,NULL); exit(ERR_EX_UNAVAILABLE); } } return 0; // never come to this } else #endif // threadpool not implemented on windows version: using a non-threadpool version { // ------------- run as server without threadpool ------------- infoprint(MULTITHREAD_INFO,NULL); // setup nanosleep for 100 microsec #if _MSC_VER #else tim.tv_sec = 0; tim.tv_nsec = 100000; #endif // prepare common block common=(struct common_data *)malloc(sizeof(struct common_data)); common->shutdown=0; // mark thread data blocks free for(i=0;i<MAX_THREADS;i++) { tdata[i].inuse=0; tdata[i].common=common; tdata[i].global=globalptr; } // prepare threads tid=0; tcount=0; maxtid=0; #if _MSC_VER #else pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //PTHREAD_CREATE_JOINABLE); #endif sd=open_listener(port); if (sd<0) { errprint(PORT_LISTEN_ERR, strerror(errno)); return -1; } clientlen = sizeof(clientaddr); while (1) { connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen); if (common->shutdown==1) break; if (connsd<0) { warnprint(CONN_ACCEPT_WARN, strerror(errno)); continue; } tid=-1; // find first free thread data block // loop until we get a free one while(tid<0) { for(i=0;i<MAX_THREADS;i++) { if (!tdata[i].inuse) { tid=i; break; } } if (tid>=0) break; #if _MSC_VER usleep(1); #else nanosleep(&tim , &tim2); #endif } if (tid>maxtid) maxtid=tid; tcount++; // init thread data block tdata[tid].isserver=1; tdata[tid].thread_id=tid; tdata[tid].realthread=1; tdata[tid].inuse=1; tdata[tid].conn=connsd; tdata[tid].ip=NULL; tdata[tid].port=0; tdata[tid].method=0; tdata[tid].res=0; tdata[tid].global=globalptr; #if _MSC_VER tdata[tid].db=db; thandle=CreateThread(NULL, 0, handle_http, (void *) &tdata[tid], 0, &threads[tid]); if (thandle==NULL) { win_err_handler(TEXT("CreateThread")); ExitProcess(3); } else { thandlearray[tid]=thandle; } #else rc=pthread_create(&threads[tid], &attr, handle_http, (void *) &tdata[tid]); #endif } return 0; // never come to this } #else // ------------ run as an iterative server ------------- sd=open_listener(port); if (sd<0) { errprint(PORT_LISTEN_ERR, strerror(errno)); return -1; } clientlen = sizeof(clientaddr); while (1) { connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen); if (connsd<0) { warnprint(CONN_ACCEPT_WARN, strerror(errno)); continue; } tid=0; tdata[tid].isserver=1; tdata[tid].thread_id=tid; tdata[tid].realthread=0; tdata[tid].conn=connsd; tdata[tid].ip=NULL; tdata[tid].port=0; tdata[tid].method=0; tdata[tid].res=0; tdata[tid].global=globalptr; #if _MSC_VER tdata[tid].db=db; #endif handle_http((void *) &tdata[tid]); } return 0; // never come to this #endif }
DWORD WINAPI handle_http(LPVOID targ) { #else void *handle_http(void *targ) { #endif int connsd,i,tid,itmp,len=0; char *method=NULL, *uri=NULL, *version=NULL, *query=NULL; char *bp=NULL, *res=NULL; char buf[MAXLINE]; char header[HTTP_HEADER_SIZE]; thread_data_p tdata; struct common_data *common; socklen_t alen; struct sockaddr_storage addr; struct sockaddr_in *s4; struct sockaddr_in6 *s6; char ipstr[INET6_ADDRSTRLEN]; int port; #ifdef USE_OPENSSL SSL* ssl=NULL; #else void* ssl=NULL; #endif #if _MSC_VER #else struct timespec tim, tim2; tim.tv_sec = 0; tim.tv_nsec = 1000; #endif tdata=(thread_data_p) targ; tid=tdata->thread_id; common=tdata->common; while(1) { // infinite loop for threadpool, just once for non-threadpool if ((tdata->realthread)!=2) { // once-run thread connsd=tdata->conn; } else { // threadpool thread #ifdef MULTI_THREAD #if THREADPOOL pthread_mutex_lock(&(common->mutex)); while ((common->count==0) && (common->shutdown==0)) { itmp=pthread_cond_wait(&(common->cond),&(common->mutex)); // wait if (itmp) { errprint(COND_WAIT_FAIL_ERR,NULL); exit(ERR_EX_UNAVAILABLE); } } if (common->shutdown) { pthread_mutex_unlock(&(common->mutex)); // ? warnprint(SHUTDOWN_THREAD_WARN,NULL); tdata->inuse=0; pthread_exit((void*) tid); return NULL; } #endif #endif connsd=common->queue[common->head].conn; #ifdef USE_OPENSSL ssl=common->queue[common->head].ssl; if (SSL_accept(ssl)==-1) { SSL_free(ssl); ssl=NULL; //fprintf(stderr,"ssl accept error\n"); //ERR_print_errors_fp(stderr); } //ShowCerts(ssl); #endif common->head+=1; common->head=(common->head == common->queue_size) ? 0 : common->head; common->count-=1; #ifdef MULTI_THREAD #if THREADPOOL pthread_mutex_unlock(&(common->mutex)); #endif #endif } // who is calling? alen = sizeof addr; getpeername(connsd, (struct sockaddr*)&addr, &alen); if (addr.ss_family == AF_INET) { s4 = (struct sockaddr_in *)&addr; port = ntohs(s4->sin_port); #if _MSC_VER InetNtop(AF_INET, &s4->sin_addr, ipstr, sizeof ipstr); } else { // AF_INET6 s6 = (struct sockaddr_in6 *)&addr; port = ntohs(s6->sin6_port); InetNtop(AF_INET6, &s6->sin6_addr, ipstr, sizeof ipstr); } #else inet_ntop(AF_INET, &s4->sin_addr, ipstr, sizeof ipstr); } else { // AF_INET6