问题 :
我已经构建了生成二进制文件的https://github.com/reorg/pg_repack项目。这个二进制文件与 postgres 9.6 redistributable 相关联(我使用那些由 EntrepriseDb 提供的)。在 Windows 7 上一切正常。在构建期间或运行时我没有问题。但在 Windows 8 或 10 上,应用程序总是会按照以下顺序崩溃。该二进制文件是在 Windows 7 上使用 Visual Studio 2013 从 C 源生成的(我尝试过在 Windows 10 上生成的版本,但它没有改变任何东西),在 x64 系统上,用于 x64 应用程序,优化被禁用和它使用动态基础。为了确保使用正确的二进制文件,我已将所有可再发行二进制文件复制到我的应用程序文件夹中。
Windows 7 上的装配细节(工作案例):
在 main 之后的几行,应用程序调用了函数 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 内存包含函数地址,mapfile 显示:0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres 可再发行,动态链接])
然后调用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 内存包含函数地址,mapfile 显示:0002:00000998 ??_C@_04FHBLDJDJ@?1bin?$AA@ libpgport:path.obj [postgres 可再发行,静态链接])
然后跳转到 00007ffe87a5cc60 之后
00007FFE87A5CC60 sub rdx,rcx
00007FFE87A5CC63 test cl,7
00007FFE87A5CC66 je 00007FFE87A5CC7C
...一切正常
Windows 10 上的装配细节(非工作案例):
在 main 之后的几行,应用程序调用了函数 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 上有如此奇怪的行为。如果有人有一些解释或想法来修复崩溃,我会很高兴的。如果需要,请不要犹豫,询问一些细节。