找出收到的指针是字符串,ushort还是数组

时间:2010-09-30 17:37:05

标签: c++ pointers code-injection library-interposition

我在C中插入memcpy()函数,因为目标应用程序使用它来连接字符串,我想找出正在创建的字符串。代码是:

void * my_memcpy ( void * destination, const void * source, size_t num )
{
    void *ret = memcpy(destination, source, num);
    // printf ("[MEMCPY] = %s \n", ret);
    return ret;
}

该函数被成功调用,但第一个参数可以是任何东西,我只想跟踪它,如果结果是字符串或数组。我不得不问它是数组还是字符串。我知道这不能直截了当:无论如何要找出RET指向的东西?

我在MACOSX下工作并与DYLD交互。

非常感谢。

4 个答案:

答案 0 :(得分:2)

由于void*代表一个原始内存块,因此无法确定那里有哪些实际数据。

但是,您可以在每个操作上进行“类似字符串”的内存转储,只需将结果输出某种“输出上限”。

这可以通过以下方式实现:

const size_t kUpperLimit = 32;

void output_memory_dump(void* memory) {
   std::cout.write(reinterpret_cast<char*>(memory), kUpperLimit);
}

对于非字符串数据,输出几乎无法解释,但除此之外你就得到了你要搜索的内容。

您可以尝试应用一些基于猜测的方法,例如迭代reinterpret_cast<void*>(memory)并对每个符号进行is_alphanumeric && is_space检查,但这种方法似乎不太稳定(谁知道什么可以实际上是void* ... )。

无论如何,对于某些可能没问题的情况。

答案 1 :(得分:1)

您可以先对复制的内存应用一些启发式方法,然后根据这些内容确定是否要打印它。

static int maybe_string(const void *data, size_t n) {
  const unsigned char *p;
  size_t i;

  p = data;
  for (i = 0; i < n; i++) {
    int c = p[i];
    if (c == '\n' || c == '\r' || c == '\t')
      continue;
    if (1 <= c && c < 32)
      return 0; /* unusual ASCII control character */
    if (c == '\0' && i > 5)
      return 1; /* null-terminated and more than a few characters long */
  }

  return 0; /* not null-terminated, so it isn't a string */
}

这种启发式并不完美。例如,它因以下模式而失败:

const char *str = "hello, world";
size_t len = strlen(str);
char *buf = malloc(1024);
memcpy(buf, str, len);
buf[len] = '\0';

如果你想抓住它,你将不得不改变上述功能。

答案 2 :(得分:0)

ret等于目标指针。但是不可能确定它是数组还是字符串,除非您知道有关数组或字符串的更多信息(例如,字符串具有一定长度并且以空值终止)。

答案 3 :(得分:0)

不,你无法从void类型的指针中弄清楚这一点。另外,您不知道源或目标的大小,因此启发式方法不起作用。由于其他原因,它也无法工作,例如,存储在void*指向的内存区域中的二进制数据最后可能确实有零字节,但这并不意味着它是字符串。