Skip to content

Instantly share code, notes, and snippets.

Created November 9, 2011 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/1350968 to your computer and use it in GitHub Desktop.
Save anonymous/1350968 to your computer and use it in GitHub Desktop.
NPAPI simple example
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.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 WINDOW_XSIZE 800
#define WINDOW_YSIZE 600
void *flash_plugin_handle;
NPNetscapeFuncs browserFuncs;
NPPluginFuncs pluginFuncs;
GtkWidget *main_window;
char* URL;
NPStream * stream;
const char * uagent = "Axt/1.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);
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=loadSymbol(handle, "NP_Initialize");
iNP_Shutdown=loadSymbol(handle, "NP_Shutdown");
iNP_GetMIMEDescription = 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_GetValueProc(NPP instance, NPNVariable variable, void *ret_value) {
printf("[D] NPN_GetValueProc instance:%p, variable:%d, abi_mask:%d\n", instance, variable, 0);
if(variable == 14)
*((int*)ret_value)=1;
else if(variable == 268435469)
*((int*)ret_value)=2;
else if(variable == 15)
*((int*)ret_value)=1;//TODO
else
*((int*)ret_value)=0;
return NPERR_NO_ERROR;
}
const char* NPN_UserAgentProc(NPP instance) {
printf("[D] NPN_UserAgentProc instance:%p\n", instance);
return uagent;
}
NPError NPN_GetURLProc(NPP instance, const char* url, const char* window) {
printf("[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;
}
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 = 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=URL;
stream->ndata = 0;
stream->end = 99782;
stream->lastmodified= 1201822722;
stream->notifyData = 0x00000000;
stream->headers = malloc(200);
return stream;
}
bool NPN_GetPropertyProc(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result) {
result->type=6;
result->value.objectValue= (NPObject*)1;
return TRUE;
}
bool NPN_InvokeProc(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) {
result->type=5;
result->value.stringValue.utf8characters=URL;
result->value.stringValue.utf8length=strlen(URL);
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) {
printf("[D] NPN_GetURLNotifyProc:%p, url: %s, window: %s\n", instance, url, window);
return 0;
}
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_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=60;
bFuncs->version=20;
}
static void destroy(GtkWidget *widget, gpointer data) {
gtk_main_quit ();
}
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();
}
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_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);
NPWindow *npwin = npwindow_construct(main_window);
printf("[+] 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[]= {"src", "menu", "quality", "bgcolor", "name", "allowscriptaccess", "type", "pluginspage", "align", "height", "width"};
char *xargm[]= {URL, "false", "high", "#ff00ff", "bmxbackflips", "sameDomain", "application/x-shockwave-flash", "http://www.macromedia.com/go/getflashplayer", "middle" , "435", "580"};
checkError("NPN_New", pluginFuncs.newp("application/x-shockwave-flash", instance, NP_EMBED, 0, xargv, xargm, 0));
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];
if(strstr(argv[1],"http:") == argv[1]) {
sprintf(buffer, "wget %s -q -O -", argv[1]);
pp = popen(buffer, "r");
}
else
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);
}
if(strstr(argv[1],"http:") == argv[1])
pclose(pp);
else
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment