![]() |
Tutorial Making a simple plugin system for your application - Printable Version +- Sinisterly (https://sinister.ly) +-- Forum: Coding (https://sinister.ly/Forum-Coding) +--- Forum: C, C++, & Obj-C (https://sinister.ly/Forum-C-C-Obj-C) +--- Thread: Tutorial Making a simple plugin system for your application (/Thread-Tutorial-Making-a-simple-plugin-system-for-your-application) |
Making a simple plugin system for your application - phyrrus9 - 02-01-2018 Ok, so since @"Pikami" has been talking a lot about back end exploitation and patching at the source code level, I figured I'd make a quick tutorial on how to do the same sorts of things for non-nefarious purposes. To do this, I'll be using a very simple project I made called HTTPProxy. You can find the github source code for that project by following the link. To follow along, go ahead and clone the repository Code: git clone git://github.com/phyrrus9/HttpProxy.git That checkout line is important! So what does HTTPProxy do? Well, it's a reverse proxy that works based on HTTP/1 by examining the requested vhost domain in the packet and forwarding it to the correct device. To do this, it uses a database, but that database is local to this program. What if we wanted to make it be able to use a different database? Like maybe we use the local database as a cache but we want to run something like this in a cluster (which it is set up to do). Well, we could rewrite the resolving mechanism to figure this out, or we could write a plugin system that would scan a directory for modules and load them at runtime to try to resolve this new stuff. How would we go about doing that? Let's start by cloning the repository and getting some edits made. ![]() Ok, so to compile this you will need the standard toolchain (gcc/llvm, make, etc). But first, let's go ahead and edit our hosts file to include a couple fake domains: ![]() I am doing this in the hosts file because I don't actually own these domains. In a real life application of this program, you would set your A records for all of the domains to be the server running HTTPProxy (not the servers running Apache). Ok, now we're going to edit the static table in HTTProxy. This is in function main, in main.c. We're only going to add test1.fake to this (and we're going to give it an IP address of 1.1.1.1) just so its easy to find. ![]() alright, now let's go ahead and build it. ![]() and run it ![]() Now, I'm going to switch to a second terminal window and I'll do a wget on test1.fake. It will fail (because that IP wont have that vhost), but we should see the debug info for resolving it. So, I had 3 issues: 1, I didn't have wget installed, so you should install that, and 2, we aren't running correctly, and we don't have the resolution debug stuff in there ![]() ![]() So, let's fix the resolution stuff too: Replace the entire determine_request method with the following (this just makes it shorter) Code: char *determine_request(char *buffer, ssize_t len) ok, now let's build and run it again: ![]() ![]() Cool, so it worked. Now, let's try it with test3.fake ![]() ![]() This tells us that it's all working fine. So, let's go ahead and kill our program and start working on our module loader: Create a file named plugin.h Code: #ifndef PLUGIN_H and a file plugin.c Code: #include <plugin.h> Ok, now we need to make 2 changes in Makefile to get our code to be included: Code: LIBS = -pthread Code: items = util main db Ok, now make clean and make ![]() Perfect. Now let's go ahead and add that in to our resolving function ![]() modify your function so it looks like this, and also add Code: #include <plugin.h> Go ahead and build it again. Right now, absolutely nothing has changed, and we're done with this program. We shouldn't need to make any more edits to it. Now, create yourself a folder called plugins and create a file called static.c Code: #include <stdio.h> ![]() And lets install it and change to our run directory, time to test ![]() ![]() as you can see, it did load our plugin, but we had a segmentation fault, so I'm going to track that down real quick and report back. It's probably a missing strdup call. Yep, it turns out we do need a strdup call. I simply wrapped the line to our plugin. Code: retval = (*plugin)(host); // send data to plugin and record result Code: retval = strdup((*plugin)(host)); // send data to plugin and record result Code: make clean ![]() Now, I'm going to go through and strip all of the debug stuff out of my plugin, and then I'll push this to github for you to browse through or use it elsewhere. Notes: I only did a simple plugin system, which only had 1 feature that used plugins, but you could expand this as much as you want. A plugin doesn't just have to work on 1 feature either, I designed this so that every feature would have an entry point, and the program uses that entry point to resolve the plugin. You could put more of those functions inside the same plugin to create a "plugin library", and that's exactly what you should do. RE: Making a simple plugin system for your application - ApatheticEuphoria - 02-01-2018 Thankyou for the tutorial. When I find the time I will follow along and see how it turns out in practice. RE: Making a simple plugin system for your application - phyrrus9 - 02-01-2018 (02-01-2018, 10:56 PM)ApatheticEuphoria Wrote: Thankyou for the tutorial. When I find the time I will follow along and see how it turns out in practice. As you should see from my mistakes, I wrote this one up exactly as I was doing it. Would be nice if one of you wrote me a mysql plugin for it though ![]() RE: Making a simple plugin system for your application - Pikami - 02-03-2018 I love the tutorial! I know this knowledge will help me someday, thanks! (02-01-2018, 10:59 PM)phyrrus9 Wrote: Would be nice if one of you wrote me a mysql plugin for it thoughChallenge accepted and completed ![]() Would you mind if I made a pull request to your repo adding my created mysql_resolve plugin? RE: Making a simple plugin system for your application - phyrrus9 - 02-03-2018 (02-03-2018, 05:56 PM)Pikami Wrote: I love the tutorial! Go right ahead. I might make some modifications to it though, fair warning. RE: Making a simple plugin system for your application - Pikami - 02-03-2018 (02-03-2018, 07:36 PM)phyrrus9 Wrote:(02-03-2018, 05:56 PM)Pikami Wrote:Go right ahead. I might make some modifications to it though, fair warning.(02-01-2018, 10:59 PM)phyrrus9 Wrote: Would be nice if one of you wrote me a mysql plugin for it thoughChallenge accepted and completed I just opened my pull request. RE: Making a simple plugin system for your application - phyrrus9 - 02-03-2018 (02-03-2018, 08:31 PM)Pikami Wrote:(02-03-2018, 07:36 PM)phyrrus9 Wrote:(02-03-2018, 05:56 PM)Pikami Wrote: Challenge accepted and completedGo right ahead. I might make some modifications to it though, fair warning. Merged, actually looks perfect in its current state, I'm impressed! Normally a plugin system would scan the directory at start time and call a register function or something (which would help to write the configuration), but I like the idea of being able to add plugins without restarting the program (if you start it, you can then run make && make install in the plugin and it will be loaded on the next request). In short: dylibs are awesome RE: Making a simple plugin system for your application - Pikami - 02-03-2018 (02-03-2018, 08:44 PM)phyrrus9 Wrote:(02-03-2018, 08:31 PM)Pikami Wrote:(02-03-2018, 07:36 PM)phyrrus9 Wrote: Go right ahead. I might make some modifications to it though, fair warning. I'm glad ![]() And yes, dylibs are awesome. |