每次在Windows 8/10而不是7上每次都会调用静态链接函数崩溃 [英] Call of statically link function crash everytimes on windows 8/10 but not 7

查看:138
本文介绍了每次在Windows 8/10而不是7上每次都会调用静态链接函数崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

我已经构建了一个生成二进制文件的 https://github.com/reorg/pg_repack 项目.该二进制文件与Postgres 9.6可再发行文件链接(我使用EntrepriseDb要求的那些文件). 在Windows 7上一切正常.在构建期间或运行时,我都没有问题.但是在Windows 8或10上,应用程序总是按照以下顺序崩溃. 二进制文件是从Visual Studio 2013的C源代码中在Windows 7上生成的(我尝试使用Windows 10上生成的版本,但它没有任何改变),在x64系统上,对于x64应用程序,优化被禁用,并且它使用动态基础. 为确保使用正确的二进制文件,已将所有可重新分发的二进制文件复制到应用程序的文件夹中.

在Windows 7上的组装详细信息(工作箱):

在主行后几行,应用程序调用函数set_pglocale_pgservice

set_pglocale_pgservice(argv[0], "pgscripts");
00007FF6E4B39C85  mov         eax,8  
00007FF6E4B39C8A  imul        rax,rax,0  
00007FF6E4B39C8E  lea         rdx,[default_options+120h (07FF6E4B43B10h)]  
00007FF6E4B39C95  mov         rcx,qword ptr [argv]  
00007FF6E4B39C9A  mov         rcx,qword ptr [rcx+rax]  
00007FF6E4B39C9E  call        qword ptr [__imp_set_pglocale_pgservice (07FF6E4B40520h)] 

内存位于07FF6E4B40520h

0x00007FF6E4B40520  00000001403e1da0   .>@....
0x00007FF6E4B40528  0000000000000000  ........
0x00007FF6E4B40530  0000000000000000  ........
0x00007FF6E4B40538  00007ff6e4b35348  HS.äö...

(注意:从0x7FF6E4B40000到0x00007FF6E4B40560的内存包含函数地址,而映射文件说:0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres redistributable,动态链接])

然后在调用qword ptr [__imp_set_pglocale_pgservice(07FF6E4B40520h)]

之后

00000001403E1DA0  mov         qword ptr [rsp+18h],rbx  
00000001403E1DA5  push        rdi  
00000001403E1DA6  sub         rsp,0C40h  
00000001403E1DAD  mov         rax,qword ptr [1405F8C60h]  
00000001403E1DB4  xor         rax,rsp  
00000001403E1DB7  mov         qword ptr [rsp+0C30h],rax  
00000001403E1DBF  mov         rbx,rdx  
00000001403E1DC2  mov         rdi,rcx  
00000001403E1DC5  lea         rdx,[140430540h]  
00000001403E1DCC  mov         rcx,rbx  
00000001403E1DCF  call        00000001403F67FA

然后在致电00000001403F67FA

00000001403F67FA  jmp         qword ptr [1403F8998h]

内存在1403F8998h

0x00000001403F8998  00007ffe87a5cc60  `Ì¥.þ...
0x00000001403F89A0  00007ffe87a47060  `p¤.þ...
0x00000001403F89A8  00007ffe87a5f8a4  ¤ø¥.þ...

(注意:从0x00000001403F8000到0x00000001403F8F08存储器包含函数地址,并且映射文件说:0002:00000998 _C @ _04FHBLDJDJ @?1bin?$ AA @ libpgport:path.obj [postgres可再发行,是静态链接的))

然后跳转到00007ffe87a5cc60

00007FFE87A5CC60  sub         rdx,rcx  
00007FFE87A5CC63  test        cl,7  
00007FFE87A5CC66  je          00007FFE87A5CC7C 

... 一切正常

在Windows 10上的组装详细信息(不适用):

在主行之后的几行中,应用程序调用了函数set_pglocale_pgservice

set_pglocale_pgservice(argv[0], "pgscripts");
00007FF7E9879C85  mov         eax,8  
00007FF7E9879C8A  imul        rax,rax,0  
00007FF7E9879C8E  lea         rdx,[default_options+120h (07FF7E9883B10h)]  
00007FF7E9879C95  mov         rcx,qword ptr [argv]  
00007FF7E9879C9A  mov         rcx,qword ptr [rcx+rax]  
00007FF7E9879C9E  call        qword ptr [__imp_set_pglocale_pgservice (07FF7E9880520h)]

内存位于07FF7E9880520h

0x00007FF7E9880520  00000001403e1da0   .>@....
0x00007FF7E9880528  0000000000000000  ........
0x00007FF7E9880530  0000000000000000  ........
0x00007FF7E9880538  00007ff7e9875348  HS.é÷...

