void setBindConnectReturnValue(struct tcb* tcp) { int sockfd = tcp->u_arg[0]; char *pidkey = db_read_pid_key(currdb, tcp->pid); char* prov_pid = getMappedPid(pidkey); // convert this pid to corresponding prov_pid ull_t sockid = db_getConnectCounterInc(currdb, pidkey); int u_rval = db_getSockResult(netdb, prov_pid, sockid); // get the result of a connect call //~ vbp(3, "here\n"); // return recorded result struct user_regs_struct regs; long pid = tcp->pid; EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, u_rval); vbp(3, "return %d\n", u_rval); if (u_rval < 0) { // set errno? TODO } else { db_setSockConnectId(currdb, pidkey, sockfd, sockid); // map this sock number to given sock in tcp // TODO: keep the addrbuf.pad memory as well } EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); // init variables for this socket db_setupSockConnectCounter(currdb, pidkey, sockfd, sockid); free(prov_pid); free(pidkey); }
void CDEnet_end_getsockname(struct tcb* tcp) { static int count = 1; vbp(0, "%ld\n", tcp->u_rval); if (CDE_provenance_mode) { print_getsockname_prov(tcp); } if (CDE_nw_mode) { long pid = tcp->pid; //~ char *pidkey = db_read_real_pid_key(currdb, pid); //~ ull_t listenid = db_getListenId(currdb, pidkey, tcp->u_arg[0]); //~ ull_t acceptid = db_getAcceptCounterInc(currdb, pidkey, listenid); //~ char* prov_pid = getMappedPid(pidkey); // convert this pid to corresponding prov_pid //~ int u_rval; // get the result of a accept call //~ char *addr = NULL; struct user_regs_struct regs; EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, 0); EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); socklen_t addrlen = sizeof(struct sockaddr); struct sockaddr sa; struct sockaddr_in *sain = (struct sockaddr_in*) &(sa.sa_data); struct in_addr *inaddr = &(sain->sin_addr); inet_pton(AF_INET, "0.0.0.0", &(inaddr->s_addr)); sain->sin_family = AF_INET; sain->sin_port = htons(2000+(count++)); // RANDOM sa.sa_family = AF_INET; memcpy_to_child(pid, (char*) tcp->u_arg[1], (char*) &sa, addrlen); memcpy_to_child(pid, (char*) tcp->u_arg[2], (char*) &addrlen, sizeof(addrlen)); // TODO: big/little endian } }
void CDEnet_end_send(struct tcb* tcp) { int sockfd = tcp->u_arg[0]; if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) { vb(2); if (socket_data_handle(tcp, SOCK_SEND) < 0) { // TODO } } if (CDE_nw_mode && db_isCapturedSock(currdb, sockfd)) { vb(2); if (CDE_verbose_mode >= 3) { char buff[KEYLEN]; size_t buflength = tcp->u_arg[2]; if (umoven(tcp, tcp->u_arg[1], buflength, buff) < 0) { return; } buff[tcp->u_arg[2]] = '\0'; vbp(3, "action %d [%ld] checksum %u ", SOCK_SEND, tcp->u_arg[2], checksum(buff, buflength)); if (CDE_verbose_mode >= 3) printbuf(buff, buflength); } long pid = tcp->pid; char *pidkey, *sockid; db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid); if (pidkey == NULL || sockid == NULL) { vbp(0, "error"); return; } ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_SEND); char* prov_pid = getMappedPid(pidkey); // convert this pid to corresponding prov_pid ull_t u_rval; db_getSendRecvResult(netdb, SOCK_SEND, prov_pid, sockid, sendid, &u_rval, NULL); // get recorded result struct user_regs_struct regs; EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, u_rval); if (u_rval < 0) { // set errno? TODO } EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); free(prov_pid); free(sockid); free(pidkey); } }
void CDEnet_end_recv(struct tcb* tcp) { int sockfd = tcp->u_arg[0]; if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) { vb(2); socket_data_handle(tcp, SOCK_RECV); } if (CDE_nw_mode && db_isCapturedSock(currdb, sockfd)) { vb(2); long pid = tcp->pid; char *pidkey, *sockid; db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid); if (pidkey == NULL || sockid == NULL) { vbp(0, "error"); return; } ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_RECV); char* prov_pid = getMappedPid(pidkey); // convert this pid to corresponding prov_pid ull_t u_rval; char *buff = db_getSendRecvResult(netdb, SOCK_RECV, prov_pid, sockid, sendid, &u_rval, NULL); // get recorded result if (buff == NULL && u_rval>0) { vbp(2, "buff == NULL && u_rval (%lld) > 0", u_rval); u_rval = 0; } struct user_regs_struct regs; EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, u_rval); EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); if (u_rval <= 0) { // set errno? TODO } else { // successed call, copy to buffer as well //~ printf("mem: %zd %d\n %s", u_rval, u_rval > 0, buff); memcpy_to_child(pid, (char*) tcp->u_arg[1], buff, u_rval); } if (buff != NULL) free(buff); free(prov_pid); free(sockid); free(pidkey); } }
// int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // on connection or binding succeeds, zero is returned; on error, -1 is returned. void CDEnet_begin_bindconnect(struct tcb* tcp, int isConnect) { vb(1); if (CDE_nw_mode) { char addrbuf[KEYLEN]; if (umoven(tcp, tcp->u_arg[1], tcp->u_arg[2], addrbuf) < 0) return; if (isConnect) { int port = getPort((void*)addrbuf); vbp(3, "Port %d\n", port); if (port == 53 || port == 22) return; } db_setCapturedSock(currdb, tcp->u_arg[0]); denySyscall(tcp->pid); } }
void get_ip_info(long pid, int sockfd, char *buf) { struct stat fdstat; char path[KEYLEN]; sprintf(path, "/proc/%ld/fd/%d", pid, sockfd); if (stat(path, &fdstat) >= 0) { char cmd[KEYLEN], sip[9], sport[5], dip[9], dport[5]; ino_t inode; sprintf(cmd, "cat /proc/net/tcp | grep %ld | head -n 1", fdstat.st_ino); FILE *fd = popen(cmd, "r"); if (fd != NULL) { fscanf(fd, "%*d: %8s:%4s %8s:%4s %*2s %*8s:%*8s %*2s:%*8s %*8s %*d %*d %ld", sip, sport, dip, dport, &inode); if (inode == fdstat.st_ino) { sprintf(buf, "%s.%s.%s.%s", sip, sport, dip, dport); vbp(3, "%ld %d %s:%s %s:%s %ld %ld\n", pid, sockfd, sip, sport, dip, dport, inode, fdstat.st_ino); } pclose(fd); } } }
void CDEnet_end_bindconnect(struct tcb* tcp, int isConnect) { int sockfd = tcp->u_arg[0]; long addr = tcp->u_arg[1]; int addrlen = tcp->u_arg[2]; union sockaddr_t addrbuf; vb(2); if (addr == 0) return; if (addrlen < 2 || addrlen > sizeof(addrbuf)) addrlen = sizeof(addrbuf); if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) return; addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0'; //~ printf("sock %d, family %d inet %d\n", sockfd, addrbuf.sa.sa_family, AF_INET); //~ if (CDE_provenance_mode && addrbuf.sa.sa_family == AF_INET) { if (CDE_provenance_mode) { int port = getPort((void*)addrbuf.pad); char buf[KEYLEN]; bzero(buf, sizeof(buf)); vbp(3, "Port %d return %ld\n", port, tcp->u_rval); if (port == 53 || port == 22) return; if (isConnect) { if (addrbuf.sa.sa_family == AF_INET) { get_ip_info(tcp->pid, sockfd, buf); } else if (addrbuf.sa.sa_family == AF_LOCAL) { sprintf(buf, "..%s", addrbuf.sau.sun_path); } } print_connect_prov(tcp, sockfd, addrbuf.pad, tcp->u_arg[2], tcp->u_rval, buf); } if (CDE_nw_mode) { // return my own network socket connect result from netdb if (isConnect) if (!isCurrCapturedSock(sockfd)) return; setBindConnectReturnValue(tcp); } }
Collision::Collision(PObject* obj1, PObject* obj2) { trueCollision = false; objects = new PObject*[2]; objects[0] = obj1; objects[1] = obj2; /* * the following was written before the Vect2D class was written * (and that's why it's so messy) */ Vect2D norm; Point p1,p2; const Point* obj1vertices = objects[0]->getVertices(); const Point* obj2vertices = objects[1]->getVertices(); int numPoints=0; float sumx=0; float sumy=0; float parametric; float parametric2; float denominator; float vec1x; float vec1y; float vec1deltax;//between this point and the next one in the shape (going counterclockwise) float vec1deltay; float vec2x; float vec2y; float vec2deltax; float vec2deltay; float deltax, deltay; //between the two points on different shapes /* * x1+k*t = x2+c*k * y1+b*t = y2+d*k */ for (int i = 0; i < objects[0]->getNumVertices(); i++) { vec1x = obj1vertices[i].x;//x1 vec1y = obj1vertices[i].y;//y1 vec1deltax = obj1vertices[(i + 1) % objects[0]->getNumVertices()].x - vec1x;//a vec1deltay = obj1vertices[(i + 1) % objects[0]->getNumVertices()].y - vec1y;//b for (int j = 0; j < objects[1]->getNumVertices(); j++) { vec2x = obj2vertices[j].x;//x2 vec2y = obj2vertices[j].y;//y2 vec2deltax = obj2vertices[(j + 1) % objects[1]->getNumVertices()].x - vec2x;//c vec2deltay = obj2vertices[(j + 1) % objects[1]->getNumVertices()].y - vec2y;//d denominator = (vec1deltax * vec2deltay) - (vec2deltax * vec1deltay);//ad-bc if (denominator != 0) { deltax = vec1x-vec2x;//x1-x2 deltay = vec1y-vec2y;//y1-y2 parametric = ((vec2deltax * (deltay)) - vec2deltay * (deltax)) / (denominator);//t parametric2 = ((vec1deltax * (deltay)) - vec1deltay * (deltax)) / (denominator);//k if (parametric <= 1 && parametric >= 0 && parametric2 <= 1 && parametric2 >= 0) { numPoints++; sumx += vec1x + (parametric * vec1deltax);//x = x1+a*t sumy += vec1y + (parametric * vec1deltay);//y = y1+b*t //uses the normal vector of the first collision if (!trueCollision){ /* old way of finding //figure out which one collided on the corner if (abs(parametric2-.5) < abs(parametric-.5)){ //vector1's point of collision was closer to the corner norm.set(vec2deltay,-vec2deltax); } else { norm.set(vec2deltax,-vec2deltay); }*/ //VERY crude approximation for normal vector at collision point norm.set(objects[1]->get_centerx()-objects[0]->get_centerx(), objects[1]->get_centery()-objects[0]->get_centery()); norm.normalize(); } trueCollision = true; } } } } if (trueCollision) { intersection.x = sumx/numPoints; intersection.y = sumy/numPoints; //calculate impulse here float e = objects[0]->get_elasticity()*objects[1]->get_elasticity(); Vect2D r1(intersection.x-objects[0]->get_centerx(), intersection.y-objects[0]->get_centery()); Vect2D r2(intersection.x-objects[1]->get_centerx(), intersection.y-objects[1]->get_centery()); //vap = vcenter + w x r1 where w is angular velocity vector that points into screen //vap = velocity of point of collision on each object Vect2D vap(objects[0]->get_vx()-objects[0]->get_dtheta()*r1.y, objects[0]->get_vy()+objects[0]->get_dtheta()*r1.x); Vect2D vbp(objects[1]->get_vx()-objects[1]->get_dtheta()*r2.y, objects[1]->get_vy()+objects[1]->get_dtheta()*r2.x); Vect2D& vabp = vap-vbp; float ran = r1.cross(norm); float rbn = r2.cross(norm); //source: http://www.myphysicslab.com/collision.html float j= (-(1+e)*vabp.dot(norm))/(1/objects[0]->get_mass() + 1/objects[1]->get_mass() + ran*ran/objects[0]->get_momentInertia() + rbn*rbn/objects[1]->get_momentInertia()); impulse.set(norm); impulse.scale(j); } }
void CDEnet_end_recvmsg(struct tcb* tcp) { int sockfd = tcp->u_arg[0]; struct msghdr mh; struct iovec *msg_iov = NULL; char memop_ok = 1; if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) { int len = tcp->u_rval; //~ char *msg_name = NULL, *msg_control = NULL; char *storage = NULL; vb(2); if (umoven(tcp, tcp->u_arg[1], sizeof(struct msghdr), (char*) &mh) < 0) return; if (len > 0) { storage = malloc(len); memop_ok &= storage != NULL; } //~ if (memop_ok && mh.msg_namelen > 0) { //~ msg_name = malloc(mh.msg_namelen); //~ memop_ok &= msg_name != NULL; //~ if (memop_ok) //~ memop_ok &= umoven(tcp, (long) mh.msg_name, mh.msg_namelen, msg_name) >= 0; //~ } if (memop_ok && mh.msg_iovlen > 0) { int memlen = mh.msg_iovlen * sizeof(struct iovec); msg_iov = malloc(memlen); memop_ok &= msg_iov != NULL; if (memop_ok) memop_ok &= umoven(tcp, (long) mh.msg_iov, memlen , (void*) msg_iov) >= 0; } //~ if (memop_ok && mh.msg_controllen > 0) { //~ msg_control = malloc(mh.msg_controllen); //~ memop_ok &= msg_control != NULL; //~ if (memop_ok) //~ memop_ok &= umoven(tcp, (long) mh.msg_control, mh.msg_controllen, msg_control) >= 0; //~ } if (memop_ok) { char *it = storage; long int read_len, i; for (i=0; i<mh.msg_iovlen && memop_ok; i++) { read_len = len + storage - it < msg_iov[i].iov_len ? len + storage - it : msg_iov[i].iov_len; memop_ok &= umoven(tcp, (long) msg_iov[i].iov_base, read_len, it) >= 0; if (memop_ok) it = it + read_len; } if (memop_ok) { print_sock_action(tcp, sockfd, storage, 0, tcp->u_arg[2], len, SOCK_RECVMSG, &mh); vbp(2, "recorded\n"); } } freeifnn(storage); //~ freeifnn(msg_control); freeifnn(msg_iov); //~ freeifnn(msg_name); } if (CDE_nw_mode && isCurrCapturedSock(sockfd)) { vb(2); long pid = tcp->pid; char *pidkey, *sockid; db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid); if (pidkey == NULL || sockid == NULL) { vbp(0, "error"); return; } ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_RECV); char* prov_pid = getMappedPid(pidkey); // convert this pid to corresponding prov_pid ull_t u_rval; struct msghdr ret_mh; char *buff = db_getSendRecvResult(netdb, SOCK_RECVMSG, prov_pid, sockid, sendid, &u_rval, &ret_mh); // get recorded result struct user_regs_struct regs; if (buff == NULL) { vbp(0, "recvmsg not captured!\n"); //~ while (1) sleep(1); EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, -1); EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); } else { EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); SET_RETURN_CODE(®s, u_rval); EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); if (u_rval <= 0) { // set errno? TODO } else { // successed call, copy to buffer as well // get the calling mh structure memop_ok &= umoven(tcp, tcp->u_arg[1], sizeof(struct msghdr), (char*) &mh) >= 0; if (memop_ok && mh.msg_iovlen > 0) { int memlen = mh.msg_iovlen * sizeof(struct iovec); msg_iov = malloc(memlen); memop_ok &= msg_iov != NULL; if (memop_ok) memop_ok &= umoven(tcp, (long) mh.msg_iov, memlen , (void*) msg_iov) >= 0; } // and copy stuff back to that mh if (memop_ok) { // data char *it = buff; long int read_len, i; for (i=0; i<mh.msg_iovlen && memop_ok; i++) { read_len = u_rval + buff - it < msg_iov[i].iov_len ? u_rval + buff - it : msg_iov[i].iov_len; memcpy_to_child(pid, msg_iov[i].iov_base, it, read_len); it = it + read_len; } // others mh.msg_flags = ret_mh.msg_flags; memcpy_to_child(pid, (char*) tcp->u_arg[1], (char*) &mh, sizeof(mh)); } freeifnn(msg_iov); } } freeifnn(buff); free(prov_pid); free(sockid); free(pidkey); } }
// get the corresponding pidkey from traced execution // some graph algorithm is needed here // @input current pidkey // @return pidkey from netdb // TODO char* getMappedPid(char* pidkey) { // TODO: need a cache for this operation as well char key[KEYLEN], *p; const char *read; size_t read_len; ull_t childid; int n=0, i; ull_t idlist[100]; // enough? p = pidkey; while (p != NULL) { sprintf(key, "prv.pid.%s.childid", p); vbp(3, "%s\n", key); db_read_ull(currdb, key, &childid); idlist[n++] = childid; sprintf(key, "prv.pid.%s.parent", p); if (p != pidkey && p != NULL) free(p); p = db_readc(currdb, key); } vbp(2, "%s -> [%d] [", pidkey, n); if (CDE_verbose_mode >= 2) { for (i=0; i<n; i++) { fprintf(stderr, "%llu, ", idlist[i]); } fprintf(stderr, "]\n"); } if (PIDKEY != NULL) { p = strdup(PIDKEY); n -= 2; } else { p = db_readc(netdb, "meta.root"); sprintf(key, "prv.pid.%s.exec.", p); //~ sprintf(key, "prv.pid.%s.actualexec.", p); free(p); leveldb_iterator_t *it = leveldb_create_iterator(netdb->db, netdb->roptions); leveldb_iter_seek(it, key, strlen(key)); read = leveldb_iter_value(it, &read_len); p = malloc(read_len + 1); memcpy(p, read, read_len); p[read_len] = '\0'; n-=2; // skip the first root -> child that I just did } while (n>0) { sprintf(key, "prv.pid.%s.child.%llu", p, idlist[n-1]); n--; free(p); p = db_readc(netdb, key); vbp(3, "%s\n", key); } vbp(2, "return %s\n", p); return p; //~ char *value; //~ const char *read; //~ size_t read_len; //~ //~ sprintf(key, "prv.pid.%s.parent.", netdb_root); //~ leveldb_iterator_t *it = leveldb_create_iterator(netdb->db, netdb->roptions); //~ leveldb_iter_seek(it, key, strlen(key)); //~ //~ read = leveldb_iter_value(it, &read_len); //~ value = malloc(read_len + 1); //~ memcpy(value, read, read_len); //~ value[read_len] = '\0'; //~ return value; }