-1

I tried to implement a solution of this question: Calling a function through its address in memory in c / c++, but I'm not very familiar with the differences in C and C++. When I try to implement the answer, my compiler throws a weird error message at me:

shellcode/findpattern.c: In function ‘shell_code’:
shellcode/findpattern.c:9:30: error: expected expression before ‘)’ token
     memchr* memchr = (memchr*)0xdeadbeef;
                              ^
shellcode/findpattern.c:10:30: error: expected expression before ‘)’ token
     memcmp* memcmp = (memcmp*)0xdeadb00f;
                              ^

Here is my code:

//#include "string.h"
#include "stdio.h"
//#include "stdlib.h"

    typedef void* memchr(const void* , int , size_t  );
    typedef int memcmp(const void* , const void* , size_t  );

void shell_code(){
    memchr* memchr = (memchr*)0xdeadbeef;
    memcmp* memcmp = (memcmp*)0xdeadb00f;

    unsigned char *current = 0x00400000;
    unsigned char *end = 0x015f1000;
    int patternlength = 8;
    unsigned char pattern[8] = "\x48\x08\x49\x8B\x48\x11\x8B\$
    unsigned char *ret;
    while(current < end){
        ret = memchr(current, pattern[0], end-current);
        if (ret != NULL){
            if (memcmp(current, &pattern, patternlength) == 0$
                return current + patternlength;
            }
        }
        current = ret;
    }
}

What am I missing here? As far as I understand this is just a cast, so why does the compiler throw an error here? Is this a C vs C++ thing that I'm unfamiliar with?

reijin
  • 133
  • 10
  • Use angle brackets around standard headers: `` etc. That's what the standard says, and there's no benefit to not doing so (at least, not until you don't ask questions like this one — and even then it's mostly debatable). The function types are a bit odd-ball; why you'd name them like that I don't know. – Jonathan Leffler Oct 21 '18 at 19:19
  • The problem is that the typenames and variable identifiers are in the same namespace. Call your function pointer by *another* name; for example `memchr* memch = (memchr*)0xdeadbeef;` – Antti Haapala -- Слава Україні Oct 21 '18 at 19:23
  • 2
    BTW; `typedef`ing functions is evil ;) – Antti Haapala -- Слава Україні Oct 21 '18 at 19:25
  • @AnttiHaapala indeed it is evil, but I have to do it for my shellcode as I need to call some functions, but I'm not very good with writing assembler. So I'm trying to use more C. – reijin Oct 21 '18 at 20:13

1 Answers1

1

Given the code (extracted from your code):

typedef void* memchr(const void *, int, size_t);

void shell_code(void)
{
    memchr* memchr = (memchr*)0xdeadbeef;
//  ^1      ^2        ^3

The ^1 mention of memchr is to the function type in the typedef; the ^2 mention is the name of a local variable. This local variable now hides the type; you can no longer access the type in the function. The ^3 mention of memchr is a reference to the local pointer-to-function variable, not to the type. You have a multiplication operator after the variable, but no RHS for the multiplication — so the compiler complains about the ) because it expected an expression there as the RHS of the multiplication.

Don't play so hard with the same name. You'll confuse people reading your code. Use different names for the type and the function pointer. For example (not necessarily good naming style, but sufficient — and avoiding functions in favour of function pointers):

typedef void *(*MemChr)(const void *, int, size_t);

void shell_code(void)
{
    MemChr p_memchr = (MemChr)0xdeadbeef;

The code now stands a chance of compiling, but will simply crash when you run it and call p_memchr because the code at 0xDEADBEEF is unlikely to be a function like memchr, assuming it is mapped as executable code at all.

Note that this notation allows you to #include <string.h> (where memchr() is declared) without interfering with it, or interference from it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278