随便逆了一下,没逆的太详细
首先你第一张图那个是WinMain,然后会调用dll导出的hngdx9Create
这玩意其实是个单例模式的类似getInstance()这样的函数,很明显
// singleton pattern
void *__stdcall hngdx9Create(int a1)
{
void *result; // eax
void *v2; // eax
if ( a1 != 528 )
return 0;
result = dword_10116B54;
if ( !dword_10116B54 )//是null,说明第一次调用,就new出来并且给那个全局变量
{
v2 = operator new(0xB60u);
if ( v2 )//一般new返回的不会是null
{
result = (void *)NGDX9_Impl_constructor((int)v2);
++counter;
dword_10116B54 = result;
return result;
}
result = 0;
dword_10116B54 = 0;
}
//不是null,就直接返回那个全局变量
++counter;
return result;
}
然后constructor里面可以看到虚表
.rdata:100FF11C ??_7NGDX9_Impl@@6B@ dd offset sub_10005540
.rdata:100FF11C ; DATA XREF: NGDX9_Impl_constructor+C↑o
.rdata:100FF120 dd offset sub_10005590
.rdata:100FF124 dd offset sub_100059A0
.rdata:100FF128 dd offset sub_10005B10
.rdata:100FF12C dd offset shutdown
.rdata:100FF130 dd offset sub_100066C0
.rdata:100FF134 dd offset sub_100066D0
.rdata:100FF138 dd offset shell_shutdown
.rdata:100FF13C dd offset sub_10006750
...
实际上,100FF12C就是楼上提到的关机函数,那么这个函数在哪被调用了呢?
else
{
(*(void (__stdcall **)(DWORD *))(*dword_520C48 + 16))(dword_520C48);
}
.text:00425173 mov eax, dword_520C48
.text:00425178 mov ecx, [eax]
.text:0042517A mov edx, [ecx+10h]
.text:0042517D push eax
.text:0042517E call edx
这里,WinMain F5之后第100行,调用了偏移是0x10的虚函数
然后这个else来自
.text:00425003 mov eax, dword_520C48
.text:00425008 mov ecx, [eax]
.text:0042500A mov edx, [ecx+4]
.text:0042500D push eax
.text:0042500E call edx
.text:00425010 test al, al
.text:00425012 jz loc_425173
对虚表+4偏移的函数调用,必须要为true,不然关机。。
所以具体判断函数是sub_10005590这个函数。。
这个函数里面好像是一些D3D的初始化之类的东西,挺长的,本渣没研究过DX。。。所以看不懂了。。。
再具体一点的话
.text:100058E9 mov ecx, esi
.text:100058EB call sub_100023A0
.text:100058F0 test al, al
.text:100058F2 jnz short loc_10005915
;是这里,jnz没有跳,所以调用了某个虚函数,然后sub_10005590就返回了0
话说这是个啥玩意。。。初始化失败就关机的吗。。。。