void ProcInfo::PrintSections(){
	MYLOG("======= SECTIONS ======= \n");
	for(int i = 0; i < this->Sections.size(); i++) {
		Section item = this->Sections.at(i);
		MYLOG("%s	->	begin : %08x		end : %08x", item.name.c_str(), item.begin, item.end);
	}
	MYLOG("================================= \n");
}
UINT32 PushadPopadheuristic::run(){
	//filter out the improper values 
	ProcInfo *proc_info = ProcInfo::getInstance();
	//if both the flag are valid our heuristic is valid 
	if( proc_info->getPopadFlag() && proc_info->getPushadFlag() ){
			MYLOG("[PUSHAD POPAD DETECTED !!]");
			MYLOG("");
			MYLOG("");
			return OEPFINDER_FOUND_OEP	
	}
示例#3
0
	bool EvalState(Coroutine* t = NULL) {
		safe_assert(tvar1_ != NULL && tvar2_ != NULL);
		Coroutine* co1 = tvar1_->thread();
		Coroutine* co2 = tvar2_->thread();
		if(co1 == NULL || co2 == NULL) {
			MYLOG(2) << "Evaluating TPThreadVarsEqual, one of them is NULL";
			return true;
		}
		MYLOG(2) << "Evaluating TPThreadVarsEqual for " << co1->tid() << " and " << co2->tid();
		return co1->tid() == co2->tid();
	}
/* Utils + Helper */
void ProcInfo::PrintStartContext(){
	MYLOG("======= START REGISTERS ======= \n");
	MYLOG("EAX: %08x " , this->reg_start_context.eax);
	MYLOG("EBX: %08x " , this->reg_start_context.ebx);
	MYLOG("ECX: %08x " , this->reg_start_context.ecx);
	MYLOG("EDX: %08x " , this->reg_start_context.edx);
	MYLOG("ESP: %08x " , this->reg_start_context.esp);
	MYLOG("EBP: %08x " , this->reg_start_context.ebp);
	MYLOG("ESI: %08x " , this->reg_start_context.esi);
	MYLOG("EDI: %08x " , this->reg_start_context.edi);
	MYLOG("============================== \n");
}
// This function is called when the application exits
VOID Fini(INT32 code, VOID *v)
{

	//DEBUG --- inspect the write set at the end of the execution
	WxorXHandler *wxorxHandler = WxorXHandler::getInstance();
	MYLOG("WRITE SET SIZE: %d\n", wxorxHandler->getWritesSet().size());
	//DEBUG --- get the execution time
	MYLOG("Total execution Time: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
	CLOSELOG();
	Log::getInstance()->closeReportFile();

}
void ProcInfo::PrintCurrContext(){

	MYLOG("======= CURRENT REGISTERS ======= \n");
	MYLOG("EAX: %08x " , this->reg_curr_context.eax);
	MYLOG("EBX: %08x " , this->reg_curr_context.ebx);
	MYLOG("ECX: %08x " , this->reg_curr_context.ecx);
	MYLOG("EDX: %08x " , this->reg_curr_context.edx);
	MYLOG("ESP: %08x " , this->reg_curr_context.esp);
	MYLOG("EBP: %08x " , this->reg_curr_context.ebp);
	MYLOG("ESI: %08x " , this->reg_curr_context.esi);
	MYLOG("EDI: %08x " , this->reg_curr_context.edi);
	MYLOG("================================= \n");
}
sqlc_handle_t sqlc_db_open(const char *filename, int flags)
{
  sqlite3 *d1;
  int r1;

  MYLOG("db_open %s %d", filename, flags);

  r1 = sqlite3_open_v2(filename, &d1, flags, NULL);

  MYLOG("db_open %s result %d ptr %p", filename, r1, d1);

  return (r1 == 0) ? HANDLE_FROM_VP(d1) : -r1;
}
示例#8
0
	//override
	bool OnRecv(EventPipe* pipe, EventBuffer* event) {
		safe_assert(event != NULL);

		ScopeMutex m(&mutex_);

		ConcurrentPipe* concpipe = static_cast<ConcurrentPipe*>(pipe);
		safe_assert(concpipe != NULL);

		MYLOG(1) << "CLIENT: Received event " << EventKindToString(event->type);

		const THREADID tid = event->threadid;

		// handle event
		switch(event->type) {
		case TestStart:
		{
			safe_assert(tid == 0);

			if(test_started) {
				safe_fail("CLIENT: Received TestStart before TestEnd!");
			}
			test_started = true;

			MYLOG(1) << "CLIENT: Test starting.";

			return false; // ignore it
		}

		case TestEnd:
		{
			safe_assert(tid == 0);

			if(!test_started) {
				safe_fail("CLIENT: Received TestEnd before TestStart!");
			}
			test_started = false;

			MYLOG(1) << "CLIENT: Test ending.";

			return false; // ignore it
		}

		default:
			MYLOG(1) << "CLIENT: Handler propagating the event " << EventKindToString(event->type) << " to thread " << event->threadid;
			break;
		}

		return true;
	}
示例#9
0
	void concurritAtPcEx(int pc, const char* filename, const char* funcname, int line) {
		if(!test_started) return;

		MYLOG(1) << "CLIENT: Sending concurritAtPc: " << pc;

		ClientShadowThread* thread = GetShadowThread();

		MYLOG(1) << "CLIENT: Sending concurritAtPc: " << pc << " to thread " << thread->tid();;

		// send event
		EventBuffer e;
		e.type = AtPc;
		e.pc = pc;
		thread->SendRecvContinue(&e);
	}
示例#10
0
	void OnEnd() {
		MYLOG(1) << "CLIENT: Sending ThreadEnd to thread " << tid_;
		// send thread end
		EventBuffer event;
		event.type = ThreadEnd;
		event.threadid = tid_;
		SendRecvContinue(&event);
		MYLOG(1) << "CLIENT: Received continue for ThreadEnd to thread " << tid_;

		// clear tls data
		set_tls(NULL);

		safe_assert(pipe_ != NULL);
		ConcurrentPipe* concpipe = static_cast<ConcurrentPipe*>(pipe_);
		concpipe->UnregisterShadowThread(this);
	}
int sqlc_st_bind_long(sqlc_handle_t st, int pos, sqlc_long_t val)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p %d %lld", __func__, myst, pos, val);

  return sqlite3_bind_int64(myst, pos, val);
}
int sqlc_st_bind_double(sqlc_handle_t st, int pos, double val)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p %d %lf", __func__, myst, pos, val);

  return sqlite3_bind_double(myst, pos, val);
}
int sqlc_st_bind_text_native(sqlc_handle_t st, int col, const char *val)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p %d %s", __func__, myst, col, val);

  return sqlite3_bind_text(myst, col, val, -1, SQLITE_TRANSIENT);
}
int sqlc_st_column_count(sqlc_handle_t st)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p", __func__, myst);

  return sqlite3_column_count(myst);
}
const char *sqlc_st_column_text_native(sqlc_handle_t st, int col)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p %d", __func__, myst, col);

  return sqlite3_column_text(myst, col);
}
int sqlc_st_column_type(sqlc_handle_t st, int col)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p %d", __func__, myst, col);

  return sqlite3_column_type(myst, col);
}
int sqlc_st_finish(sqlc_handle_t st)
{
  sqlite3_stmt *myst = HANDLE_TO_VP(st);

  MYLOG("%s %p", __func__, myst);

  return sqlite3_finalize(myst);
}
int sqlc_db_close(sqlc_handle_t db)
{
  sqlite3 *mydb = HANDLE_TO_VP(db);

  MYLOG("%s %p", __func__, mydb);

// XXX TBD consider sqlite3_close() vs sqlite3_close_v2() ??:
  return sqlite3_close(mydb);
}
示例#19
0
	/**
	 * Implementation of capture API:s exposed to JavaScript.
	 * @return true if message was handled, false if not.
	 */
	void PhoneGapCamera::handleMessage(JSONMessage& message)
	{
		if (message.getParam("action") == "getPicture")
		{
			MYLOG("PhoneGapCamera::handleMessage getPicture");

			mCaptureCallBack = message.getParam("PhoneGapCallBackId");

			//maImagePickerOpen() #EVENT_TYPE_IMAGE_PICKER

			/*
			struct {
				// #EVENT_TYPE_IMAGE_PICKER events, this will be 0 if canceled or 1 if Ok was pressed.
				int imagePickerState;
				// #EVENT_TYPE_IMAGE_PICKER event, contains the new handle to the selected image.
				MAHandle imagePickerItem;
			} imagePicker;
			*/

			mMessageHandler->callSuccess(
				mCaptureCallBack,
				PHONEGAP_CALLBACK_STATUS_OK,
				"{\"message\":\"Hello\"}",
				false);

			/*int duration = message.getArgsFieldInt("duration");
			if(duration > 0)
			{
				char durationString[16];
				maCaptureSetProperty(MA_CAPTURE_MAX_DURATION, itoa(duration,durationString,10));
			}

			mCaptureCallBack = message.getParam("PhoneGapCallBackId");

			int result = maCaptureAction(MA_CAPTURE_ACTION_RECORD_VIDEO);

			if(result == MA_CAPTURE_RES_CAMERA_NOT_AVAILABLE)
			{
				//Camera was busy by another app
				mMessageHandler->callError(
					mCaptureCallBack,
					PHONEGAP_CALLBACK_STATUS_ERROR,
					"{\"code\":\"CAPTURE_APPLICATION_BUSY\"}",
					false);
			}
			else if(result == MA_CAPTURE_RES_VIDEO_NOT_SUPPORTED)
			{
				//No camera
				mMessageHandler->callError(
					mCaptureCallBack,
					PHONEGAP_CALLBACK_STATUS_ERROR,
					"{\"code\":\"CAPTURE_NOT_SUPPORTED\"}",
					false);
			}
			*/
		}
	}