(注意:从0x00007FF7E9880000到0x00007FF7E9880560的内存包含函数地址,并且mapfile说:0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres可再发行,是动态链接的))

然后在调用qword ptr [__imp_set_pglocale_pgservice(07FF7E9880520h)]

之后

00000001403E1DA0  mov         qword ptr [rsp+18h],rbx  
00000001403E1DA5  push        rdi  
00000001403E1DA6  sub         rsp,0C40h  
00000001403E1DAD  mov         rax,qword ptr [1405F8C60h]  
00000001403E1DB4  xor         rax,rsp  
00000001403E1DB7  mov         qword ptr [rsp+0C30h],rax  
00000001403E1DBF  mov         rbx,rdx  
00000001403E1DC2  mov         rdi,rcx  
00000001403E1DC5  lea         rdx,[140430540h]  
00000001403E1DCC  mov         rcx,rbx  
00000001403E1DCF  call        00000001403F67FA

然后在致电00000001403F67FA

00000001403F67FA  jmp         qword ptr [1403F8998h] (should call C@_04FHBLDJDJ@?1bin?$AA@ libpgport:path.obj [postgres redistributable, which is linked statically]))

1403F8998h处的内存 (此处应用程序与Windows 7不同)

0x00000001403F8998  000000000059e6a2  ¢æY.....
0x00000001403F89A0  000000000059e6ac  ¾Y.....
0x00000001403F89A8  000000000059e6b6  ¶æY.....

(注意:0x00000001403F8998是函数中间的操作码的地址,而不是函数的地址)

00000001403F8998  mov         byte ptr [AC000000000059E6h],al  
00000001403F89A1  out         59h,al  
00000001403F89A3  add         byte ptr [rax],al  
...

内存为000000000059e6a2h

000000000059E69F  ?? ?? 
000000000059E6A0  ?? ?? 
000000000059E6A1  ?? ?? 

然后跳转到000000000059e6a2 =>崩溃

在Windows 7上用于加载库(此处为libpq.dll)的进程监视器详细信息:

[...]
"16:48:40,2946466","pg_repack.exe","7216","Load Image","C:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Image Base: 0x180000000, Image Size: 0x30000"
[...]

Windows 10(此处为libpq.dll)上的进程监视器详细信息(除了库的加载之外,其他所有内容都与Windows 7非常相似)

[...]
"11:52:20,6264717","pg_repack.exe","12464","QueryOpen","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","CreationTime: 21/08/2017 11:38:04, LastAccessTime: 21/08/2017 12:06:56, LastWriteTime: 09/05/2017 06:45:07, ChangeTime: 21/08/2017 18:04:09, AllocationSize: 184 320, EndOfFile: 183 296, FileAttributes: A"
"11:52:20,6265789","pg_repack.exe","12464","CreateFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Desired Access: Read Data/List Directory, Execute/Traverse, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened"
"11:52:20,6266332","pg_repack.exe","12464","QuerySecurityFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Information: 0x20"
"11:52:20,6266513","pg_repack.exe","12464","CreateFileMapping","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","FILE LOCKED WITH ONLY READERS","SyncType: SyncTypeCreateSection, PageProtection: PAGE_EXECUTE"
"11:52:20,6266921","pg_repack.exe","12464","CreateFileMapping","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","SyncType: SyncTypeOther"
"11:52:20,6267619","pg_repack.exe","12464","Load Image","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Image Base: 0x180000000, Image Size: 0x30000"
"11:52:20,6274889","pg_repack.exe","12464","CreateFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened"
"11:52:20,6275293","pg_repack.exe","12464","QuerySecurityFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Information: 0x20"
"11:52:20,6275471","pg_repack.exe","12464","QueryBasicInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","CreationTime: 21/08/2017 11:38:04, LastAccessTime: 21/08/2017 12:06:56, LastWriteTime: 09/05/2017 06:45:07, ChangeTime: 21/08/2017 18:04:09, FileAttributes: A"
"11:52:20,6276255","pg_repack.exe","12464","CloseFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS",""
"11:52:20,6291170","pg_repack.exe","12464","CloseFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS",""
[...]
"11:52:20,6539022","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539202","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539363","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539512","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539664","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6603867","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6604319","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6604778","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6605211","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6605635","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
[...]

注意:我期望与Windows 7类似,或者至少类似于:

"11:52:20,6539022","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Length: 63".

所以我不知道为什么该应用程序在Windows 8或10上具有如此奇怪的行为.如果有人对修复问题有一些解释或想法,我将感到非常满意.如果需要,请随时询问一些细节.

