托管Flash不会加载swf资源(xml,图像等)

我试图在我的unix机器上首先使用gtk2实现一个swf阅读器。 工作,我可以渲染简单的swf文件。 现在,我正在尝试使用xml配置添加配置到我的flash文件,添加图像等。失败,将无法通过geturlnotify()。 这是我的代码:

#include  #include  #include  #include  #include  #include  #include  #include  #include "npupp.h" #define FLASH_PLUGIN_SO "./libflashplayer.so" void *flash_plugin_handle; NPNetscapeFuncs browserFuncs; NPPluginFuncs pluginFuncs; GtkWidget *main_window; char* fileName = NULL; NPStream * stream; const char * uagent = "Axt/1.0"; //Default window size int WINDOW_XSIZE = 800; int WINDOW_YSIZE = 600; //Default child window position (flash player) int xPosition = 0; int yPosition = 0; NPError (*iNP_Initialize)(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs); NPError (*iNP_Shutdown)(); char* (*iNP_GetMIMEDescription)(); void* loadFlashPluginSo() { void *handle; handle = dlopen(FLASH_PLUGIN_SO, RTLD_LAZY | RTLD_LOCAL); if(!handle) { fprintf(stderr, "[-] error loading libflashplayer.so: %s\n", dlerror()); exit(1); } fprintf(stderr,"[+] loaded libflashplayer.so\n"); 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 { fprintf(stderr,"[+] loaded symbol %s, address: %p\n", name, ret); } return ret; } void loadNPEntryPoints(void *handle) { iNP_Initialize=loadSymbol(handle, "NP_Initialize"); iNP_Shutdown=loadSymbol(handle, "NP_Shutdown"); iNP_GetMIMEDescription = loadSymbol(handle,"NP_GetMIMEDescription"); } void printPluginEntrypoints(NPPluginFuncs* pFuncs) { fprintf(stderr,"[*] NPP struct:\n"); fprintf(stderr,"\t- NPP_size: %8d\n",pFuncs->size); fprintf(stderr,"\t- NPP_version: %8d\n",pFuncs->version); fprintf(stderr,"\t- NPP_NewProcPtr: %p\n", pFuncs->newp); fprintf(stderr,"\t- NPP_DestroyProcPtr: %p\n", pFuncs->destroy); fprintf(stderr,"\t- NPP_SetWindowProcPtr: %p\n", pFuncs->setwindow); fprintf(stderr,"\t- NPP_NewStreamProcPtr: %p\n", pFuncs->newstream); fprintf(stderr,"\t- NPP_DestroyStreamProcPtr: %p\n", pFuncs->destroystream); fprintf(stderr,"\t- NPP_StreamAsFileProcPtr: %p\n", pFuncs->asfile); fprintf(stderr,"\t- NPP_WriteReadyProcPtr: %p\n", pFuncs->writeready); fprintf(stderr,"\t- NPP_WriteProcPtr: %p\n", pFuncs->write); fprintf(stderr,"\t- NPP_PrintProcPtr: %p\n", pFuncs->print); fprintf(stderr,"\t- NPP_HandleEventProcPtr: %p\n", pFuncs->event); fprintf(stderr,"\t- NPP_URLNotifyProcPtr: %p\n", pFuncs->urlnotify); fprintf(stderr,"\t- javaClass: %p\n", pFuncs->javaClass); fprintf(stderr,"\t- NPP_GetValueProcPtr: %p\n", pFuncs->getvalue); fprintf(stderr,"\t- NPP_SetValueProcPtr: %p\n", pFuncs->setvalue); } NPError NPN_GetValueProc(NPP instance, NPNVariable variable, void *ret_value) { fprintf(stderr,"[D] NPN_GetValueProc instance:%p, variable:%d, abi_mask:%d\n", instance, variable, 0); switch (variable) { case NPNVSupportsXEmbedBool: *((int*)ret_value)= PR_TRUE; break; //Unix and solaris fix 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) { fprintf(stderr,"[D] NPN_UserAgentProc instance:%p\n", instance); return uagent; } NPError NPN_GetURLProc(NPP instance, const char* url, const char* window) { fprintf(stderr,"[D] NPN_GetURLProcPtr:%p, url: %s, window: %s\n", instance, url, window); return NPERR_NO_ERROR; } NPIdentifier NPN_GetStringIdentifierProc(const NPUTF8* name) { return (NPIdentifier)0x41424344; //Unique } static gboolean plug_removed_cb (GtkWidget *widget, gpointer data) { fprintf(stderr,"[!] plug_removed_cb\n"); return TRUE; } static void socket_unrealize_cb(GtkWidget *widget, gpointer data) { fprintf(stderr, "[!] 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); gtk_widget_set_uposition(socketWidget, xPosition, yPosition); 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 = 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 = 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 = malloc(sizeof(NPStream)); stream->url=fileName; stream->notifyData = 0x00000000; fprintf(stderr,"[D] NPN_StreamConstructed: %p\n", stream); return stream; } bool NPN_GetPropertyProc(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result) { fprintf(stderr,"[D] NPN_GetPropertyProc: %p\n", result); result->type = NPVariantType_Object; result->value.objectValue= (NPObject*)1; return TRUE; } bool NPN_InvokeProc(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) { fprintf(stderr,"[D] NPN_InvokeProc: %p\n", result); result->type= NPVariantType_String; result->value.stringValue.utf8characters=fileName; result->value.stringValue.utf8length=strlen(fileName); return TRUE; } void NPN_ReleaseVariantValueProc(NPVariant *variant) { } void NPN_ReleaseObjectProc(NPObject *obj) { } NPObject* NPN_CreateObjectProc(NPP npp, NPClass *aClass) { return (NPObject*)1; } NPObject* NPN_RetainObjectProc(NPObject *obj) { return (NPObject*)1; } NPError NPN_GetURLNotifyProc(NPP instance, const char* url, const char* window, void* notifyData) { fprintf(stderr,"[D] NPN_GetURLNotifyProc:%p, url: %s, window: %s\n", instance, url, window); return 0; } NPN_GetURL, NPN_GetURLNotify, and NPP_URLNotify void initNPNetscapeFuncs(NPNetscapeFuncs *bFuncs) { int i=0; for(i=1; igeturl=NPN_GetURLProc; bFuncs->getvalue=NPN_GetValueProc; bFuncs->uagent=NPN_UserAgentProc; bFuncs->getproperty=NPN_GetPropertyProc; bFuncs->getstringidentifier=NPN_GetStringIdentifierProc; bFuncs->invoke=NPN_InvokeProc; bFuncs->releasevariantvalue=NPN_ReleaseVariantValueProc; bFuncs->releaseobject=NPN_ReleaseObjectProc; bFuncs->createobject=NPN_CreateObjectProc; bFuncs->retainobject=NPN_RetainObjectProc; bFuncs->geturlnotify=NPN_GetURLNotifyProc; bFuncs->size= sizeof(bFuncs); bFuncs->version= (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;; } static void destroy(GtkWidget *widget, gpointer data) { gtk_main_quit (); } static void checkError(const char* str, NPError err) { if(err == NPERR_NO_ERROR) fprintf(stderr, "[+] %s: success\n", str); else fprintf(stderr, "[-] %s: failed (%d)\n", str, err); fflush(NULL); } int main(int argc, char **argv) { int c; extern char *optarg; while ((c = getopt(argc, argv, "f:w:h:x:y:")) != EOF){ switch (c) { case 'f': fileName = optarg; fprintf (stderr, "[+] Filename: %s\n", optarg); break; case 'w': WINDOW_XSIZE = atoi(optarg); fprintf (stderr, "[+] WINDOW_XSIZE: %s\n", optarg); break; case 'h': WINDOW_YSIZE = atoi(optarg); fprintf (stderr, "[+] WINDOW_YSIZE: %s\n", optarg); break; case 'x': xPosition = atoi(optarg); fprintf (stderr, "[+] Position in x: %s\n", optarg); break; case 'y': yPosition = atoi(optarg); fprintf (stderr, "[+] Position in y: %s\n", optarg); break; case '?': if (optopt == 'f' | optopt == 'w' | optopt == 'h') fprintf (stderr, "[-] Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "[-] Unknown option `-%c'.\n", optopt); else fprintf (stderr,"[-] Unknown option character `\\x%x'.\n", optopt); exit(-1); default: fprintf(stderr,"[-] Usage: %s -f  -x  -y \n", argv[0]); exit(-1); } } gtk_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_usize (main_window, WINDOW_XSIZE, WINDOW_YSIZE); gtk_widget_set_uposition (main_window, xPosition, yPosition); g_signal_connect (G_OBJECT (main_window), "destroy", G_CALLBACK (destroy), NULL); gtk_widget_realize(main_window); gtk_widget_show_all(main_window); fprintf(stderr,"[+] created GTK widget\n"); flash_plugin_handle = loadFlashPluginSo(); loadNPEntryPoints(flash_plugin_handle); fprintf(stderr,"[+] initialized flash plugin entry points\n"); initNPNetscapeFuncs(&browserFuncs); fprintf(stderr,"[+] initialized browser functions\n"); checkError("NP_Initialize", iNP_Initialize(&browserFuncs, &pluginFuncs)); printPluginEntrypoints(&pluginFuncs); NPWindow *npwin = npwindow_construct(main_window); fprintf(stderr,"[+] created NPWindow widget\n"); NPP_t *instancep = malloc(sizeof(NPP_t)); memset(instancep,0,sizeof(sizeof(NPP_t))); NPP instance = instancep; NPSavedData* saved = malloc(sizeof(NPSavedData)); memset(saved,0,sizeof(sizeof(NPSavedData))); stream = npstream_construct(); uint16_t stype; char *xargv[]= {"quality", "bgcolor", "width", "height", "allowScriptAccess", "loop" }; char *xargm[]= {"high", "#000000", "1360", "768", "always", "false" }; checkError("NPN_New", pluginFuncs.newp("application/x-shockwave-flash", instance, NP_EMBED, 0, xargv, xargm, saved)); 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(fileName,"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; } 

