Missing "bcrypt.dll" on Windows XP.

Everything related to MakeMKV
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

"makemkvcon.exe" depends on "libffm.dll", which depends on "bcrypt.dll", which doesn't exist. It is trying to import 3 symbols: "BCryptCloseAlgorithmProvider", "BCryptGenRandom", and "BCryptOpenAlgorithmProvider".

This is on Windows XP 32 bit SP3. I have just upgraded to MakeMKV 1.15.4. I don't remember what my prior version was, but I was able to rip on Windows XP earlier this year.

A google search found this: http://forum.doom9.org/archive/index.php/t-175173.html

I wonder why ripping a video requires cryptographically secure random numbers? The thought crosses my mind to hack my own bcrypt.dll just to provide those 3 functions, maybe even just stubs. Otherwise, I wonder if an older version of libffm.dll can be dropped in? Otherwise, I might just have to use an older version of MakeMKV with my clock set back.
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

I hacked a stub, which allows MakeMKV 1.15.4 to run on Windows XP 32 bit.

I used g++ 4.7.1 20120524 (from the MinGW that came with QB64 1.2), and cl 15.00.30729.01 x86 (from Visual C++ 2008 Express).

bcrypt.cpp

Code: Select all

// bcrypt stub to allow newer versions of MakeMKV to run on Windows XP.
// Public domain, 2020 December, Michael Calkins ("qbasicmichael"). No warranty. Use at your own risk.
// Revision 2021 January 01
// Borrows from the "w64 mingw-runtime package", which is also public domain.

// mingw: ----------------------------------- (for older mingw, remove ",--nxcompat".)
// g++.exe -O3 -Wall -shared -Wl,-s,-shared,--enable-auto-image-base,-dy,--nxcompat,--kill-at -o bcrypt.dll bcrypt.cpp

// msvc++:
// cl.exe /O2 /LD /MD bcrypt.cpp bcryptvc.def user32.lib /link /NXCOMPAT
// mt.exe -manifest bcrypt.dll.manifest -outputresource:bcrypt.dll;2

// bcryptvc.def should contain the following:
// LIBRARY bcrypt.dll
// EXPORTS
// BCryptOpenAlgorithmProvider
// BCryptCloseAlgorithmProvider
// BCryptGenRandom
// ThisDllIsJustAStub

// Place the resulting "bcrypt.dll" into the MakeMKV folder. Do not put it in the system32 folder.
// You should probably delete any resulting bcrypt.a or bcrypt.lib files afterwards, so as not to interfere with linking other projects to genuine bcrypt.

#define NOCRYPT
#include <windows.h>

typedef LONG NTSTATUS;
typedef LPVOID BCRYPT_ALG_HANDLE;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

extern "C" __declspec(dllexport) NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, DWORD dwFlags) {
 MessageBoxW(NULL, pszAlgId, L"BCryptOpenAlgorithmProvider", 0);
 return STATUS_SUCCESS;
}

extern "C" __declspec(dllexport) NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE hAlgorithm, ULONG dwFlags) {
 MessageBoxW(NULL, L"", L"BCryptCloseAlgorithmProvider", 0);
 return STATUS_SUCCESS;
}

extern "C" __declspec(dllexport) NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags) {
 MessageBoxW(NULL, L"", L"BCryptGenRandom", 0);
 return STATUS_SUCCESS;
}

extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
 return TRUE;
}

extern "C" __declspec(dllexport) const char * WINAPI ThisDllIsJustAStub(void) {
 return "This bcrypt.dll is just a stub to get MakeMKV to work on WinXP.";
}
MinGW files:

bcryptgcc.def

Code: Select all

LIBRARY bcrypt.dll
EXPORTS
BCryptOpenAlgorithmProvider@16 = bcrypt.dll.BCryptOpenAlgorithmProvider
BCryptCloseAlgorithmProvider@8 = bcrypt.dll.BCryptCloseAlgorithmProvider
BCryptGenRandom@16 = bcrypt.dll.BCryptGenRandom
ThisDllIsJustAStub@0 = bcrypt.dll.ThisDllIsJustAStub
bcryptoldgcc.def

