Embedding Flash in a Linux GTK application - sandbox violation

I embed a Flash SWF file in a Linux application using NPAPI. Everything works fine, but when Flash calls "fscommand", I get a security violation in the sandbox. I tried a program with several Linux distributions and several versions of Flash Player (9,10,11), but no luck.

Does anyone know if this is a limitation for Flash Player on Linux platforms?

In this post, Closing the gtk application when SWF (NPAPI) ends , it seems that they received Javascript events.

This is the code I'm using:

#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <string.h> #include <unistd.h> #include <ctype.h> #include <gtk/gtk.h> #include <gdk/gdkx.h> //#include "npupp.h" #include "npapi.h" #include "npfunctions.h" //#ifdef __i386__ #define FLASH_PLUGIN_SO "./flash/libflashplayer32.so" //#else //#define FLASH_PLUGIN_SO "./flash/libflashplayer64.so" //#endif #define PR_TRUE 1 #define PR_FALSE 0 #define WINDOW_XSIZE 1600/2 #define WINDOW_YSIZE 900/2 #define NO_IDENTIFIER ((NPIdentifier)0) #define SPECIAL_IDENTIFIER 0x0FEEBBCC #define SPECIAL_METHOD_NAME "swhxCall" #define FLASH_REQUEST "__flash__request" #define FSCMD "_DoFSCommand" #define INVOKE_RESPONSE "<invoke name=\"%s\" returntype=\"javascript\"><arguments><null/></arguments></invoke>" typedef intptr_t int_val; void *flash_plugin_handle; NPNetscapeFuncs browserFuncs; NPPluginFuncs pluginFuncs; GtkWidget *main_window; char* URL; NPStream * stream; const char * uagent = "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"; NPError (*iNP_Initialize)(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs); NPError (*iNP_Shutdown)(); char* (*iNP_GetMIMEDescription)(); // --- Property IDs static char **np_ids = NULL; static int_val np_id_count = 0; static NPIdentifier resolveNPId( const char *id ) { int_val i; for(i=0;i<np_id_count;i++) if( strcmp(np_ids[i],id) == 0 ) return (NPIdentifier)(i+1); if( strcmp(id,SPECIAL_METHOD_NAME) == 0 ) return (NPIdentifier)SPECIAL_IDENTIFIER; return NO_IDENTIFIER; } static NPIdentifier addNPId( const char *id ) { NPIdentifier newid = resolveNPId(id); if( newid == NO_IDENTIFIER ) { np_id_count++; printf("New npid added: %i == %s\n",np_id_count, id); np_ids = realloc(np_ids,np_id_count*sizeof(char*)); np_ids[np_id_count-1] = strdup(id); return (NPIdentifier)np_id_count; } return newid; } static const char *getNPId( NPIdentifier id ) { int_val index = ((int_val)id)-1; if( index >= 0 && index < np_id_count ) return np_ids[index]; if( id == (NPIdentifier)SPECIAL_IDENTIFIER ) return SPECIAL_METHOD_NAME; return NULL; } static int matchNPId(NPIdentifier id, const char *str) { const char *strid = getNPId(id); return ( strid != NULL && strcmp(strid,str) == 0 ); } void freeNPIds() { while( np_id_count ) free(np_ids[--np_id_count]); free(np_ids); } static bool NPN_InvokeProc( NPP npp, NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result ) ; static bool NPN_InvokeDefaultProc( NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result ) ; static bool NPN_GetPropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVariant *result ) ; static bool NPN_SetPropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value ) ; static bool NPN_RemovePropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName ) ; static bool NPN_HasPropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName ) ; static bool NPN_HasMethodProc( NPP npp, NPObject *npobj, NPIdentifier methodName ) ; static NPObject *NPN_CreateObjectProc( NPP npp, NPClass *aClass ); static NPObject *NPN_RetainObjectProc( NPObject *npobj ); // Window class; static NPClass __gen_class = { NP_CLASS_STRUCT_VERSION , (NPAllocateFunctionPtr) malloc , (NPDeallocateFunctionPtr) free , 0 , (NPHasMethodFunctionPtr) NPN_HasMethodProc , (NPInvokeFunctionPtr) NPN_InvokeProc , (NPInvokeDefaultFunctionPtr)NPN_InvokeDefaultProc , (NPHasPropertyFunctionPtr) NPN_HasPropertyProc , (NPGetPropertyFunctionPtr) NPN_GetPropertyProc , (NPSetPropertyFunctionPtr) NPN_SetPropertyProc , (NPRemovePropertyFunctionPtr) NPN_RemovePropertyProc }; static NPObject __window = { &__gen_class, 1 }; static NPObject __location = { &__gen_class, 1}; static NPObject __top = { &__gen_class, 1 }; static NPObject __top_location = { &__gen_class, 1 }; static void traceObjectOnCall(const char *f, NPObject *o){ if (o == &__top) printf("DOM object 'top': %s\n",f); else if (o == &__window) printf("DOM object 'window': %s\n",f); else if (o == &__location) printf("DOM object 'location': %s\n",f); else if (o == &__top_location) printf("DOM object 'top.location': %s\n",f); } static void checkError(const char* str, NPError err) { if(err == NPERR_NO_ERROR) printf("[+] %s: success\n", str); else printf("[-] %s: failed (%d)\n", str, err); fflush (stdout); } void* loadFlashPluginSo() { void *handle; handle = dlopen(FLASH_PLUGIN_SO, RTLD_LAZY | RTLD_LOCAL); if(!handle) { fprintf(stderr, "[-] error loading libflasplayer.so: %s\n", dlerror()); exit(1); } puts("[+] loaded libflashplayer.so"); return handle; } void* loadSymbol(void *handle, const char *name) { char *error; void *ret; ret = dlsym(handle, name); if((error = dlerror()) != NULL) { fprintf(stderr, "[-] error loading symbol %s: %s\n", name, error); exit(1); } else { printf("[+] loaded symbol %s, address: %p\n", name, ret); } return ret; } void loadNPEntryPoints(void *handle) { iNP_Initialize=(NPError (*)(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs))loadSymbol(handle, "NP_Initialize"); iNP_Shutdown=(NPError (*)())loadSymbol(handle, "NP_Shutdown"); iNP_GetMIMEDescription = (char*(*)())loadSymbol(handle,"NP_GetMIMEDescription"); } void printPluginEntrypoints(NPPluginFuncs* pFuncs) { printf("[*] NPP struct:\n"); printf("\t- NPP_size: %8d\n",pFuncs->size); printf("\t- NPP_version: %8d\n",pFuncs->version); printf("\t- NPP_NewProcPtr: %p\n", pFuncs->newp); printf("\t- NPP_DestroyProcPtr: %p\n", pFuncs->destroy); printf("\t- NPP_SetWindowProcPtr: %p\n", pFuncs->setwindow); printf("\t- NPP_NewStreamProcPtr: %p\n", pFuncs->newstream); printf("\t- NPP_DestroyStreamProcPtr: %p\n", pFuncs->destroystream); printf("\t- NPP_StreamAsFileProcPtr: %p\n", pFuncs->asfile); printf("\t- NPP_WriteReadyProcPtr: %p\n", pFuncs->writeready); printf("\t- NPP_WriteProcPtr: %p\n", pFuncs->write); printf("\t- NPP_PrintProcPtr: %p\n", pFuncs->print); printf("\t- NPP_HandleEventProcPtr: %p\n", pFuncs->event); printf("\t- NPP_URLNotifyProcPtr: %p\n", pFuncs->urlnotify); printf("\t- javaClass: %p\n", pFuncs->javaClass); printf("\t- NPP_GetValueProcPtr: %p\n", pFuncs->getvalue); printf("\t- NPP_SetValueProcPtr: %p\n", pFuncs->setvalue); } NPError NPN_SetValueProc(NPP instance, NPPVariable variable, void *value) { switch(variable) { case NPPVpluginWindowBool: printf( "NPPVpluginWindowBool - %p\n", value); break; default: printf( "SetValue %i\n", variable ); break; } return NPERR_NO_ERROR; } NPError NPN_GetValueProc(NPP instance, NPNVariable variable, void *ret_value) { printf("[D] NPN_GetValueProc instance:%p, variable:%d, abi_mask:%d\n", instance, variable, 0); switch (variable) { case NPNVSupportsXEmbedBool: *((int*)ret_value)= PR_TRUE; break; case NPNVToolkit: *((int*)ret_value)= NPNVGtk2; break; case NPNVnetscapeWindow: *((int*)ret_value)= PR_TRUE; break; default: *((int*)ret_value)=PR_FALSE; break; } return NPERR_NO_ERROR; } const char* NPN_UserAgentProc(NPP instance) { return uagent; } static void Status_( NPP instance, const char* message ) { printf( "Status\n" ); } uint32_t MemFlush( uint32_t size ) { return 0; } void ReloadPlugins( NPBool reloadPages ) { } void * GetJavaEnv(void) { return NULL; } void * GetJavaPeer( NPP instance ) { return NULL; } NPIdentifier NPN_GetStringIdentifierProc(const NPUTF8* name) { return addNPId(name); } void GetStringIdentifiers( const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers ) { } NPIdentifier GetIntIdentifier( int32_t intid ) { return NO_IDENTIFIER; } bool IdentifierIsString( NPIdentifier id ) { return getNPId(id) != NULL; } NPUTF8* UTF8FromIdentifier( NPIdentifier identifier ) { const char *result = getNPId(identifier); return result ? strdup(result) : NULL; } int32_t IntFromIdentifier( NPIdentifier id ) { return 0; } static gboolean plug_removed_cb (GtkWidget *widget, gpointer data) { printf("[!] plug_removed_cb\n"); return TRUE; } static void socket_unrealize_cb(GtkWidget *widget, gpointer data) { printf("[!] socket_unrealize_cb\n"); } static NPWindow * npwindow_construct (GtkWidget *widget) { NPWindow *npwindow; NPSetWindowCallbackStruct *ws_info = NULL; GdkWindow *parent_win = widget->window; GtkWidget *socketWidget = gtk_socket_new(); gtk_widget_set_parent_window(socketWidget, parent_win); g_signal_connect(socketWidget, "plug_removed", G_CALLBACK(plug_removed_cb), NULL); g_signal_connect(socketWidget, "unrealize", G_CALLBACK(socket_unrealize_cb), NULL); g_signal_connect(socketWidget, "destroy", G_CALLBACK(gtk_widget_destroyed), &socketWidget); gpointer user_data = NULL; gdk_window_get_user_data(parent_win, &user_data); GtkContainer *container = GTK_CONTAINER(user_data); gtk_container_add(container, socketWidget); gtk_widget_realize(socketWidget); GtkAllocation new_allocation; new_allocation.x = 0; new_allocation.y = 0; new_allocation.width = WINDOW_XSIZE; new_allocation.height = WINDOW_YSIZE; gtk_widget_size_allocate(socketWidget, &new_allocation); gtk_widget_show(socketWidget); gdk_flush(); GdkNativeWindow ww = gtk_socket_get_id(GTK_SOCKET(socketWidget)); GdkWindow *w = gdk_window_lookup(ww); npwindow = (NPWindow*) malloc (sizeof (NPWindow)); npwindow->window = (void*)(unsigned long)ww; npwindow->x = 0; npwindow->y = 0; npwindow->width = WINDOW_XSIZE; npwindow->height = WINDOW_YSIZE; ws_info = (NPSetWindowCallbackStruct*) malloc(sizeof (NPSetWindowCallbackStruct)); ws_info->type = NP_SETWINDOW; ws_info->display = GDK_WINDOW_XDISPLAY(w); ws_info->colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(w)); GdkVisual* gdkVisual = gdk_drawable_get_visual(w); ws_info->visual = GDK_VISUAL_XVISUAL(gdkVisual); ws_info->depth = gdkVisual->depth; npwindow->ws_info = ws_info; npwindow->type = NPWindowTypeWindow; return npwindow; } static NPStream * npstream_construct() { NPStream *stream = (NPStream *) malloc(sizeof(NPStream)); stream->url=strdup(URL); stream->ndata = 0; stream->end = 99782; stream->lastmodified= 1201822722; stream->notifyData = 0x00000000; stream->headers = (char*)malloc(200); return stream; } bool NPN_InvokeProc( NPP npp, NPObject *npobj, NPIdentifier npid, const NPVariant *args, uint32_t argCount, NPVariant *result ) { traceObjectOnCall(__FUNCTION__,npobj); if( matchNPId(npid,FLASH_REQUEST) && argCount == 1 && args[0].type == NPVariantType_String ) { return 1; } if( matchNPId(npid,FLASH_REQUEST) && argCount == 3 && args[0].type == NPVariantType_String && args[1].type == NPVariantType_String && args[2].type == NPVariantType_String ) { return 1; } if( matchNPId(npid,"_DoFSCommand") && argCount == 2 && args[0].type == NPVariantType_String && args[1].type == NPVariantType_String ) { printf("[D] FSCOMMAND\n"); return 1; } if( npobj == &__top_location ) { if( matchNPId(npid,"toString") ) { result->type = NPVariantType_String; // "chrome://global/content/console.xul" is what Firefox returns for 'top.location.toString()'; result->value.stringValue.UTF8Characters = strdup("chrome://global/content/console.xul"); result->value.stringValue.UTF8Length = (int)strlen(result->value.stringValue.UTF8Characters); printf("[D] Returned %s\n", result->value.stringValue.UTF8Characters); } return 1; } //On OSX, Flash retreives locations by injected functions: if( matchNPId(npid,"__flash_getWindowLocation") ) { // return the location object: result->type = NPVariantType_Object; result->value.objectValue = &__location; NPN_RetainObjectProc(&__location); return 1; } if( matchNPId(npid,"__flash_getTopLocation") ) { // return the top_location object: result->type = NPVariantType_Object; result->value.objectValue = &__top_location; NPN_RetainObjectProc(&__top_location); return 1; } return 0; } static bool NPN_InvokeDefaultProc( NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result ) { return 0; } static bool NPN_GetPropertyProc( NPP npp, NPObject *npobj, NPIdentifier npid, NPVariant *result ) { if (npobj == &__window) { if( matchNPId(npid,"location") ) { result->type = NPVariantType_Object; result->value.objectValue = &__location; NPN_RetainObjectProc(&__location); return 1; } if( matchNPId(npid,"top") ) { result->type = NPVariantType_Object; result->value.objectValue = &__top; NPN_RetainObjectProc(&__top); return 1; } } else if (npobj == &__top) { if ( matchNPId(npid,"location") ) { result->type = NPVariantType_Object; result->value.objectValue = &__top_location; NPN_RetainObjectProc(&__top_location); return 1; } } return 0; } static bool NPN_SetPropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value ) { return 0; } static bool NPN_RemovePropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName ) { return 0; } static bool NPN_HasPropertyProc( NPP npp, NPObject *npobj, NPIdentifier propertyName ) { return 0; } static bool NPN_HasMethodProc( NPP npp, NPObject *npobj, NPIdentifier methodName ) { return 0; } static int unescape( char *str, int *ssize ) { int k = 0, esc = 0; // UNESCAPE the string while( k < *ssize ) { if( !esc ) { if( str[k++] == '\\' ) esc = 1; } else { char c; switch( str[k] ) { case '"': c = '"'; break; case '\\': c = '\\'; break; case 'r': c = '\r'; break; case 'n': c = '\n'; break; case 't': c = '\t'; break; default: return 0; } (*ssize)--; memcpy(str+k,str+k+1,*ssize-k); str[k-1] = c; esc = 0; } } str[*ssize] = 0; return 1; } static const char *end_of_string( const char *send ) { int esc = 0; while( *send ) { switch( *send ) { case '"': if( !esc ) return send; esc = 0; break; case '\\': esc = !esc; break; default: esc = 0; break; } send++; } return NULL; } #define JS_CALL_START "try { __flash__toXML(" #define JS_RESULT_START "var __flash_temp = \"" bool Evaluate( NPP npp, NPObject *npobj, NPString *script, NPVariant *result ) { printf( "Evaluate %s\n", script->UTF8Characters ); if( memcmp(script->UTF8Characters,JS_CALL_START,strlen(JS_CALL_START)) == 0 ) { const char *p = script->UTF8Characters + strlen(JS_CALL_START); const char *s = p; const char *send; while( *s && *s != '(' ) s++; if( !*s || s[1] != '"' ) return 0; s += 2; send = end_of_string(s); if( send == NULL || send[1] != ')' ) return 0; { int isize = (int)(s - p) - 2; int ssize = (int)(send - s); char *ident = (char*)malloc(isize+1); char *str = (char*)malloc(ssize+1); memcpy(ident,p,isize); memcpy(str,s,ssize); ident[isize] = 0; if( !unescape(str,&ssize) ) { free(ident); free(str); return 0; } // CALLBACK { printf("CALLBACK\n"); int size = 0; const char *res = "callback"; free(ident); free(str); if( res == NULL ) return 0; result->type = NPVariantType_String; result->value.stringValue.UTF8Characters = strdup(res); result->value.stringValue.UTF8Length = size; return 1; } } } if( memcmp(script->UTF8Characters,JS_RESULT_START,strlen(JS_RESULT_START)) == 0 ) { const char *s = script->UTF8Characters + strlen(JS_RESULT_START); const char *send = end_of_string(s); char *str; int ssize; if( send == NULL || send[1] != ';' ) return 0; ssize = (int)(send - s); str = (char*)malloc(ssize+1); memcpy(str,s,ssize); if( !unescape(str,&ssize) ) { free(str); return 0; } result->type = NPVariantType_String; result->value.stringValue.UTF8Characters = str; result->value.stringValue.UTF8Length = ssize; return 1; } result->type = NPVariantType_Void; return 1; } void NPN_ReleaseObjectProc(NPObject *npobj) { if( npobj == NULL ) return; npobj->referenceCount--; if( npobj->referenceCount != 0 ) return; if( npobj->_class->deallocate ) { npobj->_class->deallocate(npobj); return; } if( npobj->_class->invalidate ) npobj->_class->invalidate(npobj); free(npobj); } NPObject* NPN_CreateObjectProc(NPP npp, NPClass *aClass) { NPObject *o; if( aClass->allocate ) o = aClass->allocate(npp,aClass); else o = (NPObject*)malloc(sizeof(NPObject)); o->_class = aClass; o->referenceCount = 1; return o; } NPObject* NPN_RetainObjectProc(NPObject *npobj) { if( npobj == NULL ) return NULL; npobj->referenceCount++; return npobj; } void NPN_ReleaseVariantValueProc(NPVariant *variant) { //printf("ReleaseVariantValueProc\n"); switch( variant->type ) { case NPVariantType_Null: case NPVariantType_Void: break; case NPVariantType_String: free( (char*)variant->value.stringValue.UTF8Characters ); variant->type = NPVariantType_Void; break; case NPVariantType_Object: NPN_ReleaseObjectProc(variant->value.objectValue); variant->type = NPVariantType_Void; break; default: break; } } void SetException( NPObject *npobj, const NPUTF8 *message ) { printf("SetException %s\n",message); } NPError NPN_GetURLNotifyProc(NPP instance, const char* url, const char* window, void* notifyData) { printf("[D] NPN_GetURLNotifyProc:%p, url: %s, window: %s\n", instance, url, window); if (window && strlen(window)==6 && memcmp("_blank",window,6)==0) { //system_launch_url(url); pluginFuncs.urlnotify(instance,url,NPRES_DONE,notifyData); } else if( memcmp(url,"javascript:",11) == 0 ) { NPStream s; uint16_t stype; int success; memset(&s,0,sizeof(NPStream)); s.url = strdup(url); success = (pluginFuncs.newstream(instance,"text/html",&s,0,&stype) == NPERR_NO_ERROR); if( success ) { int pos = 0; int size; char buf[256]; sprintf(buf,"%X__flashplugin_unique__",(int_val)instance); size = (int)strlen(buf); s.end = size; while( pos < size ) { int len = pluginFuncs.writeready(instance,&s); if( len <= 0 ) break; if( len > size - pos ) len = size - pos; len = pluginFuncs.write(instance,&s,pos,len,buf+pos); if( len <= 0 ) break; pos += len; } success = (pos == size); } pluginFuncs.urlnotify(instance,url,success?NPRES_DONE:NPRES_NETWORK_ERR,notifyData); pluginFuncs.destroystream(instance,&s,NPRES_DONE); free((void*)s.url); } else { NPStream stream; uint16_t stype;// = NP_NORMAL; memset(&stream,0,sizeof(NPStream)); stream.url = strdup(url); stream.notifyData = notifyData; pluginFuncs.newstream(instance,"application/x-shockwave-flash",&stream, 0, &stype); //fprintf(stderr, "NPP: %p URL: %s\n", instance, url); FILE *pp; char buffer[8192]; pp = fopen(url,"rb"); int len; while((len=fread(buffer, 1, sizeof(buffer), pp)) != 0) { pluginFuncs.writeready(instance, &stream); pluginFuncs.write(instance, &stream, 0, len, buffer); } fclose(pp); pluginFuncs.destroystream(instance, &stream, NPRES_DONE); free((void*)stream.url); //pluginFuncs.urlnotify(instance, url, NPRES_DONE, notifyData); } return NPERR_NO_ERROR; } NPError NPN_GetURL( NPP instance, const char* url, const char* target ) { printf( "GetURL %s\n", url ); if (target && strlen(target)==6 && memcmp("_blank",target,6)==0) { //system_launch_url(url); return NPERR_NO_ERROR; } return NPERR_NO_ERROR; } NPError NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData) { printf( "PostURLNotify (url) %s (target) %s (buf) %s[%d] (file) %i (nd) %p\n", url, target, buf, len, file, notifyData); //url_process(instance,url,buf,len,notifyData); return NPERR_NO_ERROR; } NPError NPN_PostURL( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file ) { printf( "PostURL" ); return NPERR_NO_ERROR; } NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { printf("[D] NPN_RequestRead\n"); return NPERR_NO_ERROR; } NPError NewStream( NPP instance, NPMIMEType type, const char* target, NPStream** stream ) { printf( "NewStream\n" ); return NPERR_NO_ERROR; } int32_t Write( NPP instance, NPStream* stream, int32_t len, void* buffer ) { printf( "Write\n" ); return 0; } NPError DestroyStream( NPP instance, NPStream* stream, NPReason reason ) { printf( "DestroyStream\n" ); return NPERR_NO_ERROR; } void _InvalidateRect( NPP instance, NPRect *invalidRect ) { printf( "InvalidateRect\n" ); } void InvalidateRegion( NPP instance, NPRegion invalidRegion ) { printf( "InvalidateRegion\n" ); } void ForceRedraw( NPP instance ) { printf( "ForceRedraw\n" ); } void initNPNetscapeFuncs(NPNetscapeFuncs *bFuncs) { int i=0; for(i=1; i<sizeof(*bFuncs)/sizeof(ssize_t); i++) *(((ssize_t*)bFuncs)+i)=i+1000; bFuncs->geturl=NPN_GetURL; bFuncs->posturl=NPN_PostURL; bFuncs->requestread=NPN_RequestRead; bFuncs->newstream=NewStream; bFuncs->write=Write; bFuncs->destroystream=DestroyStream; bFuncs->status=Status_; bFuncs->uagent=NPN_UserAgentProc; bFuncs->memalloc=malloc; bFuncs->memfree=free; bFuncs->memflush=MemFlush; bFuncs->reloadplugins=ReloadPlugins; bFuncs->getJavaEnv=GetJavaEnv; bFuncs->getJavaPeer=GetJavaPeer; bFuncs->geturlnotify=NPN_GetURLNotifyProc; bFuncs->posturlnotify=NPN_PostURLNotify; bFuncs->getvalue=NPN_GetValueProc; bFuncs->setvalue=NPN_SetValueProc; bFuncs->invalidaterect=_InvalidateRect; bFuncs->invalidateregion=InvalidateRegion; bFuncs->forceredraw=ForceRedraw; bFuncs->getstringidentifier=NPN_GetStringIdentifierProc; bFuncs->getstringidentifiers=GetStringIdentifiers; bFuncs->getintidentifier=GetIntIdentifier; bFuncs->identifierisstring=IdentifierIsString; bFuncs->utf8fromidentifier=UTF8FromIdentifier; bFuncs->intfromidentifier=IntFromIdentifier; bFuncs->createobject=NPN_CreateObjectProc; bFuncs->retainobject=NPN_RetainObjectProc; bFuncs->releaseobject=NPN_ReleaseObjectProc; bFuncs->invoke=NPN_InvokeProc; bFuncs->invokeDefault=NPN_InvokeDefaultProc; bFuncs->evaluate=Evaluate; bFuncs->getproperty=NPN_GetPropertyProc; bFuncs->setproperty=NPN_SetPropertyProc; bFuncs->removeproperty=NPN_RemovePropertyProc; bFuncs->hasproperty=NPN_HasPropertyProc; bFuncs->hasmethod=NPN_HasMethodProc; bFuncs->releasevariantvalue=NPN_ReleaseVariantValueProc; bFuncs->setexception=SetException; bFuncs->size= sizeof(bFuncs); // bFuncs->version=(NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; bFuncs->version=20; } static void destroy(GtkWidget *widget, gpointer data) { gtk_main_quit (); } int main(int argc, char **argv) { if(argc < 2) { printf("[-] Usage: %s <swfuri>\n", argv[0]); exit(-1); } URL = argv[1]; gtk_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_usize (main_window, WINDOW_XSIZE, WINDOW_YSIZE); g_signal_connect (G_OBJECT (main_window), "destroy", G_CALLBACK (destroy), NULL); gtk_widget_realize(main_window); //gtk_window_fullscreen((GtkWindow *)main_window); gtk_widget_show_all(main_window); printf("[+] created GTK widget\n"); flash_plugin_handle = loadFlashPluginSo(); loadNPEntryPoints(flash_plugin_handle); printf("[+] initialized flash plugin entry points\n"); initNPNetscapeFuncs(&browserFuncs); printf("[+] initialized browser functions\n"); checkError("NP_Initialize", iNP_Initialize(&browserFuncs, &pluginFuncs)); printPluginEntrypoints(&pluginFuncs); printBrowserEntrypoints(&browserFuncs); NPWindow *npwin = npwindow_construct(main_window); printf("[+] created NPWindow widget\n"); NPP_t *instancep = (NPP_t *) malloc(sizeof(NPP_t)); memset(instancep,0,sizeof(sizeof(NPP_t))); NPP instance = instancep; NPSavedData* saved = (NPSavedData*) malloc(sizeof(NPSavedData)); memset(saved,0,sizeof(sizeof(NPSavedData))); stream = npstream_construct(); uint16_t stype; NPObject object; char *xargv[]= {"allowscriptaccess", "quality", "wmode"}; char *xargm[]= {"always", "best", "direct"}; checkError("NPN_New", pluginFuncs.newp("application/x-shockwave-flash", instance, NP_EMBED, 3, xargv, xargm, 0)); checkError("NPN_GetValue NPPVpluginScriptableNPObject", pluginFuncs.getvalue(instance, NPPVpluginScriptableNPObject, &object)); checkError("NPN_SetWindow", pluginFuncs.setwindow(instance, npwin)); checkError("NPN_NewStream", pluginFuncs.newstream(instance, "application/x-shockwave-flash", stream, 0, &stype)); FILE *pp; char buffer[8192]; pp = fopen(argv[1],"rb"); int len; while((len=fread(buffer, 1, sizeof(buffer), pp)) != 0) { pluginFuncs.writeready(instance, stream); pluginFuncs.write(instance, stream, 0, len, buffer); } fclose(pp); checkError("NPN_DestroyStream",pluginFuncs.destroystream(instance, stream, NPRES_DONE)); free(stream); gtk_main(); checkError("NPN_Destroy",pluginFuncs.destroy(instance, &saved)); checkError("NP_Shutdown", iNP_Shutdown()); dlclose(flash_plugin_handle); return 0; } 
+4
source share

Source: https://habr.com/ru/post/1442887/


All Articles