【逆向工程-VC6.0 浮点未初始化bug的原因】此文章归类为:逆向工程。
VC6.0 浮点未初始化bug的原因
过程
测试代码
// test.cpp : Defines the entry point for the console application.
//
int main(int argc, char* argv[])
{
float f;
printf("please input a float: ");
scanf("%f",&f);
return 0;
}
分析异常


反汇编窗口分析

修改测试代码,并观察 __fassign 的调用
// 修改测试代码,旨在让vc6.0初始化FPU
float f = 1.0f;

符号 _cfltcvt_tab 和 _cfltcvt_init
- 从上面的分析,可以观察的一个重要的符号
_cfltcvt_tab,显然这是一个表,使用vscode查看其定义
/*-
* ...(模型相关)代码指针表 ...
*
* 六个条目,默认全部指向 _fptrap,
* 但会更改为指向相应的例程
* 如果链接了 _fltused 初始化器 (_cfltcvt_init)
* 。
*
* 如果链接了 _fltused 模块,则
* _cfltcvt_init 初始化器会将 _cfltcvt_tab 的 6 个条目设置为:
*
* _cfltcvt
* _cropzeros
* _fassign
* _forcdecpt
* _positive
* _cldcvt
-*/
void (*_cfltcvt_tab[6])(void) = {
_fptrap, _fptrap, _fptrap, _fptrap, _fptrap, _fptrap
};
- _fptrap的定义
void __cdecl _fptrap(
void
)
{
_amsg_exit(_RT_FLOAT);
}
可见 _cfltcvt_tab是一个全局的函数指针数组,且初始化赋值为 _fptrap
从注释中,可以发现决定初不初始化FPU的关键是 _cfltcvt_init,该符号在libc.lib中fpinit.obj中
调试mainCRTStartup中cinit函数,验证猜想
// 修改测试代码,旨在让vc6.0初始化FPU
float f = 1.0f;

手动初始化 FPU
// 声明函数符号
extern void __cdecl _cfltcvt_init();
int main(int argc, char* argv[])
{
int f = 0;
// 手动初始化 FPU
_cfltcvt_init();
printf("please input a float: ");
scanf("%f",&f);
printf("input float value: %f",f);
system("pause");
return 0;
}
没有异常信息

回归问题
VC6浮点未初始化bug的原因

为了更好观察 _FPinit变量,可以记录下当前指令地址 0x004017F3
使用OD调试器,调试该程序,并在断在入口点,Ctrl+G跳转到目标地址观察

更多【逆向工程-VC6.0 浮点未初始化bug的原因】相关视频教程:www.yxfzedu.com