Code: Select all

LIBRARY bcrypt.dll
EXPORTS
BCryptOpenAlgorithmProvider@16 = BCryptOpenAlgorithmProvider
BCryptCloseAlgorithmProvider@8 = BCryptCloseAlgorithmProvider
BCryptGenRandom@16 = BCryptGenRandom
ThisDllIsJustAStub@0 = ThisDllIsJustAStub
testbcryptgcc.cpp

Code: Select all

// Code to test the message boxes in the bcrypt stub. mingw version.
// Revision 2021 January 01.
// Note: the console window can cover and hide the message box.

// for older mingw, remove ",--nxcompat" from command line, and "bcrypt.dll." from before the function names on the def file lines.

// dlltool.exe -k -l bcrypt.a -d bcryptgcc.def
// g++.exe -O3 -Wall -Wl,-s,-dy,--nxcompat,--enable-stdcall-fixup -o testbcryptgcc.exe testbcryptgcc.cpp bcrypt.a

// bcryptgcc.def should contain the following:
// LIBRARY bcrypt.dll
// EXPORTS
// BCryptOpenAlgorithmProvider@16 = bcrypt.dll.BCryptOpenAlgorithmProvider
// BCryptCloseAlgorithmProvider@8 = bcrypt.dll.BCryptCloseAlgorithmProvider
// BCryptGenRandom@16 = bcrypt.dll.BCryptGenRandom
// ThisDllIsJustAStub@0 = bcrypt.dll.ThisDllIsJustAStub

#define NOCRYPT
#include <windows.h>

typedef LONG NTSTATUS;
typedef LPVOID BCRYPT_ALG_HANDLE;
extern "C" __declspec(dllimport) NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, DWORD dwFlags);
extern "C" __declspec(dllimport) NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE hAlgorithm, ULONG dwFlags);
extern "C" __declspec(dllimport) NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags);
extern "C" __declspec(dllimport) const char * WINAPI ThisDllIsJustAStub(void);

BCRYPT_ALG_HANDLE hAlgorithm = 0;
LPCWSTR pszAlgId = L"fghij";
LPCWSTR pszImplementation = L"abcde";
DWORD dwFlags = 0;
UCHAR bBuffer[16] = {};
ULONG cbBuffer = sizeof(bBuffer);

int main() {
 BCryptOpenAlgorithmProvider(& hAlgorithm, pszAlgId, pszImplementation, dwFlags);
 BCryptCloseAlgorithmProvider(hAlgorithm, dwFlags);
 BCryptGenRandom(hAlgorithm, bBuffer, cbBuffer, dwFlags);
 MessageBoxA(NULL, ThisDllIsJustAStub(), "", 0);
 return 0;
}
mbcryptgcc.bat

Code: Select all

\qb64\internal\c\c_compiler\bin\g++.exe -O3 -Wall -shared -Wl,-s,-shared,--enable-auto-image-base,-dy,--nxcompat,--kill-at -o bcrypt.dll bcrypt.cpp
mtestbcryptgcc.bat

Code: Select all

\qb64\internal\c\c_compiler\bin\dlltool.exe -k -l bcrypt.a -d bcryptgcc.def
\qb64\internal\c\c_compiler\bin\g++.exe -O3 -Wall -Wl,-s,-dy,--nxcompat,--enable-stdcall-fixup -o testbcryptgcc.exe testbcryptgcc.cpp bcrypt.a
mbcryptoldgcc.bat

Code: Select all

c:\dev-cpp\bin\g++.exe -O3 -Wall -shared -Wl,-s,-shared,--enable-auto-image-base,-dy,--kill-at -o bcrypt.dll bcrypt.cpp
mtestbcryptoldgcc.bat

Code: Select all

c:\dev-cpp\bin\dlltool.exe -k -l bcrypt.a -d bcryptoldgcc.def
c:\dev-cpp\bin\g++.exe -O3 -Wall -Wl,-s,-dy,--enable-stdcall-fixup -o testbcryptgcc.exe testbcryptgcc.cpp bcrypt.a
MSVC++ files:

