The MASM Forum

General => The Campus => Topic started by: guga on April 13, 2020, 05:33:37 AM

Title: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 13, 2020, 05:33:37 AM
Hi Guys

I faced a very very weird behavior in Windows 10. Has someone found a deadlock on LoadLibrary Api ? I never saw that before.

While i was trying to understand how ffmpeg works and making a small app to convert mkv files to hls, i found a weird behaviour inside LoadLibrayExW function. (Also in LoadLibrary api, since it calls internally to LoadLibrayExW).

This is what happened.

I was assembling a api call (with rosasm) to ffmped dll like this:
call 'avformat-58.av_register_all'

It is a simple call to avformat-58 dll from ffmpeg library. The av_register_all function does not uses any parameter (it´s a void function)

At some point, while it is assembling this dll, rosasm entered on a deadlock inside avformat-58 dll.  During assemblement, in order to find the handle of certain dlls to get their import address and functions etc, Rosasm uses a call to LoadLibraryA Api.


Analyzing from my debugger it simply does this:

call 'kernel32.LoadLibraryA' { B$ "c:\guga\avformat-58.dll", 0}

The problem is that, once LoadLibrary is called, it never returns.  The debbuger shows me that, internally immediatelly before it exits the call to avformat-58, it don´t returns to the caller in "call 'kernel32.LoadLibraryA' " from RosAsm.exe.
Instead, somehow the esp seems to be exchanged and it ends on returning to a crypt.dll (or something).


I was a bit surprised of that behavior and gave another test. This time, i tested with a naked file containing only the call to LoadLibrary, rather then a full App. I created a simple file to test and it assembled ok. Like this:

Main:
         call 'kernel32.LoadLibraryA' { B$ "c:\guga\avformat-58.dll", 0}
ret


At 1st i thought it may be a problem somewhere inside RosAsm assemblement functions that maybe where causing a incorrect stack pointer, but then i gave another test.

This time, i tried (on the full app), a call to loadlibraryExA using different flags, such as: LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE, DONT_RESOLVE_DLL_REFERENCES etc.

Everytime the function entered on a deadlock, except when using DONT_RESOLVE_DLL_REFERENCES equate. (Which is the only one that fixes somehow the deadlock internally and exits the function to the proper caller)

So, i realised that it was not a problem inside RosAsm functions, because they uses the same amount of parameters to call this api. So it must be something happening internally LoadLibraryEx.

The same error happens when i simply use NULL and 0 as the parameters of loadlibraryEx (Which is the default/internal behaviour of LoadLibrary api). Ex:
     call 'KERNEL32.LoadLibraryExA' edi, &NULL, 0



To try to fix and chase the bug, i ended rebuilding the LoadLibrary and LoadLibraryEx Api, like this:

My version of LoadLibrary Api (in windos10. Should also work for other Windows versions as well). Btw, i didn´t tested it yet for twain_32.dll, but it may works, since this is exactly as how it is built in windows10)


Proc LoadLibraryA:
    Arguments @lpLibFileName
    Structure @TwainBufferString 260, @TwainBufferString.DataDis 0
    Uses ecx, edx, esi
   
    mov esi D@lpLibFileName
    ...If esi <> 0

        call stricmp esi, {B$ "twain_32.dll", 0}
        ..If eax = 0
            mov esi D@TwainBufferString
            call 'kernel32.GetWindowsDirectoryA' esi, 247
            .If_And eax > 0, eax < 247
                C_call 'msvcrt.strncat_s' esi, 260, {B$ "\twain_32.dll", 0}, 13
            .End_If
        ..End_If


    ...End_If
    call LoadLibraryExA esi, &NULL, 0

EndP


And LoadLibraryExA Api i rebuilt it like this:

;;

UNICODE_STRING structure

[UNICODE_STRING:
UNICODE_STRING.Lenght: W$ 0
UNICODE_STRING.MaximumLenght: W$ 0
UNICODE_STRING.Buffer: D$ 0] ; Pointer to a Unicode string

[ANSI_STRING:
ANSI_STRING.Lenght: W$ 0
ANSI_STRING.MaximumLenght: W$ 0
ANSI_STRING.Buffer: D$ 0] ; Pointer to a Ansi string

;;

Proc LoadLibraryExA:
    Arguments @lpLibFileName, @hFile, @dwFlags
    Structure @UnicodeString 8, @UnicodeString.LenghtDis 0, @UnicodeString.MaximumLenghtDis 2, @UnicodeString.BufferDis 4
    Uses ecx, edx, esi

    call Basep8BitStringToDynamicUnicodeString D@UnicodeString, D@lpLibFileName
    If eax <> 0
        call 'KERNEL32.LoadLibraryExW' D@UnicodeString.BufferDis, D@hFile, D@dwFlags
        mov esi eax
        call 'ntdll.RtlFreeUnicodeString' D@UnicodeString
        mov eax esi
    End_If

