]> localhost Git - gists.git/commitdiff
Adding gists from github to gists repo
authormisomosi <[email protected]>
Mon, 8 Jun 2026 16:15:11 +0000 (12:15 -0400)
committermisomosi <[email protected]>
Mon, 8 Jun 2026 16:15:11 +0000 (12:15 -0400)
18 files changed:
AbstractPosix/README.md [new file with mode: 0644]
AbstractPosix/abstractposix.c [new file with mode: 0644]
EnableLBR/README.md [new file with mode: 0644]
EnableLBR/enablelbr.c [new file with mode: 0644]
LaserEyesPNG/README.md [new file with mode: 0644]
LaserEyesPNG/snippet.js [new file with mode: 0644]
MSVCCleanup/README.md [new file with mode: 0644]
MSVCCleanup/msvccleanup.cpp [new file with mode: 0644]
QuranComExtractSurah/QuranComExtractSurah.js [new file with mode: 0644]
QuranComExtractSurah/README.md [new file with mode: 0644]
RiichiWikiIntroExtract/README.md [new file with mode: 0644]
RiichiWikiIntroExtract/RiichiWikiIntroExtract.js [new file with mode: 0644]
SelectiveDLLInit/README.md [new file with mode: 0644]
SelectiveDLLInit/WindowsDLL.cpp [new file with mode: 0644]
SelectiveDLLInit/WindowsTarget.cpp [new file with mode: 0644]
SelectiveDLLInit/selectiveinit.cpp [new file with mode: 0644]
TSDefragger/README.md [new file with mode: 0644]
TSDefragger/TSDefragger.c [new file with mode: 0644]