bcryptvc.def

Code: Select all

LIBRARY bcrypt.dll
EXPORTS
BCryptOpenAlgorithmProvider
BCryptCloseAlgorithmProvider
BCryptGenRandom
ThisDllIsJustAStub
testbcryptvc.cpp

Code: Select all

// Code to test the message boxes in the bcrypt stub. msvc++ version.
// Revision 2021 January 01.
// Note: the console window can cover and hide the message box.

// cl.exe /O2 /MD testbcryptvc.cpp bcrypt.lib user32.lib /link /NXCOMPAT
// mt.exe -manifest testbcryptvc.exe.manifest -outputresource:testbcryptvc.exe;1

#include <windows.h>

extern "C" __declspec(dllimport) const char * WINAPI ThisDllIsJustAStub(void);

BCRYPT_ALG_HANDLE hAlgorithm = 0;
LPCWSTR pszAlgId = L"fghij";
LPCWSTR pszImplementation = L"abcde";
DWORD dwFlags = 0;
UCHAR bBuffer[16] = {};
ULONG cbBuffer = sizeof(bBuffer);

int main() {
 BCryptOpenAlgorithmProvider(& hAlgorithm, pszAlgId, pszImplementation, dwFlags);
 BCryptCloseAlgorithmProvider(hAlgorithm, dwFlags);
 BCryptGenRandom(hAlgorithm, bBuffer, cbBuffer, dwFlags);
 MessageBoxA(NULL, ThisDllIsJustAStub(), "", 0);
 return 0;
}
mbcryptvc.bat

Code: Select all

cl.exe /O2 /LD /MD \c\bcrypt.cpp bcryptvc.def user32.lib /link /NXCOMPAT
mt.exe -manifest bcrypt.dll.manifest -outputresource:bcrypt.dll;2
mtestbcryptvc.bat

Code: Select all

cl.exe /O2 /MD testbcryptvc.cpp bcrypt.lib user32.lib /link /NXCOMPAT
mt.exe -manifest testbcryptvc.exe.manifest -outputresource:testbcryptvc.exe;1
If you use the bat files, you'll have to adjust the paths. (The reason for the \c\ path on the bcrypt.cpp is so that I could have only one copy of that, because it's identical for both compilers.) (The source files should contain the same lines in the comments, but without the paths.)

The commands for msvc++ need to be run from the msvc++ command prompt shortcut, so that the environment variables will be set.

Hopefully I didn't make too many mistakes.

It seems to work. It seems like MakeMKV doesn't even call those functions, at least when ripping DVD files from a folder. I'm about to try ripping from an actual disk.

Happy ripping to my fellow XP users.

Edit: It also ripped a DVD from disk without calling those functions.
Edit: updated the bcryptvc.def within the comments in bcrypt.cpp

Edit: 2021 Jan 1:

Accommodated g++ 3.4.2, which comes with Dev-C++ 4.9.9.2. I refer to this as "older MinGW" and "oldgcc". This involves removing ",--nxcompat" from the command lines, and "bcrypt.dll." from the def lines.

Changed testbcrypt to zero initialize bBuffer, and have cbBuffer use sizeof instead of hardcoding.

Added a comment that the message boxes can be underneath and thus hidden by the console window. (I think when launching it from Windows Explorer, the initial message box can be created a fraction of a second prior to the console window.)

Come to think of it, I should have put the revision date in text strings so it'd be in the binaries. Maybe next time, if I revise them again...
bcrypt 2021 01 01.7z
(1.85 KiB) Downloaded 709 times
Last edited by qbm0000 on Fri Jan 01, 2021 8:40 am, edited 2 times in total.
preserve
Posts: 746
Joined: Sun Sep 13, 2015 10:21 pm
Location: Canada

Re: Missing "bcrypt.dll" on Windows XP.

Post by preserve »

