Surprise! We've been running on hardware provided by BuyVM for a few months and wanted to show them a little appreciation.
Running a paste site comes with unique challenges, ones that aren't always obvious and hard to control. As such, BuyVM offered us a home where we could worry less about the hosting side of things and focus on maintaining a clean and useful service! Go check them out and show them some love!
Description: rundll.c
Submitted on November 18, 2015 at 07:18 PM

Section 1 (Text)

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <windows.h>

typedef struct {
    void *data;
    size_t pos, sz;
} args;

args a_new(size_t sz);
void a_destroy(args *a);
void a_push(args *a, void *arg);
void a_print(args a);
int __fastcall a_exec(args a, FARPROC fun);

args a_new(size_t sz) {
    args a = (args) {
        .pos = 0,
        .sz = (sz+3) & ~3, // align to 4 bytes
    };
    if (!(a.data = calloc(a.sz, 1))) {
        perror("calloc");
        exit(errno);
    }
    return a;
}

void a_destroy(args *a) {
    memset(a->data, -1, a->sz);
    free(a->data);
    memset(a, 0, sizeof(args));
}

void a_push(args *a, void *arg) {
    if (a->pos == a->sz) {
        a->sz *= 2;
        void *old = a->data;
        if (!(a->data = realloc(a->data, a->sz))) {
            a_destroy(old);
            perror("realloc");
            exit(errno);
        }
        memset(a->data + a->sz/2, 0, a->sz/2);
    }
    memcpy(a->data + a->pos, arg, 4);
    a->pos += 4;
}

void a_print(args a) {
    for (unsigned int i = 0; i < a.sz; i+=4) {
        if (i == 0 || i == a.pos) puts("################################");
        int val = *(int*)(a.data + i);
        printf("%.2d %.8x\n", i, val);
    }
}

int __fastcall a_exec(args a, FARPROC fun) {
    int res;
    __asm__ __volatile__ (
        "movl %1, %%esi      # source = a->data        \n\t"
        "subl %2, %%esp      # make space on stack     \n\t"
        "movl %%esp, %%edi   # dest = stack            \n\t"
        "shrl $2, %2         # dword == 4 bytes        \n\t"
        "rep movsd           # copy args onto stack    \n\t"
        "call *%3            # call fun (stdcall)      \n\t"
        "movl %%eax, %0      # preserve result         \n\t"
        : "=r" (res)
        :  "r" (a.data),
           "c" (a.pos),
           "r" (fun)
        : "%esi", "%edi", "%eax"
    );
    return res;
}


int main(int c, char *v[static 3]) {
    void   *dll = LoadLibrary(v[1]);            if (!dll) return -1;
    FARPROC fun = GetProcAddress(dll, v[2]);    if (!fun) return -2;
    args a = a_new(64);
    
    for (int i=3; i<c; i++) {
        if (*v[i] == '.') {
            v[i]++;
            a_push(&a, &v[i]);
        }
        else {
            char *ep;
            errno = 0;
            long n = strtol(v[i], &ep, 0);      if (errno | *ep) return -3;
            a_push(&a, &n);
        }
    }
    
    if (**v < 'a') a_print(a);
    
    int ret = a_exec(a, fun);
    a_destroy(&a);
    
    return ret;
}