我%p在Stack Overflow中已经阅读了很多关于C语言中格式说明符用法的答案,但似乎没有一个解释为什么void*所有类型都需要显式转换为char*.
我当然知道这样一个事实,即强制转换的要求void*与使用可变函数(参见本答案的第一条评论)有关,而非强制性要求.
这是一个例子:
int i;
printf ("%p", &i);
Run Code Online (Sandbox Code Playgroud)
产生关于类型不兼容性的警告,并且&i应该进行铸造void*(根据标准的要求,再次参见此处).
虽然这一大块代码能够顺利编译,但没有关于类型转换的任何投诉:
char * m = "Hello";
printf ("%p", m);
Run Code Online (Sandbox Code Playgroud)
如何char*从这一要求中"解脱"?
PS:可能值得补充的是我在 x86_64架构上工作,因为指针类型大小依赖于它,并且使用 gcc作为linux上的-W -Wall -std=c11 -pedantic编译器和编译选项.
用C指针搞乱一点,我遇到了一个相当奇怪的行为.
请考虑以下代码:
int
main ()
{
char charac = 'r';
long long ptr = (long long) &charac; // Stores the address of charac into a long long variable
printf ("[ptr] points to %p containing the char %c\n", ptr, *(char*)ptr);
}
Run Code Online (Sandbox Code Playgroud)
现在,当编译为64位目标体系结构(编译命令:)时gcc -Wall -Wextra -std=c11 -pedantic test.c -o test,一切都很好,执行给出
> ./test
[ptr] points to 0x7fff3090ee47 containing the char r
Run Code Online (Sandbox Code Playgroud)
但是,如果编译的目标是32位arch(带编译命令gcc -Wall -Wextra -std=c11 -pedantic -ggdb -m32 test.c -o test:),则执行会产生这种奇怪的结果:
> ./test
[ptr] points to 0xff82d4f7 …Run Code Online (Sandbox Code Playgroud) 我已经拆解了一个使用C 函数的x86 elf二进制文件scanf.
以下是与以下内容相关的反汇编代码块scanf:
0x0804857a 89442404 mov dword [esp + 0x4], eax
0x0804857e c70424b28604. mov dword [esp], 0x80486b2
0x08048585 e8eafdffff call sym.imp.scanf
Run Code Online (Sandbox Code Playgroud)
检查时gdb,地址处的内存0x80486b2包含数据0x7325(ASCII代码中的" %s "字符串).
所以这段代码显然是在堆栈上以相反的顺序推送参数,以便用这两个参数调用.
这通常用C编码
scanfscanfscanf ("%s", &somevar);
在给定汇编代码的情况下,我所期望的是,常量的32位表示形式 0x80486b2被加载到堆栈指针所指向的地址中 ......
但是,该mov指令已经加载了32位表示的任何处于地址 0x80486b2 到堆栈指针指向的地址 ......是吗?
所以我们基本上得到的mov只是将数据从内存位置转移到另一个内存位置,根据这个x86程序集介绍(在众多其他来源中)是非法的(重点是我的):
在需要存储器传输的情况下,必须首先将源存储器内容加载到寄存器中 …
Mimtproxy docs只讨论如何增加事件日志的详细程度,在Linux上,我似乎无法在〜/ .mitmproxy或标准/ var / log文件夹中找到提到的日志文件。
有没有办法访问mitmproxy的事件日志文件?