diff --git a/AbstractPosix/README.md b/AbstractPosix/README.md
new file mode 100644 (file)
index 0000000..de63767
--- /dev/null
@@ -0,0 +1,3 @@
+## Abstract POSIX
+
+Faking UNIX abstract sockets without ancillary messages on POSIX by uinsg TCP sockets with a hashed port
diff --git a/AbstractPosix/abstractposix.c b/AbstractPosix/abstractposix.c
new file mode 100644 (file)
index 0000000..344d07a
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#pragma comment(lib, "ws2_32.lib")
+#else
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define SOCKET int
+#define InetPtonA inet_pton
+#endif
+
+#define HASH_PRIME 31
+static uint16_t memhash16(const uint8_t *mem, size_t len)
+{
+        uint16_t h = 0;
+        while (len--) {
+                h *= HASH_PRIME;
+                h += ((uint16_t)mem[len] + 1);
+        }
+        return h;
+}
+
+// This port range is generally not used by normal
+// services nor used as an ephemeral port so it's
+// a good range to use as a hash for ports.
+#define PORT_BEGIN 0x4000
+#define PORT_RANGE 0x4000
+static uint16_t porthash(const uint8_t *mem, size_t len)
+{
+        return PORT_BEGIN + memhash16(mem, len) % PORT_RANGE;
+}
+
+static void socketassert(const char *file, int line, const char *expr, int condition)
+{
+        if (!condition) {
+#ifdef _WIN32
+                int code = WSAGetLastError();
+#else
+                int code = errno;
+#endif
+                fflush(stdout);
+                fprintf(stderr, "[%s:%d] Socket error from '%s' : %d\n", file, line, expr, code);
+                exit(1);
+        }
+}
+
+#define SOCKET_ASSERT(expr) socketassert(__FILE__, __LINE__, #expr, (expr))
+
+int main(int argc, char **argv)
+{
+#ifdef _WIN32
+        WSADATA wsa_data;
+        int errcode = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+        if (errcode) {
+                fprintf(stderr, "WSAStartup failed! %d\n", errcode);
+                return 1;
+        }
+        if (wsa_data.wVersion != MAKEWORD(2, 2)) {
+                fprintf(stderr, "WSA Version != 2.2!\n");
+                return 1;
+        }
+#endif
+        const char *name = "TheBestName";
+        if (argc > 1) {
+                name = argv[1];
+        }
+        uint16_t port = porthash(name, strlen(name));
+        printf("Establishing abstract socket '%s' with port '%d'\n", name, port);
+
+        struct sockaddr_in sin;
+        memset(&sin, 0, sizeof(sin));
+        sin.sin_family = PF_INET;
+        sin.sin_port = htons(port);
+        InetPtonA(AF_INET, "127.0.0.1",  &sin.sin_addr);
+
+        SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
+        SOCKET_ASSERT(server != INVALID_SOCKET);
+        SOCKET_ASSERT(bind(server, (struct sockaddr *)&sin, sizeof(sin)) != SOCKET_ERROR);
+        SOCKET_ASSERT(listen(server, 1) != SOCKET_ERROR);
+        printf("Server is listening...\n");
+
+        SOCKET client = socket(AF_INET, SOCK_STREAM, 0);
+        SOCKET_ASSERT(client != INVALID_SOCKET);
+        SOCKET_ASSERT(connect(client, (struct sockaddr *)&sin, sizeof(sin)) != SOCKET_ERROR);
+        printf("Client connected!\n");
+
+        SOCKET connection = accept(server, NULL, 0);
+        SOCKET_ASSERT(connection != INVALID_SOCKET);
+        printf("Server accepted connection!\n");
+
+        char message[] = "Hello World!";
+        printf("Client is sending message!\n");
+        SOCKET_ASSERT(send(client, message, sizeof(message), 0) != SOCKET_ERROR);
+        memset(message, 0, sizeof(message));
+        printf("Server is receiving message!\n");
+        SOCKET_ASSERT(recv(connection, message, sizeof(message), 0) != SOCKET_ERROR);
+        printf("Server received message!\n"
+                "Message: %s\n", message);
+
+        close(server);
+        close(connection);
+        close(client);
+        return 0;
+}
diff --git a/EnableLBR/README.md b/EnableLBR/README.md
new file mode 100644 (file)
index 0000000..7e7f6e5
--- /dev/null
@@ -0,0 +1,3 @@
+## Enable LBR
+
+Enable LBR for Threads in a Process on Windows (useful for some ETW tracing)
diff --git a/EnableLBR/enablelbr.c b/EnableLBR/enablelbr.c
new file mode 100644 (file)
index 0000000..7fe915b
--- /dev/null
@@ -0,0 +1,98 @@
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#include <tlhelp32.h>
+#include <stdio.h>
+static void EnableLBR(DWORD dwProcessId)
+{
+        if (dwProcessId == GetCurrentProcessId())
+        {
+                printf("Wow, you magically guessed my PID! Can't enable LBR on myself though...\n");
+                return;
+        }
+
+        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId);
+        if (hSnapshot == INVALID_HANDLE_VALUE)
+        {
+                printf("Failed to create snapshot!\n");
+                return;
+        }
+
+        THREADENTRY32 te;
+        te.dwSize = sizeof(te);
+        printf("Enabling LBR for threads in PID %u...\n", dwProcessId);
+        if (Thread32First(hSnapshot, &te)) do
+        {
+                DWORD cbPrev = te.dwSize;
+                te.dwSize = sizeof(te);
+                if (cbPrev < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID))
+                        continue;
+                if (te.th32OwnerProcessID != dwProcessId)
+                        continue;
+
+                DWORD tid = te.th32ThreadID;
+                printf("\tEnabling LBR for TID %u...\n", tid);
+                DWORD flags = THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME;
+                HANDLE hThread = OpenThread(flags, FALSE, tid);
+                if (hThread == NULL)
+                {
+                        printf("\tFailed to open thread for ctx update!\n", tid);
+                        continue;
+                }
+                if (SuspendThread(hThread) == (DWORD)-1)
+                {
+                        printf("\tFailed to suspend thread for updating context! %08X\n", GetLastError());
+                        CloseHandle(hThread);
+                        continue;
+                }
+
+                // This weird little quirk about enabling LBR described on a CodeProject page
+                // https://www.codeproject.com/Articles/517466/Last-branch-records-and-branch-tracing
+                //
+                // In a debugger, this can get From/To values on branches
+                // You can also break on branches when setting 0x200 in Dr7
+                //
+                // Outside of a debugger, records the branch in LbrInserts when using ETW
+                CONTEXT ctx;
+                flags = CONTEXT_DEBUG_REGISTERS;
+                ctx.ContextFlags = flags;
+                BOOL status = GetThreadContext(hThread, &ctx);
+                ctx.Dr7 |= 0x100;
+                if (status) {
+                        ctx.ContextFlags = flags;
+                        SetThreadContext(hThread, &ctx);
+                }
+                ResumeThread(hThread);
+                CloseHandle(hThread);
+
+                if (!status)
+                {
+                        printf("\tFailed to update context for thread! %08x\n", GetLastError());
+                        continue;
+                }
+                printf("\tLBR enabled for TID %u!\n", tid);
+        }
+        while (Thread32Next(hSnapshot, &te)); else
+        {
+                fflush(stdout);
+                fprintf(stderr, "Failed to get a single thread in process? How?\n");
+                return;
+        }
+        printf("Threads in PID %u have LBR enabled!\n", dwProcessId);
+}
+
+int main(int argc, char **argv)
+{
+        if (argc < 2)
+        {
+                fprintf(stderr, "Usage: %s ProcessID\n", *argv);
+                return 1;
+        }
+        DWORD dwProcessId = (DWORD)atoi(argv[1]);
+        if (dwProcessId == 0)
+        {
+                fprintf(stderr, "Failed to parse process ID! Cannot enable LBR!\n");
+                return 1;
+        }
+        EnableLBR(dwProcessId);
+        return 0;
+}
diff --git a/LaserEyesPNG/README.md b/LaserEyesPNG/README.md
new file mode 100644 (file)
index 0000000..c034f47
--- /dev/null
@@ -0,0 +1,3 @@
+## Laser Eyes PNG
+
+https://memed.io/laser-eyes-meme-maker export as PNG
diff --git a/LaserEyesPNG/snippet.js b/LaserEyesPNG/snippet.js
new file mode 100644 (file)
index 0000000..a24eafd
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Javascript has an API for adding custom HTML elements
+ * that memed.io uses to define their own class for exporting
+ * the image as whatever filetype that they want.
+ *
+ * window.customElements.define('add-images-on-image', AddImagesOnImage);
+ *
+ * However, the only option available, or that I could find right now,
+ * is to export as a JPG. This is a pain because I often have images with
+ * transparent backgrounds and JPG not only removes the transparency, the
+ * lossiness makes it so that I can't just select a key color to remove the background.
+ * 
+ * No problem because we can use the browser console to export it to a PNG.
+ */
+
+// Export the data URL of the image
+document.querySelector('add-images-on-image').getCanvasDataUrl('png')
+
+// Or you can have memed.io temporarily host your image
+// and this will give you a URL back to the blob
+document.querySelector('add-images-on-image').getCanvasObjectUrl('png')
diff --git a/MSVCCleanup/README.md b/MSVCCleanup/README.md
new file mode 100644 (file)
index 0000000..97d9c96
--- /dev/null
@@ -0,0 +1,3 @@
+## MSVC Cleanup
+
+Cleanup macro for C++ which emulates gcc's \_\_cleanup\_\_ (which MSVC does not have)
diff --git a/MSVCCleanup/msvccleanup.cpp b/MSVCCleanup/msvccleanup.cpp
new file mode 100644 (file)
index 0000000..4f01c77
--- /dev/null
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+#ifdef __cplusplus
+#define CLEANUP(t, v) t v; AutoCleanup<t, t##Cleanup> ACV(&v); v
+
+template <typename T, void (*dtor)(T *)>
+class AutoCleanup {
+        T *wrapped;
+public:
+        AutoCleanup(T *wrapped) : wrapped(wrapped) {}
+        ~AutoCleanup() { dtor(wrapped); }
+};
+#else
+#define CLEANUP(t, v) t __attribute__((__cleanup__(t##Cleanup))) v
+#endif
+
+typedef struct S {
+        int x;
+} S;
+
+void SCleanup(S *h)
+{
+        printf("Hello World! %d\n", h->x);
+}
+
+int main(void)
+{
+        CLEANUP(S, v) = {2};
+        return 0;
+}
diff --git a/QuranComExtractSurah/QuranComExtractSurah.js b/QuranComExtractSurah/QuranComExtractSurah.js
new file mode 100644 (file)
index 0000000..96373a0
--- /dev/null
@@ -0,0 +1,68 @@
+// The original ayaa and translation is stored in a translation view,
+// so select the container and then, in that, select the texts.
+//
+// SeoText element has multiple divs, one text without diacritics
+// and one text with diacritics. The one with diacritics appears
+// to always show up as the last child, so use that one.
+CONTAINER_SELECTOR = 'div[class^=TranslationView_container]';
+ORIGINAL_SELECTOR = 'div[class^=SeoText] div:last-of-type';
+TRANSLATION_SELECTOR = 'div[class^=TranslationText]';
+ACTION_TIMEOUT = 1000;
+
+ARAB_CODEPOINT_0 = 0x0660;
+function arabic_number(nstr) {
+  let n = 0;
+  for (let char of nstr) {
+    n *= 10;
+    let digit = char.charCodeAt(0) - ARAB_CODEPOINT_0;
+    if (digit >= 0 && digit <= 9)
+      n += digit;
+    else
+      throw new Error("Invalid arabic numeral given in arabic_number");
+  }
+  return n;
+}
+// Quran.com specific function, ayaa from the stored text
+// has the number at the end of the text, so splitting by
+// spaces and then extracting the last string gets the number 
+function ayaa_number(ayaa) {
+  return arabic_number(ayaa.split(' ').pop());
+}
+
+tsv_lines = {};
+keylen_check = -1;
+keylen = 0;
+function tsv_iterate() {
+  if (keylen_check == -1) {
+    keylen_check = 0;
+    window.scrollTo(0,0);
+    setTimeout(tsv_iterate, ACTION_TIMEOUT);
+    return;
+  }
+  keylen_check = keylen;
+
+  containers = Array.from(document.querySelectorAll(CONTAINER_SELECTOR));
+  originals = containers.map(e => e.querySelector(ORIGINAL_SELECTOR).innerText.replace(/\s+/, ' '));
+  translations = containers.map(e => {
+    // Remove footnotes because they contribute to inner text, which we don't want
+    // Footnotes are enclosed in a "sup" element, so we can select based on this
+    node = e.querySelector(TRANSLATION_SELECTOR).cloneNode(true);
+    node.querySelectorAll('sup').forEach(e => e.remove());
+    return node.innerText.replace(/\s+/, ' ');
+  });
+  originals.forEach((e, i) => tsv_lines[e] = translations[i]);
+
+  containers[containers.length-1].scrollIntoView();
+  keylen = Object.keys(tsv_lines).length;
+
+  if (keylen_check != keylen) {
+    setTimeout(tsv_iterate, ACTION_TIMEOUT);
+  } else {
+    tsv = Object.entries(tsv_lines)
+      .sort((a,b) => ayaa_number(a[0]) - ayaa_number(b[0]))
+      .map(e => e.join('\t'))
+      .join('\n');
+    console.log(tsv);
+  }
+}
+tsv_iterate();
diff --git a/QuranComExtractSurah/README.md b/QuranComExtractSurah/README.md
new file mode 100644 (file)
index 0000000..bd5f0cb
--- /dev/null
@@ -0,0 +1,3 @@
+## Quran.com Surah Extraction
+
+Javascript to paste in dev console to extract surah and translation from quran.com/<SURAH> as a TSV (for offline processing)
diff --git a/RiichiWikiIntroExtract/README.md b/RiichiWikiIntroExtract/README.md
new file mode 100644 (file)
index 0000000..0bd6e28
--- /dev/null
@@ -0,0 +1,3 @@
+## Riichi Wiki Intro Extraction
+
+Extracting the intro of a Riichi wiki page (useful for importing Yakus from https://riichi.wiki/List_of_yaku into Anki for memorization)
diff --git a/RiichiWikiIntroExtract/RiichiWikiIntroExtract.js b/RiichiWikiIntroExtract/RiichiWikiIntroExtract.js
new file mode 100644 (file)
index 0000000..b4ec52d
--- /dev/null
@@ -0,0 +1,11 @@
+// Get nodes from the wiki page
+nodes = Array.from(document.querySelector('.mw-parser-output').childNodes).filter(e => e.nodeType != Node.TEXT_NODE);
+
+//  Extract the nodes corresponding to the intro of the page 
+desc = nodes.slice(nodes.findIndex(e => e.className == 'infobox') + 1, nodes.findIndex(e => e.id == 'toc')).map(e => e.cloneNode(true));
+
+// For if you don't want links, just want the text in HTML form
+// desc.forEach(e => e.querySelectorAll('a').forEach(a => { sp = document.createElement('span'); sp.innerHTML = a.innerHTML; a.replaceWith(sp); }));
+
+// Print out the HTML for use in Anki flash cards (or do anything else you want with the HTML)
+console.log(desc.map(e => e.outerHTML).join('').replaceAll(/href="\//ig, "href=\"https://riichi.wiki/"));
diff --git a/SelectiveDLLInit/README.md b/SelectiveDLLInit/README.md
new file mode 100644 (file)
index 0000000..b58f27a
--- /dev/null
@@ -0,0 +1,3 @@
+## Selective DLL Init
+
+Selectively initialize a DLL based on the exports of executable so that injections can be loaded in the injector itself
diff --git a/SelectiveDLLInit/WindowsDLL.cpp b/SelectiveDLLInit/WindowsDLL.cpp
new file mode 100644 (file)
index 0000000..01ad2ba
--- /dev/null
@@ -0,0 +1,77 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winnt.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <intrin.h>
+
+#define EXPORT_IGNORE "INJECTION_IGNORE"
+
+#define RvaTranslate(base, offset) ((ULONG_PTR)base + (ULONG_PTR)offset)
+#define RvaTranslateT(t, base, offset) (t *)RvaTranslate(base, offset)
+
+typedef struct expdir
+{
+        DWORD ExportFlags;
+        DWORD TimeDateStamp;
+        WORD MajorVersion;
+        WORD MinorVersion;
+        DWORD NameRva;
+        DWORD OrdinalBase;
+        DWORD AddressTableEntries;
+        DWORD NumberOfNamePointers;
+        DWORD ExportAddressTableRva;
+        DWORD NamePointerRva;
+        DWORD OrdinalTableRva;
+}
+IMAGE_DATA_DIRECTORY_EXPORT;
+
+// Only x86_64 supported to keep things simple
+static IMAGE_DOS_HEADER *GetExeBaseAddress(void)
+{
+        PTEB pteb = (PTEB)__readgsqword(0x30);
+        return (IMAGE_DOS_HEADER *)(((LPCVOID *)pteb->ProcessEnvironmentBlock)[2]);
+}
+
+// Check for special export
+static BOOL OnProcessAttach(void)
+{
+        IMAGE_DOS_HEADER *exehdr = GetExeBaseAddress();
+        printf("Hello World! Image address=%p\n", exehdr);
+        IMAGE_NT_HEADERS *headers = RvaTranslateT(IMAGE_NT_HEADERS, exehdr, exehdr->e_lfanew);
+        if (headers->OptionalHeader.NumberOfRvaAndSizes == 0)
+                return FALSE;
+        IMAGE_DATA_DIRECTORY directory = headers->OptionalHeader.DataDirectory[0];
+        if (directory.VirtualAddress == 0)
+                return FALSE;
+        IMAGE_DATA_DIRECTORY_EXPORT *ddexp = RvaTranslateT(IMAGE_DATA_DIRECTORY_EXPORT, exehdr, directory.VirtualAddress);
+        printf("Found Export directory table!\n");
+        DWORD *nameptrs = RvaTranslateT(DWORD, exehdr, ddexp->NamePointerRva);
+        DWORD nameptrcount = ddexp->NumberOfNamePointers;
+        printf("Name pointers: %p,%u\n", nameptrs, nameptrcount);
+
+        // EXEs don't normally export many names, so don't bother with bsearch
+        for (DWORD i = 0; i < nameptrcount; i++) {
+                const char *name = RvaTranslateT(const char, exehdr, nameptrs[i]);
+                printf("%s\n", name);
+                if (name != NULL && !strcmp(name, EXPORT_IGNORE))
+                        return TRUE;
+        }
+
+        return FALSE;
+}
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved)
+{
+        switch (fdwReason)
+        {
+                case DLL_PROCESS_ATTACH:
+                        BOOL marked = OnProcessAttach();
+                if (marked)
+                        printf("The process is marked with export '%s'. I will ignore it!\n", EXPORT_IGNORE);
+                else
+                        printf("Injecting evil things into the process >:)\n");
+                break;
+        }
+        return TRUE;
+}
diff --git a/SelectiveDLLInit/WindowsTarget.cpp b/SelectiveDLLInit/WindowsTarget.cpp
new file mode 100644 (file)
index 0000000..0171405
--- /dev/null
@@ -0,0 +1,9 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+int main(void)
+{
+        fprintf(stderr, "Please don't hurt me...\n");
+        LoadLibraryA("WindowsDLL.DLL");
+        return 0;
+}
\ No newline at end of file
diff --git a/SelectiveDLLInit/selectiveinit.cpp b/SelectiveDLLInit/selectiveinit.cpp
new file mode 100644 (file)
index 0000000..623f36b
--- /dev/null
@@ -0,0 +1,16 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#ifdef __cplusplus
+#define EXPORT extern "C" __declspec(dllexport)
+#else
+#define EXPORT __declspec(dllexport)
+#endif
+
+EXPORT void INJECTION_IGNORE(void) {}
+
+int main(void)
+{
+        LoadLibraryA("WindowsDLL.DLL");
+        return 0;
+}
\ No newline at end of file
diff --git a/TSDefragger/README.md b/TSDefragger/README.md
new file mode 100644 (file)
index 0000000..38c04d9
--- /dev/null
@@ -0,0 +1,3 @@
+## MPEG-TS Packet Defragger
+
+Reassemble fragmented MPEG-TS packets from FFMPEG
diff --git a/TSDefragger/TSDefragger.c b/TSDefragger/TSDefragger.c
new file mode 100644 (file)
index 0000000..2331b4a
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * FFMPEG and friends like to fragment big packets
+ * into datagrams that fit inside an ethernet MTU
+ * when sending to a UDP MPEG-TS stream.
+ *
+ * This is technically good practice, but FFMPEG receivers
+ * drop packets fragmented like this. Most video packets
+ * and some audio packets are fragmented like this.
+ *
+ * For localhost, the MTU can be made arbitrarily high,
+ * and IPv4 allows for packet fragmentation, so sending
+ * bigger packets is possible in most cases.
+ *
+ * Therefore, reassemble MPEG-TS packets and send them
+ * as singular datagrams so FFMPEG readers accept them.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#pragma comment(lib, "ws2_32.lib")
+#include <windows.h>
+#include <winsock2.h>
+#else
+#error Linux not supported yet!
+#endif
+
+#define SOCK_ERR_LIMIT 50
+#define SYNC_BYTE 0x47
+enum program_error {
+        ERROR_USAGE = 1,
+        ERROR_PARSE_SRC = 2,
+        ERROR_PARSE_DST = 3,
+        ERROR_SOCK_SRC = 4,
+        ERROR_SOCK_DST = 5,
+        ERROR_BIND_SRC = 6,
+        ERROR_COMMS = 7,
+        ERROR_PROG_EXIT = 8,
+        ERROR_WSA_INIT = 9,
+        ERROR_WSA_UNSUPPORTED = 10,
+};
+
+static int parse_addr(const char *url, SOCKADDR_IN *sin) {
+        if (!strncmp(url, "udp://", 6))
+                url += 6;
+        uint8_t a[4];
+        uint16_t p;
+        int nfields = sscanf(url, "%hhu.%hhu.%hhu.%hhu:%hu", a, a+1, a+2, a+3, &p);
+
+        sin->sin_family = AF_INET;
+        sin->sin_port = htons(p);
+        memcpy(&sin->sin_addr, a, sizeof(sin->sin_addr));
+        memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+        return nfields == 5;
+}
+int main(int argc, char **argv) {
+        // Parse arguments
+        SOCKADDR_IN src, dst;
+        if (argc != 3) {
+                fprintf(stderr, "Usage: %s SRC_URL DST_URL", *argv);
+                return ERROR_USAGE;
+        } else if (!parse_addr(argv[1], &src)) {
+                fprintf(stderr, "Source URL '%s' failed to parse!\n", argv[1]);
+                return ERROR_PARSE_SRC;
+        } else if (!parse_addr(argv[2], &dst)) {
+                fprintf(stderr, "Destination URL '%s' failed to parse!\n", argv[2]);
+                return ERROR_PARSE_DST;
+        }
+
+#if _WIN32
+        WSADATA wsaData;
+        if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
+                fprintf(stderr, "WSAStartup failed!\n");
+                return ERROR_WSA_INIT;
+        }
+        if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
+                fprintf(stderr, "WSAStartup does not support 2.2!\n");
+                return ERROR_WSA_UNSUPPORTED;
+        }
+#endif
+
+        // Open sockets and bind to src
+        SOCKET ssock = socket(AF_INET, SOCK_DGRAM, 0);
+        if (ssock == INVALID_SOCKET) {
+                fprintf(stderr, "Source socket failed to create!\n");
+                return ERROR_SOCK_SRC;
+        }
+        SOCKET dsock = socket(AF_INET, SOCK_DGRAM, 0);
+        if (dsock == INVALID_SOCKET) {
+                fprintf(stderr, "Destination socket failed to create!\n");
+                return ERROR_SOCK_DST;
+        }
+        if (bind(ssock, (struct sockaddr *)&src, sizeof(src))) {
+                fprintf(stderr, "Failed to bind to destination URL '%s'\n", argv[2]);
+                return ERROR_BIND_SRC;
+        }
+        printf("%s -> %s flow started!\n", argv[1], argv[2]);
+
+        // Main loop
+        static uint8_t buffer[65535];
+        int sock_err_cnt = 0;
+        uint16_t top = 0;
+        while (1) {
+                // If there are excessive errors, just quit
+                if (sock_err_cnt > SOCK_ERR_LIMIT) {
+                        fprintf(stderr, "Had %d consecutive socket errors! Exiting!\n");
+                        return ERROR_COMMS;
+                }
+
+                //
+                int nbytes = recvfrom(ssock, buffer + top, sizeof(buffer) - top, 0, 0, 0);
+                if (nbytes < 0) {
+                        fprintf(stderr, "Recvfrom failed!\n");
+                        sock_err_cnt++;
+                        continue;
+                }
+                top += nbytes;
+
+                for (uint16_t i = 1; i < top; i++) {
+                        if (buffer[i] != SYNC_BYTE)
+                                continue;
+
+                        nbytes = 0;
+                        if (buffer[0] == SYNC_BYTE)
+                                nbytes = sendto(dsock, buffer, i, 0, (struct sockaddr *)&dst, sizeof(dst));
+                        memmove(buffer, buffer + i, top - i);
+                        top -= i;
+                        i = 1;
+
+                        if (nbytes < 0) {
+                                fprintf(stderr, "Sendto failed!\n");
+                                sock_err_cnt++;
+                                break;
+                        }
+                }
+        }
+
+        // This shouldn't ever return
+        return ERROR_PROG_EXIT;
+}