qbm0000 wrote:
Sat Dec 12, 2020 9:15 am
I hacked a stub, which allows MakeMKV 1.15.4 to run on Windows XP 32 bit.
^ I normally think of myself as a technical person, but unfortunately, this is mostly beyond me. This is C++ that needs to be compiled? Can you share the compiled result?

I run a Windows XP SP3 machine solely for ripping, and while it's been fine through 1.15.3 (though Mike keeps nagging me to get off XP), with 1.15.4 I can confirm the same error that you encountered.

Perhaps Mike can address this within MakeMKV for 1.15.5.

Image
Using: ASUS BW-16D1HT 3.00
gonca
Posts: 24
Joined: Mon Feb 19, 2018 10:35 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by gonca »

Try this link
https://www.dll-files.com/bcrypt.dll.html
Pick the correct one and download

NOTE
Please sandbox and check for malware before using.
I never had need to use that site before so I can't tell you if they are legit or not
dcoke22
Posts: 2607
Joined: Wed Jul 22, 2020 11:25 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by dcoke22 »

Out of curiosity… why continue to run a Windows XP machine only for ripping?
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

preserve wrote:
Sat Dec 26, 2020 6:52 am
Can you share the compiled result?
I just happened to check back on a whim, and noticed your response.

I'm not comfortable uploading binaries here.

I'll walk you through it using the old version of MinGW (3.4.2) that comes with the old version of Bloodshed Dev-C++ (4.9.9.2). This is a very old compiler, but it should be sufficient for this. The download is <9MB.

https://sourceforge.net/projects/dev-cp ... e/download

Proceed through the setup.

On the "Choose components" part, it's up to you. Definitely leave "MinGW compiler system" checked. Starting from "Typical", I would suggest leaving "Help files" and "Create shortcuts in Start Menu" checked. I would recommend unchecking "Associate C and C++ files" and "Create Quick Launch shortcut". (I like having the files associated with Notepad.)

The default folder is "C:\Dev-Cpp", and I'll assume you install there.

It asks whether you want to install for all users. It probably won't matter, but I'm choosing "Yes".

After installation, you don't have to run Dev-C++. If you do, it will ask you a few configuration questions. But we won't be using the IDE. We'll be compiling directly from the command line.

Now, you can create a new folder. I'll assume you create a folder named "bcrypt" in your "C:" drive.

Extract the following Zip file into that folder.
bcrypt 2021 01 01 oldgcc.zip
(2.74 KiB) Downloaded 720 times
Now, go to the "Start" menu, "All Programs", "Accessories", and run "Command Prompt".

Type:

Code: Select all

c:
cd \bcrypt
mbcryptoldgcc
copy bcrypt.dll "c:\program files\makemkv\"
The result should look something like this:
bcrypt screenshot.png
bcrypt screenshot.png (46.48 KiB) Viewed 22381 times
That should do it.

I edited my earlier post to update the source code.

Please let me know if it works, or if you have trouble.
preserve
Posts: 746
Joined: Sun Sep 13, 2015 10:21 pm
Location: Canada

Re: Missing "bcrypt.dll" on Windows XP.

Post by preserve »

qbm0000 wrote:
Fri Jan 01, 2021 6:22 am
I'll walk you through it using the old version of MinGW ... Please let me know if it works, or if you have trouble.
Worked perfectly, thank you very much for making this, and taking the time to write out the instructions!
dcoke22 wrote:
Sat Dec 26, 2020 6:27 pm
Out of curiosity… why continue to run a Windows XP machine only for ripping?
Just because I have a lot to rip, and I'm often gaming, processing video, etc. on my primary system, so until I get a new system, I've been using my old XP system for ripping, and I haven't had the time or the energy to look into whether a newer Windows would even run on that system... it's currently the path of least resistance lol.
Using: ASUS BW-16D1HT 3.00
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

preserve wrote:
Sat Jan 02, 2021 8:15 am
Worked perfectly, thank you very much for making this, and taking the time to write out the instructions!
That's good. You're welcome. I'm glad it was useful.
schreiberstein
Posts: 1
Joined: Wed Jan 13, 2021 10:46 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by schreiberstein »