示例#20
0
int main(int argc, char **argv)
{
    // init global vars
    initSharedMem();

    // register exit callback
    atexit(exitCB);

    // init GLUT and GL
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(200, 200);
    int handle = glutCreateWindow(argv[0]);
    glutDisplayFunc(displayCB);
    glutReshapeFunc(reshapeCB);
    glutKeyboardFunc(keyboardCB);

    glewInit();
    if (glewIsSupported("GL_VERSION_2_1"))
    {
        MYLOG("Ready for OpenGL 2.1\n");
    }
    else
    {
        MYLOG("OpenGL 2.1 not supported\n");
        exit(1);
    }
    if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader && GL_EXT_geometry_shader4)
    {
        MYLOG("Ready for GLSL - vertex, fragment, and geometry units\n");
    }
    else
    {
        MYLOG("Not totally ready :( \n");
        exit(1);
    }

    initRS();
    glutMainLoop();

    return 0;
}
sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char *sql)
{
  sqlite3 *mydb = HANDLE_TO_VP(db);
  sqlite3_stmt *s;
  int rv;

  MYLOG("prepare db %p sql %s", mydb, sql);

  rv = sqlite3_prepare_v2(mydb, sql, -1, &s, NULL);

  return (rv == 0) ? HANDLE_FROM_VP(s) : -rv;
}
示例#22
0
	// override
	void concurritEndTest() {
		MYLOG(1) << "CLIENT: concurritEndTest called.";

		// send test end
		EventBuffer e;
		e.type = TestEnd;
		e.threadid = 0;
		pipe_->Send(NULL, &e);

		pipe_->Recv(NULL, &e);
		safe_assert(e.type == concurrit::Continue);
	}
