Beispiel #1
0
static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f) {
	struct s_reader *rdr = setting;
	if (value) {
		char *ptr, *ptr2, *ptr3, *saveptr1 = NULL;
		struct s_ecmWhitelist *tmp, *last;
		struct s_ecmWhitelistIdent *tmpIdent, *lastIdent;
		struct s_ecmWhitelistLen *tmpLen, *lastLen;
		for(tmp = rdr->ecmWhitelist; tmp; tmp=tmp->next){
			for(tmpIdent = tmp->idents; tmpIdent; tmpIdent=tmpIdent->next){
				for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen=tmpLen->next){
					add_garbage(tmpLen);
				}
				add_garbage(tmpIdent);
			}
			add_garbage(tmp);
		}
		rdr->ecmWhitelist = NULL;
		if(strlen(value) > 0){
			saveptr1 = NULL;
			char *saveptr2 = NULL;
			for (ptr = strtok_r(value, ";", &saveptr1); ptr; ptr = strtok_r(NULL, ";", &saveptr1)) {
				int16_t caid = 0, len;
				uint32_t ident = 0;
				ptr2=strchr(ptr,':');
				if(ptr2 != NULL){
					ptr2[0] = '\0';
					++ptr2;
					ptr3=strchr(ptr,'@');
					if(ptr3 != NULL){
						ptr3[0] = '\0';
						++ptr3;
						ident = (uint32_t)a2i(ptr3, 6);
					}
					caid = (int16_t)dyn_word_atob(ptr);
				} else ptr2 = ptr;
				for (ptr2 = strtok_r(ptr2, ",", &saveptr2); ptr2; ptr2 = strtok_r(NULL, ",", &saveptr2)) {
					len = (int16_t)dyn_word_atob(ptr2);
					last = NULL, tmpIdent = NULL, lastIdent = NULL, tmpLen = NULL, lastLen = NULL;
					for(tmp = rdr->ecmWhitelist; tmp; tmp=tmp->next){
						last = tmp;
						if(tmp->caid == caid){
							for(tmpIdent = tmp->idents; tmpIdent; tmpIdent=tmpIdent->next){
								lastIdent = tmpIdent;
								if(tmpIdent->ident == ident){
									for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen=tmpLen->next){
										lastLen = tmpLen;
										if(tmpLen->len == len) break;
									}
									break;
								}
							}
						}
					}
					if(tmp == NULL){
						if (cs_malloc(&tmp, sizeof(struct s_ecmWhitelist))) {
							tmp->caid = caid;
							tmp->idents = NULL;
							tmp->next = NULL;
							if(last == NULL){
								rdr->ecmWhitelist = tmp;
							} else {
								last->next = tmp;
							}
						}
					}
					if(tmp != NULL && tmpIdent == NULL){
						if (cs_malloc(&tmpIdent, sizeof(struct s_ecmWhitelistIdent))) {
							tmpIdent->ident = ident;
							tmpIdent->lengths = NULL;
							tmpIdent->next = NULL;
							if(lastIdent == NULL){
								tmp->idents = tmpIdent;
							} else {
								lastIdent->next = tmpIdent;
							}
						}
					}
					if(tmp != NULL && tmpIdent != NULL && tmpLen == NULL){
						if (cs_malloc(&tmpLen, sizeof(struct s_ecmWhitelistLen))) {
							tmpLen->len = len;
							tmpLen->next = NULL;
							if(lastLen == NULL){
								tmpIdent->lengths = tmpLen;
							} else {
								lastLen->next = tmpLen;
							}
						}
					}
				}
			}
		}
		return;
	}

	value = mk_t_ecmwhitelist(rdr->ecmWhitelist);
	if (strlen(value) > 0 || cfg.http_full_cfg)
		fprintf_conf(f, token, "%s\n", value);
	free_mk_t(value);
}
Beispiel #2
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static int omode = 0;
	int mode, ret;
	ut64 off = a->pc;

	mode = (a->bits==64)? CS_MODE_64: 
		(a->bits==32)? CS_MODE_32:
		(a->bits==16)? CS_MODE_16: 0;
	if (cd && mode != omode) {
		cs_close (&cd);
		cd = 0;
	}
	op->size = 0;
	omode = mode;
	if (cd == 0) {
		ret = cs_open (CS_ARCH_X86, mode, &cd);
		if (ret) return 0;
	}
	if (a->features && *a->features) {
		cs_option (cd, CS_OPT_DETAIL, CS_OPT_ON);
	} else {
		cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	}
	if (a->syntax == R_ASM_SYNTAX_ATT) {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
	} else {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
	}
	op->size = 1;
#if USE_ITER_API
	{
		size_t size = len;
		if (insn == NULL)
			insn = cs_malloc (cd);
		insn->size = 1;
		memset (insn, 0, insn->size);
		n = cs_disasm_iter (cd, (const uint8_t**)&buf, &size, (uint64_t*)&off, insn);
	}
#else
	n = cs_disasm (cd, (const ut8*)buf, len, off, 1, &insn);
#endif
	op->size = 0;
	if (a->features && *a->features) {
		if (!check_features (a, insn)) {
			op->size = insn->size;
			strcpy (op->buf_asm, "illegal");
		}
	}
	if (op->size==0 && n>0 && insn->size>0) {
		char *ptrstr;
		op->size = insn->size;
		snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
				insn->mnemonic, insn->op_str[0]?" ":"",
				insn->op_str);
		ptrstr = strstr (op->buf_asm, "ptr ");
		if (ptrstr) {
			memmove (ptrstr, ptrstr+4, strlen (ptrstr+4)+1);
		}
	}
	if (a->syntax == R_ASM_SYNTAX_JZ) {
		if (!strncmp (op->buf_asm, "je ", 3)) {
			memcpy (op->buf_asm, "jz", 2);
		} else if (!strncmp (op->buf_asm, "jne ", 4)) {
			memcpy (op->buf_asm, "jnz", 3);
		}
	}
#if USE_ITER_API
	/* do nothing because it should be allocated once and freed in the_end */
#else
	cs_free (insn, n);
	insn = NULL;
