[Bug 33236] Multiple application virtualization schemes rely on LdrLoadDll to behave like native Windows loader w.r.t. use of NtXXXSectionAPI (VMWare ThinApp 4.x)

WineHQ Bugzilla wine-bugs at winehq.org
Mon Oct 26 05:25:18 CDT 2020


https://bugs.winehq.org/show_bug.cgi?id=33236

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Multiple application        |Multiple application
                   |virtualization schemes rely |virtualization schemes rely
                   |on LdrLoadDll to behave     |on LdrLoadDll to behave
                   |like native Windows loader  |like native Windows loader
                   |(NtOpenFile, NtXXXSection)  |w.r.t. use of
                   |(VMWare ThinApp 4.x,        |NtXXXSectionAPI (VMWare
                   |BoxedApp)                   |ThinApp 4.x)
                URL|https://archive.org/details |https://web.archive.org/web
                   |/boxedappsdk__demo__3_3_5_7 |/20200503205120/https://fil
                   |                            |es.downloadnow.com/s/softwa
                   |                            |re/12/86/09/39/Bible_Conver
                   |                            |ter_v2.3.exe?token=15885750
                   |                            |54_eaedbdae9ef08c617743d400
                   |                            |590e2e97&fileName=Bible_Con
                   |                            |verter_v2.3.exe

--- Comment #9 from Anastasius Focht <focht at gmx.net> ---
Hello Paul,

--- quote ---
I suppose this should be fixed, at least in general, in the current Wine. In
case some issues are remaining they probably deserve more specific bugs.
--- quote ---

no, I've checked some VMWare ThinApp 4.x wrapped apps - they don't work. This
includes 'Simple_Bible_Reader_v2.3.exe' this bug was initially created for.
Wine's loader still doesn't match the needed native API callouts/sequences of
Windows loader to have this work.

The BoxedApp 'Sample1_DLLEmbedding' example from comment #6 works now - but
that's due to a different reason. I mixed that in here which was a mistake. I
will rework meta-bug #22797 to make it useful.

--- snip ---
...
0270:Call ntdll.LdrLoadDll(00000000,00000000,7fda4218,0031ec2c) ret=7fd903c3
0270:Ret  ntdll.LdrLoadDll() retval=c0000135 ret=7fd903c3
0270:Call
ntdll.NtRaiseHardError(40000015,00000001,00000001,0031e420,00000000,0031e414)
ret=7fd8c895
0270:fixme:ntdll:NtRaiseHardError 40000015 stub
0270:Ret  ntdll.NtRaiseHardError() retval=c0000002 ret=7fd8c895
0270:Call ntdll.NtTerminateProcess(ffffffff,c0000001) ret=7fd8c8bf
--- snip ---

--- snip ---
...
7FD91B66 | mov ecx,esi                    |
7FD91B68 | call 7FD903B0                  | LdrLoadDll "nt0_dll.dll"
7FD91B6D | mov esi,eax                    | 0xc0000135
7FD91B6F | test esi,esi                   |
7FD91B71 | jge 7FD91B9B                   |
7FD91B73 | push 0                         |
7FD91B75 | push 1EF                       |
7FD91B7A | push 7FDA5B48                  | "..\\nt0_lib\\Runtime2.cpp"
7FD91B7F | call 7FD8C6C0                  | NtRaiseHardError()
7FD91B84 | add esp,C                      |
7FD91B87 | mov dword ptr ss:[esp+280],ebp |
7FD91B8E | lea ecx,dword ptr ss:[esp+14]  |
7FD91B92 | call 7FD87A20                  |
7FD91B97 | mov eax,esi                    |
7FD91B99 | jmp 7FD91BAD                   |
7FD91B9B | mov dword ptr ss:[esp+280],ebp |
7FD91BA2 | lea ecx,dword ptr ss:[esp+14]  |
7FD91BA6 | call 7FD87A20                  |
...
7FD903B0 | push ecx                       |
7FD903B1 | lea eax,dword ptr ss:[esp]     |
7FD903B4 | push eax                       |
7FD903B5 | push 7FDA4218                  |
7FD903BA | push 0                         |
7FD903BC | push 0                         |
7FD903BE | call <JMP.&LdrLoadDll>         |
7FD903C3 | pop ecx                        |
7FD903C4 | ret                            |
...
--- snip ---

ThinApp native API runtime/wrapper hooks only very few native API/syscalls in
Wine at this point and expects them to be called:

--- snip ---
...
<ntdll.NtClose>
7BC0B8D0 | E9 2B7E1804   | jmp 7FD93700             |
7BC0B8D5 | BA 80C5C07B   | mov edx,ntdll.7BC0C580   |
7BC0B8DA | FFD2          | call edx                 |
7BC0B8DC | C2 0400       | ret 4                    |
...
<ntdll.ZwMapViewOfSection>
7BC0BC80 | E9 6B7D1804   | jmp 7FD939F0             |
7BC0BC85 | BA 80C5C07B   | mov edx,ntdll.7BC0C580   |
7BC0BC8A | FFD2          | call edx                 |
7BC0BC8C | C2 2800       | ret 28                   |
...
<ntdll.NtOpenSection>
7BC0BDA0 | E9 CB7D1804   | jmp 7FD93B70             |
7BC0BDA5 | BA 80C5C07B   | mov edx,ntdll.7BC0C580   |
7BC0BDAA | FFD2          | call edx                 |
7BC0BDAC | C2 0C00       | ret C                    |
...
<ntdll.NtQuerySection>
7BC0BFB0 | E9 FB7D1804   | jmp 7FD93DB0             |
7BC0BFB5 | BA 80C5C07B   | mov edx,ntdll.7BC0C580   |
7BC0BFBA | FFD2          | call edx                 |
7BC0BFBC | C2 1400       | ret 14                   |
...
<ntdll.NtUnmapViewOfSection>
7BC0C440 | E9 CB7C1804   | jmp 7FD94110             |
7BC0C445 | BA 80C5C07B   | mov edx,ntdll.7BC0C580   |
7BC0C44A | FFD2          | call edx                 |
7BC0C44C | C2 0800       | ret 8                    |
...
--- snip ---

There are few more hooks but they are not relevant here (yet).

I've already provided the needed information in my comment #5 from 2013.

https://web.archive.org/web/20200730075037/https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/march/windows-2000-loader-what-goes-on-inside-windows-2000-solving-the-mysteries-of-the-loader

--- quote ---
LdrpCheckForKnownDll allocates two Unicode strings to hold the fully qualified
DLL file name and the file name by itself. By calling NtOpenSection with the
fully qualified file name, a FileExists operation is performed and
LdrpCheckForKnownDll returns a section handle if the DLL is known. Otherwise,
the two Unicode strings are freed and LdrpMapDll must call on the services of
LdrpResolveDllName and LdrpCreateDllSection.
--- quote ---

There is a lot more useful information in this article but this is the first
blocker.

https://source.winehq.org/git/wine.git/blob/6373792eec0f122295723cae77b0115e6c96c3e4:/dlls/ntdll/loader.c#l2217

--- snip ---
2222 static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm,
void **module,
2223                                SECTION_IMAGE_INFORMATION *image_info,
struct file_id *id )
2224 {
2225     FILE_BASIC_INFORMATION info;
2226     OBJECT_ATTRIBUTES attr;
2227     IO_STATUS_BLOCK io;
2228     LARGE_INTEGER size;
2229     FILE_OBJECTID_BUFFER fid;
2230     SIZE_T len = 0;
2231     NTSTATUS status;
2232     HANDLE handle, mapping;
2233 
2234     if ((*pwm = find_fullname_module( nt_name )))
2235     {
2236         NtUnmapViewOfSection( NtCurrentProcess(), *module );
2237         *module = NULL;
2238         return STATUS_SUCCESS;
2239     }
2240 
2241     attr.Length = sizeof(attr);
2242     attr.RootDirectory = 0;
2243     attr.Attributes = OBJ_CASE_INSENSITIVE;
2244     attr.ObjectName = nt_name;
2245     attr.SecurityDescriptor = NULL;
2246     attr.SecurityQualityOfService = NULL;
2247     if ((status = NtOpenFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr,
&io,
2248                               FILE_SHARE_READ | FILE_SHARE_DELETE,
2249                               FILE_SYNCHRONOUS_IO_NONALERT |
FILE_NON_DIRECTORY_FILE )))
2250     {
2251         if (status != STATUS_OBJECT_PATH_NOT_FOUND &&
2252             status != STATUS_OBJECT_NAME_NOT_FOUND &&
2253             !NtQueryAttributesFile( &attr, &info ))
2254         {
2255             /* if the file exists but failed to open, report the error */
2256             return status;
2257         }
2258         /* otherwise continue searching */
2259         return STATUS_DLL_NOT_FOUND;
2260     }
...
--- snip ---

ThinApp 4.x doesn't hook NtOpenFile() - Wine's equivalent for the "FileExists
operation" mentioned in the article, hence it bails early for "special" dlls.
It uses the hooked section API to map "special" dlls from/to memory.

$ wine --version
wine-5.20

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list