解决方案

我查看您的二进制包,并查看您执行的pg_repack.exe是从postgres.exe静态导入的.和问题的根源-是从exe文件导入.更准确地来自 PE 文件,该文件在 IMAGE_FILE_DLL 会导入).换句话说,它像 strcmp ).

这仅在win10上发生.在win 8.1(内部版本9600)和win 7导入的 exe 文件(作为 dll 加载)上已解决. (您说在win 8.1上它崩溃了-可能是您使用了更多的新版本或某些更新?还是更好地检查了)

从测试 exe 对该行为调用的最简单测试

在win10上崩溃,因为 MatchToken 在内部尝试从msvcrt.dll调用_wcsnicmp,但是在win10中,此导入无法解决.但是在win8.1,win7,win xp上-此代码可以很好地工作.

更复杂的示例:

if (HMODULE hmod = LoadLibraryW(L"wshelper.dll"))
{
    DWORD (WINAPI * InitHelperDll)(_In_ DWORD dwNetshVersion, PVOID pReserved);

    if (*(void**)&InitHelperDll = GetProcAddress(hmod, "InitHelperDll"))
    {
        InitHelperDll(1, 0);// crash here on win10 only
    }
    FreeLibrary(hmod);
}

在这里我们加载标准Windows NetShell帮助程序dll-"wshelper.dll" 并调用 InitHelperDll 调用 RegisterHelper Netsh.exe 的a>函数.但是同样,因为 Netsh.exe 在Win 10中作为DLL加载时未初始化(导入未解析),它在https://github.com/reorg/pg_repack project whose generate a binary. This binary is linked with postgres 9.6 redistributable (I use those delievered by EntrepriseDb). All works fine on windows 7. I have no issue during the build or during the runtime. But on windows 8 or 10, the application always crashs with the following sequences. The binary is generated from C sources with visual studio 2013, on windows 7 (I have tried with a version generated on windows 10 but it doesn't change anythings), on a x64 system, for a x64 application and the optimisation is disabled and it use dynamic base. To be sure that I use the right binaries, I have copy all the redistributable binaries into the folder of my application.

Assembly details on windows 7 (working case) :

Few lines after the main, the application calls the function set_pglocale_pgservice

set_pglocale_pgservice(argv[0], "pgscripts");
00007FF6E4B39C85  mov         eax,8  
00007FF6E4B39C8A  imul        rax,rax,0  
00007FF6E4B39C8E  lea         rdx,[default_options+120h (07FF6E4B43B10h)]  
00007FF6E4B39C95  mov         rcx,qword ptr [argv]  
00007FF6E4B39C9A  mov         rcx,qword ptr [rcx+rax]  
00007FF6E4B39C9E  call        qword ptr [__imp_set_pglocale_pgservice (07FF6E4B40520h)] 

Memory at 07FF6E4B40520h

0x00007FF6E4B40520  00000001403e1da0   .>@....
0x00007FF6E4B40528  0000000000000000  ........
0x00007FF6E4B40530  0000000000000000  ........
0x00007FF6E4B40538  00007ff6e4b35348  HS.äö...

(note : from 0x7FF6E4B40000 to 0x00007FF6E4B40560 memory contains functions addresses, and mapfile says : 0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres redistributable, is linked dynamicly])

Then after the call qword ptr [__imp_set_pglocale_pgservice (07FF6E4B40520h)]

00000001403E1DA0  mov         qword ptr [rsp+18h],rbx  
00000001403E1DA5  push        rdi  
00000001403E1DA6  sub         rsp,0C40h  
00000001403E1DAD  mov         rax,qword ptr [1405F8C60h]  
00000001403E1DB4  xor         rax,rsp  
00000001403E1DB7  mov         qword ptr [rsp+0C30h],rax  
00000001403E1DBF  mov         rbx,rdx  
00000001403E1DC2  mov         rdi,rcx  
00000001403E1DC5  lea         rdx,[140430540h]  
00000001403E1DCC  mov         rcx,rbx  
00000001403E1DCF  call        00000001403F67FA

Then after the call 00000001403F67FA

00000001403F67FA  jmp         qword ptr [1403F8998h]

Memory at 1403F8998h

0x00000001403F8998  00007ffe87a5cc60  `Ì¥.þ...
0x00000001403F89A0  00007ffe87a47060  `p¤.þ...
0x00000001403F89A8  00007ffe87a5f8a4  ¤ø¥.þ...

(note : from 0x00000001403F8000 to 0x00000001403F8F08 memory contains functions address, and mapfile says : 0002:00000998 ??_C@_04FHBLDJDJ@?1bin?$AA@ libpgport:path.obj [postgres redistributable, is linked statically])