示例#23
0
	static ClientShadowThread* GetShadowThread() {
		ClientShadowThread* thread = get_tls();
		if(thread == NULL) {
			safe_assert(pipe_ != NULL);

			THREADID tid = get_next_threadid();

			MYLOG(1) << "CLIENT: Creating new ClientShadowThread: " << tid;

			thread = new ClientShadowThread(tid, pipe_);
			thread->OnStart();
		}
		return thread;
	}
示例#24
0
	void concurritFuncReturnEx(void* addr, uintptr_t retval, const char* filename, const char* funcname, int line) {
		if(!test_started) return;

		ClientShadowThread* thread = GetShadowThread();

		MYLOG(1) << "CLIENT: Sending FuncReturn for function addr " << addr << " to thread " << thread->tid();

		// send event
		EventBuffer e;
		e.type = FuncReturn;
		e.addr = PTR2ADDRINT(addr);
		e.retval = retval;
		thread->SendRecvContinue(&e);
	}
float ProcInfo::GetEntropy(){

	IMG binary_image = APP_ImgHead();

	const double d1log2 = 1.4426950408889634073599246810023;
	double Entropy = 0.0;
	unsigned long Entries[256];
	unsigned char* Buffer;

	ADDRINT start_address = IMG_LowAddress(binary_image);
	ADDRINT end_address = IMG_HighAddress(binary_image);
	UINT32 size = end_address - start_address;

	Buffer = (unsigned char *)malloc(size);

	MYLOG("size to dump is %d" , size);
	MYLOG("Start address is %08x" , start_address);
	MYLOG("Start address is %08x" , end_address);
	MYLOG("IMAGE NAME IS %s" , IMG_Name(binary_image));

	PIN_SafeCopy(Buffer , (void const *)start_address , size);

	memset(Entries, 0, sizeof(unsigned long) * 256);

	for (unsigned long i = 0; i < size; i++)
		Entries[Buffer[i]]++;
	for (unsigned long i = 0; i < 256; i++)
	{
		double Temp = (double) Entries[i] / (double) size;
		if (Temp > 0)
			Entropy += - Temp*(log(Temp)*d1log2); 
	}

	MYLOG("ENTROPY IS %f" , Entropy);

	return Entropy;
}
示例#26
0
	// override
	void concurritAddressOfSymbolEx(const char* symbol, uintptr_t addr) {
		// size of symbol must be at most 63
		safe_check(strnlen(symbol, 64) < 64);

		ClientShadowThread* thread = GetShadowThread();

		MYLOG(1) << "CLIENT: Sending AddressOfSymbol for function addr " << ADDRINT2PTR(addr) << " to thread " << thread->tid();

		// send event
		EventBuffer e;
		e.type = AddressOfSymbol;
		e.addr = addr;
		strncpy(e.str, symbol, 63);
		thread->SendRecvContinue(&e);
	}
