我在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交互。
非常感谢。
答案 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*
指向的内存区域中的二进制数据最后可能确实有零字节,但这并不意味着它是字符串。