Then after the jump to 00007ffe87a5cc60

00007FFE87A5CC60  sub         rdx,rcx  
00007FFE87A5CC63  test        cl,7  
00007FFE87A5CC66  je          00007FFE87A5CC7C 

... and all works fine

Assembly details on windows 10 (not working case) :

Few line after the main, the application calls the funciton set_pglocale_pgservice

set_pglocale_pgservice(argv[0], "pgscripts");
00007FF7E9879C85  mov         eax,8  
00007FF7E9879C8A  imul        rax,rax,0  
00007FF7E9879C8E  lea         rdx,[default_options+120h (07FF7E9883B10h)]  
00007FF7E9879C95  mov         rcx,qword ptr [argv]  
00007FF7E9879C9A  mov         rcx,qword ptr [rcx+rax]  
00007FF7E9879C9E  call        qword ptr [__imp_set_pglocale_pgservice (07FF7E9880520h)]

Memory at 07FF7E9880520h

0x00007FF7E9880520  00000001403e1da0   .>@....
0x00007FF7E9880528  0000000000000000  ........
0x00007FF7E9880530  0000000000000000  ........
0x00007FF7E9880538  00007ff7e9875348  HS.é÷...

(note : from 0x00007FF7E9880000 to 0x00007FF7E9880560 memory contains functions address, and mapfile says : 0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres redistributable, is linked dynamicly])

Then after the call qword ptr [__imp_set_pglocale_pgservice (07FF7E9880520h)]

00000001403E1DA0  mov         qword ptr [rsp+18h],rbx  
00000001403E1DA5  push        rdi  
00000001403E1DA6  sub         rsp,0C40h  
00000001403E1DAD  mov         rax,qword ptr [1405F8C60h]  
00000001403E1DB4  xor         rax,rsp  
00000001403E1DB7  mov         qword ptr [rsp+0C30h],rax  
00000001403E1DBF  mov         rbx,rdx  
00000001403E1DC2  mov         rdi,rcx  
00000001403E1DC5  lea         rdx,[140430540h]  
00000001403E1DCC  mov         rcx,rbx  
00000001403E1DCF  call        00000001403F67FA

Then after the call 00000001403F67FA

00000001403F67FA  jmp         qword ptr [1403F8998h] (should call C@_04FHBLDJDJ@?1bin?$AA@ libpgport:path.obj [postgres redistributable, which is linked statically]))

Memory at 1403F8998h (here the application diverges from windows 7)

0x00000001403F8998  000000000059e6a2  ¢æY.....
0x00000001403F89A0  000000000059e6ac  ¾Y.....
0x00000001403F89A8  000000000059e6b6  ¶æY.....

(note : 0x00000001403F8998 is the address of op code in the middle of the function, not the address of a function)

00000001403F8998  mov         byte ptr [AC000000000059E6h],al  
00000001403F89A1  out         59h,al  
00000001403F89A3  add         byte ptr [rax],al  
...

Memory at 000000000059e6a2h

000000000059E69F  ?? ?? 
000000000059E6A0  ?? ?? 
000000000059E6A1  ?? ?? 

Then after the jump to 000000000059e6a2 => crash

Process monitor details on windows 7 for the loading of libraries (here libpq.dll):

[...]
"16:48:40,2946466","pg_repack.exe","7216","Load Image","C:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Image Base: 0x180000000, Image Size: 0x30000"
[...]

Process monitor details on windows 10 (here libpq.dll) (all is very similar to windows 7, except for the loading of libraries)

