C++ 如何在MSVC+下解除对函数指针的引用并将其作为数据读取+;?
下面是我试图读取函数指针指向的机器代码并将其打印出来。目前,正在打印的数据与生成的代码不同。。。我已经检查了在生成的可执行文件中创建并由反汇编程序列出的指针的值(代码/调试器之间存在差异),但没有发现任何太麻烦的地方,也没有理解如何解决问题C++ 如何在MSVC+下解除对函数指针的引用并将其作为数据读取+;?,c++,c,windows,assembly,C++,C,Windows,Assembly,下面是我试图读取函数指针指向的机器代码并将其打印出来。目前,正在打印的数据与生成的代码不同。。。我已经检查了在生成的可执行文件中创建并由反汇编程序列出的指针的值(代码/调试器之间存在差异),但没有发现任何太麻烦的地方,也没有理解如何解决问题 void dummy(); int _tmain(int argc, _TCHAR* argv[]) { int i; printf("\nReading dummy...\n"); for(i = 0; i < 25; i
void dummy();
int _tmain(int argc, _TCHAR* argv[])
{
int i;
printf("\nReading dummy...\n");
for(i = 0; i < 25; i++)
printf("%.2X ", ((char *)((void *)dummy))[i]);
puts("");
dummy();
getchar();
return 0;
}
void __declspec(naked) dummy()
{
__asm
{
nop;
nop;
nop;
nop;
ret;
}
}
void dummy();
int _tmain(int argc,_TCHAR*argv[]
{
int i;
printf(“\n读取虚拟…\n”);
对于(i=0;i<25;i++)
printf(“%.2X”,((char*)((void*)dummy))[i];
认沽权(“”);
dummy();
getchar();
返回0;
}
void uuu declspec(裸)假人()
{
__asm
{
否;
否;
否;
否;
ret;
}
}
给你:
#include <stdio.h>
void PrintHex(const char* input, const int len)
{
char * tmp=new char[len*3+1];
for(int i=0;i<len;++i)
sprintf(tmp+i*3,"%02x ",*(input+i)&0xFF);
printf("%s\n",tmp);
};
#包括
无效打印十六进制(常量字符*输入,常量整数长度)
{
char*tmp=新字符[len*3+1];
对于(int i=0;i让我猜一下,它打印了以下内容:
FFFFFF90 FFFFFF90 FFFFFF90 FFFFFF90 FFFFFFC3
输出:
90 90 90 90 C3
90 C3
X
说明符本身将值打印为unsigned int
,但是您传入了一个升级为signed int
的char
。hh
修饰符将其更改为unsigned char
,而不是unsigned int
,这是两个常见的错误。首先,转换为unsignedchar*
而不是char*。下一步,也是重要的一步,项目+属性,链接器,常规,并关闭增量链接
在启用增量链接的情况下,函数地址实际上指向一个小存根,该存根只包含一个指向实际函数的JMP。这允许链接器用新代码替换旧代码,而无需重建整个可执行映像。当启用增量链接时,您的代码将读取该存根而不是实际函数正确输出:
Reading dummy...
90 90 90 90 C3 //... rest is random
换线
printf("%.2X ", ((char *)((void *)dummy))[i]);
到
你能把调用发布到printf()吗
最终打印?当您在函数地址上使用内存转储窗口时,您期望得到什么、得到什么以及调试器显示了什么?-1,这将给出与OP的代码相同的结果,或者更糟。它还错误地使用了带符号的字符
,除了这里它实际上会导致缓冲区溢出。allo的意义是什么当您可以直接输出值时,对缓冲区进行分类?谢谢,这正是我所需要的。我应该更仔细地查看正在转储的代码-我认为这是链接器的愚蠢行为,但我不确定是什么。:)
printf("%.2X ", ((char *)((void *)dummy))[i]);
printf("%.2X ", ((unsigned char *)dummy)[i]);