qbm0000 wrote:
Fri Jan 01, 2021 6:22 am
preserve wrote:
Sat Dec 26, 2020 6:52 am
Can you share the compiled result?
Please let me know if it works, or if you have trouble.
Hello qbasic michael,

thank you very much for your effort to keep achieve Windows XP compatibility.
Sadly, I am experiencing problems with the latest MakeMKVversion 1.15.4.0 on Windows XP.
I successfully built the stub library and copied it to the program directory, but the program crashes.
First, a child process (?)gets terminated in the background "MakeMKV console application has encountered a problem and needs to close."
The main program window launches though. I can also see that it tries to establish a server connection.
Then a corrupted error message appears (black window - see attached screenshot) and the program hangs and needs to be terminated.

IDA Pro Debugger is able to detect these errors:

Debugged application message: OpenThemeData() failed for theme 5 (MENU). (Element not found.)
[...]
Debugged application message: OpenThemeData() failed for theme 11 (TASKDIALOG). (Element not found.)
[ ...]

Debugger: thread 5688 has exited (code 0)
Debugger: thread 5160 has exited (code 0)
Debugger: thread 5328 has exited (code 0)
Debugger: process has exited (exit code 0)

Do you have any idea how to fix this?

On another note: I am not an experienced programmer, but I think it should be possible to make the library load of bcrypt.dll conditional (e.g. NT VERSION > NT5) in makemkv's main source code. If backwards compatibility is desired, that is.

Cheers,
schreiberstein
Attachments
Error message
Error message
makemkv-11540-winxp.PNG (29.87 KiB) Viewed 20988 times
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

schreiberstein wrote:
Wed Jan 13, 2021 11:09 pm
Then a corrupted error message appears (black window - see attached screenshot) and the program hangs and needs to be terminated.

IDA Pro Debugger is able to detect these errors:

Debugged application message: OpenThemeData() failed for theme 5 (MENU). (Element not found.)
[...]
Debugged application message: OpenThemeData() failed for theme 11 (TASKDIALOG). (Element not found.)
[ ...]
Hello schreiberstein.

Sorry. I just today saw your response.

OpenThemeData is a function in uxtheme.dll, which is delay-loaded by shell32.dll, which is loaded by makemkv.exe.

The "MakeMKV BETA popup" message box is supposed to be saying "Fatal error occurred, program will now exit.", which is what it says (in a larger than normal font) in the Windows Classic style. In the Windows XP Luna blue style, it displays that black box without legible text.

I assume that OpenThemeData stuff is some glitch related to themes. As others have pointed out elsewhere ( https://www.makemkv.com/forum/viewtopic.php?f=1&t=22088 ), the font sizes are wrong, and the open DVD folder dialog has issues in this version of MakeMKV.

But that's a minor, secondary problem. That popup happens, because makemkvcon.exe crashed for some reason.
schreiberstein wrote:
Wed Jan 13, 2021 11:09 pm
First, a child process (?)gets terminated in the background "MakeMKV console application has encountered a problem and needs to close."
I'm not familiar with IDA Pro Debugger, but I am familiar with crash logs from the Dr Watson postmortem debugger. ("Documents and Settings\All Users\Application Data\Microsoft\Dr Watson\drwtsn32.log")

You can delete or rename "drwtsn32.log" to get a clean slate, then let it crash again, let Dr Watson dump it, then attach the entire log.

Does IDA Pro Debugger generate full logs/dumps? If for some reason Dr Watson doesn't generate a log, but your IDA Pro Debugger does, please attach that.

I need the log specifically for makemkvcon.exe.

What I'd like to see, if possible, is the exact reason makemkvcon.exe crashed. If possible, the address of the faulting instruction which caused the exception to be raised, (the address contained in the eip register). And a stack dump/trace to see which functions were calling which. (I'll only be able to tell function names from external DLL symbols, as internal symbols are usually stripped.) But hopefully this can tell whether it was a bcrypt stub error, or some other error that the MakeMKV devs should look into.
schreiberstein wrote:
Wed Jan 13, 2021 11:09 pm
I successfully built the stub library and copied it to the program directory, but the program crashes.
You can use dependency walker to check whether there are link problems with the bcrypt.dll that you compiled. You can get Dependency Walker 2.2.6000 here: http://www.dependencywalker.com/