#endif
	return op->size;
}
int32_t coolapi_set_filter (int32_t fd, int32_t num, int32_t pid, uchar * flt, uchar * mask, int32_t type)
{
	dmx_t * dmx =  find_demux(fd, 0);
	if(!dmx) {
		cs_debug_mask(D_DVBAPI, "dmx is NULL!");
		return -1;
	}

	int32_t result, channel_found=0;

	void * channel = NULL;

	if (ll_count(ll_cool_chanhandle) > 0) {
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;
		while ((handle_item=ll_iter_next(&itr))) {
			if (handle_item->demux_index == dmx->demux_index && handle_item->pid == pid) {
				channel = handle_item->channel;
				channel_found=1;
				break;
			}
		}
	}

	if (!channel) {
		buffer_open_arg_t bufarg;
		int32_t uBufferSize = 8256;
		memset(&bufarg, 0, sizeof(bufarg));

		bufarg.type = 3;
		bufarg.size = uBufferSize;
		bufarg.unknown3 = (uBufferSize * 7) / 8;

		result = cnxt_cbuf_open(&dmx->buffer1, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		bufarg.type = 0;

		result = cnxt_cbuf_open(&dmx->buffer2, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		channel_open_arg_t chanarg;
		memset(&chanarg, 0, sizeof(channel_open_arg_t));
		chanarg.type = 4;

		result = cnxt_dmx_channel_open(dmx->device, &dmx->channel, &chanarg, dmx_callback, dmx);
		coolapi_check_error("cnxt_dmx_channel_open", result);

		result = cnxt_dmx_set_channel_buffer(dmx->channel, 0, dmx->buffer1);
		coolapi_check_error("cnxt_dmx_set_channel_buffer", result);

		result = cnxt_dmx_channel_attach(dmx->channel, 0xB, 0, dmx->buffer2);
		coolapi_check_error("cnxt_dmx_channel_attach", result);

		result = cnxt_cbuf_attach(dmx->buffer2, 2, dmx->channel);
		coolapi_check_error("cnxt_cbuf_attach", result);

		result = cnxt_dmx_set_channel_pid(dmx->channel, pid);
		coolapi_check_error("cnxt_dmx_set_channel_pid", result);

		result = cnxt_cbuf_flush (dmx->buffer1, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);
		result = cnxt_cbuf_flush (dmx->buffer2, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);

		S_COOL_CHANHANDLE *handle_item;
		if (cs_malloc(&handle_item,sizeof(S_COOL_CHANHANDLE))) {
			handle_item->pid 			= pid;
			handle_item->channel 		= dmx->channel;
			handle_item->buffer1 		= dmx->buffer1;
			handle_item->buffer2		= dmx->buffer2;
			handle_item->demux_index 	= dmx->demux_index;
			ll_append(ll_cool_chanhandle, handle_item);
		}
		cs_debug_mask(D_DVBAPI, "opened new channel %x", (int32_t) dmx->channel);
   } else {
		channel_found=1;
		dmx->channel = channel;
		dmx->buffer1 = NULL;
		dmx->buffer2 = NULL;
	}

	cs_debug_mask(D_DVBAPI, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x", fd, dmx->demux_index, (int32_t) dmx->channel, num, pid, flt[0], mask[0]);

	pthread_mutex_lock(&dmx->mutex);

	filter_set_t filter;
	dmx->filter_num = num;
	dmx->pid = pid;
	dmx->type = type;

	memset(&filter, 0, sizeof(filter));
	filter.length = 12;
	memcpy(filter.filter, flt, 16);
	memcpy(filter.mask, mask, 16);

	result = cnxt_dmx_open_filter(dmx->device, &dmx->filter);
	coolapi_check_error("cnxt_dmx_open_filter", result);

	result = cnxt_dmx_set_filter(dmx->filter, &filter, NULL);
	coolapi_check_error("cnxt_dmx_set_filter", result);

	result = cnxt_dmx_channel_attach_filter(dmx->channel, dmx->filter);
	coolapi_check_error("cnxt_dmx_channel_attach_filter", result);

	if (channel_found) {
		result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);
	}

	result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0);
	coolapi_check_error("cnxt_dmx_channel_ctrl", result);

	pthread_mutex_unlock(&dmx->mutex);

	S_COOL_FILTER *filter_item;
	if (cs_malloc(&filter_item,sizeof(S_COOL_FILTER))) {
		// fill filter item
		filter_item->fd = fd;
		filter_item->pid = pid;
		filter_item->channel = (int32_t) dmx->channel;
		memcpy(filter_item->filter16, flt, 16);
		memcpy(filter_item->mask16, mask, 16);

		//add filter item
		ll_append(ll_cool_filter, filter_item);
	}
	return 0;
}
Beispiel #4
0
void cc_cacheex_push_in(struct s_client *cl, uchar *buf)
{
	struct cc_data *cc = cl->cc;
	ECM_REQUEST *er;
	if(!cc) { return; }

	if(cl->reader)
		{ cl->reader->last_s = cl->reader->last_g = time((time_t *)0); }
	if(cl) { cl->last = time(NULL); }

	int8_t rc = buf[14];
	if(rc != E_FOUND && rc != E_UNHANDLED)  //Maybe later we could support other rcs
		{ return; }
	uint16_t size = buf[12] | (buf[13] << 8);
	if(size != sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw))
	{
		cs_log_dbg(D_CACHEEX, "cacheex: %s received old cash-push format! data ignored!", username(cl));
		return;
	}
	if(!(er = get_ecmtask()))
		{ return; }

	er->caid = b2i(2, buf + 0);
	er->prid = b2i(4, buf + 2);
	er->srvid = b2i(2, buf + 10);
	er->ecm[0] = buf[19]!=0x80 && buf[19]!=0x81 ? 0 : buf[19]; //odd/even byte, usefull to send it over CSP and to check cw for swapping
	er->rc = rc;

	er->ecmlen = 0;

	if(buf[18])
	{
		if(buf[18] & (0x01 << 7))
		{
			er->cwc_cycletime = (buf[18] & 0x7F); // remove bit 8 to get cycletime
			er->cwc_next_cw_cycle = 1;
		}
		else
		{
			er->cwc_cycletime = buf[18];
			er->cwc_next_cw_cycle = 0;
		}
	}

	if (er->cwc_cycletime && er->cwc_next_cw_cycle < 2)
	{
		if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
			{ cl->account->cwc_info++; }
		else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
			{ cl->cwc_info++; }
		cs_log_dbg(D_CWC, "CWC (CE) received from %s cycletime: %isek - nextcwcycle: CW%i for %04X:%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid);
	}

	uint8_t *ofs = buf + 20;

	//Read ecmd5
	memcpy(er->ecmd5, ofs, sizeof(er->ecmd5)); //16
	ofs += sizeof(er->ecmd5);

	if(!check_cacheex_filter(cl, er))
		{ return; }

	//Read csp_hash:
	er->csp_hash = ntohl(b2i(4, ofs));
	ofs += 4;

	//Read cw:
	memcpy(er->cw, ofs, sizeof(er->cw)); //16
	ofs += sizeof(er->cw);

	//Read lastnode count:
	uint8_t count = *ofs;
	ofs++;

	//check max nodes:
	if(count > cacheex_maxhop(cl))
	{
			cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes (max=%d), ignored! %s", (int32_t)count, cacheex_maxhop(cl), username(cl));
		NULLFREE(er);
		return;
	}
	cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes %s", (int32_t)count, username(cl));
	//Read lastnodes:
	uint8_t *data;
	if (er){
		er->csp_lastnodes = ll_create("csp_lastnodes");
	}
	while(count)
	{
		if(!cs_malloc(&data, 8))
			{ break; }
		memcpy(data, ofs, 8);
		ofs += 8;
		ll_append(er->csp_lastnodes, data);
		count--;
		cs_log_dbg(D_CACHEEX, "cacheex: received node %" PRIu64 "X %s", cacheex_node_id(data), username(cl));
	}

	//for compatibility: add peer node if no node received:
	if(!ll_count(er->csp_lastnodes))
	{
		if(!cs_malloc(&data, 8))
			{ return; }
		memcpy(data, cc->peer_node_id, 8);
		ll_append(er->csp_lastnodes, data);
		cs_log_dbg(D_CACHEEX, "cacheex: added missing remote node id %" PRIu64 "X", cacheex_node_id(data));
	}

	cacheex_add_to_cache(cl, er);
}
Beispiel #5
0
//Todo #ifdef CCCAM
int32_t init_provid(void)
{
	FILE *fp = open_config_file(cs_provid);
	if(!fp)
		{ return 0; }

	int32_t nr;
	char *payload, *saveptr1 = NULL, *token;
	if(!cs_malloc(&token, MAXLINESIZE))
		{ return 0; }
	static struct s_provid *provid = (struct s_provid *)0;

	nr = 0;
	while(fgets(token, MAXLINESIZE, fp))
	{

		int32_t l;
		void *ptr;
		char *tmp, *providasc;
		tmp = trim(token);

		if(tmp[0] == '#') { continue; }
		if((l = strlen(tmp)) < 11) { continue; }
		if(!(payload = strchr(token, '|'))) { continue; }
		if(!(providasc = strchr(token, ':'))) { continue; }

		*payload++ = '\0';

		if(!cs_malloc(&ptr, sizeof(struct s_provid)))
		{
			NULLFREE(token);
			fclose(fp);
			return (1);
		}
		if(provid)
			{ provid->next = ptr; }
		else
			{ cfg.provid = ptr; }

		provid = ptr;

		int32_t i;
		char *ptr1;
		for(i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1; ptr1 = strtok_r(NULL, "|", &saveptr1), i++)
		{
			switch(i)
			{
			case 0:
				cs_strncpy(provid->prov, trim(ptr1), sizeof(provid->prov));
				break;
			case 1:
				cs_strncpy(provid->sat, trim(ptr1), sizeof(provid->sat));
				break;
			case 2:
				cs_strncpy(provid->lang, trim(ptr1), sizeof(provid->lang));
				break;
			}
		}

		*providasc++ = '\0';
		provid->provid = a2i(providasc, 3);
		provid->caid = a2i(token, 3);
		nr++;
	}
	NULLFREE(token);
	fclose(fp);
	if(nr > 0)
		{ cs_log("%d provid's loaded", nr); }
	return (0);
}
bool NetBase::CheckIn()
{    
    // check for incoming packets
    SOCKADDR_IN addr;
    memset (&addr, 0, sizeof(SOCKADDR_IN));
    socklen_t len = sizeof(SOCKADDR_IN);

    if (!input_buffer)
    {
        input_buffer = (char*) cs_malloc(MAXPACKETSIZE);

        if (!input_buffer)
        {
            Error2("Failed to cs_malloc %d bytes for packet buffer!\n",MAXPACKETSIZE);
            return false;
        }
    }

    // Connection must be initialized!
    CS_ASSERT(ready);
    
    int packetlen = RecvFrom (&addr, &len, (void*) input_buffer, MAXPACKETSIZE);

    if (packetlen <= 0)
    {
        return false;
    }
    // Identify the connection
    Connection* connection = GetConnByIP(&addr);

    // Extract the netpacket from the buffer and prep for use locally.
    psNetPacket *bufpacket = psNetPacket::NetPacketFromBuffer(input_buffer,packetlen);
    if (bufpacket==NULL)
    {
        char addrText[INET_ADDRSTRLEN];

        //for win32 for now only inet_ntoa as inet_ntop wasn't supported till vista.
        //it has the same degree of compatibility of the previous code and it's supported till win2000
        #ifdef WIN32
        strncpy(addrText, inet_ntoa(addr.sin_addr), INET_ADDRSTRLEN);
        #else
        //there was a failure in conversion if null
        if(!inet_ntop(addr.sin_family,&addr.sin_addr, addrText, sizeof(addrText)))
        {
            strncpy(addrText, "UNKNOWN", INET_ADDRSTRLEN);
        }
        #endif

        // The data received was too small to make a full packet.
        if (connection)
        {
            Debug4(LOG_NET, connection->clientnum, "Too short packet received from client %d (IP: %s) (%d bytes)", connection->clientnum, addrText, packetlen);
        }
        else
        {
            Debug3(LOG_NET, 0, "Too short packet received from IP address %s. (%d bytes) No existing connection from this IP.",
                addrText, packetlen);
        }
        return true; // Continue processing more packets if available
    }
    input_buffer = NULL; //input_buffer now hold by the bufpacket pointer.

    // Endian correction
    bufpacket->UnmarshallEndian();

    // Check for too-big packets - no harm in processing them, but probably a bug somewhere
    if (bufpacket->GetPacketSize() < static_cast<unsigned int>(packetlen))
    {
        char addrText[INET_ADDRSTRLEN];

        //for win32 for now only inet_ntoa as inet_ntop wasn't supported till vista.
        //it has the same degree of compatibility of the previous code and it's supported till win2000
        #ifdef WIN32
        strncpy(addrText, inet_ntoa(addr.sin_addr), INET_ADDRSTRLEN);
        #else
        //there was a failure in conversion if null
        if(!inet_ntop(addr.sin_family,&addr.sin_addr, addrText, sizeof(addrText)))
        {
            strncpy(addrText, "UNKNOWN", INET_ADDRSTRLEN);
        }
        #endif
        
        if (connection)
        {
            Debug5(LOG_NET, connection->clientnum, "Too long packet received from client %d (IP: %s) (%d bytes received, header reports %zu bytes)",
                connection->clientnum, addrText, packetlen, bufpacket->GetPacketSize());
        }
        else
        {
            
            Debug4(LOG_NET, 0,"Too long packet received from IP address %s. (%d bytes received, header reports %zu bytes) No existing connection from this IP.",
                   addrText, packetlen, bufpacket->GetPacketSize());
        }
    }

    //Create new net packet entry and transfer ownership of bufpacket to pkt.
    csRef<psNetPacketEntry> pkt;
    pkt.AttachNew(new psNetPacketEntry( bufpacket, 
            connection ? connection->clientnum : 0, packetlen));
    
    if(TEST_PACKETLOSS > 0.0 && randomgen->Get() < TEST_PACKETLOSS)
    {
        psNetPacket* packet = pkt->packet;
        int type = 0;

        if (packet->offset == 0) 
        {
            psMessageBytes* msg = (psMessageBytes*) packet->data;
            type = msg->type;
        }

        Error3("Packet simulated lost. Type %s ID %d.\n", type == 0 ? "Fragment" : (const char *)  GetMsgTypeName(type), pkt->packet->pktid);
        return true;
    }

    // ACK packets can get eaten by HandleAck
    if (HandleAck(pkt, connection, &addr))
    {
        return true;
    }

    // printf("Got packet with sequence %d.\n", pkt->packet->GetSequence());
    //
    // Check for doubled packets and drop them
    if (pkt->packet->pktid != 0)
    {
        if (connection && CheckDoublePackets (connection, pkt))
        {
#ifdef PACKETDEBUG
            Debug2(LOG_NET,0,"Dropping doubled packet (ID %d)\n", pkt->packet->pktid);
#endif
            return true;
        }
    }
    
#ifdef PACKETDEBUG
    Debug7(LOG_NET,0,"Received Pkt, ID: %d, offset %d, from %d size %d (actual %d) flags %d\n", 
        pkt->packet->pktid, pkt->packet->offset, pkt->clientnum, pkt->packet->pktsize,packetlen, pkt->packet->flags);
#endif

    /**
    * Now either send this packet to BuildMessage, or loop through
    * subpackets if they are merged.
    */
    csRef<psNetPacketEntry> splitpacket = pkt;
    psNetPacket      *packetdata = NULL;

    do
    {
        splitpacket = pkt->GetNextPacket(packetdata);
        if (splitpacket)
            BuildMessage(splitpacket, connection, &addr);
    } while (packetdata);
    return true;
}
Beispiel #7
0
static void ac_load_config(void)
{
	FILE *fp = open_config_file(cs_ac);
	if(!fp)
		{ return; }

	int32_t nr;
	char *saveptr1 = NULL, *token;
	if(!cs_malloc(&token, MAXLINESIZE))
		{ return; }
	struct s_cpmap *cur_cpmap, *first_cpmap = NULL, *last_cpmap = NULL;

	for(nr = 0; fgets(token, MAXLINESIZE, fp);)
	{
		int32_t i, skip;
		uint16_t caid, sid, chid, dwtime;
		uint32_t  provid;
		char *ptr, *ptr1;

		if(strlen(token) < 4) { continue; }

		caid = sid = chid = dwtime = 0;
		provid = 0;
		skip = 0;
		ptr1 = 0;
		for(i = 0, ptr = strtok_r(token, "=", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, "=", &saveptr1), i++)
		{
			trim(ptr);
			if(*ptr == ';' || *ptr == '#' || *ptr == '-')
			{
				skip = 1;
				break;
			}
			switch(i)
			{
			case 0:
				ptr1 = ptr;
				break;
			case 1:
				dwtime = atoi(ptr);
				break;
			}
		}

		if(!skip)
		{
			for(i = 0, ptr = strtok_r(ptr1, ":", &saveptr1); (i < 4) && (ptr); ptr = strtok_r(NULL, ":", &saveptr1), i++)
			{
				trim(ptr);
				switch(i)
				{
				case 0:
					if(*ptr == '*') { caid = 0; }
					else { caid = a2i(ptr, 4); }
					break;
				case 1:
					if(*ptr == '*') { provid = 0; }
					else { provid = a2i(ptr, 6); }
					break;
				case 2:
					if(*ptr == '*') { sid = 0; }
					else { sid = a2i(ptr, 4); }
					break;
				case 3:
					if(*ptr == '*') { chid = 0; }
					else { chid = a2i(ptr, 4); }
					break;
				}
			}
			if(!cs_malloc(&cur_cpmap, sizeof(struct s_cpmap)))
			{
				for(cur_cpmap = first_cpmap; cur_cpmap;)
				{
					last_cpmap = cur_cpmap;
					cur_cpmap = cur_cpmap->next;
					NULLFREE(last_cpmap);
				}
				NULLFREE(token);
				return;
			}
			if(last_cpmap)
				{ last_cpmap->next = cur_cpmap; }
			else
				{ first_cpmap = cur_cpmap; }
			last_cpmap = cur_cpmap;

			cur_cpmap->caid   = caid;
			cur_cpmap->provid = provid;
			cur_cpmap->sid    = sid;
			cur_cpmap->chid   = chid;
			cur_cpmap->dwtime = dwtime;
			cur_cpmap->next   = 0;

			cs_log_dbg(D_CLIENT, "nr=%d, caid=%04X, provid=%06X, sid=%04X, chid=%04X, dwtime=%d",
						  nr, caid, provid, sid, chid, dwtime);
			nr++;
		}
	}
	NULLFREE(token);
	fclose(fp);

	last_cpmap = cfg.cpmap;
	cfg.cpmap = first_cpmap;
	for(cur_cpmap = last_cpmap; cur_cpmap; cur_cpmap = cur_cpmap->next)
		{ add_garbage(cur_cpmap); }
	//cs_log("%d lengths for caid guessing loaded", nr);
	return;
}
jump_block* init_jump_block (jump_block* to_init, unsigned int start_addr, unsigned int stop_addr)
{
	to_init->instructions = NULL;
	to_init->calls = NULL;
	to_init->conditional_jumps = NULL;
	to_init->flags = next_flags;
	next_flags = 0;
	to_init->next = NULL;

	//Locals to cut down on dereference operators; this code was a disaster the first time around with no locals
	size_t size = file_size;
	int num_instructions = 0;
	int num_calls = 0;
	int num_conditional_jumps = 0;
	unsigned long long relative_address = 0;
	unsigned int current_addr = start_addr;
	uint8_t* current = file_buf + addr_to_index (current_addr);
	unsigned int next_addr;
	cs_insn* instruction = cs_malloc (handle);

	to_init->start = start_addr;

	do
	{
		num_instructions ++;

		//Dynamic memory allocation stuff here
		if (num_instructions - 1)
		{
			if (num_instructions * sizeof (cs_insn) > to_init->instructions_buf_size)
			{
				to_init->instructions_buf_size *= 2; //Just double the buffer; I'd rather allocate too much than reallocate memory every single iteration
				to_init->instructions = (cs_insn*)realloc (to_init->instructions, to_init->instructions_buf_size);
			}
		}
		else
		{
			to_init->instructions_buf_size = 256 * sizeof (cs_insn); //My memory allocator screams at me for numbers that aren't a multiple of 8
			to_init->instructions = (cs_insn*)malloc (to_init->instructions_buf_size);
		}

		//Partially disassemble the instruction into machine readable format
		cs_disasm_iter (handle, (const uint8_t **)&current, &file_size, (uint64_t*)&relative_address, instruction);
		to_init->instructions [num_instructions-1] = *instruction;
		to_init->instructions [num_instructions-1].detail = (cs_detail*)malloc (sizeof(cs_detail));
		*(to_init->instructions [num_instructions-1].detail) = *(instruction->detail);
		current_addr = index_to_addr ((char*)current - file_buf);

		//Identify references to conditional jump blocks and function calls for later disassembly.
		if (instruction->detail->x86.op_count && instruction->detail->x86.operands [0].type > X86_OP_REG) //Please don't go chasing rax...
		{
			//Keep track of calls
			if (instruction->id == X86_INS_CALL)
			{
				num_calls ++;

				//More dynamic memory allocation stuff here
				if (num_calls - 1)
				{
					if (num_calls * sizeof (unsigned int) > to_init->calls_buf_size)
					{
						to_init->calls_buf_size *= 2;
						to_init->calls = realloc (to_init->calls, to_init->calls_buf_size);
					}
				}
				else
				{
					to_init->calls_buf_size = 8 * sizeof (unsigned int);
					to_init->calls = malloc (to_init->calls_buf_size);
				}

				//Add operand address to call buffer 
				to_init->calls [num_calls-1] = relative_insn (instruction, current_addr);
			}
		}
		//Keep track of how many times we've seen the instruction "push %ebp". One too many and we've started on the adjacent function.
		if ((instruction->id >= X86_INS_PUSH && instruction->id <= X86_INS_PUSHFQ) && (instruction->detail->x86.operands [0].reg == X86_REG_EBP || instruction->detail->x86.operands [0].reg == X86_REG_RBP))
			num_push_ebp ++;
		if (current_addr > stop_addr) //If we're outside the text section, we should be done.
			num_push_ebp = 2;
	//Stop disassembly of jump block at next unconditional jump or call
	} while (instruction->mnemonic [0] != 'j' && num_push_ebp != 2); //Jump block ends on jump or return

	//Synchronize the jump block with locals
	to_init->end = current_addr;
	to_init->num_conditional_jumps = num_conditional_jumps;
	to_init->num_calls = num_calls;
	to_init->num_instructions = num_instructions;
	if (instruction->id >= X86_INS_JAE && instruction->id <= X86_INS_JS && instruction->id != X86_INS_JMP)
	{
		if (relative_insn (instruction, current_addr) < current_addr - instruction->size)
		{
			to_init->flags |= IS_LOOP;
			next_flags |= IS_AFTER_LOOP;
		}
	}

	cs_free (instruction, 1);

	//Print jump block start address; uncomment for debugging information
	//printf ("%p\n", to_init->start);

	return to_init; //Convenient to return the to_init param so we can chain function calls like "example (init_jump_block (malloc (sizeof (jump_block)), some_addr, block))"
}
Beispiel #9
0
static int32_t dre_card_init(struct s_reader *reader, ATR *newatr)
{
	get_atr;
	def_resp;
	uchar ua[] = { 0x43, 0x15 };  // get serial number (UA)
	uchar providers[] = { 0x49, 0x15 };   // get providers
	int32_t i;
	char *card;
	char tmp[9];

	if((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
				((atr[4] != 0xca) || (atr[5] != 0x07)) &&
				((atr[4] != 0x01) || (atr[5] != 0x01))
			))
		{ return ERROR; }

	if(!cs_malloc(&reader->csystem_data, sizeof(struct dre_data)))
		{ return ERROR; }
	struct dre_data *csystem_data = reader->csystem_data;

	csystem_data->provider = atr[6];
	uchar checksum = xor(atr + 1, 6);

	if(checksum != atr[7])
		{ rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]); }

	switch(atr[6])
	{
	case 0x11:
		card = "Tricolor Centr";
		reader->caid = 0x4ae1;
		break;          //59 type card = MSP (74 type = ATMEL)
	case 0x12:
		card = "Cable TV";
		reader->caid = 0x4ae1;  //TODO not sure about this one
		break;
	case 0x14:
		card = "Tricolor Syberia / Platforma HD new";
		reader->caid = 0x4ae1;
		break;          //59 type card
	case 0x15:
		card = "Platforma HD / DW old";
		reader->caid = 0x4ae1;
		break;          //59 type card
	default:
		card = "Unknown";
		reader->caid = 0x4ae1;
		break;
	}

	memset(reader->prid, 0x00, 8);

	static const uchar cmd30[] =
	{
		0x30, 0x81, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x06, 0x87, 0x08, 0x09, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05,
		0x00
	};
	dre_cmd(cmd30);       //unknown command, generates error on card 0x11 and 0x14
	/*
	response:
	59 03 E2 E3
	FE 48 */

	uchar cmd54[] = { 0x54, 0x14 };   // geocode
	cmd54[1] = csystem_data->provider;
	uchar geocode = 0;
	if((dre_cmd(cmd54)))      //error would not be fatal, like on 0x11 cards
		{ geocode = cta_res[3]; }

	providers[1] = csystem_data->provider;
	if(!(dre_cmd(providers)))
		{ return ERROR; }           //fatal error
	if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
		{ return ERROR; }
	uchar provname[128];
	for(i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++)
	{
		provname[i] = cta_res[6 + i];
		if(provname[i] == 0x00)
			{ break; }
	}
	int32_t major_version = cta_res[3];
	int32_t minor_version = cta_res[4];

	ua[1] = csystem_data->provider;
	dre_cmd(ua);          //error would not be fatal

	int32_t hexlength = cta_res[1] - 2;   //discard first and last byte, last byte is always checksum, first is answer code

	reader->hexserial[0] = 0;
	reader->hexserial[1] = 0;
	memcpy(reader->hexserial + 2, cta_res + 3, hexlength);

	int32_t low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
	int32_t dre_chksum = 0;
	uchar buf[32];
	snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider - 16, major_version + 1, low_dre_id);
	for(i = 0; i < 32; i++)
	{
		if(buf[i] == 0x00)
			{ break; }
		dre_chksum += buf[i] - 48;
	}

	rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
			reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider - 16,
			major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
	rdr_log(reader, "Provider name:%s.", provname);


	memset(reader->sa, 0, sizeof(reader->sa));
	memcpy(reader->sa[0], reader->hexserial + 2, 1);  //copy first byte of unique address also in shared address, because we dont know what it is...

	rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
					  reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));

	reader->nprov = 1;

	if(!dre_set_provider_info(reader))
		{ return ERROR; }           //fatal error

	rdr_log(reader, "ready for requests");
	return OK;
}
Beispiel #10
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
#if USE_ITER_API
	static
#endif
	cs_insn *insn = NULL;
	int mode = (a->bits==64)? CS_MODE_64:
		(a->bits==32)? CS_MODE_32:
		(a->bits==16)? CS_MODE_16: 0;
	int n, ret = cs_open (CS_ARCH_X86, mode, &handle);
	int regsz = 4;

	if (ret != CS_ERR_OK) {
		return 0;
	}
	switch (a->bits) {
	case 64: regsz = 8; break;
	case 16: regsz = 2; break;
	default:
	case 32: regsz = 4; break;
	}
	memset (op, '\0', sizeof (RAnalOp));
	op->cycles = 1; // aprox
	op->type = R_ANAL_OP_TYPE_NULL;
	op->jump = UT64_MAX;
	op->fail = UT64_MAX;
	op->ptr = op->val = UT64_MAX;
	op->src[0] = NULL;
	op->src[1] = NULL;
	op->size = 0;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	// capstone-next
#if USE_ITER_API
	{
		ut64 naddr = addr;
		size_t size = len;
		if (insn == NULL)
			insn = cs_malloc (handle);
		n = cs_disasm_iter (handle, (const uint8_t**)&buf,
			&size, (uint64_t*)&naddr, insn);
	}
#else
	n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn);
