我有这个代码:
#include <stdio.h>
#include <strings.h>
int main(int ac, char **av)
{
char text[] = "PASS_KEY";
printf("Hey\n");
return 0;
}
我知道这些字符串在内存中确实是一对一的。
如何使用 LD_Preload 重新定义 printf 以读取 text
?
最佳答案
定义一个 shim printf
来围绕它传递的指针转储内存并不是一项艰巨的任务:
#include <stdio.h>
void dump(const char *data) {
fwrite(data - 32, 1, 64, stdout);
}
int printf(const char *data, ...) {
dump(data);
}
编译:
gcc -c -fPIC print.c -o print.o
ld -shared -o libprint.so print.o
现在您可以LD_PRELOAD=./libprint.so ./program
并获取 key 。或者你可以......你在这里有几个不同的问题。
GCC 至少将格式字符串中没有占位符的 printf
优化为 puts
。所以你的程序调用的不是 printf
。好吧,让我们也填充 puts
:
int puts(const char *data) {
dump(data);
}
现在你在屏幕上看到了转储:
..............Hey........
所以它正在工作。但是没有 key 的踪迹。为什么?
因为text
是一个局部变量(数组)而"Hey\n"
是一个常量字符串。所以text
分配在栈上,"Hey\n"
分配在常量池中,不完全是“next to it”。你的假设是错误的。如果您将程序修改为:
#include <stdio.h>
#include <strings.h>
int main(int ac, char **av)
{
char text[] = "PASS_KEY";
char format[] = "Hey\n";
printf(format);
return 0;
}
顺便说一下,这是一件您在做之前要三思的事情,因为对 printf
使用非常量格式字符串是 B.A.D。在大多数情况下,它会起作用:
............Hey
PASS_KEY.
成功!
关于c - 在c中读取另一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28721258/