It should look like this:
malemkvcon depends.png
malemkvcon depends.png (54.35 KiB) Viewed 20248 times
When you navigate to makemkvcon.exe --> libffm.dll --> bcrypt.dll, (collapsing other trees to unclutter the view), it should show the 3 symbols in the import pane. All 3 should have green "C " boxes next to them. In the export pane, the 3 symbols should have cyan "C " boxes with little blue circles on the left. The 4th symbol will be have a gray "C " box.

If it can't find bcrypt.dll, then it should say "Error: At least one required implicit or forwarded dependency was not found." And there will be a yellow circle with a question mark by bcrypt.dll in the module list. Like this:
miss.png
miss.png (54.05 KiB) Viewed 20248 times
If it finds bcrypt.dll, but there's something wrong with the symbols, then one or more of the boxes in the import pane will be red instead of green. And if there are symbols in the export pane, more than one might be gray instead of cyan. If the 4 symbols show up, make sure they are spelled correctly in the export pane, with no "_" or "@" or anything. That is, the names should lack decoration. For example, the following screenshot shows what happens if the "--kill-at" linker command is removed from the g++ compiler command line. Thus the function names are decorated with "@##", which they shouldn't be.
makemkvcon dll bad.png
makemkvcon dll bad.png (58.15 KiB) Viewed 20248 times
schreiberstein wrote:
Wed Jan 13, 2021 11:09 pm
but I think it should be possible to make the library load of bcrypt.dll conditional (e.g. NT VERSION > NT5) in makemkv's main source code.
makemkvcon.exe does not depend on bcrypt directly. It depends on libffm.dll, which depends on bcrypt.dll. It seems the choice to link to bcrypt was made by the FFmpeg developers. I don't know whether MakeMKV's devs compile their own libffm.dll, in which case they might be able to follow your suggestion, or whether they get a binary from someone else.

I don't know what MakeMKV uses from libffm. It imports 23 symbols, "ffm_audio_decode_get_info" being one example. But whatever it uses, it doesn't seem to actually use bcrypt. After all, ripping a DVD shouldn't need cryptographically secure random numbers.

Let me know, please, if you do see any of the message boxes from the bcrypt stub (using makemkv, not the test program), as that would mean that those functions actually do get called. If that's the case, I might make the BCryptGenRandom function fill the buffer, perhaps using the C standard library "rand" function, (though that would definitely not be cryptographically secure), just in case it's checking for a changed buffer. And maybe try to return some sort of (fake?) handle value, in case it's checking that.

Cheers.
Username1267
Posts: 17
Joined: Sat May 02, 2020 12:15 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by Username1267 »

qbm0000 wrote:
Sat Dec 12, 2020 9:15 am
It seems like MakeMKV doesn't even call those functions
If this is true, we can simply throw out the import descriptor (attachment below). If this is not true, the application will crash somewhen.

But actually the developers should fix this instead of us providing hacks.
Attachments
makemkvcon.exe.zip
(2.39 MiB) Downloaded 487 times
qbm0000
Posts: 8
Joined: Mon Nov 02, 2015 2:17 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by qbm0000 »

Username1267 wrote:
Sat Jan 23, 2021 8:35 pm
qbm0000 wrote:
Sat Dec 12, 2020 9:15 am
It seems like MakeMKV doesn't even call those functions
If this is true, we can simply throw out the import descriptor (attachment below). If this is not true, the application will crash somewhen.
I meant, I don't think the bcrypt functions get called. I'd be surprised if the libffm functions don't get called. That having been said, I was able to start ripping from a folder with your modified exe, and it didn't crash. I cancelled it before it finished.

Comparing your file:

Code: Select all