EndP


And the Basep8BitStringToDynamicUnicodeString function is like:

[UNICODE_STRING.LenghtDis 0
UNICODE_STRING.MaximumLenghtDis 2
UNICODE_STRING.BufferDis 4]

[Size_of_UNICODE_STRING 8]

; This function exists in Kernelbase.dll in windows 10

Proc Basep8BitStringToDynamicUnicodeString:
    Arguments @DestinationString, @SourceString
    Structure @AnsiString 8, @AnsiString.LenghtDis 0, @AnsiString.MaximumLenghtDis 2, @AnsiString.BufferDis 4
    Uses ecx, edx

    call RtlInitAnsiStringEx D@AnsiString, D@SourceString
    .If eax <> &STATUS_SUCCESS
        call 'ntdll.RtlSetLastWin32Error' &ERROR_FILENAME_EXCED_RANGE
        xor eax eax
    .Else
        call 'ntdll.RtlAnsiStringToUnicodeString' D@DestinationString, D@AnsiString, &TRUE
        .If eax = &STATUS_SUCCESS
            mov eax &TRUE
        .Else
            If eax = &STATUS_BUFFER_OVERFLOW
                call 'ntdll.RtlSetLastWin32Error' &ERROR_FILENAME_EXCED_RANGE
            Else
                call BaseSetLastNTError eax
            End_If
            xor eax eax
        .End_If
    .End_If

EndP

;;
       RtlInitAnsiStringEx   (NTDLL.@)

  Initializes a buffered ansi string.

Arguuments
    Source - Pointer to a Ansi string
    Target - Pointer to a UNICODE_STRING structure

  RETURNS
   An appropriate NTSTATUS value.

  NOTES
   Assigns source to target->Buffer. The length of source is assigned to
   target->Length and target->MaximumLength. If source is NULL the length of source is assumed to be 0.

reference:
https://stuff.mit.edu/afs/sipb/project/wine/src/wine-0.9.37/dlls/ntdll/rtlstr.c
;;

[ANSI_STRING.LenghtDis 0
ANSI_STRING.MaximumLenghtDis 2
ANSI_STRING.BufferDis 4]

[Size_of_ANSI_STRING 8]

Proc RtlInitAnsiStringEx:
    Arguments @Target, @Source
    Uses ecx, edx

    mov edx D@Target
    mov ecx D@Source

    mov W$edx+ANSI_STRING.LenghtDis 0
    mov W$edx+ANSI_STRING.MaximumLenghtDis 0
    mov D$edx+ANSI_STRING.BufferDis ecx

    ...If ecx = 0
        mov eax &STATUS_SUCCESS
    ...Else
        ;lea esi D$ecx+1
        call StrLenProc D@Source
        If eax <= 0FFFE
            mov W$edx+ANSI_STRING.LenghtDis ax
            inc eax
            mov W$edx+ANSI_STRING.MaximumLenghtDis ax
            mov eax &STATUS_SUCCESS
        Else
            mov eax &STATUS_NAME_TOO_LONG
        End_If

    ...End_If

EndP

Proc BaseSetLastNTError:
    Arguments @Status
    Uses esi, ecx, edx

    call 'ntdll.RtlNtStatusToDosError' D@Status
    mov esi eax
    call 'ntdll.RtlSetLastWin32Error' eax
    mov eax esi

EndP




So far so good. My version of LoadLibrary and LoadLibraryEx Api worked fine....untill....i made the same test on that damn avformat-58 library. And the deadlock showed up again.

Tracing my funcion on the debugger i found that the deadlock was being caused by LoadLibraryExW Api which is called inside my LoadLibraryExA or the default windows one.



How to fix that stuff ???? Someone ever foudn anything like that before ?  I would like to know if someone has any clue how to fix it, because i don´t want to rebuild completelly the LoadLibraryExW Api for something that maybe fixed more easily, and neither i know if it could also works even if i decided to rebuiild this api.



References:
I´m not sure, but a similar problem i found here
https://en.programqa.com/question/11933212/
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 13, 2020, 04:35:25 PM
LoadLibrary works fine, it is used billions of times every day by millions of people in this planet.

First, you can learn about its limitations by reading the documentation "The DLL entry-point function (aka DllMain) should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order.
Second, you must also guarantee that all avformat-58 dependent DLLs can be loaded by avformat-58 itself.
Finally, you can use this confinement period to learn MASM because nobody really uses or is interested in using Rosasm. You can market it 24 hours a day like others do with their own pseudo MASM combos but results will not improve at all.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 13, 2020, 08:05:23 PM
QuoteLoadLibrary works fine, it is used billions of times every day by millions of people in this planet.
Yeah, i already thought that way, untill i faced this deadlock issue inside LoadLibrary. People using the api billions of times is something that really don´t bother me. What bothers me is when i face some bug like this. Btw, me and a lot of people who eventually face a problem like this.