如果我加载没有xml的swf。 有用。 当我有一个配置到我的xml。 它停止了。

这是我得到的输出:

 ~/test-flash$ ./test-flash -f xml_sample.swf -w 400 -h 600 -x 15 -y 15 [+] Filename: xml_sample.swf [+] WINDOW_XSIZE: 400 [+] WINDOW_YSIZE: 600 [+] Position in x: 15 [+] Position in y: 15 [+] created GTK widget [+] loaded libflashplayer.so [+] loaded symbol NP_Initialize, address: 0x7ff03fb634d0 [+] loaded symbol NP_Shutdown, address: 0x7ff03fb634c0 [+] loaded symbol NP_GetMIMEDescription, address: 0x7ff03fb63870 [+] initialized flash plugin entry points [+] initialized browser functions [+] NP_Initialize: success [*] NPP struct: - NPP_size: 0 - NPP_version: 0 - NPP_NewProcPtr: 0x7ff03fb63990 - NPP_DestroyProcPtr: 0x7ff03fb63980 - NPP_SetWindowProcPtr: 0x7ff03fb63970 - NPP_NewStreamProcPtr: 0x7ff03fb63960 - NPP_DestroyStreamProcPtr: 0x7ff03fb63910 - NPP_StreamAsFileProcPtr: 0x7ff03fb63920 - NPP_WriteReadyProcPtr: 0x7ff03fb63950 - NPP_WriteProcPtr: 0x7ff03fb63940 - NPP_PrintProcPtr: 0x7ff03fb63900 - NPP_HandleEventProcPtr: 0x7ff03fb638f0 - NPP_URLNotifyProcPtr: 0x7ff03fb63930 - javaClass: (nil) - NPP_GetValueProcPtr: 0x7ff03fb63860 - NPP_SetValueProcPtr: (nil) [+] created NPWindow widget [D] NPN_StreamConstructed: 0x25ce5e0 [D] NPN_GetValueProc instance:0x25cc720, variable:14, abi_mask:0 [D] NPN_GetValueProc instance:0x25cc720, variable:268435469, abi_mask:0 [D] NPN_UserAgentProc instance:(nil) [D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0 [D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0 [D] NPN_GetValueProc instance:0x25cc720, variable:18, abi_mask:0 [+] NPN_New: success [D] NPN_GetValueProc instance:0x25cc720, variable:14, abi_mask:0 [+] NPN_SetWindow: success [D] NPN_GetURLNotifyProc:0x25cc720, url: javascript:top.location+"__flashplugin_unique__", window: (null) [D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0 [+] NPN_NewStream: success Lenght: 455 [D] NPN_UserAgentProc instance:0x25cc720 [+] NPN_DestroyStream: success [D] NPN_GetURLNotifyProc:0x25cc720, url: sample.xml, window: (null) 

谢谢!

编辑:

我试过这样的事情(代码在NPN_GetURLNotifyProc函数中)。 但随后,我的应用程序冻结在我的geturlnotifyproc中……

 NPStream s; uint16 stype; memset(&s,0,sizeof(NPStream)); s.url = strdup(url); fprintf(stderr, "URL: %s\n", s.url); checkError("NPN_NewStream", pluginFuncs.newstream(instance,"text/html",&s,0,&stype)); writeStream(instance, &pluginFuncs, &s); pluginFuncs.urlnotify(instance,url,NPRES_DONE,notifyData); checkError("NPN_DestroyStream", pluginFuncs.destroystream(instance,&s,NPRES_DONE)); free((void*)s.url); 

我忘了将通知添加到我的流…

 NPError NPN_GetURLNotifyProc(NPP instance, const char* url, const char* target, void* notifyData) { fprintf(stderr,"[D] NPN_GetURLNotifyProc:%p, url: %s, window: %s, data: %p\n", instance, url, target, notifyData); NPStream s; uint16 stype; memset(&s,0,sizeof(NPStream)); s.url = strdup(url); s.notifyData = notifyData; fprintf(stderr, "NPP: %p URL: %s\n", instance, url); checkError("NPN_NewStream", pluginFuncs.newstream(instance,"text/html",&s,0,&stype)); writeStream(instance, &pluginFuncs, &s); checkError("NPN_DestroyStream", pluginFuncs.destroystream(instance,&s,NPRES_DONE)); free((void*)s.url); pluginFuncs.urlnotify(instance, url, NPRES_DONE, notifyData); return 0; } 

我现在有一个可以运行编译flash(swf)的独立gtk应用程序。 希望它能帮助将来的某个人。 我建议做一个插件来读取另一个插件(也就是Sniffer)来实际知道调用哪个函数(“以及如何工作”)来使用一个像样的日志文件。