C:\Program Files\MakeMKV>fc /B makemkvcon.exe modified-makemkvcon.exe
Comparing files makemkvcon.exe and MODIFIED-MAKEMKVCON.EXE
0039AC1C: 0C 00
0039AC1D: C6 00
0039AC1E: 39 00
0039AC28: 14 00
0039AC29: D6 00
0039AC2A: 39 00
0039AC2C: C8 00
0039AC2D: 91 00
0039AC2E: 1F 00
You zeroed out the entry for "libffm.dll" in the import directory table of "makemkvcon.exe" at file offset 0x0039ac1c, memory address 0x0079c41c.

Each of these entries is twenty (0x14) bytes long, and the last one is supposed to be all zeros. In this case, "libffm.dll" was the last entry in the table.

If you wanted to similarly edit "libffm.dll" to zero out "bcrypt.dll", the import directory entry for it is at memory address 0x00ac8014, "libffm.dll" file offset 0x00104e14. But unfortunately, there are entries for 2 more DLLs after it: "kernel32.dll" and "msvcrt.dll". If you were to remove the entry for bcrypt, you'd have to move those other entries back twenty bytes each.

The import address table for "bcrypt.dll" within "libffm.dll" is at memory address 0x00ac8224, file offset 0x00105024. This is initially identical to the import lookup table (at memory address 0x00ac807c, file offset 0x00104e7c). But when the operating system loads the DLL, it patches the function addresses into the import address table. If we remove the entry for "bcrypt.dll" from the import directory table, the operating system won't know to modify the import address table. If the program then tries to call any of those functions, it will try to execute the import lookup table as if it were code. (Edit: This is wrong. See note at the end of this post.) Hopefully, this would trigger data execution prevention. But if not, it would be trying to execute garbage, which hopefully would cause a fault sooner rather than later. Much better to zero out the import address table also, and thus guarantee a page fault and an access violation exception, if the program tries to call the functions. There are 3 dwords that need to be zeroed out in the import address table starting at file offset 0x00105024 within "libffm.dll", a total of twelve (0xc) bytes, 4 bytes for each of the 3 imported functions.

Thus:

Code: Select all

C:\Program Files\MakeMKV>fc /B libffm.dll modified-libffm.dll
Comparing files libffm.dll and MODIFIED-LIBFFM.DLL
00104E14: 7C 8C
00104E20: 7C FC
00104E24: 24 34
00104E28: 8C 04
00104E29: 80 81
00104E34: FC 10
00104E35: 89 8B
00104E38: 34 AC
00104E3C: 04 00
00104E3D: 81 00
00104E3E: 2B 00
00104E48: 10 00
00104E49: 8B 00
00104E4A: 2B 00
00104E4C: AC 00
00104E4D: 82 00
00104E4E: 2B 00
00105024: 0C 00
00105025: 84 00
00105026: 2B 00
00105028: 2C 00
00105029: 84 00
0010502A: 2B 00
0010502C: 3E 00
0010502D: 84 00
0010502E: 2B 00
Personally, I prefer my stub dll, because at least then you should see a message box if the function does get called. And I think compiling a stub dll is somewhat more elegant than hex editing a binary. There'd be a risk of confusion if somehow the edited binary with the same file name got distributed. I mean, of course, if it works, it's a legitimate hack, for those who have hex editors, but who don't want to compile the stub. Whatever floats your boat. Of the 2 hex edits, I'd feel less uncomfortable with the one that removes bcrypt from libffm and zeros out the import address table, than the one that removes libffm from makemkvcon.

For information about the structure of EXE and DLL files, including the import tables being discussed, see "Microsoft Portable Executable and Common Object File Format Specification". The one I've been using is revision 8.2.

(I used WinDbg to explore the memory and dump the headers. I used MS-DOS Editor in binary mode to edit. (Yeah, it's clumsy as hell, but it's what I have.))

I hope the addresses given here are correct. I'll recheck them when I get time. To anyone wondering, the differences between memory addresses and file offsets can vary between different sections of an executable, because sections are aligned to 512 bytes in files, but 4096 bytes in memory. Also, sections can be loaded to arbitrary addresses. The addresses given in the tables are "RVA"s, which need to be added to the image base (0x00400000 for normal EXE files, 0x00810000 for "libffm.dll") to get the memory addresses.