About Dllmain, i have no idea what is inside the dllmain of avformat-58.dll. Since it was written with Mingw, most likely it do contains complex initialization data inside the dll entrypoint. It also may contains some apis used in CRYPT32.dll since this is where the LoadLibrary api is stuck while debugging. Therefore, i have no control on this ffmpeg dll. I can´t modify it or rewrite it.

I could, however use the executable version of that ffmpeg library which also contains exported functions that i´l test eventually, but the point is, if loadlibrary is not returning from whatever reason inside the avformat-58 dll, then there´s nothing to stop others dls to behave the same way.

So, it most likely a bug (a very rare one) inside windows loadlibrary api that i´m trying to find a way to fix without being forced to make a full rewrite of MS api or keeping using DONT_RESOLVE_DLL_REFERENCES in whatever dll i´m feeding in RosAsm. Specially because DONT_RESOLVE_DLL_REFERENCES is flawed (even M$ discourage it´s usage)
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa
https://devblogs.microsoft.com/oldnewthing/20050214-00/?p=36463
https://stackoverflow.com/questions/16620982/load-dll-without-execute-dllmain-function

QuoteSecond, you must also guarantee that all avformat-58 dependent DLLs can be loaded by avformat-58 itself.
I´m not sure what you meant, but all dlls dependent with avformat-58 are in the same directory as him. Also, it do works when i create a small file containing only one call to the api inside avformat-58 using loadlibrary api.  So, if it works for a tiny app there should be no reason why it wouldn´t work on a bigger one, specially because the file is not running while being assembled. All it is doing is call loadlibrary api to get the proper handle of the functions.

So, it works on a small file, but a bigger one, it fails miserably without any apparent reason.

QuoteFinally, you can use this confinement period to learn MASM because nobody really uses or is interested in using Rosasm. You can market it 24 hours a day like others do with their own pseudo MASM combos but results will not improve at all.

Well...sorry, but don´t. You really didn´t deserved an answer for that, but....well...ok then.

I don´t use masm on a regular daily basis although i do worked with it back in the 90´s when i met here excellent people from which i feel free to call them as friends despite never actually met, guys like Steve, Iczelion, Edgar, Jonchen, Gunther, DayDreamer, Betov, Randall, Seikmanski, Wayne, EWayne, Sven,  etc etc. And yes...i´m the co-author and main maintainer of RosAsm since ages.

No, RosAsm is not a pseudo Masm combo or style or what ever. It don´t even uses any masm files. The style is more similar to Nasm but it is a different assembler as Fasm, Tasm, Nasm, GoAsm.

No, i don´t have plans now to 'market" RosAsm in any extent. If i did i would certainly have done it almost 20 years ago, right ?

Anyway, i´m trying to be polite answering you, even if you don´t deserve it. In decades i have absolutely no problem with anyone around here or in the old forum, and it won´t be the 1st time either.  So, if you woke up out of the bed today, sorry, but i have nothing to do with that.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 13, 2020, 08:12:52 PM
guga,

I don't care what your opinion about me is. I think you are totally wrong.

You appear to be hanging in time-space. When a product is dead, discontinue it, period.
I have done it with many products, even products featured in main stream magazines like PcMagazine. When a product is dead, assume it don't inject it by force. Something from the 90's with no public is to be buried don't keep it like a zombie!
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: jj2007 on April 13, 2020, 08:22:34 PM
Quote from: guga on April 13, 2020, 08:05:23 PMAnyway, i´m trying to be polite answering you, even if you don´t deserve it. In decades i have absolutely no problem with anyone around here or in the old forum, and it won´t be the 1st time either.  So, if you woke up out of the bed today, sorry, but i have nothing to do with that.

Guga, you are a true gentleman :thumbsup:
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 13, 2020, 09:49:25 PM

include \masm32\include\masm32rt.inc


.data
avformat58dll db "avformat-58.dll",0
havformat58dll dd 0

.code

main proc
;int 3
invoke LoadLibrary, offset avformat58dll
mov havformat58dll, eax

ret
main endp

end


I download the ffmpeg stuff to test.
The above does not hang in my Windows 10, so it appears that you have some sort of a priori animosity against Microsoft.
Poor Microsoft is blamed for everyone's own faults.   :sad:

Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 13, 2020, 10:17:14 PM
As i said, a single call does not showed me the error. It happened when i was assembling this dll and others as well.