void imageLoadCallback(IMG img,void *){
	//get the initial entropy of the PE
	//we have to consder only the main executable and avìvoid the libraries
	if(IMG_IsMainExecutable(img)){
		
		ProcInfo *proc_info = ProcInfo::getInstance();

		proc_info->setFirstINSaddress(IMG_Entry(img));

		MYLOG("INIT : %08x", proc_info->getFirstINSaddress());

		MYLOG("----------------------------------------------");
		float initial_entropy = proc_info->GetEntropy();
		proc_info->setInitialEntropy(initial_entropy);
		MYLOG("----------------------------------------------");


		for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){
			Section item;
			item.name = SEC_Name(sec);
			item.begin = SEC_Address(sec);
			item.end = item.begin + SEC_Size(sec);
			proc_info->insertSection(item);
		}

		proc_info->PrintSections();

	}
	FilterHandler *filterH = FilterHandler::getInstance();
	ADDRINT startAddr = IMG_LowAddress(img);
	ADDRINT endAddr = IMG_HighAddress(img);
	const string name = IMG_Name(img); 
	if(!IMG_IsMainExecutable(img) && filterH->isKnownLibrary(name)){		
		filterH->addLibrary(name,startAddr,endAddr);
	}
}
int main(int argc, char * argv[])
{


	MYLOG("Strating prototype ins\n");
	FilterHandler *filterH = FilterHandler::getInstance();
	filterH->setFilters("teb");

	tStart = clock();
	
	// Initialize pin
	PIN_InitSymbols();

	if (PIN_Init(argc, argv)) return Usage();
	
	//	TRACE_AddInstrumentFunction(Trace,0);
	INS_AddInstrumentFunction(Instruction,0);
	PIN_AddThreadStartFunction(OnThreadStart, 0);
	// Register ImageLoad to be called when an image is loaded

	IMG_AddInstrumentFunction(imageLoadCallback, 0);

	// Register ImageUnload to be called when an image is unloaded
	IMG_AddUnloadFunction(ImageUnloadCallback, 0);

	//PIN_AddApplicationStartFunction(bootstrap, 0);

	// Register Fini to be called when the application exits
	PIN_AddFiniFunction(Fini, 0);
	
	// Start the program, never returns
	PIN_StartProgram();
	
	return 0;

}
示例#29
0
int match_line_with_keyword(const char *line, int line_length, const char *keyword, MatchMode mode)
{
    MYLOG("line_length %d", line_length);

    wchar_t line_char,keyword_char; 
    int match_hanzi_count = 0;

    utf8vector line_vector = utf8vector_create(line, line_length);
    utf8vector keyword_vector = utf8vector_create(keyword, -1);

    int keyword_length = utf8vector_uni_count(keyword_vector);
    int keyword_index = 0;
    wchar_t *keyword_uni = malloc(sizeof(wchar_t) * keyword_length);

    while ((keyword_char = utf8vector_next_unichar(keyword_vector)) != '\0')
    {
        keyword_uni[keyword_index] = keyword_char;
        keyword_index ++;
    }

    //printf("keyword length %d\n", keyword_length);

    int match_rt = 1;
    keyword_index = 0;

    while((line_char = utf8vector_next_unichar(line_vector)) != '\0'
            && keyword_index < keyword_length)
    {
        keyword_char = keyword_uni[keyword_index];
        //printf("keyword index %d\n", keyword_index);

        if (pinyin_ishanzi(line_char))
        {
            if (pinyin_ishanzi(keyword_char))
            {
                if (line_char != keyword_char)
                {
                    match_rt = 0;
                    break;
                }
            }
            else if (pinyin_isabc(keyword_char))
            {
                keyword_char = pinyin_lowercase(keyword_char);
                //printf("keyword_char %d\n", keyword_char);
                const char **pinyins;
                int count = pinyin_get_pinyins_by_unicode(line_char, &pinyins);
                if (mode == MatchModeFirstLetter)
                {
                    int finded = 0;
                    for (int i = 0; i < count; i++)
                    {
                        //printf("pinyin0 %d\n", pinyins[i][0]);
                        if (keyword_char == pinyins[i][0])
                        {
                            finded = 1;
                            //printf("matched !!!!\n");
                            break;
                        }
                    }

                    if (finded == 0)
                        match_rt = 0;
                    else
                        match_hanzi_count ++;
                }
                else if (mode == MatchModeFull)
                {
                    int finded = 0;
                    for (int i = 0; i < count; i++)
                    {
                        int kindex_start = keyword_index;
                        const char *pinyin = pinyins[i];
                        int j = 0;
                        char pinyin_char;

                        while ((pinyin_char = pinyin[j]) != '\0' && kindex_start < keyword_length)
                        {
                            if (pinyin_char != pinyin_lowercase(keyword_uni[kindex_start]))
                            {
                                break;
                            }
                            j++;
                            kindex_start ++;
                        }
                       
                        int matched = (pinyin_char == '\0');
                        
                        if (matched)
                        {
                            finded = 1;
                            keyword_index = kindex_start - 1;
                            break;
                        }
                    }

                    if (finded == 0)
                        match_rt = 0;
                    else
                        match_hanzi_count ++;
                }

                free(pinyins);

                if (match_rt == 0)
                    break;
            }
            else
            {
                //printf("not hanzi or abc %d\n", keyword_char);
                match_rt = 0;
                break;
            }
        }
        else
        {
            if (line_char != keyword_char)
            {
                match_rt = 0;
                break;
            }
        }

        keyword_index ++;
    }
    
    //keyword.length > line.length
    if (match_rt == 1 && keyword_index < keyword_length)
        match_rt = 0;

    free(keyword_uni);
    utf8vector_free(line_vector);
    utf8vector_free(keyword_vector);
    if (match_rt == 0)
        return -1;
    else
        return match_hanzi_count;
}
示例#30
0
GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist)
{
	int len, i, currentLineNumber;
	FILE * f=NULL;
	char *m3u8_payload;
	u32 m3u8_size, m3u8pos;
	VariantPlaylist * pl;
	char currentLine[M3U8_BUF_SIZE];
	char ** attributes = NULL;
	s_accumulated_attributes attribs;

	if (!strncmp(file, "gmem://", 7)) {
		if (sscanf(file, "gmem://%d@%p", &m3u8_size, &m3u8_payload) != 2) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Cannot Open m3u8 source %s for reading\n", file));
			return GF_SERVICE_ERROR;
		}
	} else {
		f = gf_f64_open(file, "rt");
		if (!f) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Cannot Open m3u8 file %s for reading\n", file));
			return GF_SERVICE_ERROR;
		}
	}
	if (*playlist == NULL) {
		*playlist = variant_playlist_new();
		if (!(*playlist)) {
			if (f) fclose(f);
			return GF_OUT_OF_MEM;
		}
	}
	pl = *playlist;
	currentLineNumber = 0;
	bzero(&attribs, sizeof(s_accumulated_attributes));
	attribs.bandwidth = 0;
	attribs.durationInSeconds = 0;
	attribs.targetDurationInSeconds = 0;
	attribs.isVariantPlaylist = 0;
	attribs.isPlaylistEnded = 0;
	attribs.minMediaSequence = 0;
	attribs.currentMediaSequence = 0;
	m3u8pos=0;
	while (1) {
		char * eof;
		if (f) {
			if (!fgets(currentLine, sizeof(currentLine), f))
				break;
		} else {
			u32 __idx=0;
			if (m3u8pos>=m3u8_size)
				break;
			while (1) {
				currentLine[__idx] = m3u8_payload[m3u8pos];
				__idx++;
				m3u8pos++;
				if ((currentLine[__idx-1]=='\n') || (currentLine[__idx-1]=='\r')) {
					currentLine[__idx]=0;
					break;
				}
			}
		}
		currentLineNumber++;
		eof = strchr(currentLine, '\r');
		if (eof)
			eof[0] = '\0';
		eof = strchr(currentLine, '\n');
		if (eof)
			eof[0] = '\0';
		len = strlen( currentLine);
		if (len < 1)
			continue;
		if (currentLineNumber == 1) {
			/* Playlist MUST start with #EXTM3U */
/*			if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) {
				fclose(f);
				variant_playlist_del(pl);
				GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine));
				return GF_STREAM_NOT_FOUND;
			}
			continue;
*/		}
		if (currentLine[0] == '#') {
			/* A comment or a directive */
			if (strncmp("#EXT", currentLine, 4)==0) {
				attributes = parseAttributes(currentLine, &attribs);
				if (attributes == NULL) {
					MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine));
				} else {
					MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine));
					i = 0;
					while (attributes[i] != NULL) {
						MYLOG((" [%d]='%s'", i, attributes[i]));
						gf_free(attributes[i]);
						attributes[i] = NULL;
						i++;
					}
					MYLOG(("\n"));
					gf_free(attributes);
					attributes = NULL;
				}
				if (attribs.isPlaylistEnded) {
					pl->playlistNeedsRefresh = 0;
				}
			}
		} else {
			char * fullURL = currentLine;

			if (gf_url_is_local(currentLine)) {
				/*
				if (gf_url_is_local(baseURL)){
				int num_chars = -1;
				if (baseURL[strlen(baseURL)-1] == '/'){
				num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine);
				} else {
				num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine);
				}
				if (num_chars < 0 || fullURL == NULL){
				variant_playlist_del(*playlist);
				playlist = NULL;
				return GF_OUT_OF_MEM;
				}
				} else */ {
					fullURL = gf_url_concatenate(baseURL, currentLine);
			}
			assert( fullURL );
			}
			{
				u32 count;
				PlaylistElement * currentPlayList = sub_playlist;
				/* First, we have to find the matching program */
				Program * program = in_program;
				if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId);
				/* We did not found the program, we create it */
				if (program == NULL) {
					program = program_new(attribs.programId);
					if (program == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						if (f) fclose(f);
						playlist = NULL;
						return GF_OUT_OF_MEM;
					}
					gf_list_add(pl->programs, program);
					if (pl->currentProgram < 0)
						pl->currentProgram = program->programId;
				}

				/* OK, we have a program, we have to choose the elements with same bandwidth */
				assert( program );
				assert( program->bitrates);
				count = gf_list_count( program->bitrates);

				if (!currentPlayList) {
					for (i = 0; i < (s32) count; i++) {
						PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i);
						assert( itPlayListElement );
						if (itPlayListElement->bandwidth == attribs.bandwidth) {
							currentPlayList = itPlayListElement;
							break;
						}
					}
				}

				if (attribs.isVariantPlaylist) {
					/* We are the Variant Playlist */
					if (currentPlayList != NULL) {
						/* should not happen, it means we redefine something previsouly added */
						//assert( 0 );
					}
					currentPlayList = playlist_element_new(
						TYPE_UNKNOWN,
						fullURL,
						attribs.title,
						attribs.codecs,
						attribs.durationInSeconds,
						attribs.byteRangeStart, attribs.byteRangeEnd);
					if (currentPlayList == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						playlist = NULL;
						if (f) fclose(f);
						return GF_OUT_OF_MEM;
					}
					assert( fullURL);
					currentPlayList->url = gf_strdup(fullURL);
					currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL;
					currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL;
					gf_list_add(program->bitrates, currentPlayList);
					currentPlayList->width = attribs.width;
					currentPlayList->height = attribs.height;
				} else {
					/* Normal Playlist */
					assert( pl->programs);
					if (currentPlayList == NULL) {
						/* This is in facts a "normal" playlist without any element in it */
						PlaylistElement * subElement;
						assert(baseURL);
						currentPlayList = playlist_element_new(
							TYPE_PLAYLIST,
							baseURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (currentPlayList == NULL) {
							/* OUT of memory */
							variant_playlist_del(*playlist);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						assert(currentPlayList->element.playlist.elements);
						assert( fullURL);
						assert( currentPlayList->url);
						currentPlayList->title = NULL;
						currentPlayList->codecs = NULL;
						subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
						gf_list_add(program->bitrates, currentPlayList);
						currentPlayList->element.playlist.computed_duration += subElement->durationInfo;
						assert( program );
						assert( program->bitrates);
						assert( currentPlayList);

					} else {
						PlaylistElement * subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (currentPlayList->elementType != TYPE_PLAYLIST) {
							currentPlayList->elementType = TYPE_PLAYLIST;
							if (!currentPlayList->element.playlist.elements)
								currentPlayList->element.playlist.elements = gf_list_new();
						}
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
						currentPlayList->element.playlist.computed_duration += subElement->durationInfo;
					}
				}

				currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ;
				/* We first set the default duration for element, aka targetDuration */
				if (attribs.targetDurationInSeconds > 0) {
					currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds;
					currentPlayList->durationInfo = attribs.targetDurationInSeconds;
				}
				if (attribs.durationInSeconds) {
					if (currentPlayList->durationInfo == 0) {
						/* we set the playlist duration info as the duration of a segment, only if it's not set
						   There are cases of playlist with the last segment with a duration different from the others
						   (example: Apple bipbop test)*/
						currentPlayList->durationInfo = attribs.durationInSeconds;
					}
				}
				currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence;
				currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++;
				if (attribs.bandwidth > 1)
					currentPlayList->bandwidth = attribs.bandwidth;
				if (attribs.isPlaylistEnded)
					currentPlayList->element.playlist.is_ended = 1;
			}
			/* Cleanup all line-specific fields */
			if (attribs.title) {
				gf_free(attribs.title);
				attribs.title = NULL;
			}
			attribs.durationInSeconds = 0;
			attribs.bandwidth = 0;
			attribs.programId = 0;
			if (attribs.codecs != NULL) {
				gf_free(attribs.codecs);
				attribs.codecs = NULL;
			}
			if (fullURL != currentLine) {
				gf_free(fullURL);
			}
		}
	}
	if (f) fclose(f);

	for (i=0; i < (int) gf_list_count(pl->programs); i++) {
		u32 j;
		Program *prog = gf_list_get(pl->programs, i);
		prog->computed_duration = 0;
		for (j=0; j<gf_list_count(prog->bitrates); j++) {
			PlaylistElement *ple = gf_list_get(prog->bitrates, j);
			if (ple->elementType==TYPE_PLAYLIST) {
				if (ple->element.playlist.computed_duration > prog->computed_duration)
					prog->computed_duration = ple->element.playlist.computed_duration;
			}
		}
	}
	return GF_OK;
}