Edit: On the assumption that "ffm_init" might be called before any of the others, one could load makemkv.exe into WinDbg, type ".childdbg 1", and type "g". Then for makemkvcon.exe, type "bp ffm_init" to set a breakpoint, and type "g" again. Try to rip something, then type "g" again for mmccextr.exe. It might be safer to set breakpoints on all 23 functions just in case. Just to see if it does call libffm. I tried setting the breakpoint on ffm_init, and it didn't call it for starting a rip. When I get time, I'll try it with breakpoints on all of them, and rip something all the way through to see.

Edit (Jan 24): I said that if the libffm's import address table for bcrypt was left as is, and the program tried to call the functions, that it would execute the import lookup table as if it were code. That's wrong. I was confused. The import address table would contain the same RVAs which are in the input lookup table, which are RVAs to the hint/name table. But the program would expect them to be the virtual addresses of the functions. So, it would try to execute whatever is at 0x002b840c, 0x002b842c, or 0x002b843e as if they were the bcrypt functions. At least on my computer, these locations appear to be data within "locale.nls". Trying to execute it causes an access violation exception, presumably because of data execution prevention.
Username1267
Posts: 17
Joined: Sat May 02, 2020 12:15 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by Username1267 »

Wow, nowadays there are not much people who have such a deep knowledge about the PE32 file format like you have. I am really impressed.

Yes, it's a quick and dirty hack. And your solution is much cleaner than mine. But many in here are pure consumers. They want an executable that works somehow. Not a bunch of souce code where you need to download a compiler from somewhere and then figure it out how to get it working.

As I noted my hack completely relies on the time intensive work you made. I do have knowledge about every bit and byte in this file format but to be honest, I just used a tool that edits the exe and didn't even check what it did. I didn't even read good enough what you wrote so I mixed it up.

By my own tests I can say that the software didn't crash and it rips DVDs.
Username1267
Posts: 17
Joined: Sat May 02, 2020 12:15 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by Username1267 »

If you wanted to similarly edit "libffm.dll" to zero out "bcrypt.dll", the import directory entry .... But unfortunately, there are entries for 2 more DLLs after it: "kernel32.dll" and "msvcrt.dll". If you were to remove the entry for bcrypt, you'd have to move those other entries back twenty bytes each.
Yes, that is how I would have done it if I would have edited the file manually. I hope my tool did that, too.

The attachment should be a little bit cleaner hack as suggested by qbm0000. With this dll the original makemkvcon.exe can be used.
The import address table would contain the same RVAs which are in the input lookup table, which are RVAs to the hint/name table. But the program would expect them to be the virtual addresses of the functions. So, it would try to execute whatever is at 0x002b840c, 0x002b842c, or 0x002b843e as if they were the bcrypt functions. At least on my computer, these locations appear to be data within "locale.nls". Trying to execute it causes an access violation exception, presumably because of data execution prevention.
Yes, but the libffm.dll machine code would read from the import address table not the import lookup table. But I think that is what you meant anyway and it doesn't change anything as you pointed out, it would be the same content. We could go further and zero out the import address table to cause a memory fault when executing the call command. This would lead to an instant termination of the process (a controlled crash). If someone reports a crash we can use your stub library to track calls or to return dummy values to prevent a crash.

But as I said: The developers should provide a working programm not us providing hacks.
Attachments
libffm.dll.zip
(565.89 KiB) Downloaded 428 times
E-Gwen
Posts: 7
Joined: Tue Feb 23, 2021 2:04 pm

Re: Missing "bcrypt.dll" on Windows XP.

Post by E-Gwen »

Hi,

I was about to post a ticket for MakeMKV 1.15.4 not running with Windows XP, and I found your discussion.

By downloading the "makemkvcon.exe.zip" and installing it, it now works ! :D

Thank you very much !

Keep ripping. 8)

See you.
E-Gwen.
Post Reply