Free me :(
 The UAF vuln happens when there exists a pointer which points to heap data even after it is free'd and the pointer is used after it .
    So now we control the area when we have  another call to  malloc().  
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
struct toystr 
  {
     int (*fp)();
    char buffer[100];
  };
void winner()
{
  printf("level passed\n");
}
void nowinner()
{
  printf("level has not been passed\n");
}
void main(int arc , char **argv)
{  struct toystr *coolguy;
   char  *service;
   coolguy = malloc(sizeof(struct toystr));
   coolguy->fp = &nowinner;
   coolguy->fp();
  free(coolguy);
  service = strdup(argv[1]);
  coolguy->fp();
   
}
#include 
struct toystr 
  {
     int (*fp)();
    char buffer[100];
  };
void winner()
{
  printf("level passed\n");
}
void nowinner()
{
  printf("level has not been passed\n");
}
void main(int arc , char **argv)
{  struct toystr *coolguy;
   char  *service;
   coolguy = malloc(sizeof(struct toystr));
   coolguy->fp = &nowinner;
   coolguy->fp();
  free(coolguy);
  service = strdup(argv[1]);
  coolguy->fp();
   
}
 
 So u could look above in the code the pointer coolguy is used to funtion ptr even after it is free'd . 
   So after free we have strdup which basically call malloc of size of string . And copies that to allocated memory (which used to be area of toystr) now we copie our req 
   address which then called by coolguy (actually poor guy :P ) 
  But there is one catchy point here  as our toystr chunk is small after free it gets into fast-bin so only if malloc size (strlen+8) is equal to chunk size we could 
    get the control of free'd memory  chunk   
payload = &winner+"A"*12