Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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;
- if (!(a = malloc(sizeof(args)))) {
- perror("malloc");
- exit(errno);
- }
- a->pos = 0;
- a->sz = (sz+3) & ~3; // align to 4 bytes
- if (!(a->data = calloc(a->sz, 1))) {
- free(a);
- perror("calloc");
- exit(errno);
- }
- return a;
- }
- void a_destroy(args *a) {
- memset(a->data, -1, a->sz);
- free(a->data);
- memset(a, -1, sizeof(args));
- free(a);
- }
- 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) {
- puts("################################");
- for (int i = 0; i < a->pos; i+=4) {
- int val = *(int*)(a->data + i);
- printf("%.2d %.8x\n", i, val);
- }
- puts("################################");
- for (int i = a->pos; i < a->sz; i+=4) {
- 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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement