0

I have relatively simple code here for the proxy DllMain() function:

BOOL APIENTRY DllMain(HMODULE hDll, DWORD reason, LPVOID reserved)
{


if (reason != DLL_PROCESS_ATTACH) {
    return TRUE;
}

library = LoadLibrary("vcruntime140_.dll");
if (!library) {
    MessageBox(NULL, "Failed to load vcruntime140_.dll", "vcruntime140.dll proxy", MB_OK);
    return FALSE;
}

if (reason == DLL_PROCESS_DETACH) {
    FreeLibrary(library);
    return TRUE;
}

setupVftableHooks();
return setupHooks();
}

For some reason, it doesn't load the original DLL, i.e. vcruntime140_.dll. It loads the proxy one, aka vcruntime140.dll. It tries to load it several times, in fact:

Loaded   Binaries\Windows-x86_64\vcruntime140.dll'. Symbols loaded.
Loaded   Binaries\Windows-x86_64\vcruntime140.dll'. Symbols loaded.
Unloaded Binaries\Windows-x86_64\vcruntime140.dll'
Loaded   Binaries\Windows-x86_64\vcruntime140.dll'. Symbols loaded.
Unloaded Binaries\Windows-x86_64\vcruntime140.dll'

But

  • a) never once it actually tries to load vcruntime140_.dll, which is the original DLL,

  • b) it is suspicious that last record in the debugger is Unloaded. Although it must've been loaded at the end, as the program doesn't crash (not on DLL loading anyway),

  • c) when the program tries to execute, it complains about

    0xC0000139: Entry Point Not Found for different functions in the original DLL.

    I suspect it is because the original DLL simply was not loaded (as I've checked the Dependency Walker and Entry Points look fine for all of the original functions).

Update 06.08.21: Created a x86 version of the DLL. It loads and the program starts. The difference with the above x64 version is that the program doesn't complain about Entry points for the functions. It loads the DLL from it's location within the game folder, but it also loads the equivalent dll from System32, i.e.:

Binaries\Windows-x86_64\vcruntime140.dll'.      
Binaries\Windows-x86_64\vcruntime140.dll'       
Binaries\Windows-x86_64\vcruntime140.dll'.      
Binaries\Windows-x86_64\vcruntime140.dll'       
(Win32): Loaded 'C:\Windows\System32\vcruntime140.dll'
(Win32): Loaded 'C:\Windows\System32\vcruntime140.dll'
(Win32): Unloaded 'C:\Windows\System32\vcruntime140.dll'    

What is confusing about this is that it doesn't load the actual DLL from the game folder, i.e. vcruntime140_.dll. Will continue trying to debug, but since it doesn't stop at breakpoints in DllMain() function, I don't know what's the best way to do it.

Note that the program runs in the mixed environment, as you can see from the name of the folder, from which it actually starts: Windows-x86_64

1 Answer 1

0

Fixed this in several steps:

  1. Confirmed with Dependency Walker that the DLL is x64 (it wasn't apparent as the environment was mixed as I've mentioned above)

  2. Added .def as Module Definition File on Linker (on some architectures I forgot to do it as I was experimenting with different options)

  3. Main thing is, the code as it was in .def file is not working:

    swr_alloc@1=swresample-3_.swr_alloc@1

    swr_alloc_set_opts@2=swresample-3_.swr_alloc_set_opts@2

It had to be replaced with this in the .def file:

  swr_alloc=PROXY__swr_alloc @1

And change in the mainDLL():

case DLL_PROCESS_ATTACH:
{

    hLThis = hInst;
    hL = LoadLibrary(".\\swresample-3_.dll");
    if (!hL) {
        MessageBox(NULL, "Failed to load swresample-3_.dll", "swresample-3.dll proxy", MB_OK);
        return FALSE;
    }

    p[0] = GetProcAddress(hL, "swr_alloc");
    p[1] = GetProcAddress(hL, "swr_alloc_set_opts");   

.....

extern "C"
{
FARPROC PA = NULL;
int RunASM();

void PROXY__swr_alloc() {
    PA = p[0];
    RunASM();
}
void PROXY__swr_alloc_set_opts() {
    PA = p[1];
    RunASM();
}

With .asm file:

.data
extern PA : qword
.code
RunASM proc
jmp qword ptr [PA]
RunASM endp
end

This is a more "standard" approach to proxy dll creation. But I still don't understand why the original dll setup, i.e. the layout of the .def file didn't work. I saw that working on some other projects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.