[...]
"11:52:20,6264717","pg_repack.exe","12464","QueryOpen","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","CreationTime: 21/08/2017 11:38:04, LastAccessTime: 21/08/2017 12:06:56, LastWriteTime: 09/05/2017 06:45:07, ChangeTime: 21/08/2017 18:04:09, AllocationSize: 184 320, EndOfFile: 183 296, FileAttributes: A"
"11:52:20,6265789","pg_repack.exe","12464","CreateFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Desired Access: Read Data/List Directory, Execute/Traverse, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened"
"11:52:20,6266332","pg_repack.exe","12464","QuerySecurityFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Information: 0x20"
"11:52:20,6266513","pg_repack.exe","12464","CreateFileMapping","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","FILE LOCKED WITH ONLY READERS","SyncType: SyncTypeCreateSection, PageProtection: PAGE_EXECUTE"
"11:52:20,6266921","pg_repack.exe","12464","CreateFileMapping","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","SyncType: SyncTypeOther"
"11:52:20,6267619","pg_repack.exe","12464","Load Image","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Image Base: 0x180000000, Image Size: 0x30000"
"11:52:20,6274889","pg_repack.exe","12464","CreateFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened"
"11:52:20,6275293","pg_repack.exe","12464","QuerySecurityFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Information: 0x20"
"11:52:20,6275471","pg_repack.exe","12464","QueryBasicInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","CreationTime: 21/08/2017 11:38:04, LastAccessTime: 21/08/2017 12:06:56, LastWriteTime: 09/05/2017 06:45:07, ChangeTime: 21/08/2017 18:04:09, FileAttributes: A"
"11:52:20,6276255","pg_repack.exe","12464","CloseFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS",""
"11:52:20,6291170","pg_repack.exe","12464","CloseFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS",""
[...]
"11:52:20,6539022","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539202","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539363","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539512","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6539664","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Name: \testF"
"11:52:20,6603867","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6604319","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6604778","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6605211","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
"11:52:20,6605635","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","SUCCESS","Name: \testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll"
[...]

Note : I was expecting something similar to windows 7 or at least something like :

"11:52:20,6539022","pg_repack.exe","12464","QueryNameInformationFile","B:\testFolder\pg_repack-master\msvc\bin\x64\Debug\libpq.dll","BUFFER OVERFLOW","Length: 63".

So I have no clue why this application has a so stranges behaviors on windows 8 or 10. I will be greatfull if someone would have some explainations or ideas in order to fix crashes. Don't hesitate to ask some details if needed.

解决方案

i look your binary package and view that you exec pg_repack.exe which statically import from postgres.exe. and root of problem - is import from exe file. more exactly from PE file which have not flag IMAGE_FILE_DLL in IMAGE_FILE_HEADER.Characteristics , because formal extension (exe, dll, etc not play role). for short i will in next under exe mean PE file without IMAGE_FILE_DLL in Characteristics, but not formal file extension

at first load exe as dll is incorrect - when exe loaded this way - it entry point not called. and can not be called, because it not designed be called as callback, receiving DLL_PROCESS_* notification, and call ExitProcess at the end. when entry point of module is not called - in general it not initialized. assume you call some exported function from exe, but what if this exported function use some data, which normally initialized in exe entry point ? so conclusion - we can call exported functions from exe only from dll loaded in this exe process. and in every process must be only one exe (as executable code).

at second specific postgres.exe have no relocation's ( IMAGE_FILE_RELOCS_STRIPPED flag in IMAGE_FILE_HEADER.Characteristics) - as result this PE can be loaded only at hard-coded address. this not problem for exe, which always mapped first to process, when almost all address space is free. but this in general is problem when PE loaded as DLL - not first in process - the hard-code imagebase can be already busy. so conclusion - you can not safe use any exe without relocation's as DLL

however the root of crash on windows 10 - because windows 10 not resolve PE ("exe") import if this pe have no flag IMAGE_FILE_DLL. in other words it process this PE like LoadLibraryEx with flag DONT_RESOLVE_DLL_REFERENCES - does not load additional executable modules that are referenced by the specified module and nor resolve imports. as result this PE not initialized and will crash at first import function call (in your case this is strcmp).

and this is happens only on win10. on win 8.1 (build 9600) and win 7 import for exe files (loaded as dll) resolved. (you say that on your win 8.1 it crashed - may be you use more new build or some update ? or better check)

the simplest test for this behavior call from test exe MatchToken, function, which exported from Netsh.exe. code can be next:

#include <Netsh.h>
#pragma comment(linker, "/defaultlib:Netsh.lib")

MatchToken(L"*", L"*");// crash here on win 10

crash on win10 because MatchToken internally try call _wcsnicmp from msvcrt.dll, but in win10 this import not resolved. but on win8.1, win7, win xp - this code work well.

little more complex example:

if (HMODULE hmod = LoadLibraryW(L"wshelper.dll"))
{
    DWORD (WINAPI * InitHelperDll)(_In_ DWORD dwNetshVersion, PVOID pReserved);

    if (*(void**)&InitHelperDll = GetProcAddress(hmod, "InitHelperDll"))
    {
        InitHelperDll(1, 0);// crash here on win10 only
    }
    FreeLibrary(hmod);
}

here we load standard windows NetShell helper dll - "wshelper.dll" and call InitHelperDll callback function. internally InitHelperDll call the RegisterHelper function from Netsh.exe. but again, because Netsh.exe not initialized (import not resolved) when it loades as DLL in win 10 - it crashed inside RegisterHelper

这篇关于每次在Windows 8/10而不是7上每次都会调用静态链接函数崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