(https://i.ibb.co/xzd1VWn/test-Image2.jpg) (https://ibb.co/xzd1VWn)


And this image below shows the same file assembling without any error (Only is ok, when i use DONT_RESOLVE_DLL_REFERENCES btw)

(https://i.ibb.co/fNyzK7Y/test-Image1.jpg) (https://ibb.co/fNyzK7Y)

QuoteThe above does not hang in my Windows 10, so it appears that you have some sort of a priori animosity against Microsoft.

At some extent, well....Who doesn´t ? :biggrin: :biggrin: :biggrin: :biggrin: :biggrin: :biggrin: :biggrin:
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 13, 2020, 10:57:58 PM
Guga,

It may be useful to disassemble the DLL to see if it does something unusual at its entry point, the nominal DLLMAIN. The problems you are having seem unusual as DLLs are very well understood in 32 bit. Normally with LoadLibrary() you test its return value to see if you get a valid handle then you check is the the next call to GetProcAddress() and again test the return value to ensure the procedure exists.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 13, 2020, 11:16:20 PM
Hi Steve


I did that a couple of hours ago and the DllMain is huge. It has several calls to some windows Apis and other functions used by the avformat-58 and  seems to have also others that call to more dlls  dependent to it. I really don´t know what was the mess that was being done with that dll. All i can see is that somehow it breaks loadlibrary badly and this is what i´m trying to figure it out how to fix without needing to rebuild LoadLibraryEx completely from scratch  :sad: .

(https://i.ibb.co/7ChR1Rb/ggsg-Image4.jpg) (https://ibb.co/7ChR1Rb)

QuoteNormally with LoadLibrary() you test its return value to see if you get a valid handle then you check..

Yes   :smiley: The problem is that LoadLibrary is not returning somehow. It is stuck inside another dll called by this damn ffmpeg library. While i was debugging loadlibrary i saw that before it returns, the value at eax had the proper handle, but once it reached the "ret" instruction (inside LoadLibrary), instead it returns to the caller (that is RosAsm.exe), it was going inside another dll (crypt or something) called anywhere in avformat-58.dll

I wonder if there is a way to fix such problematic dlls more easily. I´m clueless of what maybe causing the problem and a way to fix it . I never saw this weird behavior before.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: daydreamer on April 14, 2020, 02:38:12 AM
Quote from: guga on April 13, 2020, 08:05:23 PM

I don´t use masm on a regular daily basis although i do worked with it back in the 90´s when i met here excellent people from which i feel free to call them as friends despite never actually met, guys like Steve, Iczelion, Edgar, Jonchen, Gunther, DayDreamer, Betov, Randall, Seikmanski, Wayne, EWayne, Sven,  etc etc. And yes...i´m the co-author and main maintainer of RosAsm since ages.

I totally agree Guga  :thumbsup: :thumbsup: :thumbsup:
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 14, 2020, 03:10:11 AM
Guga,

This does not answer your question but where I have used ffmpeg, I have written interfaces that interface with ffmpeg.exe via a simple batch file. The logic is simple, work out what you want ffmpeg to do, construct a command line that will do what you want then place it in a batch file which you then run. I do it for licencing reasons due to MASM not being compatible with anything GPL.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 14, 2020, 03:37:09 AM
I don't think the problem is related to ffmpeg because, unlike pieces of code with no users, is something heavily scrutinized.
But to investigate ffmpeg I would go directly to the source code, instead of trying to disassemble the DLL.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 14, 2020, 03:50:17 AM
One other suggestion, ffmpeg documentation is truly lousy and you need to make sure you are passing the right number and type of arguments. This could account for the unusual problems you are having.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 14, 2020, 10:10:01 AM
QuoteOne other suggestion, ffmpeg documentation is truly lousy and you need to make sure you are passing the right number and type of arguments. This could account for the unusual problems you are having.

Hi Steve, i´m aware that. The documentation is really pain but the error is showing when the assembler tries to parse a function that have no parameter whatsoever (a void function) such as av_register_all.

What RosAsm does is simply analyse the source code i´m building and parse the text before it tries to build the import function of dlls. The sequence is like that:

1 - Parse the text and create a table of a array of strings related to the dll name + dll function.
2 - Before the main import function, it then tries to load the imports to see if they do exists on the system we are currently working on. So, it will take from that list of strings the dll name and pass it on the LoadLibrary Api
3 - If a handle is found, it then simply stores the result (of the handle of the dll) on another table to check for duplication when it will later go onto the true routines that create the import section of the generated PE file.  But, if the handle is not found, it simply shows the proper error message and exit that  parsing routine.
4 - After finding the dll handles it then enters onto another routine to parse the list of api names related to those dlls. So, GetProcAddress is used only after the dll name verification is done. It do the same thing on the item 3 for the function names but this time to check for the api functions only
5 - while filling all the table and checking for duplication etc, it then releases the loaded library an perfom a loop to the next dllname+apiname of the list . After filling all the table it then exits this parsing routine
6 - Sort the Api tables created
7 - And finally create the import section.

What is going on here is that when it finds this weird dll (during item "2" and 3 above), and tries to import it with LoadLibrary, is that where somehow it hangs. So, LoadLibrary does not returns to the main caller routine to begin part 4, no matter which function name is used since, this part of the code does not use GetProcAddress yet.

Btw, did you used ffmpeg ?

Offtopic. Do you think you can help me trying to work with it ? I´m trying to create a hls file from a mkv one to be streamed. The generated hls file must contains multiple audio languages, multiple subtitles and multiple video resolutions to be exported on their own directories.

I found a tutorial but i got clueless because it wasn't made to work on windows, i presume. My goal is:

1 - Input a mkv containing a video (in mp4 format encoded with h264), 2 or more audio channels (mp3 files, in portuguese, spanish, english etc), 2 or more subtitles (srt files, in portuguese, spanish, english etc)
2 - Output a playlist (m3u8) and the needed hls (ts, aac and vtt files)
3 - Audio, video and subtitles must be converted to their own formats, but, split on chunks of 6 seconds and places on their own directories with the following condition:

a - Each video inside the mkv  (in mp4 coded with h264) must be converted to ts format and also must be decoded to different resolutions, so for 1280*960, 960*720, 640*480 etc. and place them on their proper directories with the corresponding m3u8 file.
b - Each audio inside the mkv  (in mp3 format ) file must also be converted to aac format (or whatever other format a server uses for this hls stuff) and place them on their proper directories with the corresponding m3u8 file.
c - Each subtitle inside the mkv  (in srt format ) file must also be converted to vtt format (webtt or whatever other format a server uses for this hls stuff) and place them on their proper directories with the corresponding m3u8 file.

4 -Finally create a general playlist in m3u8 format to the used by a html5 player to be streamed.

So, the mkv file (Ex: guga.mkv) will then transcoded to different resolutions in small chunks and place them on a main directory (Ex: gugamovie), which wil contains a playlist in m3u8 format and inside of it it will contain subdirectories related to the different file types. Ex: a subdir named gugaaudio containing the generated playlist to the proper subdirectories inside of it for each language. Ex. inside this dir will create a subdirectory called "portuguese' to store the pieces of aac file in portuguese language, other subdir labeled as "english" containing the english audio and so on.  The samething happens to the suubtitles, creating a directory named (gugasubtitle) and internally the proper m3u8 files ans long with their own subdirs containing the generated vtt files. And for the different video resolutions, the same thing is done.

The goal of what i´m trying to achieve is something like the result from this page, but using a mkv as input.
https://kipalog.com/posts/FFMPEG-HLS-STREAM-MULTIPLE-AUDIO-SUBTITLES



Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 15, 2020, 05:27:42 PM
Hi Guys


What are these flags that do exists internally LoadLibraryEx function in Windows10 ? Do it have any documentation about it ?

LOAD_LIBRARY_REQUIRE_SIGNED_TARGET ; value = 0x80h
LOAD_PACKAGED_LIBRARY ; value = 0x4h
LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY ; value = 0x8000h

Those flags are used to convert the dwFlags to DllCharacteristics flags to be passed onto LdrLoadDll from ntdll.dll


I found those flags here
https://www.cyberforum.ru/blogs/172954/blog5934.html
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 16, 2020, 07:09:38 AM
Hi Guys

I found the problem. Indeed there is a very rare and uncommon error inside LoadLibraryExW when it reaches LdrLoadDll in ntdll.dll. In windows10 (for 64 bits), for some odd reason, in rare situations the stack is changed in one of the functions used internally the loadlibrary api.
Image1
(https://i.ibb.co/sF3nN9d/ghfhg-Image1.jpg) (https://ibb.co/sF3nN9d)

I´m making some tests on a rebuild of t6his LoadLibraryExW to see if it can fix the error. So far, my rebuild is like this (untested yet)


Proc LoadLibraryExW::
    Arguments @lpLibFileName, @hFile, @dwFlags
    Local @DllCharacteristics, @BaseAddress, @Var1, @Var2, @AndFlag, @NTStatus, @SearchPathFlag
    Structure @UnicodeString 8, @UnicodeString.LenghtDis 0, @UnicodeString.MaximumLenghtDis 2, @UnicodeString.BufferDis 4
    Uses ebx, esi, ecx, edx

    ; LOAD_LIBRARY_AS_DATAFILE and  LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE cannot be combined
    mov eax D@dwFlags | and eax &LOAD_LIBRARY_AS_DATAFILE__&LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | mov D@AndFlag eax
    If_Or D@lpLibFileName = 0, D@hFile <> 0, D@dwFlags > 0FFFF, eax = &LOAD_LIBRARY_AS_DATAFILE__&LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
        call BaseSetLastNTError &STATUS_INVALID_PARAMETER
        xor eax eax
        ExitP
    End_If

    call RtlInitUnicodeStringEx D@UnicodeString, D@lpLibFileName
    If eax <> &STATUS_SUCCESS
        call BaseSetLastNTError eax
        xor eax eax
        ExitP
    Else_If W@UnicodeString.LenghtDis = 0
        call BaseSetLastNTError &STATUS_INVALID_PARAMETER
        xor eax eax
        ExitP
    End_If


    ; Verify if the string ends with spaces. If it do recalculate the lenght without them.
    movzx ecx W@UnicodeString.LenghtDis | sub ecx 2 ; don´ count the null terminated byte
    mov edx D@UnicodeString.BufferDis
    While W$edx+ecx = ' '
        sub ecx 2
    End_While
    add ecx 2 ; add the next word to we have the full lenght
    If cx = 0
        call BaseSetLastNTError &STATUS_INVALID_PARAMETER
        xor eax eax
        ExitP
    End_If
    mov W@UnicodeString.LenghtDis cx

    mov eax D@dwFlags
    mov ebx eax
    mov D@BaseAddress 0
    and eax 07F08 ; &LOAD_WITH_ALTERED_SEARCH_PATH convert to DllCharacteristics . Weird, weird value, since the DwFlags, have at most the bit 12 activated.
                            ; Therefore, this should be and eax 01F08 ? Also, maybe necessary build some flag coherence checks to because LOAD_LIBRARY_SEARCH_DEFAULT_DIRS is not the combination of the equates said in the official documentation.
                            ; Also, there seems to be some sort of ilogical situation. If the flags are checked to jmp over when it don´t have &LOAD_LIBRARY_AS_DATAFILE__&LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE__&LOAD_LIBRARY_AS_IMAGE_RESOURCE
                            ; Therefore, a check is necessary to avoid the user to input those flags combined with &DONT_RESOLVE_DLL_REFERENCES, &LOAD_IGNORE_CODE_AUTHZ_LEVEL, &LOAD_WITH_ALTERED_SEARCH_PATH
                            ; But, before implementing this check, i need to analyze what´s going on with LdrGetDllPath and BasepLoadLibraryAsDataFile

    ;mov eax (Not &IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE__&LOAD_WITH_ALTERED_SEARCH_PATH)
    ; https://www.cyberforum.ru/blogs/172954/blog5934.html
    ; mov eax (not &LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY__&LOAD_WITH_ALTERED_SEARCH_PATH)
    mov D@SearchPathFlag eax

    ; only files with bl flag as &LOAD_LIBRARY_AS_DATAFILE__&LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE__&LOAD_LIBRARY_AS_IMAGE_RESOURCE are allowed here.
    ; So, the flags: &DONT_RESOLVE_DLL_REFERENCES, &LOAD_IGNORE_CODE_AUTHZ_LEVEL, &LOAD_WITH_ALTERED_SEARCH_PATH cannot be combined with those above
    ...Test_If bl &LOAD_LIBRARY_AS_DATAFILE__&LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE__&LOAD_LIBRARY_AS_IMAGE_RESOURCE;062
        lea edx D@Var2
        lea ecx D@Var1
        ; from wine: https://git.froggi.es/tkg/PKGBUILDS/commit/6be3bb886b5748b63669475aadb314cf8abcbf3e
        ; https://github.com/wine-mirror/wine/blob/master/dlls/ntdll/loader.c
        call 'ntdll.LdrGetDllPath' D@UnicodeString.BufferDis, D@SearchPathFlag, ecx, edx
        If eax <> &STATUS_SUCCESS
            call BaseSetLastNTError eax
            xor eax eax
            ExitP
        End_If
        lea eax D@BaseAddress
        call BasepLoadLibraryAsDataFile D@UnicodeString, D@Var2, D@dwFlags, eax, D@Var1
        mov D@NTStatus eax

        .If eax >s= &STATUS_SUCCESS
            call 'ntdll.RtlReleasePath' D@Var1
            mov eax D@BaseAddress
            ExitP
        .Else_If eax = &STATUS_NO_SUCH_FILE
            call 'ntdll.RtlReleasePath' D@Var1
            call BaseSetLastNTError D@NTStatus ; status Parameter at ecx
            xor eax eax
            ExitP
        .Else
            .Test_If bl &LOAD_LIBRARY_AS_IMAGE_RESOURCE
                If D@AndFlag <> 0
                    lea eax D@BaseAddress
                    call BasepLoadLibraryAsDataFile D@UnicodeString, D@Var2, D@AndFlag, eax, D@Var1
                    mov D@NTStatus eax
                End_If
            .Test_End
            call 'ntdll.RtlReleasePath' D@Var1
        .End_If

    ...Test_Else

        or D@SearchPathFlag 1
        call LoadFlagsToDllCharacteristics D@dwFlags
        mov D@DllCharacteristics eax

        lea edx D@BaseAddress
        lea ecx D@DllCharacteristics
        call 'ntdll.LdrLoadDll' D@SearchPathFlag, ecx, D@UnicodeString, edx
        mov D@NTStatus eax

    ...Test_End

    If D@NTStatus >s= &STATUS_SUCCESS
        mov eax D@BaseAddress
    Else
        call BaseSetLastNTError D@NTStatus; status Parameter at ecx
        xor eax eax
    End_If

EndP




Proc LoadFlagsToDllCharacteristics:
    Arguments @LoadFlags
    Uses ecx

    mov ecx D@LoadFlags

    xor eax eax
    Test_If cl &DONT_RESOLVE_DLL_REFERENCES
        mov eax &IMAGE_FILE_EXECUTABLE_IMAGE
    Test_End

    ;If cl <s 0; same as Test_If cl 080 &LOAD_LIBRARY_REQUIRE_SIGNED_TARGET
     ;   or eax 0800000
    ;End_If

    Test_If cl &LOAD_LIBRARY_REQUIRE_SIGNED_TARGET; from: https://www.cyberforum.ru/blogs/172954/blog5934.html
        or eax 0800000
    Test_End

    Test_If cl &LOAD_PACKAGED_LIBRARY; from: https://www.cyberforum.ru/blogs/172954/blog5934.html
        or eax 4
    Test_End

    Test_If ecx &LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY; from: https://www.cyberforum.ru/blogs/172954/blog5934.html
        or eax 080000000
    Test_End

EndP




Proc BaseSetLastNTError:
    Arguments @Status
    Uses esi, ecx, edx

    call 'ntdll.RtlNtStatusToDosError' D@Status
    mov esi eax
    call 'ntdll.RtlSetLastWin32Error' eax
    mov eax esi

EndP


before i finish rebuilding this, i´ll make a couple of tests on LdrLoadDll on a smaller version of the loadlibrary rebuild, just to make sure if it is the one that is ruining the stack before i try to rebuild this thing completely. Maybe using a smaller variation only with this ntdll api, would be enough .
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: jj2007 on April 16, 2020, 12:39:34 PM
Quote from: guga on April 16, 2020, 07:09:38 AMIn windows10 (for 64 bits), for some odd reason, in rare situations the stack is changed

Probably unrelated to http://masm32.com/board/index.php?topic=8458.msg92581#msg92581 but it may indicate that M$ is fumbling with the design of Win10
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 16, 2020, 02:49:51 PM
Quote from: jj2007 on April 16, 2020, 12:39:34 PM
Quote from: guga on April 16, 2020, 07:09:38 AMIn windows10 (for 64 bits), for some odd reason, in rare situations the stack is changed

Probably unrelated to http://masm32.com/board/index.php?topic=8458.msg92581#msg92581 but it may indicate that M$ is fumbling with the design of Win10

Indeed, definitely is some weird stack problem that windows10 is not being able to handle. Although i never store huge data in the stack using local variables, windows is doing a mess-up with the stack somehow.

I´m finishing rebuilding another internal function called BasepTrackDataFileHandle. The main problem i see in windows kernelbase.dll is that it heavily contains spaghetti coding style and also function chunks all over the place rather inside their own procedures. I really thought M$ have fixed this weird style of compilation, but, it seems they didn´t. It have the same horror as i saw in some windowsXp core functions. To get things worst, there is unused code and flags insides this LoadLibrayExW that seems to be a left over or simply  junk code to be used later.

I´ll see during this night  if i can make it work with a tiny variation of LoadLibrary without the inner code that uses the flags LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE and LOAD_LIBRARY_AS_IMAGE_RESOURCE. Since inside RosAsm, the functions that uses LoadLibrary don´t actually uses those flags, then, perhaps if i made a small routine to directly use LdrLoadDll to get the handles of the dlls, it may works.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 16, 2020, 02:56:06 PM
Guga, can you get your hands on an old SDK tool called Depends.exe. That will give you something like a dependency tree as this sounds like what your problem is.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 16, 2020, 03:01:27 PM
Quote from: hutch-- on April 16, 2020, 02:56:06 PM
Guga, can you get your hands on an old SDK tool called Depends.exe. That will give you something like a dependency tree as this sounds like what your problem is.

Hi Steve. Is dependencywalker, right ? Good idea :thumbsup: :thumbsup:. I´ll download it and see what it shows to me.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 16, 2020, 03:24:35 PM
I can only guess the mess that RosAsm itself is so that mr. guga is not able to isolate the piece of code responsible for the imaginary problem, build a model and show to everybody. This is called a proof of concept.
Instead, blames Microsoft and ffmpeg the King Trump way without presenting any evidence. This sucks.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: TimoVJL on April 16, 2020, 03:35:13 PM
Where that avformat-58.dll came from ?
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 16, 2020, 03:38:00 PM
Quote from: AW on April 16, 2020, 03:24:35 PM
I can only guess the mess that RosAsm itself is so that mr. guga is not able to isolate the piece of code responsible for the imaginary problem, build a model and show to everybody. This is called a proof of concept.
Instead, blames Microsoft and ffmpeg the King Trump way without presenting any evidence. This sucks.

Don´t forget your pills :badgrin: :badgrin: :badgrin:
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 16, 2020, 03:42:17 PM
Quote from: guga on April 16, 2020, 03:38:00 PM
Quote from: AW on April 16, 2020, 03:24:35 PM
I can only guess the mess that RosAsm itself is so that mr. guga is not able to isolate the piece of code responsible for the imaginary problem, build a model and show to everybody. This is called a proof of concept.
Instead, blames Microsoft and ffmpeg the King Trump way without presenting any evidence. This sucks.

Don´t forget your pills :badgrin: :badgrin: :badgrin:

Try to learn some MASM and Windows API before spamming the forum with beginner problems.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: guga on April 16, 2020, 03:51:40 PM
Quote from: TimoVJL on April 16, 2020, 03:35:13 PM
Where that avformat-58.dll came from ?

Hi timo. From here:

https://ffmpeg.zeranoe.com/builds

The version i´m testing is: ffmpeg-20200403-52523b6-win32-shared

To reproduce the error it would be necessary for me do upload the version of RosAsm i´m currently working and also this small piece of code to test. Creating a small app just to assemble one single line using ffmpeg dlls is ok, but the problem happens when i´m testing a bigger app that contains more dlls.

Dependency walker showed me the dll that is used in avformat-58 from where loadlibrary is stucked inside. When it should return to the caller at rosasm.exe, instead it returns to crypt32.dll. I´m not sure yet, why it works for smaller files and not works for bigger ones containing more dlls to analyse.

But, the main problems is not in ffmpeg itself, because it do works. The problem seems how windows10 handles the stack when the dllmain os such dlls contains complex code as in ffmpeg library. I know ffmpeg should keep dllmain more simple, but it doesn´t and yet, still works. Therefore, windows 10 should be able to handle such situations.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: TimoVJL on April 16, 2020, 05:47:44 PM
This doesn't hang.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void __cdecl mainCRTStartup(void)
{
HMODULE hMod = LoadLibrary(TEXT("avformat-58.dll"));
if (hMod) {
FreeLibrary(hMod);
}
ExitProcess(0);
}
00000000  55                       push ebp
00000001  89E5                     mov ebp, esp
00000003  6800000000               push @279
00000008  FF1500000000             call [__imp__LoadLibraryA@4]
0000000E  85C0                     test eax, eax
00000010  7407                     jz 00000019h
00000012  50                       push eax
00000013  FF1500000000             call [__imp__FreeLibrary@4]
00000019  6A00                     push 00
0000001B  FF1500000000             call [__imp__ExitProcess@4]
00000021  5D                       pop ebp
00000022  C3                       ret
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: jj2007 on April 16, 2020, 06:17:52 PM
Quote from: guga on April 16, 2020, 03:38:00 PMDon´t forget your pills :badgrin: :badgrin: :badgrin:

Again, Guga: you are a gentleman! Far too soft :badgrin:
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 16, 2020, 06:32:02 PM
Hi Guga,

I would be inclined to use LoadLibrary()/GetProcAddress() to get each DLL function address you wish to call first before you call any DLL function. The two API functions work OK in all instances and I have used them for years from Win3.0 to Win10 64 bit with no problems. I of course don't know what your code layout happens to be but I would be very careful about mixing the address code with the function calls. This sounds like what the problem may happen to be.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: aw27 on April 16, 2020, 07:22:19 PM
Quote from: jj2007 on April 16, 2020, 06:17:52 PM
Quote from: guga on April 16, 2020, 03:38:00 PMDon´t forget your pills :badgrin: :badgrin: :badgrin:

Again, Guga: you are a gentleman! Far too soft :badgrin:

You both could use the isolation period to learn some Masm and Windows API.  :icon_idea:
It is not nice to use the Campus to promote tools without users, it will just scare and confuse newbies that land here for the first time - 99% of them never return.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 16, 2020, 10:32:00 PM
Guys, a favour, I know all of you guys and you are all more or less reasonable human beings, can we keep the invective down as it starts to piss people off and we don't need that here. I have known Guga for many years and he took over the reins from "Betov" with RosAsm and has persevered with what must be a difficult task. Playing in binary has always been a ton of fun.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: Vortex on April 16, 2020, 11:44:20 PM
Hi Guga,

You can use Microsoft's dumpbin or Pelle's podump to see the exported functions.
Title: Re: How to fix a deadlock in LoadLibrary Api ?
Post by: hutch-- on April 17, 2020, 08:48:17 AM
 :dazzled:

PHARK - What does it take to keep the peace ?