#endif
	struct Getarg gop = {
		.handle = handle,
		.insn = insn,
		.bits = a->bits
	};
	if (n<1) {
		op->type = R_ANAL_OP_TYPE_ILL;
	} else {
		int rs = a->bits/8;
		const char *pc = (a->bits==16)?"ip":
			(a->bits==32)?"eip":"rip";
		const char *sp = (a->bits==16)?"sp":
			(a->bits==32)?"esp":"rsp";
		const char *bp = (a->bits==16)?"bp":
			(a->bits==32)?"ebp":"rbp";
		op->size = insn->size;
		op->family = 0;
		op->prefix = 0;
		switch (insn->detail->x86.prefix[0]) {
		case X86_PREFIX_REPNE:
			op->prefix |= R_ANAL_OP_PREFIX_REPNE;
			break;
		case X86_PREFIX_REP:
			op->prefix |= R_ANAL_OP_PREFIX_REP;
			break;
		case X86_PREFIX_LOCK:
			op->prefix |= R_ANAL_OP_PREFIX_LOCK;
			break;
		}
		switch (insn->id) {
		case X86_INS_FNOP:
		case X86_INS_NOP:
		case X86_INS_PAUSE:
			op->type = R_ANAL_OP_TYPE_NOP;
			if (a->decode)
				esilprintf (op, ",");
			break;
		case X86_INS_HLT:
			op->type = R_ANAL_OP_TYPE_TRAP;
			break;
		case X86_INS_FBLD:
		case X86_INS_FBSTP:
		case X86_INS_FCOMPP:
		case X86_INS_FDECSTP:
		case X86_INS_FEMMS:
		case X86_INS_FFREE:
		case X86_INS_FICOM:
		case X86_INS_FICOMP:
		case X86_INS_FINCSTP:
		case X86_INS_FNCLEX:
		case X86_INS_FNINIT:
		case X86_INS_FNSTCW:
		case X86_INS_FNSTSW:
		case X86_INS_FPATAN:
		case X86_INS_FPREM:
		case X86_INS_FPREM1:
		case X86_INS_FPTAN:
#if CS_API_MAJOR >=4
		case X86_INS_FFREEP:
#endif
		case X86_INS_FRNDINT:
		case X86_INS_FRSTOR:
		case X86_INS_FNSAVE:
		case X86_INS_FSCALE:
		case X86_INS_FSETPM:
		case X86_INS_FSINCOS:
		case X86_INS_FNSTENV:
		case X86_INS_FXAM:
		case X86_INS_FXSAVE:
		case X86_INS_FXSAVE64:
		case X86_INS_FXTRACT:
		case X86_INS_FYL2X:
		case X86_INS_FYL2XP1:
		case X86_INS_FISTTP:
		case X86_INS_FSQRT:
		case X86_INS_FXCH:
		case X86_INS_FTST:
		case X86_INS_FUCOMPI:
		case X86_INS_FUCOMI:
		case X86_INS_FUCOMPP:
		case X86_INS_FUCOMP:
		case X86_INS_FUCOM:
			op->type = R_ANAL_OP_TYPE_SUB;
			op->family = R_ANAL_OP_FAMILY_FPU;
			break;
		case X86_INS_FLDCW:
		case X86_INS_FLDENV:
		case X86_INS_FLDL2E:
		case X86_INS_FLDL2T:
		case X86_INS_FLDLG2:
		case X86_INS_FLDLN2:
		case X86_INS_FLDPI:
		case X86_INS_FLDZ:
		case X86_INS_FLD1:
		case X86_INS_FLD:
			op->type = R_ANAL_OP_TYPE_LOAD;
			op->family = R_ANAL_OP_FAMILY_FPU;
			break;
		case X86_INS_FIST:
		case X86_INS_FISTP:
		case X86_INS_FST:
		case X86_INS_FSTP:
		case X86_INS_FSTPNCE:
		case X86_INS_FXRSTOR:
		case X86_INS_FXRSTOR64:
			op->type = R_ANAL_OP_TYPE_STORE;
			op->family = R_ANAL_OP_FAMILY_FPU;
			break;
		case X86_INS_FDIV:
		case X86_INS_FIDIV:
		case X86_INS_FDIVP:
		case X86_INS_FDIVR:
		case X86_INS_FIDIVR:
		case X86_INS_FDIVRP:
		case X86_INS_FSUBR:
		case X86_INS_FISUBR:
		case X86_INS_FSUBRP:
		case X86_INS_FSUB:
		case X86_INS_FISUB:
		case X86_INS_FSUBP:
			op->type = R_ANAL_OP_TYPE_SUB;
			op->family = R_ANAL_OP_FAMILY_FPU;
			break;
		case X86_INS_FMUL:
		case X86_INS_FIMUL:
		case X86_INS_FMULP:
			op->type = R_ANAL_OP_TYPE_MUL;
			op->family = R_ANAL_OP_FAMILY_FPU;
			break;
		case X86_INS_CLI:
		case X86_INS_STI:
		case X86_INS_CLC:
		case X86_INS_STC:
			op->type = R_ANAL_OP_TYPE_SWI;
			op->family = R_ANAL_OP_FAMILY_PRIV;
			break;
		// cmov
		case X86_INS_SETNE:
		case X86_INS_SETNO:
		case X86_INS_SETNP:
		case X86_INS_SETNS:
		case X86_INS_SETO:
		case X86_INS_SETP:
		case X86_INS_SETS:
		case X86_INS_SETL:
		case X86_INS_SETLE:
		case X86_INS_SETB:
		case X86_INS_SETG:
		case X86_INS_SETAE:
		case X86_INS_SETA:
		case X86_INS_SETBE:
		case X86_INS_SETE:
		case X86_INS_SETGE:
			op->type = R_ANAL_OP_TYPE_CMOV;
			op->family = 0;
			if (a->decode) {
				char *dst = getarg (&gop, 0, 0, NULL);
				switch (insn->id) {
				case X86_INS_SETE:  esilprintf (op, "zf,%s,=", dst); break;
				case X86_INS_SETNE: esilprintf (op, "zf,!,%s,=", dst); break;
				case X86_INS_SETO:  esilprintf (op, "of,%s,=", dst); break;
				case X86_INS_SETNO: esilprintf (op, "of,!,%s,=", dst); break;
				case X86_INS_SETP:  esilprintf (op, "pf,%s,=", dst); break;
				case X86_INS_SETNP: esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETS:  esilprintf (op, "sf,%s,=", dst); break;
				case X86_INS_SETNS: esilprintf (op, "sf,!,%s,=", dst); break;

				case X86_INS_SETB:  esilprintf (op, "cf,%s,=", dst); break;
				case X86_INS_SETAE: esilprintf (op, "cf,!,%s,=", dst); break;

				/* TODO */
#if 0
SETLE/SETNG
	Sets the byte in the operand to 1 if the Zero Flag is set or the
	Sign Flag is not equal to the Overflow Flag,  otherwise sets the
	operand to 0.
SETBE/SETNA
	Sets the byte in the operand to 1 if the Carry Flag or the Zero
        Flag is set, otherwise sets the operand to 0.
SETL/SETNGE
	Sets the byte in the operand to 1 if the Sign Flag is not equal
        to the Overflow Flag, otherwise sets the operand to 0.

				case X86_INS_SETL:  esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETLE: esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETG:  esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETA:  esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETBE: esilprintf (op, "pf,!,%s,=", dst); break;
				case X86_INS_SETGE: esilprintf (op, "pf,!,%s,=", dst); break;
						    break;
#endif
				}
				free (dst);
			}
			break;
		// cmov
		case X86_INS_CMOVA:
		case X86_INS_CMOVAE:
		case X86_INS_CMOVB:
		case X86_INS_CMOVBE:
		case X86_INS_FCMOVBE:
		case X86_INS_FCMOVB:
		case X86_INS_CMOVE:
		case X86_INS_FCMOVE:
		case X86_INS_CMOVG:
		case X86_INS_CMOVGE:
		case X86_INS_CMOVL:
		case X86_INS_CMOVLE:
		case X86_INS_FCMOVNBE:
		case X86_INS_FCMOVNB:
		case X86_INS_CMOVNE:
		case X86_INS_FCMOVNE:
		case X86_INS_CMOVNO:
		case X86_INS_CMOVNP:
		case X86_INS_FCMOVNU:
		case X86_INS_CMOVNS:
		case X86_INS_CMOVO:
		case X86_INS_CMOVP:
		case X86_INS_FCMOVU:
		case X86_INS_CMOVS:
		// mov
		case X86_INS_MOV:
		case X86_INS_MOVAPS:
		case X86_INS_MOVAPD:
		case X86_INS_MOVZX:
		case X86_INS_MOVUPS:
		case X86_INS_MOVABS:
		case X86_INS_MOVHPD:
		case X86_INS_MOVHPS:
		case X86_INS_MOVLPD:
		case X86_INS_MOVLPS:
		case X86_INS_MOVBE:
		case X86_INS_MOVSB:
		case X86_INS_MOVSD:
		case X86_INS_MOVSQ:
		case X86_INS_MOVSS:
		case X86_INS_MOVSX:
		case X86_INS_MOVSXD:
		case X86_INS_MOVSW:
		case X86_INS_MOVD:
		case X86_INS_MOVQ:
		case X86_INS_MOVDQ2Q:
			{
			op->type = R_ANAL_OP_TYPE_MOV;
			op->ptr = UT64_MAX;
			switch (INSOP(0).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(0).mem.disp;
				op->refptr = INSOP(0).size;
				if (INSOP(0).mem.base == X86_REG_RIP) {
					op->ptr += addr + insn->size;
				} else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
					op->ptr = UT64_MAX;
					op->stackop = R_ANAL_STACK_SET;
					op->stackptr = regsz;
				} else {
					op->ptr = UT64_MAX;
				}
				if (a->decode) {
					if (op->prefix & R_ANAL_OP_PREFIX_REP) {
						int width = INSOP(0).size;
						const char *src = cs_reg_name(handle, INSOP(1).mem.base);
						const char *dst = cs_reg_name(handle, INSOP(0).mem.base);
						const char *counter = (a->bits==16)?"cx":
							(a->bits==32)?"ecx":"rcx";
						esilprintf (op, "%s,!,?{,BREAK,},%s,DUP,%s,DUP,"\
								"%s,[%d],%s,=[%d],df,?{,%d,%s,-=,%d,%s,-=,},"\
								"df,!,?{,%d,%s,+=,%d,%s,+=,},%s,--=,%s," \
								"?{,8,GOTO,},%s,=,%s,=",
								counter, src, dst, src, width, dst,
								width, width, src, width, dst, width, src,
								width, dst, counter, counter, dst, src);
					} else {
						char *src = getarg (&gop, 1, 0, NULL);
						char *dst = getarg (&gop, 0, 1, NULL);
						esilprintf (op, "%s,%s", src, dst);
						free (src);
						free (dst);
					}
				}
				break;
			default:
				if (a->decode) {
					char *src = getarg (&gop, 1, 0, NULL);
					char *dst = getarg (&gop, 0, 0, NULL);
					esilprintf (op, "%s,%s,=", src, dst);
					free (src);
					free (dst);
				}
				break;
			}
			if (op->refptr<1 || op->ptr == UT64_MAX) {
				switch (INSOP(1).type) {
				case X86_OP_MEM:
					op->ptr = INSOP(1).mem.disp;
					op->refptr = INSOP(1).size;
					if (INSOP(1).mem.base == X86_REG_RIP) {
						op->ptr += addr + insn->size;
					} else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
						op->stackop = R_ANAL_STACK_GET;
						op->stackptr = regsz;
					}
					break;
				case X86_OP_IMM:
					if (INSOP(1).imm > 10)
						op->ptr = INSOP(1).imm;
					break;
				default:
					break;
				}
			}
			}
			break;
		case X86_INS_SHL:
		case X86_INS_SHLD:
		case X86_INS_SHLX:
			op->type = R_ANAL_OP_TYPE_SHL;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "<<");
				esilprintf (op, "%s,%s,$z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SAR:
		case X86_INS_SARX:
			op->type = R_ANAL_OP_TYPE_SAR;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, ">>");
				esilprintf (op, "%s,%s,$z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SAL:
			op->type = R_ANAL_OP_TYPE_SAL;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "<<");
				esilprintf (op, "%s,%s,$z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SALC:
			op->type = R_ANAL_OP_TYPE_SAL;
			if (a->decode) {
				esilprintf (op, "$z,DUP,zf,=,al,=");
			}
			break;
		case X86_INS_SHR:
		case X86_INS_SHRD:
		case X86_INS_SHRX:
			op->type = R_ANAL_OP_TYPE_SHR;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 0, NULL);
				esilprintf (op, "%s,%s,>>=,$z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_CMP:
		case X86_INS_CMPPD:
		case X86_INS_CMPPS:
		case X86_INS_CMPSW:
		case X86_INS_CMPSD:
		case X86_INS_CMPSQ:
		case X86_INS_CMPSB:
		case X86_INS_CMPSS:
		case X86_INS_TEST:
			if (insn->id == X86_INS_TEST) {
				op->type = R_ANAL_OP_TYPE_ACMP;					//compare via and
				if (a->decode) {
					char *src = getarg (&gop, 1, 0, NULL);
					char *dst = getarg (&gop, 0, 0, NULL);
					esilprintf (op, "0,%s,%s,&,==,$z,zf,=,$p,pf,=,$s,sf,=,0,cf,=,0,of,=",
						src, dst);
					free (src);
					free (dst);
				}
			} else {
				op->type = R_ANAL_OP_TYPE_CMP;
				if (a->decode) {
					char *src = getarg (&gop, 1, 0, NULL);
					char *dst = getarg (&gop, 0, 0, NULL);
					esilprintf (op,  "%s,%s,==,$z,zf,=,$b%d,cf,=,$p,pf,=,$s,sf,=",
						src, dst, (INSOP(0).size*8));
					free (src);
					free (dst);
				}
			}
			switch (INSOP(0).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(0).mem.disp;
				op->refptr = INSOP(0).size;
				if (INSOP(0).mem.base == X86_REG_RIP) {
					op->ptr += addr + insn->size;
				} else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
					op->stackop = R_ANAL_STACK_SET;
					op->stackptr = regsz;
				}
				op->ptr = INSOP(1).imm;
				break;
			default:
				switch (INSOP(1).type) {
				case X86_OP_MEM:
					op->ptr = INSOP(1).mem.disp;
					op->refptr = INSOP(1).size;
					if (INSOP(1).mem.base == X86_REG_RIP) {
						op->ptr += addr + insn->size;
					} else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
						op->stackop = R_ANAL_STACK_SET;
						op->stackptr = regsz;
					}
					break;
				case X86_OP_IMM:
					op->ptr = INSOP(1).imm;
					break;
				default:
					break;
				}
				break;
			}
			break;
		case X86_INS_LEA:
			op->type = R_ANAL_OP_TYPE_LEA;
			if (a->decode) {
				char *src = getarg (&gop, 0, 0, NULL);
				char *dst = getarg (&gop, 1, 2, NULL);
				esilprintf (op, "%s,%s,=", dst, src);
				free (src);
				free (dst);
			}
			switch (INSOP(1).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(1).mem.disp;
				op->refptr = INSOP(1).size;
				switch (INSOP(1).mem.base) {
				case X86_REG_RIP:
					op->ptr += addr + op->size;
					break;
				case X86_REG_RBP:
				case X86_REG_EBP:
					op->stackop = R_ANAL_STACK_GET;
					op->stackptr = regsz;
					break;
				default:
					/* unhandled */
					break;
				}
				break;
			case X86_OP_IMM:
				if (INSOP(1).imm > 10)
					op->ptr = INSOP(1).imm;
				break;
			default:
				break;
			}
			break;
		case X86_INS_ENTER:
		case X86_INS_PUSH:
		case X86_INS_PUSHAW:
		case X86_INS_PUSHAL:
		case X86_INS_PUSHF:
			{
				char *dst = getarg (&gop, 0, 0, NULL);
				esilprintf (op,  "%d,%s,-=,%s,%s,=[%d]", rs, sp, dst, sp, rs);
				free (dst);
			}
			switch (INSOP(0).type) {
			case X86_OP_IMM:
				op->ptr = INSOP(0).imm;
				op->type = R_ANAL_OP_TYPE_PUSH;
				break;
			default:
				op->type = R_ANAL_OP_TYPE_UPUSH;
				break;
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = regsz;
			break;
		case X86_INS_LEAVE:
			op->type = R_ANAL_OP_TYPE_POP;
			if (a->decode) {
				esilprintf (op, "%s,%s,=,%s,[%d],%s,=,%d,%s,+=",
					bp, sp, sp, rs, bp, rs, sp);
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_POP:
		case X86_INS_POPF:
		case X86_INS_POPAW:
		case X86_INS_POPAL:
		case X86_INS_POPCNT:
			op->type = R_ANAL_OP_TYPE_POP;
			if (a->decode) {
				char *dst = getarg (&gop, 0, 0, NULL);
				esilprintf (op,
					"%s,[%d],%s,=,%d,%s,+=",
					sp, rs, dst, rs, sp);
				free (dst);
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_RET:
		case X86_INS_RETF:
		case X86_INS_RETFQ:
		case X86_INS_IRET:
		case X86_INS_IRETD:
		case X86_INS_IRETQ:
		case X86_INS_SYSRET:
			op->type = R_ANAL_OP_TYPE_RET;
			if (a->decode)
				esilprintf (op, "%s,[%d],%s,=,%d,%s,+=",
					sp, rs, pc, rs, sp);
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_INT3:
			if (a->decode)
				esilprintf (op, "3,$");
			op->type = R_ANAL_OP_TYPE_TRAP; // TRAP
			break;
		case X86_INS_INT1:
			if (a->decode)
				esilprintf (op, "1,$");
			op->type = R_ANAL_OP_TYPE_SWI; // TRAP
			break;
		case X86_INS_INT:
			if (a->decode)
				esilprintf (op, "%d,$",
					R_ABS((int)INSOP(0).imm));
			op->type = R_ANAL_OP_TYPE_SWI;
			break;
		case X86_INS_SYSCALL:
			op->type = R_ANAL_OP_TYPE_SWI;
			break;
		case X86_INS_INTO:
		case X86_INS_VMCALL:
		case X86_INS_VMMCALL:
			op->type = R_ANAL_OP_TYPE_TRAP;
			if (a->decode)
				esilprintf (op, "%d,$", (int)INSOP(0).imm);
			break;
		case X86_INS_JL:
		case X86_INS_JLE:
		case X86_INS_JA:
		case X86_INS_JAE:
		case X86_INS_JB:
		case X86_INS_JBE:
		case X86_INS_JCXZ:
		case X86_INS_JECXZ:
		case X86_INS_JRCXZ:
		case X86_INS_JO:
		case X86_INS_JNO:
		case X86_INS_JS:
		case X86_INS_JNS:
		case X86_INS_JP:
		case X86_INS_JNP:
		case X86_INS_JE:
		case X86_INS_JNE:
		case X86_INS_JG:
		case X86_INS_JGE:
		case X86_INS_LOOP:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = INSOP(0).imm;
			op->fail = addr+op->size;
			if (a->decode) {
				char *dst = getarg (&gop, 0, 2, NULL);
				switch (insn->id) {
				case X86_INS_JL:
					esilprintf (op, "of,sf,^,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JLE:
					esilprintf (op, "of,sf,^,zf,|,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JA:
					esilprintf (op, "cf,zf,|,!,?{,%s,%s,=,}",dst, pc);
					break;
				case X86_INS_JAE:
					esilprintf (op, "cf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JB:
					esilprintf (op, "cf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JO:
					esilprintf (op, "of,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNO:
					esilprintf (op, "of,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JE:
					esilprintf (op, "zf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JGE:
					esilprintf (op, "of,!,sf,^,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNE:
					esilprintf (op, "zf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JG:
					esilprintf (op, "sf,of,!,^,zf,!,&,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JS:
					esilprintf (op, "sf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNS:
					esilprintf (op, "sf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JP:
					esilprintf (op, "pf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNP:
					esilprintf (op, "pf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JBE:
					esilprintf (op, "zf,cf,|,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JCXZ:
					esilprintf (op, "cx,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JECXZ:
					esilprintf (op, "ecx,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JRCXZ:
					esilprintf (op, "rcx,!,?{,%s,%s,=,}", dst, pc);
					break;
				}
				free (dst);
			}
			break;
		case X86_INS_CALL:
		case X86_INS_LCALL:
			switch (INSOP(0).type) {
			case X86_OP_IMM:
				op->type = R_ANAL_OP_TYPE_CALL;
				// TODO: what if UCALL?
				// TODO: use imm_size
				op->jump = INSOP(0).imm;
				op->fail = addr+op->size;
				break;
			case X86_OP_MEM:
				op->type = R_ANAL_OP_TYPE_UCALL;
				op->jump = UT64_MAX;
				if (INSOP(0).mem.base == 0) {
					op->ptr = INSOP(0).mem.disp;
				}
				break;
			default:
				op->type = R_ANAL_OP_TYPE_UCALL;
				op->jump = UT64_MAX;
				break;
			}
			if (a->decode) {
				char* arg = getarg (&gop, 0, 0, NULL);
				esilprintf (op,
						"%s,"
						"%d,%s,-=,%s,"
						"=[],"
						"%s,%s,=",
						pc, rs, sp, sp, arg, pc);
				free (arg);
			}
			break;
		case X86_INS_JMP:
		case X86_INS_LJMP:
			if (a->decode) {
				char *src = getarg (&gop, 0, 0, NULL);
				esilprintf (op, "%s,%s,=", src, pc);
				free (src);
			}
			// TODO: what if UJMP?
			switch (INSOP(0).type) {
			case X86_OP_IMM:
				op->jump = INSOP(0).imm;
				op->type = R_ANAL_OP_TYPE_JMP;
				if (a->decode) {
					ut64 dst = INSOP(0).imm;
					esilprintf (op, "0x%"PFMT64x",%s,=", dst, pc);
				}
				break;
			case X86_OP_MEM:
				op->type = R_ANAL_OP_TYPE_UJMP;
				if (INSOP(0).mem.base == X86_REG_RIP) {
					op->ptr = INSOP(0).mem.disp;
					op->ptr += addr + insn->size;
					op->refptr = 8;
				} else {
					cs_x86_op in = INSOP(0);
					if (in.mem.index == 0 && in.mem.base == 0 && in.mem.scale == 1) {
						op->type = R_ANAL_OP_TYPE_UJMP;
						op->ptr = in.mem.disp;
						if (a->decode) {
							esilprintf (op, "0x%"PFMT64x",[],%s,=", op->ptr, pc);
						}
					}
				}
				break;
			case X86_OP_REG:
			case X86_OP_FP:
			default: // other?
				op->type = R_ANAL_OP_TYPE_UJMP;
				break;
			}
			break;
		case X86_INS_IN:
		case X86_INS_INSW:
		case X86_INS_INSD:
		case X86_INS_INSB:
		case X86_INS_OUT:
		case X86_INS_OUTSB:
		case X86_INS_OUTSD:
		case X86_INS_OUTSW:
			op->type = R_ANAL_OP_TYPE_IO;
			break;
		case X86_INS_VXORPD:
		case X86_INS_VXORPS:
		case X86_INS_VPXORD:
		case X86_INS_VPXORQ:
		case X86_INS_VPXOR:
		case X86_INS_XORPS:
		case X86_INS_KXORW:
		case X86_INS_PXOR:
		case X86_INS_XOR:
			op->type = R_ANAL_OP_TYPE_XOR;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "^");
				esilprintf (op, "%s,%s,$z,zf,=,$p,pf,=,0,cf,=,0,of,=,$s,sf,=",
					src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_OR:
			op->type = R_ANAL_OP_TYPE_OR;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 0, NULL);
				esilprintf (op, "%s,%s,|=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_INC:
			op->type = R_ANAL_OP_TYPE_ADD;
			op->val = 1;
			if (a->decode) {
				char *src = getarg (&gop, 0, 0, NULL);
				esilprintf (op, "%s,++=", src);
				free (src);
			}
			break;
		case X86_INS_DEC:
			op->type = R_ANAL_OP_TYPE_SUB;
			op->val = 1;
			if (a->decode) {
				char *src = getarg (&gop, 0, 0, NULL);
				esilprintf (op, "%s,--=", src);
				free (src);
			}
			break;
		case X86_INS_SUB:
		case X86_INS_PSUBB:
		case X86_INS_PSUBW:
		case X86_INS_PSUBD:
		case X86_INS_PSUBQ:
		case X86_INS_PSUBSB:
		case X86_INS_PSUBSW:
		case X86_INS_PSUBUSB:
		case X86_INS_PSUBUSW:
			op->type = R_ANAL_OP_TYPE_SUB;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "-");
				esilprintf (op, "%s,%s,$c,cf,=,$z,zf,=,$s,sf,=,$o,of,=",
					src, dst); // TODO: update flags
				free (src);
				free (dst);
			}
			if (INSOP(0).type == X86_OP_REG && INSOP(1).type == X86_OP_IMM) {
				if (INSOP(0).reg == X86_REG_RSP || INSOP(0).reg == X86_REG_ESP) {
					op->stackop = R_ANAL_STACK_INC;
					op->stackptr = INSOP(1).imm;
				}
			}
			break;
		case X86_INS_LIDT:
			op->type = R_ANAL_OP_TYPE_LOAD;
			op->family = R_ANAL_OP_FAMILY_PRIV;
			break;
		case X86_INS_SIDT:
			op->type = R_ANAL_OP_TYPE_STORE;
			op->family = R_ANAL_OP_FAMILY_PRIV;
			break;
		case X86_INS_RDRAND:
		case X86_INS_RDSEED:
		case X86_INS_RDMSR:
		case X86_INS_RDPMC:
		case X86_INS_RDTSC:
		case X86_INS_RDTSCP:
		case X86_INS_CRC32:
		case X86_INS_SHA1MSG1:
		case X86_INS_SHA1MSG2:
		case X86_INS_SHA1NEXTE:
		case X86_INS_SHA1RNDS4:
		case X86_INS_SHA256MSG1:
		case X86_INS_SHA256MSG2:
		case X86_INS_SHA256RNDS2:
		case X86_INS_AESDECLAST:
		case X86_INS_AESDEC:
		case X86_INS_AESENCLAST:
		case X86_INS_AESENC:
		case X86_INS_AESIMC:
		case X86_INS_AESKEYGENASSIST:
			// AES instructions
			op->family = R_ANAL_OP_FAMILY_CRYPTO;
			op->type = R_ANAL_OP_TYPE_MOV; // XXX
			break;
		case X86_INS_AND:
		case X86_INS_ANDN:
		case X86_INS_ANDPD:
		case X86_INS_ANDPS:
		case X86_INS_ANDNPD:
		case X86_INS_ANDNPS:
			op->type = R_ANAL_OP_TYPE_AND;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "&");
				// TODO: update of = cf = 0
				// TODO: update sf, zf and pf
				// TODO: af is undefined
				esilprintf (op, "0,of,=,0,cf,=," // set carry and overflow flags
					"%s,%s," // set reg value
					"$z,zf,=,"  // update zero flag
					"$s,sf,=,"  // update sign flag
					"$o,pf,=",  // update parity flag
					// TODO: add sign and parity flags here
					src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_DIV:
		case X86_INS_IDIV:
			op->type = R_ANAL_OP_TYPE_DIV;
			if (a->decode) {
				int width = INSOP(0).size;
				char *dst = getarg (&gop, 0, 0, NULL);
				const char *r_ax = (width==2)?"ax": (width==4)?"eax":"rax";
				const char *r_dx = (width==2)?"dx": (width==4)?"edx":"rdx";
				// TODO update flags & handle signedness
				esilprintf (op, "%s,%s,%%,%s,=,%s,%s,/,%s,=",
					dst, r_ax, r_dx, dst, r_ax, r_ax);
				free (dst);
			}
			break;
		case X86_INS_MUL:
		case X86_INS_MULX:
		case X86_INS_MULPD:
		case X86_INS_MULPS:
		case X86_INS_MULSD:
		case X86_INS_MULSS:
			op->type = R_ANAL_OP_TYPE_MUL;
			if (a->decode) {
				char *src = getarg (&gop, 1, 0, NULL);
				char *dst = getarg (&gop, 0, 1, "*");
				if (!src && dst) {
					switch (dst[0]) {
					case 'r':
						src = strdup ("rax");
						break;
					case 'e':
						src = strdup ("eax");
						break;
					default:
						src = strdup ("al");
						break;
					}
				}
				esilprintf (op, "%s,%s", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_PACKSSDW:
		case X86_INS_PACKSSWB:
		case X86_INS_PACKUSWB:
			op->type = R_ANAL_OP_TYPE_MOV;
			op->family = R_ANAL_OP_FAMILY_MMX;
			break;
		case X86_INS_PADDB:
		case X86_INS_PADDD:
		case X86_INS_PADDW:
		case X86_INS_PADDSB:
		case X86_INS_PADDSW:
		case X86_INS_PADDUSB:
		case X86_INS_PADDUSW:
			op->type = R_ANAL_OP_TYPE_ADD;
			op->family = R_ANAL_OP_FAMILY_MMX;
			break;
		case X86_INS_FADD:
		case X86_INS_FADDP:
			op->family = R_ANAL_OP_FAMILY_FPU;
			/* pass thru */
		case X86_INS_ADD:
		case X86_INS_ADDPS:
		case X86_INS_ADDSD:
		case X86_INS_ADDSS:
		case X86_INS_ADDSUBPD:
		case X86_INS_ADDSUBPS:
		case X86_INS_ADDPD:
		case X86_INS_XADD:
			op->type = R_ANAL_OP_TYPE_ADD;
			if (a->decode) {
				if (INSOP(0).type == X86_OP_MEM) {
					char *src = getarg (&gop, 1, 0, NULL);
					char *src2 = getarg (&gop, 0, 0, NULL);
					char *dst = getarg (&gop, 0, 1, NULL);
					// TODO: update flags
					esilprintf (op, "%s,%s,+,%s", src, src2, dst);
					free (src);
					free (src2);
					free (dst);
				} else {
					char *src = getarg (&gop, 1, 0, NULL);
					char *dst = getarg (&gop, 0, 1, "+");
					esilprintf (op, "%s,%s", src, dst);		// TODO: update flags
					free (src);
					free (dst);
				}
			}
			if (INSOP(0).type == X86_OP_REG && INSOP(1).type == X86_OP_IMM) {
				if (INSOP(0).reg == X86_REG_RSP || INSOP(0).reg == X86_REG_ESP) {
					op->stackop = R_ANAL_STACK_INC;
					op->stackptr = -INSOP(1).imm;
				}
			}
			break;
			/* Direction flag */
		case X86_INS_CLD:
			if (a->decode)
				esilprintf (op, "0,df,=");
			break;
		case X86_INS_STD:
			if (a->decode)
				esilprintf (op, "1,df,=");
			break;
		}
	}
//#if X86_GRP_PRIVILEGE>0
	if (insn) {
#if HAVE_CSGRP_PRIVILEGE
		if (cs_insn_group (handle, insn, X86_GRP_PRIVILEGE))
			op->family = R_ANAL_OP_FAMILY_PRIV;
#endif
#if !USE_ITER_API
		cs_free (insn, n);
#endif
	}
	cs_close (&handle);
	return op->size;
}
Beispiel #11
0
int32_t gbox_cmd_hello(struct s_client *cli, uchar *data, int32_t n)
{
	struct gbox_peer *peer = cli->gbox;
	int32_t i;
	int32_t ncards_in_msg = 0;
	int32_t payload_len = n;
	//TODO: checkcode_len can be made void
	int32_t checkcode_len = 0;
	int32_t hostname_len = 0;
	int32_t footer_len = 0;
	uint8_t *ptr = 0;

	if(!(data[0] == 0x48 && data[1] == 0x49))  // if not MSG_HELLO1
	{
		gbox_decompress(data, &payload_len);
	}
	cs_ddump_mask(D_READER, data, payload_len, "gbox: decompressed data (%d bytes):", payload_len);

	if((data[0x0B] == 0) | ((data[0x0A] == 1) && (data[0x0B] == 0x80)))
	{
		if(peer->gbox.cards)
			{ gbox_remove_cards_without_goodsids(peer->gbox.cards); }
		else
			{ peer->gbox.cards = ll_create("peer.cards"); }
	}
	if((data[0xB] & 0xF) == 0)
	{
		checkcode_len = 7;
		hostname_len = data[payload_len - 1];
		footer_len = hostname_len + 2;
	}

	if(data[0] == 0x48 && data[1] == 0x49)  // if MSG_HELLO1
		{ ptr = data + 11; }
	else
		{ ptr = data + 12; }

	while(ptr < data + payload_len - footer_len - checkcode_len - 1)
	{
		uint16_t caid;
		uint32_t provid;
		uint32_t provid1;

		switch(ptr[0])
		{
			//Viaccess
		case 0x05:
			caid = ptr[0] << 8;
			provid =  ptr[1] << 16 | ptr[2] << 8 | ptr[3];
			break;
			//Cryptoworks
		case 0x0D:
			caid = ptr[0] << 8 | ptr[1];
			provid =  ptr[2];
			break;
		default:
			caid = ptr[0] << 8 | ptr[1];
			provid =  ptr[2] << 8 | ptr[3];
			break;
		}

		//caid check
		if(chk_ctab(caid, &cli->reader->ctab))
		{

			provid1 =  ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
			uint8_t ncards = ptr[4];

			ptr += 5;

			for(i = 0; i < ncards; i++)
			{
				// for all n cards and current caid/provid,
				// create card info from data and add card to peer.cards
				struct gbox_card *card;
				if(!cs_malloc(&card, sizeof(struct gbox_card)))
					{ continue; }

				card->caid = caid;
				card->provid = provid;
				card->provid_1 = provid1;
				card->slot = ptr[0];
				card->dist = ptr[1] & 0xf;
				card->lvl = ptr[1] >> 4;
				card->peer_id = ptr[2] << 8 | ptr[3];
				ptr += 4;

				if((cli->reader->gbox_maxdist >= card->dist) && (card->peer_id != local_gbox.id))
				{

					LL_ITER it = ll_iter_create(peer->gbox.cards);
					struct gbox_card *card_s;
					uint8_t v_card = 0;
					while((card_s = ll_iter_next(&it)))    // don't add card if already in peer.cards list
					{
						if(card_s->peer_id == card->peer_id && card_s->provid_1 == card->provid_1)
						{
							gbox_free_card(card);
							card = NULL;
							v_card = 1;
							break;
						}
					}

					if(v_card != 1)    // new card - not in list
					{
						card->badsids = ll_create("badsids");
						card->goodsids = ll_create("goodsids");
						ll_append(peer->gbox.cards, card);
						ncards_in_msg++;
						cs_debug_mask(D_READER, "   card: caid=%04x, provid=%06x, slot=%d, level=%d, dist=%d, peer=%04x",
									  card->caid, card->provid, card->slot, card->lvl, card->dist, card->peer_id);
					}
				}
				else     // don't add card
				{
					gbox_free_card(card);
					card = NULL;
				}
				cli->reader->tcp_connected = 2; // we have card
			} // end for ncards
		}
		else
		{
Beispiel #12
0
static int32_t ecm_ratelimit_findspace(struct s_reader *reader, ECM_REQUEST *er, struct ecmrl rl, int32_t reader_mode)
{

	int32_t h, foundspace = -1;
	int32_t maxecms = MAXECMRATELIMIT; // init maxecms
	int32_t totalecms = 0; // init totalecms
	struct timeb actualtime;
	cs_ftime(&actualtime);
	for(h = 0; h < MAXECMRATELIMIT; h++)    // release slots with srvid that are overtime, even if not called from reader module to maximize available slots!
	{
		if(reader->rlecmh[h].last.time == -1) { continue; }
		int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last);
		if( gone >= (reader->rlecmh[h].ratelimittime + reader->rlecmh[h].srvidholdtime) || gone < 0) // gone <0 fixup for bad systemtime on dvb receivers while changing transponders
		{
			cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X released from slot %d/%d of reader %s (%"PRId64">=%d ratelimit ms + %d ms srvidhold!)",
						  reader->rlecmh[h].srvid, h + 1, MAXECMRATELIMIT, reader->label, gone,
						  reader->rlecmh[h].ratelimittime, reader->rlecmh[h].srvidholdtime);
			reader->rlecmh[h].last.time = -1;
			reader->rlecmh[h].srvid = -1;
			reader->rlecmh[h].kindecm = 0;
			reader->rlecmh[h].once = 0;
		}
		if(reader->rlecmh[h].last.time == -1) { continue; }
		if(reader->rlecmh[h].ratelimitecm < maxecms) { maxecms = reader->rlecmh[h].ratelimitecm; }  // we found a more critical ratelimit srvid
		totalecms++;
	}

	cs_log_dbg(D_CLIENT, "ratelimiter found total of %d srvid for reader %s most critical is limited to %d requests", totalecms, reader->label, maxecms);

	if(reader->cooldown[0] && reader->cooldownstate != 1) { maxecms = MAXECMRATELIMIT; }  // dont apply ratelimits if cooldown isnt in use or not in effect

	for(h = 0; h < MAXECMRATELIMIT; h++)    // check if srvid is already in a slot
	{
		if(reader->rlecmh[h].last.time == -1) { continue; }
		if(reader->rlecmh[h].srvid == er->srvid && reader->rlecmh[h].caid == rl.caid && reader->rlecmh[h].provid == rl.provid
				&& (!reader->rlecmh[h].chid || (reader->rlecmh[h].chid == rl.chid)))
		{
			int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last);
			cs_log_dbg(D_CLIENT, "ratelimiter found srvid %04X for %"PRId64" ms in slot %d/%d of reader %s", er->srvid, gone, h + 1, MAXECMRATELIMIT, reader->label);

			// check ecmunique if enabled and ecmunique time is done
			if(reader_mode && reader->ecmunique)
			{
				gone = comp_timeb(&actualtime, &reader->rlecmh[h].last);
				if(gone < reader->ratelimittime)
				{
					if(memcmp(reader->rlecmh[h].ecmd5, er->ecmd5, CS_ECMSTORESIZE)) //some boxes seem to send different ecms but asking in fact for same cw!
					{   // different ecm request than one in the slot!
						if(er->ecm[0] == reader->rlecmh[h].kindecm)
						{
							// same ecm type!
							char ecmd5[17 * 3];
							cs_hexdump(0, reader->rlecmh[h].ecmd5, 16, ecmd5, sizeof(ecmd5));
							cs_log_dbg(D_CLIENT, "ratelimiter ecm %s in this slot for next %d ms!", ecmd5,
										  (int)(reader->rlecmh[h].ratelimittime - gone));

							struct ecm_request_t *erold = NULL;
							if(!cs_malloc(&erold, sizeof(struct ecm_request_t)))
								{ return -2; }
							memcpy(erold, er, sizeof(struct ecm_request_t)); // copy ecm all
							memcpy(erold->ecmd5, reader->rlecmh[h].ecmd5, CS_ECMSTORESIZE); // replace md5 hash
							struct ecm_request_t *ecm = NULL;
							ecm = check_cache(erold, erold->client); //CHECK IF FOUND ECM IN CACHE
							NULLFREE(erold);
							if(ecm)   //found in cache
								{ write_ecm_answer(reader, er, ecm->rc, ecm->rcEx, ecm->cw, NULL, 0, &ecm->cw_ex); } // return controlword of the ecm sitting in the slot!
							else
								{ write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: no slots free!", 0, NULL); }

							NULLFREE(ecm);
							return -2;
						}
					}
				}
				if((er->ecm[0] != reader->rlecmh[h].kindecm) && (gone <= reader->ratelimittime))
				{
					if(!reader->rlecmh[h].once) // 1 premature ecmtype change is allowed (useful right after zapping to a channel!)
					{
						reader->rlecmh[h].once = 1;
						cs_log_dbg(D_CLIENT, "ratelimiter changing slot %d srvid %04X ecmtype once from %s to %s!", h+1, er->srvid,
							(reader->rlecmh[h].kindecm == 0x80 ? "even":"odd"), (er->ecm[0] == 0x80 ? "even":"odd"));
					}
					else
					{
						cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X only allowing ecmtype %s for next %d ms in slot %d/%d of reader %s -> skipping this slot!", reader->rlecmh[h].srvid,
							(reader->rlecmh[h].kindecm == 0x80 ? "even" : "odd"), (int)(reader->rlecmh[h].ratelimittime - gone), h + 1, maxecms, reader->label);
							continue;
					}
				}
			}

			if(h > 0)
			{
				for(foundspace = 0; foundspace < h; foundspace++)    // check for free lower slot
				{
					if(reader->rlecmh[foundspace].last.time == -1)
					{
						reader->rlecmh[foundspace] = reader->rlecmh[h]; // replace ecm request info
						reader->rlecmh[h].last.time = -1;
						reader->rlecmh[h].srvid = -1;
						reader->rlecmh[h].kindecm = 0;
						reader->rlecmh[h].once = 0;
						if(foundspace < maxecms)
						{
							cs_log_dbg(D_CLIENT, "ratelimiter moved srvid %04X to slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label);
							return foundspace; // moving to lower free slot!
						}
						else
						{
							cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label);
							reader->rlecmh[foundspace].last.time = -1; // free this slot since we are over ratelimit!
							return -1; // sorry, ratelimit!
						}
					}
				}
			}
			if(h < maxecms)    // found but cant move to lower position!
			{
				return h; // return position if within ratelimits!
			}
			else
			{
				reader->rlecmh[h].last.time = -1; // free this slot since we are over ratelimit!
				reader->rlecmh[h].srvid = -1;
				reader->rlecmh[h].kindecm = 0;
				reader->rlecmh[h].once = 0;
				cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", er->srvid, h + 1, maxecms, reader->label);
				return -1; // sorry, ratelimit!
			}
		}
	}

	// srvid not found in slots!

	// do we use cooldown at all, are we in cooldown fase?
	if((reader->cooldown[0] && reader->cooldownstate == 1) || !reader->cooldown[0])
	{
		// we are in cooldown or no cooldown configured!
		if(totalecms + 1 > maxecms || totalecms + 1 > rl.ratelimitecm)  // check if this channel fits in!
		{
			cs_log_dbg(D_CLIENT, "ratelimiter for reader %s has no free slots!", reader->label);
			return -1;
		}
	}
	else
	{
		maxecms = MAXECMRATELIMIT; // no limits right now!
	}

	for(h = 0; h < maxecms; h++)    // check for free slot
	{
		if(reader->rlecmh[h].last.time == -1)
		{
			if(reader_mode) { cs_log_dbg(D_CLIENT, "ratelimiter added srvid %04X to slot %d/%d of reader %s", er->srvid, h + 1, maxecms, reader->label); }
			return h; // free slot found -> assign it!
		}
		else { 
			int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last);
		cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X for %"PRId64" ms present in slot %d/%d of reader %s", reader->rlecmh[h].srvid, gone , h + 1,
			maxecms, reader->label); }  //occupied slots
	}

	foundspace = dvbapi_override_prio(reader, er, maxecms, &actualtime);
	if (foundspace > -1)
		return foundspace;

	return (-1); // no slot found
}
Beispiel #13
0
static void write_to_log_int(char *txt, uint8_t header_len, uint8_t hdr_logcount_offset, uint8_t hdr_date_offset, uint8_t hdr_time_offset, uint8_t hdr_info_offset)
{
#if !defined(WEBIF) && !defined(MODULE_MONITOR)
	if(cfg.disablelog) { return; }
#endif
	char *newtxt = cs_strdup(txt);
	if(!newtxt)
		{ return; }
	struct s_log *log;
	if(!cs_malloc(&log, sizeof(struct s_log)))
	{
		NULLFREE(newtxt);
		return;
	}
	log->txt = newtxt;
	log->header_len = header_len;
	log->header_logcount_offset = hdr_logcount_offset;
	log->header_date_offset = hdr_date_offset;
	log->header_time_offset = hdr_time_offset;
	log->header_info_offset = hdr_info_offset;		
	log->direct_log = 0;
	struct s_client *cl = cur_client();
	log->cl_usr = "";
	if(!cl)
	{
		log->cl_text = "undef";
		log->cl_typ = ' ';
	}
	else
	{
		switch(cl->typ)
		{
		case 'c':
		case 'm':
			if(cl->account)
			{
				log->cl_text = cl->account->usr;
				log->cl_usr = cl->account->usr;
			}
			else { log->cl_text = ""; }
			break;
		case 'p':
		case 'r':
			log->cl_text = cl->reader ? cl->reader->label : "";
			break;
		default:
			log->cl_text = "server";
			break;
		}
		log->cl_typ = cl->typ;
	}

	if(exit_oscam == 1 || cfg.disablelog)  //Exit or log disabled. if disabled, just display on webif/monitor
	{
		char buf[LOG_BUF_SIZE];
		cs_strncpy(buf, log->txt, LOG_BUF_SIZE);
		write_to_log(buf, log, 1);
		NULLFREE(log->txt);
		NULLFREE(log);
	}
	else
		{ log_list_add(log); }
}
Beispiel #14
0
csEventFlattenerError csEventFlattener::Unflatten (iObjectRegistry *object_reg,
						   iEvent* event, 
						   const char *buffer, 
						   size_t length)
{
  csMemFile b((char *)buffer, length, csMemFile::DISPOSITION_IGNORE);
  uint8 ui8;
  int8 i8;
  uint16 ui16;
  int16 i16;
  uint32 ui32;
  int32 i32;
  uint64 ui64;
  int64 i64;
  double d;
  char *name;
  size_t size;

  b.Read((char *)&ui32, sizeof(ui32));                 // protocol version
  ui32 = csLittleEndian::Convert (ui32);
  if (ui32 != CS_CRYSTAL_PROTOCOL)
  {
    //csPrintf("protocol version invalid: %" PRIX32 "\n", ui32);
    return csEventFlattenerErrorWrongFormat;
  }
  b.Read((char *)&ui64, sizeof(uint64));               // packet size
  size = csLittleEndian::Convert (ui64);
  b.Read((char *)&ui32, sizeof(uint32));               // iEvent.Time
  event->Time = csLittleEndian::Convert (ui32);
  b.Read((char *)&event->Broadcast, sizeof(uint8));    // iEvent.Broadcast flag
  b.Read((char *)&ui16, sizeof(uint16));               // textual name length
  ui16 = csLittleEndian::Convert (ui16);
  char *buf = (char *) cs_malloc(ui16+1);
  b.Read(buf, ui16);                                   // textual name
  buf[ui16] = '\0';
  event->Name = csEventNameRegistry::GetID(object_reg, buf); // EventID
  cs_free(buf);

  while (b.GetPos() < size)
  {
    b.Read((char *)&ui16, sizeof(uint16));
    ui16 = csLittleEndian::Convert (ui16);
    name = new char[ui16+1];
    b.Read(name, ui16);
    name[ui16] = 0;

    b.Read((char *)&ui8, sizeof(uint8));
    switch(ui8)
    {
      case CS_DATATYPE_INT8:
        b.Read((char *)&i8, sizeof(int8));
        event->Add (name, i8);
        break;
      case CS_DATATYPE_UINT8:
        b.Read((char *)&ui8, sizeof(uint8));
        event->Add (name, ui8);
        break;
      case CS_DATATYPE_INT16:
        b.Read((char *)&i16, sizeof(int16));
        i16 = csLittleEndian::Convert (i16);
        event->Add (name, i16);
        break;
      case CS_DATATYPE_UINT16:
        b.Read((char *)&ui16, sizeof(uint16));
        ui16 = csLittleEndian::Convert (ui16);
        event->Add (name, ui16);
        break;
      case CS_DATATYPE_INT32:
        b.Read((char *)&i32, sizeof(int32));
        i32 = csLittleEndian::Convert (i32);
        event->Add (name, i32);
        break;
      case CS_DATATYPE_UINT32:
        b.Read((char *)&ui32, sizeof(uint32));
        ui32 = csLittleEndian::Convert (ui32);
        event->Add (name, ui32);
        break;
      case CS_DATATYPE_INT64:
        b.Read((char *)&i64, sizeof(int64));
        i64 = csLittleEndian::Convert (i64);
        event->Add (name, i64);
        break;
      case CS_DATATYPE_UINT64:
        b.Read((char *)&ui64, sizeof(uint64));
        ui64 = csLittleEndian::Convert (ui64);
        event->Add (name, ui64);
        break;
      case CS_DATATYPE_DOUBLE:
        b.Read((char *)&i64, sizeof(int64));
        d = csLongLongToDouble(i64);
        event->Add (name, d);
        break;
      case CS_DATATYPE_DATABUFFER:
        {
          b.Read((char *)&ui64, sizeof(uint64));
          ui64 = csLittleEndian::Convert (ui64);
          char* data = new char[ui64];
          b.Read(data, ui64);
          event->Add (name, data, ui64);
	  delete[] data;
        }
        break;
      case CS_DATATYPE_EVENT:
        {
          b.Read((char *)&ui64, sizeof (uint64));
          ui64 = csLittleEndian::Convert (ui64);
	  csRef<iEvent> e;
	  e.AttachNew (new csEvent ());
	  event->Add (name, e);
	  csEventFlattenerError unflattenResult = 
	    Unflatten (object_reg, e, 
		       buffer+b.GetPos(), ui64);
	  if (unflattenResult != csEventFlattenerErrorNone)
	  {
	    delete[] name;
	    return unflattenResult;
	  }
          b.SetPos (b.GetPos() + (size_t)ui64);
        }
        break;
      default:
        break;
    }  
    delete[] name;
  } 
  return csEventFlattenerErrorNone;
}
Beispiel #15
0
void add_cache(ECM_REQUEST *er){
	if(!er->csp_hash) return;

	ECMHASH *result = NULL;
	CW *cw = NULL;
#ifdef CS_CACHEEX
	bool add_new_cw=false;
#endif

	pthread_rwlock_wrlock(&cache_lock);

	//add csp_hash to cache
	result = find_hash_table(&ht_cache, &er->csp_hash, sizeof(int32_t), &compare_csp_hash);
	if(!result){
		if(cs_malloc(&result, sizeof(ECMHASH))){
			result->csp_hash = er->csp_hash;
			init_hash_table(&result->ht_cw, &result->ll_cw);
			cs_ftime(&result->first_recv_time);

			add_hash_table(&ht_cache, &result->ht_node, &ll_cache, &result->ll_node, result, &result->csp_hash, sizeof(int32_t));

		}else{
			pthread_rwlock_unlock(&cache_lock);
			cs_log("ERROR: NO added HASH to cache!!");
			return;
		}
	}

	cs_ftime(&result->upd_time);   //need to be updated at each cw! We use it for deleting this hash when no more cws arrive inside max_cache_time!


	//add cw to this csp hash
	cw = find_hash_table(&result->ht_cw, er->cw, sizeof(er->cw), &compare_cw);

	if(!cw){

		if(count_hash_table(&result->ht_cw)>=10){  //max 10 different cws stored
			pthread_rwlock_unlock(&cache_lock);
			return;
		}

		while(1){
			if(cs_malloc(&cw, sizeof(CW))){
				memcpy(cw->cw, er->cw, sizeof(er->cw));
				cw->odd_even = get_odd_even(er);
				cw->cwc_cycletime = er->cwc_cycletime;
				cw->cwc_next_cw_cycle = er->cwc_next_cw_cycle;
				cw->count= 0;
				cw->csp = 0;
				cw->cacheex = 0;
				cw->localcards=0;
				cw->proxy=0;
				cw->grp = 0;
				cw->caid = er->caid;
				cw->prid = er->prid;
				cw->srvid = er->srvid;
				cw->selected_reader=er->selected_reader;
	#ifdef CS_CACHEEX
				cw->cacheex_src=er->cacheex_src;
	#endif
				cw->pushout_client = NULL;

				while(1){
					if (pthread_rwlock_init(&cw->pushout_client_lock, NULL) == 0)
						break;

					cs_log("Error creating lock pushout_client_lock!");
					cs_sleepms(1);
				}


				add_hash_table(&result->ht_cw, &cw->ht_node, &result->ll_cw, &cw->ll_node, cw, cw->cw, sizeof(er->cw));

	#ifdef CS_CACHEEX
				add_new_cw=true;
	#endif
				break;
			}

			cs_log("ERROR: NO added CW to cache!! Re-trying...");
			cs_sleepms(1);
		}
	}

	//update if answered from csp/cacheex/local_proxy
	if(er->from_cacheex) cw->cacheex = 1;
	if(er->from_csp) cw->csp = 1;
#ifdef CS_CACHEEX
	if(!er->cacheex_src){
#endif
		if(is_localreader(er->selected_reader, er)) cw->localcards=1;
		else cw->proxy = 1;
#ifdef CS_CACHEEX
	}
#endif

	//always update group and counter
	cw->grp |= er->grp;
	cw->count++;

	//sort cw_list by counter (DESC order)
	if(cw->count>1)
		sort_list(&result->ll_cw, count_sort);

	pthread_rwlock_unlock(&cache_lock);


#ifdef CS_CACHEEX

	er->cw_cache=cw;
	cacheex_cache_push(er);


	//cacheex debug log lines and cw diff stuff
	if(check_client(er->cacheex_src)){
		if(add_new_cw){
			debug_ecm(D_CACHEEX|D_CSP, "got pushed ECM %s from %s", buf, er->from_csp ? "csp" : username(er->cacheex_src));

			CW *cw_first = get_first_cw(result, er);

			if(er && cw_first){
			
			//compare er cw with mostly counted cached cw
			if(memcmp(er->cw, cw_first->cw, sizeof(er->cw)) != 0) {
				er->cacheex_src->cwcacheexerrcw++;
				if (er->cacheex_src->account)
					er->cacheex_src->account->cwcacheexerrcw++;

				if (((0x0200| 0x0800) & cs_dblevel)) { //avoid useless operations if debug is not enabled
					char cw1[16*3+2], cw2[16*3+2];
					cs_hexdump(0, er->cw, 16, cw1, sizeof(cw1));
					cs_hexdump(0, cw_first->cw, 16, cw2, sizeof(cw2));

					char ip1[20]="", ip2[20]="";
					if (check_client(er->cacheex_src))
						cs_strncpy(ip1, cs_inet_ntoa(er->cacheex_src->ip), sizeof(ip1));
					if (check_client(cw_first->cacheex_src))
						cs_strncpy(ip2, cs_inet_ntoa(cw_first->cacheex_src->ip), sizeof(ip2));
					else if (cw_first->selected_reader && check_client(cw_first->selected_reader->client))
						cs_strncpy(ip2, cs_inet_ntoa(cw_first->selected_reader->client->ip), sizeof(ip2));

					debug_ecm(D_CACHEEX| D_CSP, "WARNING: Different CWs %s from %s(%s)<>%s(%s): %s<>%s ", buf,
						er->from_csp ? "csp" : username(er->cacheex_src), ip1,
						check_client(cw_first->cacheex_src)?username(cw_first->cacheex_src):(cw_first->selected_reader?cw_first->selected_reader->label:"unknown/csp"), ip2,
						cw1, cw2);
				}
			}

		}
		}else
			debug_ecm(D_CACHEEX| D_CSP, "got duplicate pushed ECM %s from %s", buf, er->from_csp ? "csp" : username(er->cacheex_src));
	}

#endif
}
Beispiel #16
0
static int32_t dre_get_emm_filter(struct s_reader *rdr, struct s_csystem_emm_filter **emm_filters, unsigned int *filter_count)
{
	if(*emm_filters == NULL)
	{
		const unsigned int max_filter_count = 7;
		if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
			{ return ERROR; }

		struct s_csystem_emm_filter *filters = *emm_filters;
		*filter_count = 0;

		int32_t idx = 0;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x80;
		filters[idx].filter[1] = rdr->sa[0][0];
		filters[idx].mask[0]   = 0xF2;
		filters[idx].mask[1]   = 0xFF;
		idx++;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x82;
		filters[idx].filter[1] = rdr->sa[0][0];
		filters[idx].mask[0]   = 0xF3;
		filters[idx].mask[1]   = 0xFF;
		idx++;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x83;
		filters[idx].filter[1] = rdr->sa[0][0];
		filters[idx].mask[0]   = 0xF3;
		if(rdr->caid == 0x4ae1)
		{
			memcpy(&filters[idx].filter[1], &rdr->sa[0][0], 4);
			memset(&filters[idx].mask[1], 0xFF, 4);
		}
		filters[idx].mask[1]   = 0xFF;
		idx++;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x86;
		filters[idx].filter[1] = rdr->sa[0][0];
		filters[idx].mask[0]   = 0xFF;
		filters[idx].mask[1]   = 0xFF;
		idx++;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x8c;
		filters[idx].filter[1] = rdr->sa[0][0];
		filters[idx].mask[0]   = 0xFF;
		filters[idx].mask[1]   = 0xFF;
		idx++;

		filters[idx].type = EMM_SHARED;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x89;
		filters[idx].mask[0]   = 0xFF;
		// FIXME: Seems to be that SA is only used with caid 0x4ae1
		if(rdr->caid == 0x4ae1)
		{
			memcpy(&filters[idx].filter[1], &rdr->sa[0][0], 4);
			memset(&filters[idx].mask[1], 0xFF, 4);
		}
		idx++;

		filters[idx].type = EMM_UNIQUE;
		filters[idx].enabled   = 1;
		filters[idx].filter[0] = 0x87;
		filters[idx].mask[0]   = 0xFF;
		//FIXME: No filter for hexserial
		idx++;

		*filter_count = idx;
	}

	return OK;
}
Beispiel #17
0
/* sparse QR factorization [V,beta,pinv,R] = qr (A) */
csn *cs_qr (const cs *A, const css *S)
{
    double *Rx, *Vx, *Ax, *x,  *Beta ;
    int i, k, p, n, vnz, p1, top, m2, len, col, rnz, *s, *leftmost, *Ap, *Ai,
        *parent, *Rp, *Ri, *Vp, *Vi, *w, *pinv, *q ;
    cs *R, *V ;
    csn *N ;
    if (!CS_CSC (A) || !S) return (NULL) ;
    n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ;
    q = S->q ; parent = S->parent ; pinv = S->pinv ; m2 = S->m2 ;
    vnz = (int)S->lnz ; rnz = (int)S->unz ; leftmost = S->leftmost ;
    w = (int*) cs_malloc (m2+n, sizeof (int)) ;            /* get int workspace */
    x = (double*) cs_malloc (m2, sizeof (double)) ;           /* get double workspace */
    N = (csn*) cs_calloc (1, sizeof (csn)) ;               /* allocate result */
    if (!w || !x || !N) return (cs_ndone (N, NULL, w, x, 0)) ;
    s = w + m2 ;                                    /* s is size n */
    for (k = 0 ; k < m2 ; k++) x [k] = 0 ;          /* clear workspace x */
    N->L = V = cs_spalloc (m2, n, vnz, 1, 0) ;      /* allocate result V */
    N->U = R = cs_spalloc (m2, n, rnz, 1, 0) ;      /* allocate result R */
    N->B = Beta = (double*) cs_malloc (n, sizeof (double)) ;  /* allocate result Beta */
    if (!R || !V || !Beta) return (cs_ndone (N, NULL, w, x, 0)) ;
    Rp = R->p ; Ri = R->i ; Rx = R->x ;
    Vp = V->p ; Vi = V->i ; Vx = V->x ;
    for (i = 0 ; i < m2 ; i++) w [i] = -1 ; /* clear w, to mark nodes */
    rnz = 0 ; vnz = 0 ;
    for (k = 0 ; k < n ; k++)               /* compute V and R */
    {
        Rp [k] = rnz ;                      /* R(:,k) starts here */
        Vp [k] = p1 = vnz ;                 /* V(:,k) starts here */
        w [k] = k ;                         /* add V(k,k) to pattern of V */
        Vi [vnz++] = k ;
        top = n ;
        col = q ? q [k] : k ;
        for (p = Ap [col] ; p < Ap [col+1] ; p++)   /* find R(:,k) pattern */
        {
            i = leftmost [Ai [p]] ;         /* i = min(find(A(i,q))) */
            for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up to k */
            {
                s [len++] = i ;
                w [i] = k ;
            }
            while (len > 0) s [--top] = s [--len] ; /* push path on stack */
            i = pinv [Ai [p]] ;             /* i = permuted row of A(:,col) */
            x [i] = Ax [p] ;                /* x (i) = A(:,col) */
            if (i > k && w [i] < k)         /* pattern of V(:,k) = x (k+1:m) */
            {
                Vi [vnz++] = i ;            /* add i to pattern of V(:,k) */
                w [i] = k ;
            }
        }
        for (p = top ; p < n ; p++) /* for each i in pattern of R(:,k) */
        {
            i = s [p] ;                     /* R(i,k) is nonzero */
            cs_happly (V, i, Beta [i], x) ; /* apply (V(i),Beta(i)) to x */
            Ri [rnz] = i ;                  /* R(i,k) = x(i) */
            Rx [rnz++] = x [i] ;
            x [i] = 0 ;
            if (parent [i] == k) vnz = cs_scatter (V, i, 0, w, NULL, k, V, vnz);
        }
        for (p = p1 ; p < vnz ; p++)        /* gather V(:,k) = x */
        {
            Vx [p] = x [Vi [p]] ;
            x [Vi [p]] = 0 ;
        }
        Ri [rnz] = k ;                     /* R(k,k) = norm (x) */
        Rx [rnz++] = cs_house (Vx+p1, Beta+k, vnz-p1) ; /* [v,beta]=house(x) */
    }
    Rp [n] = rnz ;                          /* finalize R */
    Vp [n] = vnz ;                          /* finalize V */
    return (cs_ndone (N, NULL, w, x, 1)) ;  /* success */
}
Beispiel #18
0
/*
 * Creates a string ready to write as a token into config or WebIf for AESKeys. You must free the returned value through free_mk_t().
 */
char *mk_t_aeskeys(struct s_reader *rdr) {
	AES_ENTRY *current = rdr->aes_list;
	int32_t i, pos = 0, needed = 1, prevKeyid = 0, prevCaid = 0;
	uint32_t prevIdent = 0;

	/* Precheck for the approximate size that we will need; it's a bit overestimated but we correct that at the end of the function */
	while(current) {
		/* The caid, ident, "@" and the trailing ";" need to be output when they are changing */
		if(prevCaid != current->caid || prevIdent != current->ident) needed += 12 + (current->keyid * 2);
		/* "0" keys are not saved so we need to check for gaps */
		else if(prevKeyid != current->keyid + 1) needed += (current->keyid - prevKeyid - 1) * 2;
		/* The 32 byte key plus either the (heading) ":" or "," */
		needed += 33;
		prevCaid = current->caid;
		prevIdent = current->ident;
		prevKeyid = current->keyid;
		current = current->next;
	}

	/* Set everything back and now create the string */
	current = rdr->aes_list;
	prevCaid = 0;
	prevIdent = 0;
	prevKeyid = 0;
	char tmp[needed];
	char dot;
	if(needed == 1) tmp[0] = '\0';
	char tmpkey[33];
	while(current) {
		/* A change in the ident or caid means that we need to output caid and ident */
		if(prevCaid != current->caid || prevIdent != current->ident) {
			if(pos > 0) {
				tmp[pos] = ';';
				++pos;
			}
			pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%04X@%06X", current->caid, current->ident);
			prevKeyid = -1;
			dot = ':';
		} else dot = ',';
		/* "0" keys are not saved so we need to check for gaps and output them! */
		for (i = prevKeyid + 1; i < current->keyid; ++i) {
			pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%c0", dot);
			dot = ',';
		}
		tmp[pos] = dot;
		++pos;
		for (i = 0; i < 16; ++i) snprintf(tmpkey + (i*2), sizeof(tmpkey) - (i*2), "%02X", current->plainkey[i]);
		/* A key consisting of only FFs has a special meaning (just return what the card outputted) and can be specified more compact */
		if(strcmp(tmpkey, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") == 0) pos += snprintf(tmp+pos, sizeof(tmp)-pos, "FF");
		else pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%s", tmpkey);
		prevCaid = current->caid;
		prevIdent = current->ident;
		prevKeyid = current->keyid;
		current = current->next;
	}

	/* copy to result array of correct size */
	char *value;
	if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
	memcpy(value, tmp, pos + 1);
	return(value);
}
Beispiel #19
0
 void* Malloc (size_t size) { return cs_malloc (size); }
int32_t stapi_open(void) {
	uint32_t ErrorCode;

	DIR *dirp;
	struct dirent entry, *dp = NULL;
	struct stat buf;
	int32_t i;
	char pfad[80];
	stapi_on=1;
	int32_t stapi_priority=0;

	dirp = opendir(PROCDIR);
	if (!dirp) {
		cs_log("opendir failed (errno=%d %s)", errno, strerror(errno));
		return 0;
	}

	memset(dev_list, 0, sizeof(struct STDEVICE)*PTINUM);

	if (dvbapi_priority) {
		struct s_dvbapi_priority *p;
		for (p=dvbapi_priority; p != NULL; p=p->next) {
			if (p->type=='s') {
				stapi_priority=1;
				break;
			}
		}
	}

	if (!stapi_priority) {
		cs_log("WARNING: no PTI devices defined, stapi disabled");
		return 0;
	}

	oscam_stapi_CheckVersion();

	i=0;
	while (!cs_readdir_r(dirp, &entry, &dp)) {
		if (!dp) break;

		snprintf(pfad, sizeof(pfad), "%s%s", PROCDIR, dp->d_name);
		if (stat(pfad,&buf) != 0)
			continue;

		if (!(buf.st_mode & S_IFDIR && strncmp(dp->d_name, ".", 1)!=0))
			continue;

		int32_t do_open=0;
		struct s_dvbapi_priority *p;

		for (p=dvbapi_priority; p != NULL; p=p->next) {
			if (p->type!='s') continue;
			if(strcmp(dp->d_name, p->devname)==0) {
				do_open=1;
				break;
			}
		}

		if (!do_open) {
			cs_log("PTI: %s skipped", dp->d_name);
			continue;
		}

		ErrorCode= oscam_stapi_Open(dp->d_name, &dev_list[i].SessionHandle);
		if (ErrorCode != 0) {
			cs_log("STPTI_Open ErrorCode: %d", ErrorCode);
			continue;
		}

		//debug
		//oscam_stapi_Capability(dp->d_name);

		cs_strncpy(dev_list[i].name,dp->d_name, sizeof(dev_list[i].name));
		cs_log("PTI: %s open %d", dp->d_name, i);
		
		ErrorCode = oscam_stapi_SignalAllocate(dev_list[i].SessionHandle, &dev_list[i].SignalHandle);
		if (ErrorCode != 0)
			cs_log("SignalAllocate: ErrorCode: %d SignalHandle: %x", ErrorCode, dev_list[i].SignalHandle);

		i++;
		if (i>=PTINUM) break;
	}
	closedir(dirp);

	if (i==0) return 0;

	pthread_mutex_init(&filter_lock, NULL);

	for (i=0;i<PTINUM;i++) {
		if (dev_list[i].SessionHandle==0)
			continue;

		struct read_thread_param *para;
		if (!cs_malloc(&para, sizeof(struct read_thread_param)))
			return 0;
		para->id=i;
		para->cli=cur_client();

		int32_t ret = pthread_create(&dev_list[i].thread, NULL, stapi_read_thread, (void *)para);
		if(ret){
			cs_log("ERROR: can't create stapi read thread (errno=%d %s)", ret, strerror(ret));
			return 0;
		} else
			pthread_detach(dev_list[i].thread);
	}

	atexit(stapi_off);

	cs_log("liboscam_stapi v.%s initialized", oscam_stapi_LibVersion());
	return 1;
}
Beispiel #21
0
static int32_t cc_cacheex_push_out(struct s_client *cl, struct ecm_request_t *er)
{
	int8_t rc = (er->rc < E_NOTFOUND) ? E_FOUND : er->rc;
	if(rc != E_FOUND && rc != E_UNHANDLED) { return -1; }  //Maybe later we could support other rcs

	if(cl->reader)
	{
		if(!cl->reader->tcp_connected)
			{ cc_cli_connect(cl); }
	}

	struct cc_data *cc = cl->cc;
	if(!cc || !cl->udp_fd)
	{
		cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl));
		return (-1);
	}

	uint32_t size = sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw) + sizeof(uint8_t) +
					(ll_count(er->csp_lastnodes) + 1) * 8;

	unsigned char *buf;
	if(!cs_malloc(&buf, size + 20))  //camd35_send() adds +20
		{ return -1; }

	// build ecm message
	//buf[0] = er->caid >> 8;
	//buf[1] = er->caid & 0xff;
	//buf[2] = er->prid >> 24;
	//buf[3] = er->prid >> 16;
	//buf[4] = er->prid >> 8;
	//buf[5] = er->prid & 0xff;
	//buf[10] = er->srvid >> 8;
	//buf[11] = er->srvid & 0xff;
	buf[12] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) & 0xff;
	buf[13] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) >> 8;
	//buf[12] = 0;
	//buf[13] = 0;
	buf[14] = rc;

	i2b_buf(2, er->caid, buf + 0);
	i2b_buf(4, er->prid, buf + 2);
	i2b_buf(2, er->srvid, buf + 10);

	if(er->cwc_cycletime && er->cwc_next_cw_cycle < 2)
	{
		buf[18] = er->cwc_cycletime; // contains cwc stage3 cycletime
		if(er->cwc_next_cw_cycle == 1)
		{ buf[18] = (buf[18] | 0x80); } // set bit 8 to high

		if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
			{ cl->account->cwc_info++; }
		else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
			{ cl->cwc_info++; }
		cs_log_dbg(D_CWC, "CWC (CE) push to %s cycletime: %isek - nextcwcycle: CW%i for %04X:%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid);
	}

	buf[19] = er->ecm[0] != 0x80 && er->ecm[0] != 0x81 ? 0 : er->ecm[0];

	uint8_t *ofs = buf + 20;

	//write oscam ecmd5:
	memcpy(ofs, er->ecmd5, sizeof(er->ecmd5)); //16
	ofs += sizeof(er->ecmd5);

	//write csp hashcode:
	i2b_buf(4, htonl(er->csp_hash), ofs);
	ofs += 4;

	//write cw:
	memcpy(ofs, er->cw, sizeof(er->cw)); //16
	ofs += sizeof(er->cw);

	//write node count:
	*ofs = ll_count(er->csp_lastnodes) + 1;
	ofs++;

	//write own node:
	memcpy(ofs, cc->node_id, 8);
	ofs += 8;

	//write other nodes:
	LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0);
	uint8_t *node;
	while((node = ll_li_next(li)))
	{
		memcpy(ofs, node, 8);
		ofs += 8;
	}
	ll_li_destroy(li);

	int32_t res = cc_cmd_send(cl, buf, size + 20, MSG_CACHE_PUSH);
	if(res > 0)   // cache-ex is pushing out, so no receive but last_g should be updated otherwise disconnect!
	{
		if(cl->reader)
			{ cl->reader->last_s = cl->reader->last_g = time((time_t *)0); } // correct
		if(cl) { cl->last = time(NULL); }
	}
	NULLFREE(buf);
	return res;
}
Beispiel #22
0
static void do_emm_from_file(struct s_reader * reader)
{
  //now here check whether we have EMM's on file to load and write to card:
  if (reader->emmfile == NULL)
     return;

   //handling emmfile
   char token[256];
   FILE *fp;

   if (reader->emmfile[0] == '/')
      snprintf (token, sizeof(token), "%s", reader->emmfile); //pathname included
   else
      snprintf (token, sizeof(token), "%s%s", cs_confdir, reader->emmfile); //only file specified, look in confdir for this file

   if (!(fp = fopen (token, "rb"))) {
      rdr_log(reader, "ERROR: Cannot open EMM file '%s' (errno=%d %s)\n", token, errno, strerror(errno));
      return;
   }
   EMM_PACKET *eptmp;
   if(!cs_malloc(&eptmp,sizeof(EMM_PACKET), -1)) {
      	fclose (fp);
      	return;
   }

   size_t ret = fread(eptmp, sizeof(EMM_PACKET), 1, fp);
   if (ret < 1 && ferror(fp)) {
        rdr_log(reader, "ERROR: Can't read EMM from file '%s' (errno=%d %s)", token, errno, strerror(errno));
        free(eptmp);
        fclose(fp);
        return;
   }
   fclose (fp);

   eptmp->caid[0] = (reader->caid >> 8) & 0xFF;
   eptmp->caid[1] = reader->caid & 0xFF;
   if (reader->nprov > 0)
      memcpy(eptmp->provid, reader->prid[0], sizeof(eptmp->provid));
   eptmp->l = eptmp->emm[2] + 3;

   struct s_cardsystem *cs = get_cardsystem_by_caid(reader->caid);
   if (cs && cs->get_emm_type && !cs->get_emm_type(eptmp, reader)) {
      rdr_debug_mask(reader, D_EMM, "emm skipped, get_emm_type() returns error");
      free(eptmp);
      return;
   }
   //save old b_nano value
   //clear lsb and lsb+1, so no blocking, and no saving for this nano
   uint16_t save_s_nano = reader->s_nano;
   uint16_t save_b_nano = reader->b_nano;
   uint32_t save_saveemm = reader->saveemm;

   reader->s_nano = reader->b_nano = 0;
   reader->saveemm = 0;

   int32_t rc = reader_emm(reader, eptmp);
   if (rc == OK)
      rdr_log(reader, "EMM from file %s was successful written.", token);
   else
      rdr_log(reader, "ERROR: EMM read from file %s NOT processed correctly! (rc=%d)", token, rc);

   //restore old block/save settings
   reader->s_nano = save_s_nano;
   reader->b_nano = save_b_nano;
   reader->saveemm = save_saveemm;

   free(eptmp);
}
Beispiel #23
0
int32_t init_sidtab(void)
{
	FILE *fp = open_config_file(cs_sidt);
	if(!fp)
		{ return 1; }

	int32_t nr, nro, nrr;
	char *value, *token;
	if(!cs_malloc(&token, MAXLINESIZE))
		{ return 1; }
	struct s_sidtab *ptr;
	struct s_sidtab *sidtab = (struct s_sidtab *)0;

	for(nro = 0, ptr = cfg.sidtab; ptr; nro++)
	{
		struct s_sidtab *ptr_next;
		ptr_next = ptr->next;
		free_sidtab(ptr);
		ptr = ptr_next;
	}
	nr = 0;
	nrr = 0;
	while(fgets(token, MAXLINESIZE, fp))
	{
		int32_t l;
		if((l = strlen(trim(token))) < 3) { continue; }
		if((token[0] == '[') && (token[l - 1] == ']'))
		{
			token[l - 1] = 0;
			if(nr > MAX_SIDBITS)
			{
				fprintf(stderr, "Warning: Service No.%d - '%s' ignored. Max allowed Services %d\n", nr, strtolower(token + 1), MAX_SIDBITS);
				nr++;
				nrr++;
			}
			else
			{
				if(!cs_malloc(&ptr, sizeof(struct s_sidtab)))
				{
					NULLFREE(token);
					return (1);
				}
				if(sidtab)
					{ sidtab->next = ptr; }
				else
					{ cfg.sidtab = ptr; }
				sidtab = ptr;
				nr++;
				cs_strncpy(sidtab->label, strtolower(token + 1), sizeof(sidtab->label));
				continue;
			}
		}
		if(!sidtab) { continue; }
		if(!(value = strchr(token, '='))) { continue; }
		*value++ = '\0';
		chk_sidtab(trim(strtolower(token)), trim(strtolower(value)), sidtab);
	}
	NULLFREE(token);
	fclose(fp);

#ifdef DEBUG_SIDTAB
	show_sidtab(cfg.sidtab);
#endif
	++cfg_sidtab_generation;
	cs_log("services reloaded: %d services freed, %d services loaded, rejected %d", nro, nr, nrr);
	return (0);
}
Beispiel #24
0
static int32_t pcsc_init(struct s_reader *pcsc_reader)
{
	ULONG rv;
	DWORD dwReaders = 0;
	LPSTR mszReaders = NULL;
	char *ptr, **readers = NULL;
	char *device = pcsc_reader->device;
	int32_t nbReaders;
	int32_t reader_nb;

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC establish context for PCSC pcsc_reader %s", device);
	SCARDCONTEXT hContext;
	memset(&hContext, 0, sizeof(hContext));
	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	if(rv == SCARD_S_SUCCESS)
	{
		if(!cs_malloc(&pcsc_reader->crdr_data, sizeof(struct pcsc_data)))
			{ return ERROR; }
		struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
		crdr_data->hContext = hContext;

		// here we need to list the pcsc readers and get the name from there,
		// the pcsc_reader->device should contain the pcsc_reader number
		// and after the actual device name is copied in crdr_data->pcsc_name .
		rv = SCardListReaders(crdr_data->hContext, NULL, NULL, &dwReaders);
		if(rv != SCARD_S_SUCCESS)
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC failed listing readers [1] : (%lx)", (unsigned long)rv);
			return ERROR;
		}
		if(!cs_malloc(&mszReaders, dwReaders))
			{ return ERROR; }
		rv = SCardListReaders(crdr_data->hContext, NULL, mszReaders, &dwReaders);
		if(rv != SCARD_S_SUCCESS)
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC failed listing readers [2]: (%lx)", (unsigned long)rv);
			NULLFREE(mszReaders);
			return ERROR;
		}
		/* Extract readers from the null separated string and get the total
		 * number of readers
		 */
		nbReaders = 0;
		ptr = mszReaders;
		while(*ptr != '\0')
		{
			ptr += strlen(ptr) + 1;
			nbReaders++;
		}

		if(nbReaders == 0)
		{
			rdr_log(pcsc_reader, "PCSC : no pcsc_reader found");
			NULLFREE(mszReaders);
			return ERROR;
		}

		if(!cs_malloc(&readers, nbReaders * sizeof(char *)))
		{
			NULLFREE(mszReaders);
			return ERROR;
		}

		/* fill the readers table */
		nbReaders = 0;
		ptr = mszReaders;
		while(*ptr != '\0')
		{
			rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %d: %s", nbReaders, ptr);
			readers[nbReaders] = ptr;
			ptr += strlen(ptr) + 1;
			nbReaders++;
		}

		reader_nb = atoi((const char *)&pcsc_reader->device);
		if(reader_nb < 0 || reader_nb >= nbReaders)
		{
			rdr_log(pcsc_reader, "Wrong pcsc_reader index: %d", reader_nb);
			NULLFREE(mszReaders);
			NULLFREE(readers);
			return ERROR;
		}

		if (readers)
		{
		snprintf(crdr_data->pcsc_name, sizeof(crdr_data->pcsc_name), "%s", readers[reader_nb]);
		NULLFREE(readers);
		}
		NULLFREE(mszReaders);
	}
	else
	{
		rdr_log(pcsc_reader, "PCSC failed establish context (%lx)", (unsigned long)rv);
		return ERROR;
	}
	return OK;
}
Beispiel #25
0
int32_t init_srvid(void)
{
	FILE *fp = open_config_file(cs_srid);
	if(!fp)
		{ return 0; }

	int32_t nr = 0, i;
	char *payload, *tmp, *saveptr1 = NULL, *token;
	if(!cs_malloc(&token, MAXLINESIZE))
		{ return 0; }
	struct s_srvid *srvid = NULL, *new_cfg_srvid[16], *last_srvid[16];
	// A cache for strings within srvids. A checksum is calculated which is the start point in the array (some kind of primitive hash algo).
	// From this point, a sequential search is done. This greatly reduces the amount of string comparisons.
	char **stringcache[1024];
	int32_t allocated[1024] = { 0 };
	int32_t used[1024] = { 0 };
	struct timeb ts, te;
	cs_ftime(&ts);

	memset(last_srvid, 0, sizeof(last_srvid));
	memset(new_cfg_srvid, 0, sizeof(new_cfg_srvid));

	while(fgets(token, MAXLINESIZE, fp))
	{
		int32_t l, j, len = 0, len2, srvidtmp;
		uint32_t pos;
		char *srvidasc;
		tmp = trim(token);

		if(tmp[0] == '#') { continue; }
		if((l = strlen(tmp)) < 6) { continue; }
		if(!(srvidasc = strchr(token, ':'))) { continue; }
		if(!(payload = strchr(token, '|'))) { continue; }
		*payload++ = '\0';

		if(!cs_malloc(&srvid, sizeof(struct s_srvid)))
		{
			NULLFREE(token);
			fclose(fp);
			return (1);
		}

		char tmptxt[128];

		int32_t offset[4] = { -1, -1, -1, -1 };
		char *ptr1, *searchptr[4] = { NULL, NULL, NULL, NULL };
		char **ptrs[4] = { &srvid->prov, &srvid->name, &srvid->type, &srvid->desc };

		for(i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1 && (i < 4) ; ptr1 = strtok_r(NULL, "|", &saveptr1), ++i)
		{
			// check if string is in cache
			len2 = strlen(ptr1);
			pos = 0;
			for(j = 0; j < len2; ++j) { pos += (uint8_t)ptr1[j]; }
			pos = pos % 1024;
			for(j = 0; j < used[pos]; ++j)
			{
				if(!strcmp(stringcache[pos][j], ptr1))
				{
					searchptr[i] = stringcache[pos][j];
					break;
				}
			}
			if(searchptr[i]) { continue; }

			offset[i] = len;
			cs_strncpy(tmptxt + len, trim(ptr1), sizeof(tmptxt) - len);
			len += strlen(ptr1) + 1;
		}

		char *tmpptr = NULL;
		if(len > 0 && !cs_malloc(&tmpptr, len))
			{ continue; }

		srvid->data = tmpptr;
		if(len > 0) { memcpy(tmpptr, tmptxt, len); }

		for(i = 0; i < 4; i++)
		{
			if(searchptr[i])
			{
				*ptrs[i] = searchptr[i];
				continue;
			}
			if(offset[i] > -1)
			{
				*ptrs[i] = tmpptr + offset[i];
				// store string in stringcache
				tmp = *ptrs[i];
				len2 = strlen(tmp);
				pos = 0;
				for(j = 0; j < len2; ++j) { pos += (uint8_t)tmp[j]; }
				pos = pos % 1024;
				if(used[pos] >= allocated[pos])
				{
					if(allocated[pos] == 0)
					{
						if(!cs_malloc(&stringcache[pos], 16 * sizeof(char *)))
							{ break; }
					}
					else
					{
						if(!cs_realloc(&stringcache[pos], (allocated[pos] + 16) * sizeof(char *)))
							{ break; }
					}
					allocated[pos] += 16;
				}
				stringcache[pos][used[pos]] = tmp;
				used[pos] += 1;
			}
		}

		*srvidasc++ = '\0';
		srvidtmp = dyn_word_atob(srvidasc) & 0xFFFF;
		//printf("srvid %s - %d\n",srvidasc,srvid->srvid );

		if(srvidtmp < 0)
		{
			NULLFREE(tmpptr);
			NULLFREE(srvid);
			continue;
		}
		else { srvid->srvid = srvidtmp; }

		srvid->ncaid = 0;
		for(i = 0, ptr1 = strtok_r(token, ",", &saveptr1); (ptr1) && (i < 10) ; ptr1 = strtok_r(NULL, ",", &saveptr1), i++)
		{
			srvid->caid[i] = dyn_word_atob(ptr1);
			srvid->ncaid = i + 1;
			//cs_debug_mask(D_CLIENT, "ld caid: %04X srvid: %04X Prov: %s Chan: %s",srvid->caid[i],srvid->srvid,srvid->prov,srvid->name);
		}
		nr++;

		if(new_cfg_srvid[srvid->srvid >> 12])
			{ last_srvid[srvid->srvid >> 12]->next = srvid; }
		else
			{ new_cfg_srvid[srvid->srvid >> 12] = srvid; }

		last_srvid[srvid->srvid >> 12] = srvid;
	}
Beispiel #26
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
#if USE_ITER_API
	static
#endif
	cs_insn *insn = NULL;
	int mode = (a->bits==64)? CS_MODE_64:
		(a->bits==32)? CS_MODE_32:
		(a->bits==16)? CS_MODE_16: 0;
	int n, ret = cs_open (CS_ARCH_X86, mode, &handle);
	int regsz = 4;

	if (ret != CS_ERR_OK) {
		return 0;
	}
	switch (a->bits) {
	case 64: regsz = 8; break;
	case 16: regsz = 2; break;
	default:
	case 32: regsz = 4; break;
	}
	memset (op, '\0', sizeof (RAnalOp));
	op->type = R_ANAL_OP_TYPE_NULL;
	op->jump = UT64_MAX;
	op->fail = UT64_MAX;
	op->ptr = op->val = UT64_MAX;
	op->src[0] = NULL;
	op->src[1] = NULL;
	op->size = 0;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	// capstone-next
#if USE_ITER_API
	{
		ut64 naddr = addr;
		size_t size = len;
		if (insn == NULL)
			insn = cs_malloc (handle);
		n = cs_disasm_iter (handle, (const uint8_t**)&buf,
			&size, (uint64_t*)&naddr, insn);
	}
#else
	n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn);
#endif
	if (n<1) {
		op->type = R_ANAL_OP_TYPE_ILL;
	} else {
		int rs = a->bits/8;
		const char *pc = (a->bits==16)?"ip":
			(a->bits==32)?"eip":"rip";
		const char *sp = (a->bits==16)?"sp":
			(a->bits==32)?"esp":"rsp";
		const char *bp = (a->bits==16)?"bp":
			(a->bits==32)?"ebp":"rbp";
		op->size = insn->size;
		op->prefix = 0;
		switch (insn->detail->x86.prefix[0]) {
		case X86_PREFIX_REPNE:
			op->prefix |= R_ANAL_OP_PREFIX_REPNE;
		case X86_PREFIX_REP:
			op->prefix |= R_ANAL_OP_PREFIX_REP;
		case X86_PREFIX_LOCK:
			op->prefix |= R_ANAL_OP_PREFIX_LOCK;
		}
		switch (insn->id) {
		case X86_INS_FNOP:
		case X86_INS_NOP:
			op->type = R_ANAL_OP_TYPE_NOP;
			if (a->decode)
				esilprintf (op, ",");
			break;
		case X86_INS_HLT:
			op->type = R_ANAL_OP_TYPE_TRAP;
			break;
		case X86_INS_CLI:
		case X86_INS_STI:
		case X86_INS_CLC:
		case X86_INS_STC:
			break;
		// cmov
		case X86_INS_CMOVA:
		case X86_INS_CMOVAE:
		case X86_INS_CMOVB:
		case X86_INS_CMOVBE:
		case X86_INS_FCMOVBE:
		case X86_INS_FCMOVB:
		case X86_INS_CMOVE:
		case X86_INS_FCMOVE:
		case X86_INS_CMOVG:
		case X86_INS_CMOVGE:
		case X86_INS_CMOVL:
		case X86_INS_CMOVLE:
		case X86_INS_FCMOVNBE:
		case X86_INS_FCMOVNB:
		case X86_INS_CMOVNE:
		case X86_INS_FCMOVNE:
		case X86_INS_CMOVNO:
		case X86_INS_CMOVNP:
		case X86_INS_FCMOVNU:
		case X86_INS_CMOVNS:
		case X86_INS_CMOVO:
		case X86_INS_CMOVP:
		case X86_INS_FCMOVU:
		case X86_INS_CMOVS:
		// mov
		case X86_INS_MOV:
		case X86_INS_MOVZX:
		case X86_INS_MOVABS:
		case X86_INS_MOVHPD:
		case X86_INS_MOVHPS:
		case X86_INS_MOVLPD:
		case X86_INS_MOVLPS:
		case X86_INS_MOVBE:
		case X86_INS_MOVSB:
		case X86_INS_MOVSD:
		case X86_INS_MOVSQ:
		case X86_INS_MOVSS:
		case X86_INS_MOVSW:
		case X86_INS_MOVD:
		case X86_INS_MOVQ:
		case X86_INS_MOVDQ2Q:
			{
			op->type = R_ANAL_OP_TYPE_MOV;
			switch (INSOP(0).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(0).mem.disp;
				op->refptr = INSOP(0).size;
				if (INSOP(0).mem.base == X86_REG_RIP) {
					op->ptr += addr + insn->size;
				} else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
					op->stackop = R_ANAL_STACK_SET;
					op->stackptr = regsz;
				}
				if (a->decode) {
					char *src = getarg (handle, insn, 1, 0);
					char *dst = getarg (handle, insn, 0, 1);
					esilprintf (op, "%s,%s", src, dst);
					free (src);
					free (dst);
				}
				break;
			default:
				if (a->decode) {
					char *src = getarg (handle, insn, 1, 0);
					char *dst = getarg (handle, insn, 0, 0);
					esilprintf (op, "%s,%s,=", src, dst);
					free (src);
					free (dst);
				}
				break;
			}
			switch (INSOP(1).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(1).mem.disp;
				op->refptr = INSOP(1).size;
				if (INSOP(1).mem.base == X86_REG_RIP) {
					op->ptr += addr + insn->size;
				} else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
					op->stackop = R_ANAL_STACK_GET;
					op->stackptr = regsz;
				}
				break;
			case X86_OP_IMM:
				if (INSOP(1).imm > 10)
					op->ptr = INSOP(1).imm;
				break;
			default:
				break;
			}
			}
			break;
		case X86_INS_SHL:
		case X86_INS_SHLD:
		case X86_INS_SHLX:
			op->type = R_ANAL_OP_TYPE_SHL;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,<<=,cz,%%z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SAR:
		case X86_INS_SARX:
			op->type = R_ANAL_OP_TYPE_SAR;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,>>=,%%z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SAL:
		case X86_INS_SALC:
			op->type = R_ANAL_OP_TYPE_SAL;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,<<=,%%z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SHR:
		case X86_INS_SHRD:
		case X86_INS_SHRX:
			op->type = R_ANAL_OP_TYPE_SHR;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,>>=,cz,%%z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_CMP:
		case X86_INS_VCMP:
		case X86_INS_CMPPD:
		case X86_INS_CMPPS:
		case X86_INS_CMPSW:
		case X86_INS_CMPSD:
		case X86_INS_CMPSQ:
		case X86_INS_CMPSB:
		case X86_INS_CMPSS:
		case X86_INS_TEST:
			op->type = R_ANAL_OP_TYPE_CMP;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op,  "%s,%s,==,%%z,zf,=", src, dst);
				free (src);
				free (dst);
			}
			switch (INSOP(0).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(0).mem.disp;
				op->refptr = INSOP(0).size;
				if (INSOP(0).mem.base == X86_REG_RIP) {
					op->ptr += addr + insn->size;
				} else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
					op->stackop = R_ANAL_STACK_SET;
					op->stackptr = regsz;
				}
				break;
			default:
				switch (INSOP(1).type) {
				case X86_OP_MEM:
					op->ptr = INSOP(1).mem.disp;
					op->refptr = INSOP(1).size;
					if (INSOP(1).mem.base == X86_REG_RIP) {
						op->ptr += addr + insn->size;
					} else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
						op->stackop = R_ANAL_STACK_SET;
						op->stackptr = regsz;
					}
					break;
				case X86_OP_IMM:
					op->ptr = INSOP(1).imm;
					break;
				default:
					break;
				}
				break;
			}
			break;
		case X86_INS_LEA:
			op->type = R_ANAL_OP_TYPE_LEA;
			if (a->decode) {
				char *src = getarg (handle, insn, 0, 0);
				char *dst = getarg (handle, insn, 1, 2);
				esilprintf (op, "%s,%s,=", dst, src);
				free (src);
				free (dst);
			}
			switch (INSOP(1).type) {
			case X86_OP_MEM:
				op->ptr = INSOP(1).mem.disp;
				op->refptr = INSOP(1).size;
				switch (INSOP(1).mem.base) {
				case X86_REG_RIP:
					op->ptr += addr + op->size;
					break;
				case X86_REG_RBP:
				case X86_REG_EBP:
					op->stackop = R_ANAL_STACK_GET;
					op->stackptr = regsz;
					break;
				}
				break;
			case X86_OP_IMM:
				if (INSOP(1).imm > 10)
					op->ptr = INSOP(1).imm;
				break;
			default:
				break;
			}
			break;
		case X86_INS_ENTER:
		case X86_INS_PUSH:
		case X86_INS_PUSHAW:
		case X86_INS_PUSHAL:
		case X86_INS_PUSHF:
			{
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op,  "%d,%s,-=,%s,%s,=[%d]", rs, sp, dst, sp, rs);
				free (dst);
			}
			switch (INSOP(0).type) {
			case X86_OP_IMM:
				op->ptr = INSOP(0).imm;
				op->type = R_ANAL_OP_TYPE_PUSH;
				break;
			default:
				op->type = R_ANAL_OP_TYPE_UPUSH;
				break;
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = regsz;
			break;
		case X86_INS_LEAVE:
			op->type = R_ANAL_OP_TYPE_POP;
			if (a->decode) {
				esilprintf (op, "%s,%s,=,%s,[%d],%s,%d,%s,-=",
					bp, sp, sp, rs, bp, rs, sp);
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_POP:
		case X86_INS_POPAW:
		case X86_INS_POPAL:
		case X86_INS_POPF:
		case X86_INS_POPCNT:
			op->type = R_ANAL_OP_TYPE_POP;
			if (a->decode) {
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op,
					"%s,[%d],%s,=,%d,%s,+=",
					sp, rs, dst, rs, sp);
				free (dst);
			}
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_RET:
		case X86_INS_RETF:
		case X86_INS_IRET:
		case X86_INS_IRETD:
		case X86_INS_IRETQ:
		case X86_INS_SYSRET:
			op->type = R_ANAL_OP_TYPE_RET;
			if (a->decode)
				esilprintf (op, "%s,[%d],%s,=,%d,%s,+=",
					sp, rs, pc, rs, sp);
			op->stackop = R_ANAL_STACK_INC;
			op->stackptr = -regsz;
			break;
		case X86_INS_INT:
			if (a->decode)
				esilprintf (op, "%d,$", (int)INSOP(0).imm);
			op->type = R_ANAL_OP_TYPE_SWI;
			break;
		case X86_INS_INT1:
		case X86_INS_INT3:
		case X86_INS_INTO:
		case X86_INS_VMCALL:
		case X86_INS_VMMCALL:
		case X86_INS_SYSCALL:
			op->type = R_ANAL_OP_TYPE_TRAP;
			if (a->decode)
				esilprintf (op, "%d,$", (int)INSOP(0).imm);
			break;
		case X86_INS_JL:
		case X86_INS_JLE:
		case X86_INS_JA:
		case X86_INS_JAE:
		case X86_INS_JB:
		case X86_INS_JBE:
		case X86_INS_JCXZ:
		case X86_INS_JECXZ:
		case X86_INS_JRCXZ:
		case X86_INS_JO:
		case X86_INS_JNO:
		case X86_INS_JS:
		case X86_INS_JNS:
		case X86_INS_JP:
		case X86_INS_JNP:
		case X86_INS_JE:
		case X86_INS_JNE:
		case X86_INS_JG:
		case X86_INS_JGE:
		case X86_INS_LOOP:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = INSOP(0).imm;
			op->fail = addr+op->size;
			if (a->decode) {
				char *dst = getarg (handle, insn, 0, 2);
				switch (insn->id) {
				case X86_INS_JL:
					esilprintf (op, "of,sf,^,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JLE:
					esilprintf (op, "of,sf,^,zf,|,%s,%s,=", dst, pc);
					break;
				case X86_INS_JA:
					esilprintf (op, "cf,!,zf,!,&,?{,%s,%s,=,}",dst, pc);
					break;
				case X86_INS_JAE:
					esilprintf (op, "cf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JB:
					esilprintf (op, "cf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JO:
					esilprintf (op, "of,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNO:
					esilprintf (op, "of,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JE:
					esilprintf (op, "zf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JGE:
					esilprintf (op, "of,!,sf,^,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNE:
					esilprintf (op, "zf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JG:
					esilprintf (op, "sf,of,!,^,zf,!,&,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JS:
					esilprintf (op, "sf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNS:
					esilprintf (op, "sf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JP:
					esilprintf (op, "pf,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JNP:
					esilprintf (op, "pf,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JBE:
					esilprintf (op, "zf,cf,&,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JCXZ:
					esilprintf (op, "cx,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JECXZ:
					esilprintf (op, "ecx,!,?{,%s,%s,=,}", dst, pc);
					break;
				case X86_INS_JRCXZ:
					esilprintf (op, "rcx,!,?{,%s,%s,=,}", dst, pc);
					break;
				}
				free (dst);
			}
			break;
		case X86_INS_CALL:
		case X86_INS_LCALL:
			switch (INSOP(0).type) {
			case X86_OP_IMM:
				op->type = R_ANAL_OP_TYPE_CALL;
				// TODO: what if UCALL?
				// TODO: use imm_size
				op->jump = INSOP(0).imm;
				op->fail = addr+op->size;
				break;
			case X86_OP_MEM:
				op->type = R_ANAL_OP_TYPE_UCALL;
				op->jump = UT64_MAX;
				if (INSOP(0).mem.base == 0) {
					op->ptr = INSOP(0).mem.disp;
				}
				break;
			default:
				op->type = R_ANAL_OP_TYPE_UCALL;
				op->jump = UT64_MAX;
				break;
			}
			if (a->decode) {
				char* arg = getarg (handle, insn, 0, 1);
				esilprintf (op,
						"%d,%s,+,"
						"%d,%s,-=,%s,"
						"=[],"
						"%s,%s,=",
						op->size, pc,
						rs, sp, sp, arg, pc);
				free (arg);
			}
			break;
		case X86_INS_JMP:
		case X86_INS_LJMP:
			if (a->decode) {
				char *src = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,=", src, pc);
				free (src);
			}
			// TODO: what if UJMP?
			if (INSOP(0).type == X86_OP_IMM) {
				op->jump = INSOP(0).imm;
				op->type = R_ANAL_OP_TYPE_JMP;
				if (a->decode) {
					ut64 dst = INSOP(0).imm;
					esilprintf (op, "0x%"PFMT64x",%s,=", dst, pc);
				}
			} else {
				op->type = R_ANAL_OP_TYPE_UJMP;
			}
			break;
		case X86_INS_IN:
		case X86_INS_INSW:
		case X86_INS_INSD:
		case X86_INS_INSB:
		case X86_INS_OUT:
		case X86_INS_OUTSB:
		case X86_INS_OUTSD:
		case X86_INS_OUTSW:
			op->type = R_ANAL_OP_TYPE_IO;
			break;
		case X86_INS_VXORPD:
		case X86_INS_VXORPS:
		case X86_INS_VPXORD:
		case X86_INS_VPXORQ:
		case X86_INS_VPXOR:
		case X86_INS_KXORW:
		case X86_INS_PXOR:
		case X86_INS_XOR:
			op->type = R_ANAL_OP_TYPE_XOR;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,^=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_OR:
			op->type = R_ANAL_OP_TYPE_OR;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,|=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_SUB:
		case X86_INS_DEC:
		case X86_INS_PSUBB:
		case X86_INS_PSUBW:
		case X86_INS_PSUBD:
		case X86_INS_PSUBQ:
		case X86_INS_PSUBSB:
		case X86_INS_PSUBSW:
		case X86_INS_PSUBUSB:
		case X86_INS_PSUBUSW:
			op->type = R_ANAL_OP_TYPE_SUB;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,-=,%%c,cf,=,%%z,zf,=,%%s,sf,=,%%o,of,=", src, dst); // TODO: update flags
				free (src);
				free (dst);
			}
			if (INSOP(0).type == X86_OP_REG && INSOP(1).type == X86_OP_IMM) {
				if (INSOP(0).reg == X86_REG_RSP || INSOP(0).reg == X86_REG_ESP) {
					op->stackop = R_ANAL_STACK_INC;
					op->stackptr = INSOP(1).imm;
				}
			}
			break;
		case X86_INS_AND:
		case X86_INS_ANDN:
		case X86_INS_ANDPD:
		case X86_INS_ANDPS:
		case X86_INS_ANDNPD:
		case X86_INS_ANDNPS:
			op->type = R_ANAL_OP_TYPE_AND;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,&=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_DIV:
			op->type = R_ANAL_OP_TYPE_DIV;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,/=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_MUL:
			op->type = R_ANAL_OP_TYPE_MUL;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,*=", src, dst);
				free (src);
				free (dst);
			}
			break;
		case X86_INS_INC:
			op->type = R_ANAL_OP_TYPE_ADD;
			if (a->decode) {
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "1,%s,+=", dst);
				free (dst);
			}
			break;
		case X86_INS_ADD:
		case X86_INS_FADD:
		case X86_INS_ADDPD:
			op->type = R_ANAL_OP_TYPE_ADD;
			if (a->decode) {
				char *src = getarg (handle, insn, 1, 0);
				char *dst = getarg (handle, insn, 0, 0);
				esilprintf (op, "%s,%s,+=", src, dst);
				free (src);
				free (dst);
			}
			if (INSOP(0).type == X86_OP_REG && INSOP(1).type == X86_OP_IMM) {
				if (INSOP(0).reg == X86_REG_RSP || INSOP(0).reg == X86_REG_ESP) {
					op->stackop = R_ANAL_STACK_INC;
					op->stackptr = -INSOP(1).imm;
				}
			}
			break;
		}
	}
#if !USE_ITER_API
	cs_free (insn, n);
#endif
	cs_close (&handle);
	return op->size;
}
Beispiel #27
0
int32_t init_config(void)
{
	FILE *fp;

	if(config_enabled(WEBIF))
	{
		fp = open_config_file(cs_conf);
	}
	else
	{
		fp = open_config_file_or_die(cs_conf);
	}

	const struct config_sections *cur_section = oscam_conf; // Global
	char *token;

	config_sections_set_defaults(oscam_conf, &cfg);

	if(!fp)
	{
		// no oscam.conf but webif is included in build, set it up for lan access and tweak defaults
#ifdef WEBIF
		cfg.http_port = DEFAULT_HTTP_PORT;
		chk_iprange(cs_strdup(DEFAULT_HTTP_ALLOW), &cfg.http_allowed);
#endif
		NULLFREE(cfg.logfile);
		cfg.logtostdout = 1;
#ifdef HAVE_DVBAPI
		cfg.dvbapi_enabled = 1;
#endif
		return 0;
	}

	if(!cs_malloc(&token, MAXLINESIZE))
		{ return 1; }

	int line = 0;
	int valid_section = 1;
	while(fgets(token, MAXLINESIZE, fp))
	{
		++line;
		int len = strlen(trim(token));
		if(len < 3)  // a=b or [a] are at least 3 chars
			{ continue; }
		if(token[0] == '#')  // Skip comments
			{ continue; }
		if(token[0] == '[' && token[len - 1] == ']')
		{
			token[len - 1] = '\0';
			valid_section = 0;
			const struct config_sections *newconf = config_find_section(oscam_conf, token + 1);
			if(config_section_is_active(newconf) && cur_section)
			{
				config_list_apply_fixups(cur_section->config, &cfg);
				cur_section = newconf;
				valid_section = 1;
			}
			if(!newconf)
			{
				fprintf(stderr, "WARNING: %s line %d unknown section [%s].\n",
						cs_conf, line, token + 1);
				continue;
			}
			if(!config_section_is_active(newconf))
			{
				fprintf(stderr, "WARNING: %s line %d section [%s] is ignored (support not compiled in).\n",
						cs_conf, line, newconf->section);
			}
			continue;
		}
		if(!valid_section)
			{ continue; }
		char *value = strchr(token, '=');
		if(!value)  // No = found, well go on
			{ continue; }
		*value++ = '\0';
		char *tvalue = trim(value);
		char *ttoken = trim(strtolower(token));
		if(cur_section && !config_list_parse(cur_section->config, ttoken, tvalue, &cfg))
		{
			fprintf(stderr, "WARNING: %s line %d section [%s] contains unknown setting '%s=%s'\n",
					cs_conf, line, cur_section->section, ttoken, tvalue);
		}
	}
	free(token);
	fclose(fp);
	if(cur_section) { config_list_apply_fixups(cur_section->config, &cfg); }
	return 0;
}
Beispiel #28
0
/*
 * This function returns cw (mostly received) in cache for er, or NULL if not found.
 * IMPORTANT:
 * 		- If found, DON'T forget to free returned ecm, because it is a copy useful to get data
 * 		- If found, and cacheex_src client of returned ecm is not NULL, and we want to access it,
 *        remember to check for its validity (client structure is still existent)
 *        E.g.: if(ecm->cacheex_src && is_valid_client(ecm->cacheex_src) && !ecm->cacheex_src->kill)
 *        We don't want make this stuff here to avoid useless cpu time if outside function we would not access to it.
 */
struct ecm_request_t *check_cache(ECM_REQUEST *er, struct s_client *cl)
{
	if(!er->csp_hash) return NULL;

	ECM_REQUEST *ecm = NULL;
	ECMHASH *result;
	CW *cw;
	uint64_t grp = cl?cl->grp:0;

	pthread_rwlock_rdlock(&cache_lock);

	result = find_hash_table(&ht_cache, &er->csp_hash, sizeof(int32_t),&compare_csp_hash);
	cw = get_first_cw(result, er);

	if(
		cw
		&&
	    (
			cw->csp    //csp have no grp!
			||
			!grp		   			     //csp client(no grp) searching for cache
			||
			(
			  grp
			  &&
			  cw->grp  //ecm group --> only when readers/ex-clients answer (e_found) it
			  && (grp & cw->grp)
			)
		 )
	){


#ifdef CS_CACHEEX

		//if preferlocalcards=2 for this ecm request, we can server ONLY cw from localcards readers until stage<3
		if(er->preferlocalcards==2 && !cw->localcards && er->stage<3){
		    pthread_rwlock_unlock(&cache_lock);
		    return NULL;
		}

		CWCHECK check_cw = get_cwcheck(er);
		if((!cw->proxy && !cw->localcards)  //cw received from ONLY cacheex/csp peers
		   && check_cw.counter>1
		   && cw->count < check_cw.counter
		   && (check_cw.mode || !er->cacheex_wait_time_expired)
		){
		    pthread_rwlock_unlock(&cache_lock);
		    return NULL;
		}
#endif


#ifdef CW_CYCLE_CHECK
		uint8_t cwc_ct = cw->cwc_cycletime > 0 ? cw->cwc_cycletime : 0;
		uint8_t cwc_ncwc = cw->cwc_next_cw_cycle < 2 ? cw->cwc_next_cw_cycle : 2;
		if(cw->got_bad_cwc)
		{
			pthread_rwlock_unlock(&cache_lock);
			return NULL;
		}
		if(checkcwcycle(cl, er, NULL, cw->cw, 0, cwc_ct, cwc_ncwc) != 0){
			cs_debug_mask(D_CWC | D_LB, "{client %s, caid %04X, srvid %04X} [check_cache] cyclecheck passed ecm in INT. cache, ecm->rc %d", (cl ? cl->account->usr : "******"), er->caid, er->srvid, ecm ? ecm->rc : -1);
		}else{
			cs_debug_mask(D_CWC, "cyclecheck [BAD CW Cycle] from Int. Cache detected.. {client %s, caid %04X, srvid %04X} [check_cache] -> skip cache answer", (cl ? cl->account->usr : "******"), er->caid, er->srvid);
			cw->got_bad_cwc = 1; // no need to check it again
			pthread_rwlock_unlock(&cache_lock);
			return NULL;
		}
#endif

		if (cs_malloc(&ecm, sizeof(ECM_REQUEST))){
			ecm->rc = E_FOUND;
			ecm->rcEx = 0;
			memcpy(ecm->cw, cw->cw, 16);
			ecm->grp = cw->grp;
			ecm->selected_reader = cw->selected_reader;
			ecm->cwc_cycletime = cw->cwc_cycletime;
			ecm->cwc_next_cw_cycle = cw->cwc_next_cw_cycle;
#ifdef CS_CACHEEX
			ecm->cacheex_src = cw->cacheex_src;
#endif
			ecm->cw_count = cw->count;
		}
	}

    pthread_rwlock_unlock(&cache_lock);
    return ecm;
}
Beispiel #29
0
int32_t disas_executable_and_examine(void)
{
    int32_t rtrn;
    uint64_t file_size;
    uint32_t count = 0;
    int32_t file auto_close = 0;
    char *file_buffer = NULL;
    char *exec_path auto_free = NULL;

    /* Ask the file module for the path of the binary to test. */
    rtrn = get_exec_path(&exec_path);
    if(rtrn < 0)
    {
        output(ERROR, "Can't get exec path\n");
        return -1;
    }

    /* Open the target binary. */
    file = open(exec_path, O_RDONLY);
    if(file < 0)
    {
        output(ERROR, "open: %s\n", strerror(errno));
        return (-1);
    }

    /* Read file in to memory. */
    rtrn = map_file_in(file, &file_buffer, &file_size, READ);
    if(rtrn < 0)
    {
        output(ERROR, "Can't memory map file\n");
        return (-1);
    }

    /* Create a const pointer to the file buffer so we can avoid
    a warning when using cs_disasm_iter(). */
    const uint8_t *file_buffer_copy = (uint8_t *)file_buffer;

    /* Create capstone handle.*/
    csh handle;
    cs_open(CS_ARCH_X86, CS_MODE_32, &handle);

    /* Allocate memory cache for 1 instruction, to be used by cs_disasm_iter later. */
    cs_insn *insn = cs_malloc(handle);

    uint64_t address = 0;

    /* Disassemble one instruction at a time & store the result into the insn variable above */
    while(cs_disasm_iter(handle, (const uint8_t **)&file_buffer_copy,
                         (unsigned long *)&file_size, &address, insn))
    {
        /* Check for branchs in the disasembly, maybe switch to a hash map in the future. */
        if(strncmp(insn->mnemonic, "jne", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "je", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jg", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jle", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jl", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jge", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jo", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jno", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "js", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jns", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jz", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jb", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnae", 4) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jc", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnb", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jae", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnc", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jbe", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jna", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "ja", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnbe", 4) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jl", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnge", 4) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jge", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jng", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnle", 4) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jp", 2) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jpe", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jnp", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jpo", 3) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jcxz", 4) == 0)
        {
            goto found_branch;
        }
        else if(strncmp(insn->mnemonic, "jecxz", 5) == 0)
        {
            goto found_branch;
        }
        else
        {
            /* We didn't find a branch instruction so cotinue looping */
            continue;
        }

    found_branch:

        /*map->exec_ctx->address_index = realloc(map->exec_ctx->address_index, sizeof(char *) * count);
        if(map->exec_ctx->address_index == NULL)
        {
            output(ERROR, "Can't realloc address index: %s\n", strerror(errno));
            return -1;
        }

        rtrn = asprintf(&map->exec_ctx->address_index[count], "%s", insn->address);
        if(rtrn < 0)
        {
            output(ERROR, "Can't alloc address index slot: %s\n", strerror(errno));
            return -1;
        } */

        count++;

        continue;
    }

    /* Save the offset of where the program ends. */
    rtrn = set_end_offset(insn[0].address);
    if(rtrn < 0)
    {
        output(ERROR, "Can't set end offset\n");
        return -1;
    }

    cs_free(insn, 1); // release the cache memory when done
    munmap(file_buffer, (size_t)file_size);

    return 0;
}
Beispiel #30
0
static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f) {
	struct s_reader *rdr = setting;
	if (value) {
		char *ptr, *ptr2, *ptr3;
		struct s_ecmHeaderwhitelist *tmp, *last = NULL;

		if (strlen(value) == 0) {
			for (tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next)
				add_garbage(tmp);
			rdr->ecmHeaderwhitelist = NULL;
		} else {
			char *ptr4, *ptr5, *ptr6, *saveptr = NULL, *saveptr4 = NULL, *saveptr5 = NULL, *saveptr6 = NULL;
			uint16_t caid = 0;
			uint32_t provid = 0;
			int16_t len = 0;
			for (ptr = strtok_r(value, ";", &saveptr); ptr; ptr = strtok_r(NULL, ";", &saveptr)) {
				caid = 0;
				provid = 0;
				ptr2 = strchr(ptr, '@');
				ptr3 = strchr(ptr, ':');
				if (ptr2 == NULL && ptr3 == NULL) { //no Caid no Provid
					for (ptr4 = strtok_r(ptr, ",", &saveptr4); ptr4; ptr4 = strtok_r(NULL, ",", &saveptr4)) {
						if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) {
							ptr4 = trim(ptr4);
							len = strlen(ptr4);
							key_atob_l(ptr4, tmp->header, len);
							tmp->len = len;
							tmp->caid = 0;
							tmp->provid = 0;
							tmp->next = NULL;
							if (last == NULL) {
								rdr->ecmHeaderwhitelist = tmp;
							} else {
								last->next = tmp;
							}
							last = tmp;
						}
					}
				}

				if (ptr3 != NULL && ptr2 == NULL) { // only with Caid
					ptr3[0] = '\0';
					++ptr3;
					caid = (int16_t)dyn_word_atob(ptr);
					for (ptr5 = strtok_r(ptr3, ",", &saveptr5); ptr5; ptr5 = strtok_r(NULL, ",", &saveptr5)) {
						if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) {
							tmp->caid = caid;
							tmp->provid = 0;
							ptr5 = trim(ptr5);
							len = strlen(ptr5);
							key_atob_l(ptr5, tmp->header, len);
							tmp->len = len;
							tmp->next = NULL;
							if (last == NULL) {
								rdr->ecmHeaderwhitelist = tmp;
							} else {
								last->next = tmp;
							}
							last = tmp;
						}
					}
				}

				if (ptr3 != NULL && ptr2 != NULL) { // with Caid & Provid
					ptr2[0] = '\0';
					++ptr2; // -> provid
					ptr3[0] = '\0';
					++ptr3; // -> headers
					caid = (int16_t)dyn_word_atob(ptr);
					provid = (uint32_t)a2i(ptr2, 6);
					for (ptr6 = strtok_r(ptr3, ",", &saveptr6); ptr6; ptr6 = strtok_r(NULL, ",", &saveptr6)) {
						if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) {
							tmp->caid = caid;
							tmp->provid = provid;
							ptr6 = trim(ptr6);
							len = strlen(ptr6);
							key_atob_l(ptr6, tmp->header, len);
							tmp->len = len;
							tmp->next = NULL;
							if (last == NULL) {
								rdr->ecmHeaderwhitelist = tmp;
							} else {
								last->next = tmp;
							}
							last = tmp;
						}
					}
				}
			}
		}
/*	if (rdr->ecmHeaderwhitelist != NULL) { // debug
		cs_log("**********Begin ECM Header List for Reader: %s **************", rdr->label);

		struct s_ecmHeaderwhitelist *tmp;
		for(tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next){
			cs_log("Caid: %i Provid: %i Header: %02X Len: %i", tmp->caid, tmp->provid, tmp->header[0], tmp->len);
		}
		cs_log("***********End ECM Header List for Reader: %s ***************", rdr->label);
	} */
		return;
	}

	value = mk_t_ecmheaderwhitelist(rdr->ecmHeaderwhitelist);
	if (strlen(value) > 0 || cfg.http_full_cfg)
		fprintf_conf(f, token, "%s\n", value);
	free_mk_t(value);
}