Skip to content

Instantly share code, notes, and snippets.

@ess7
Last active November 4, 2021 06:11
Show Gist options
  • Save ess7/723f5d289e0eda0d89831ad14cd7b5c0 to your computer and use it in GitHub Desktop.
Save ess7/723f5d289e0eda0d89831ad14cd7b5c0 to your computer and use it in GitHub Desktop.
Call C function from Reaper JSFX PoC
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <math.h>
#include "ns-eel.h"
#ifndef I_KNOW_WHAT_I_AM_DOING
#error Hardcoded offsets are for 32-bit 5.95 and possibly other versions
#endif
#define BASE 0x10000000UL
typedef void (*pNSEEL_addfunc_ret_type_t)(const char *, int, int, NSEEL_PPPROC, void *, eel_function_table *);
static pNSEEL_addfunc_ret_type_t pNSEEL_addfunc_ret_type = (pNSEEL_addfunc_ret_type_t)(0x10002220UL - BASE);
static NSEEL_PPPROC NSEEL_PProc_THIS = (NSEEL_PPPROC)(0x10008b00UL - BASE);
static void NSEEL_addfunc_ret_type(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination) {
pNSEEL_addfunc_ret_type(name, np, ret_type, pproc, fptr, destination);
}
static EEL_F NSEEL_CGEN_CALL add(void *opaque, EEL_F *a, EEL_F *b) {
return *a + *b;
}
static int NSEEL_CGEN_CALL setReaEQCircleSize(void *opaque, EEL_F *size) {
HMODULE reaeq = GetModuleHandle("reaeq.dll");
if (reaeq == NULL) {
return 0;
}
DWORD textSize = 0x31000;
DWORD prot;
if (!VirtualProtect(reaeq+0x1000, textSize, PAGE_EXECUTE_READWRITE, &prot)) {
return 0;
}
*(float *)(0x1001416CUL - BASE + (DWORD)reaeq) = *size;
char sz = lround(*size) + 1;
*(char *)(0x10016D04UL - BASE + (DWORD)reaeq) = -sz;
*(char *)(0x10016D43UL - BASE + (DWORD)reaeq) = sz;
*(char *)(0x10016DF2UL - BASE + (DWORD)reaeq) = sz;
*(char *)(0x10016E4FUL - BASE + (DWORD)reaeq) = -sz;
DWORD t;
VirtualProtect(reaeq+0x1000, textSize, prot, &t);
return 1;
}
static DWORD (*JesusonicAPI_init)(DWORD, DWORD, DWORD);
static DWORD init(DWORD arg1, DWORD arg2, DWORD arg3) {
DWORD ret = JesusonicAPI_init(arg1, arg2, arg3);
NSEEL_addfunc_retval("myadd", 2, NSEEL_PProc_THIS, add);
NSEEL_addfunc_retbool("setReaEQCircleSize", 1, NSEEL_PProc_THIS, setReaEQCircleSize);
return ret;
}
__declspec(dllexport)
int ReaperPluginEntry(HINSTANCE hInstance, void *rec) {
if (rec == NULL) { return 0; }
HMODULE jsfx = GetModuleHandle("jsfx.dll");
if (jsfx == NULL) { return 0; }
pNSEEL_addfunc_ret_type = (pNSEEL_addfunc_ret_type_t)((DWORD)pNSEEL_addfunc_ret_type + (DWORD)jsfx);
NSEEL_PProc_THIS = (NSEEL_PPPROC)((DWORD)NSEEL_PProc_THIS + (DWORD)jsfx);
void **JesusonicAPI = (void **)GetProcAddress(jsfx, "JesusonicAPI");
if (JesusonicAPI == NULL) { return 0; }
JesusonicAPI_init = (DWORD (*)(DWORD,DWORD,DWORD))JesusonicAPI[1];
JesusonicAPI[1] = init;
return 1;
}
@ess7
Copy link
Author

ess7 commented Nov 4, 2021

Added a new gist that works on 6.40 x64:
https://gist.github.com/ess7/6c75c111194a9159d05472aadc956c01

I'll add some commentary later. If it doesn't work try a "Full recompile/reset"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment