assembly - Call of statically link function crash everytimes on windows 8/10 but not 7 -
the issue :
i have build https://github.com/reorg/pg_repack project generate binary. binary linked postgres 9.6 redistributable (i use delievered entreprisedb). works fine on windows 7. have no issue during build or during runtime. on windows 8 or 10, application crashs following sequences. binary generated c sources visual studio 2013, on windows 7 (i have tried version generated on windows 10 doesn't change anythings), on x64 system, x64 application , optimisation disabled , use dynamic base. sure use right binaries, have copy redistributable binaries folder of application.
assembly details on windows 7 (working case) :
few lines after main, application calls 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 @ 07ff6e4b40520h
0x00007ff6e4b40520 00000001403e1da0 .>@.... 0x00007ff6e4b40528 0000000000000000 ........ 0x00007ff6e4b40530 0000000000000000 ........ 0x00007ff6e4b40538 00007ff6e4b35348 hs.äö...
(note : 0x7ff6e4b40000 0x00007ff6e4b40560 memory contains functions addresses, , mapfile says : 0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres redistributable, linked dynamicly])
then after 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 call 00000001403f67fa
00000001403f67fa jmp qword ptr [1403f8998h]
memory @ 1403f8998h
0x00000001403f8998 00007ffe87a5cc60 `Ì¥.þ... 0x00000001403f89a0 00007ffe87a47060 `p¤.þ... 0x00000001403f89a8 00007ffe87a5f8a4 ¤ø¥.þ...
(note : 0x00000001403f8000 0x00000001403f8f08 memory contains functions address, , mapfile says : 0002:00000998 ??_c@_04fhbldjdj@?1bin?$aa@ libpgport:path.obj [postgres redistributable, linked statically])
then after jump 00007ffe87a5cc60
00007ffe87a5cc60 sub rdx,rcx 00007ffe87a5cc63 test cl,7 00007ffe87a5cc66 je 00007ffe87a5cc7c
... , works fine
assembly details on windows 10 (not working case) :
few line after main, application calls 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 @ 07ff7e9880520h
0x00007ff7e9880520 00000001403e1da0 .>@.... 0x00007ff7e9880528 0000000000000000 ........ 0x00007ff7e9880530 0000000000000000 ........ 0x00007ff7e9880538 00007ff7e9875348 hs.é÷...
(note : 0x00007ff7e9880000 0x00007ff7e9880560 memory contains functions address, , mapfile says : 0002:00000520 __imp_set_pglocale_pgservice postgres:postgres.exe [postgres redistributable, linked dynamicly])
then after 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 call 00000001403f67fa
00000001403f67fa jmp qword ptr [1403f8998h] (should call c@_04fhbldjdj@?1bin?$aa@ libpgport:path.obj [postgres redistributable, linked statically]))
memory @ 1403f8998h (here application diverges windows 7)
0x00000001403f8998 000000000059e6a2 ¢æy..... 0x00000001403f89a0 000000000059e6ac ¬æy..... 0x00000001403f89a8 000000000059e6b6 ¶æy.....
(note : 0x00000001403f8998 address of op code in middle of function, not address of function)
00000001403f8998 mov byte ptr [ac000000000059e6h],al 00000001403f89a1 out 59h,al 00000001403f89a3 add byte ptr [rax],al ...
memory @ 000000000059e6a2h
000000000059e69f ?? ?? 000000000059e6a0 ?? ?? 000000000059e6a1 ?? ??
then after jump 000000000059e6a2 => crash
process monitor details on windows 7 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 similar windows 7, except 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 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 : expecting similar windows 7 or @ least :
"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 have no clue why application has stranges behaviors on windows 8 or 10. greatfull if have explainations or ideas in order fix crashes. don't hesitate ask details if needed.
i binary package , view exec pg_repack.exe
statically import postgres.exe
. , root of problem - import exe file. more pe file have not flag image_file_dll
in image_file_header
.characteristics
, because formal extension (exe, dll, etc not play role). short in next under exe mean pe file without image_file_dll
in characteristics
, not formal file extension
at first load exe dll incorrect - when exe loaded way - entry point not called. , can not called, because not designed called callback, receiving dll_process_*
notification, , call exitprocess
@ end. when entry point of module not called - in general not initialized. assume call exported function exe, if exported function use data, initialized in exe entry point ? conclusion - can call exported functions exe dll loaded in exe process. , in every process must 1 exe (as executable code).
at second specific postgres.exe
have no relocation's ( image_file_relocs_stripped
flag in image_file_header.characteristics
) - result pe can loaded @ hard-coded address. not problem exe, mapped first process, when address space free. in general problem when pe loaded dll - not first in process - hard-code imagebase can busy. conclusion - can not safe use exe without relocation's dll
however root of crash on windows 10 - because windows 10 not resolve pe ("exe") import if pe have no flag image_file_dll
. in other words process pe loadlibraryex
flag dont_resolve_dll_references
- not load additional executable modules referenced specified module , nor resolve imports. result pe not initialized , crash @ first import function call (in case strcmp
).
and happens on win10. on win 8.1 (build 9600) , win 7 import exe files (loaded dll) resolved. (you on win 8.1 crashed - may use more new build or update ? or better check)
the simplest test behavior call test exe matchtoken
, function, exported netsh.exe
. code can 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
msvcrt.dll
, in win10 import not resolved. on win8.1, win7, win xp - 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 } freelibrary(hmod); }
here load standard windows netshell helper dll - "wshelper.dll" , call inithelperdll
callback function. internally inithelperdll
call registerhelper
function netsh.exe. again, because netsh.exe not initialized (import not resolved) when loades dll in win 10 - crashed inside registerhelper
wiki
Comments
Post a Comment