【问题标题】:Calling a function via its address C [duplicate]通过地址 C 调用函数 [重复]
【发布时间】:2019-03-25 21:53:59
【问题描述】:

我试图实现这个问题的解决方案:Calling a function through its address in memory in c / c++,但我对 C 和 C++ 的区别不是很熟悉。当我尝试实现答案时,我的编译器向我抛出了一个奇怪的错误消息:

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;
                              ^

这是我的代码:

//#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;
    }
}

我在这里缺少什么?据我了解,这只是一个演员表,那么为什么编译器会在这里抛出错误?这是我不熟悉的 C 与 C++ 的事情吗?

【问题讨论】:

  • 在标准标题周围使用尖括号:&lt;stdio.h&gt; 等。这就是标准所说的,不这样做没有任何好处(至少,除非你不问这样的问题——即便如此,它也大多是有争议的)。函数类型有点奇怪。为什么你会这样命名我不知道。
  • 问题是类型名和变量标识符在同一个命名空间中。用另一个名字调用你的函数指针;例如memchr* memch = (memchr*)0xdeadbeef;
  • 顺便说一句; typedefing 函数是邪恶的 ;)
  • @AnttiHaapala 确实是邪恶的,但我必须为我的 shellcode 这样做,因为我需要调用一些函数,但我不太擅长编写汇编程序。所以我尝试使用更多的 C。

标签: c pointers memory function-pointers memory-address


【解决方案1】:

给定代码(从您的代码中提取):

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

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

^1 提及memchr 是针对typedef 中的函数类型; ^2 提到的是局部变量的名称。这个局部变量现在隐藏了类型;您无法再访问函数中的类型。 ^3 提到的memchr 是对局部函数指针变量的引用,而不是对类型的引用。您在变量后面有一个乘法运算符,但没有 RHS 用于乘法 - 所以编译器抱怨 ) 因为它期望那里有一个表达式作为乘法的 RHS。

不要用同一个名字这么努力。你会让阅读你的代码的人感到困惑。为类型和函数指针使用不同的名称。例如(不一定是好的命名风格,但足够了——并且避免使用有利于function pointers 的函数):

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

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

代码现在有编译的机会,但是当您运行它并调用 p_memchr 时会简单地崩溃,因为 0xDEADBEEF 处的代码不太可能是像 memchr 这样的函数,假设它被映射为可执行代码.

请注意,此符号允许您 #include &lt;string.h&gt;(其中声明了 memchr())而不干扰它,或受到它的干​​扰。

【讨论】:

  • 谢谢,很好的解释!我犯了一个多么明显的错误!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
相关资源
最近更新 更多