How to protect dlls?

Hello all ,

Please, I have two questions,

the first :

I have a dll file that I inject into a game, is it possible using curl Inside dll?

The second How protect dll,
As we know, there are many programs to inject a dll file into any process .
How do I make this dll can only be injected by my exe .

dll file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <Windows.h>
#include <iostream>
#include "Functions.h"
#pragma comment( lib, "psapi.lib" )
using namespace std;
char AmmoOpCode[] = "\x90\x90";
//char AmmoOpCode[] = "\x75";
void InitiateHooks()
{
DWORD ammoAddy = FindPattern("ac_client.exe", "\x8B\x56\x18\x89\x0A\x8B\x76\x14\xFF\x0E\x57\x8B\x7C\x24\x14\x8D\x74\x24\x28\xE8\x87\xE3\xFF\xFF", "xxxxxxxxxxxxxxxxxxxx????");
ammoAddy += 8; //addres to NOP is offet 8 bytes from the address of this pattern

//MsgBoxAddy(ammoAddy);
//	DWORD ammoAddy = 0x00B25E57;
WriteToMemory(ammoAddy, AmmoOpCode, 1);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
InitiateHooks();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Last edited on
1) yes, you can invoke anything in your dll.
2) you can't, directly. You can add some protection, like a secret handshake between your program and the dll that if is not done, the dll functions exit/terminate/crash/something using shared memory or something like that. There are probably tools to do that, or you can make a stab at it yourself. This is the kind of thing you need to either buy a high quality one or accept that your home rolled solution is likely going to be cracked by anyone who has both your program and the dll in hand, and the motivation to do so. Its challenging to do this in a way that is hard to break. Its like those little locks you put on luggage or a locker: it keeps honest people out.
Last edited on
Thanks so much jonnin , please any example to use curl with dll
DLL code can use GetModuleFileName() with hModule set to NULL to get the full path of the EXE file that has loaded the DLL. If the EXE file is not the "expected" one (e.g. by checking the "file name" part of the path), the DLL may cause the process to terminate/crash.

Once you have the full path of the EXE file, it is also possible to use GetFileVersionInfo() to get more information about the EXE file, provided that the EXE file has a proper VERSIONINFO resource. Then "FileDescription", "ProductName" or "InternalName" can be checked. If those properties do not have the "expected" value (or if they are absent), the DLL could cause the process to terminate/crash.
https://docs.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource#examples

Obviously, none of this is a 100% "secure" protection and it could easily be worked around by someone who knows what they're doing...

________

One way to "crash" the running process, out of indefinitely many:

1
2
3
4
5
6
#include <intrin.h>

void crash_program(void)
{
    __halt();
}
Last edited on
Thanks for the idea kigar64551 , but I don't know how to use it because I'm a beginner. Please explain this to my dll code

You can try something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <intrin.h>
#include <Windows.h>

const wchar_t *get_file_name(const wchar_t *path)
{
    const wchar_t *retval = path;
    for (; *path; ++path)
    {
        if ((*path == L'\\') || (*path == L'/'))
        {
            retval = path + 1U;
        }
    }
    return retval;
}

void check_executable_filename(void)
{
    wchar_t exe_path[MAX_PATH];
    if (GetModuleFileNameW(NULL, exe_path, MAX_PATH))
    {
        const wchar_t *const exe_name = get_file_name(exe_path);
        if (lstrcmpiW(exe_name, L"my_program.exe") != 0)
        {
            __halt(); /* <-- DLL was loaded by a program other than "my_program.exe", so force termination! */
        }
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        check_executable_filename();
        break;

    /* ... */

    }
}
Last edited on
Edit: I was focused on the protect the DLL portion, and skipped over the DLL injection bit, so obviously my suggestion here doesn't apply:
[What about sandboxing the whole program using Docker or RLBox?
Sure a bad dll could crash your program or do whatever with your game, so they are still given a lot of power in that sense; but they can't leave the box. They only have access to the things that you give them.]
Last edited on
Thanks kigar ,
i use cheat engine to inject my dll ,
but game is crashed ,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <intrin.h>
#include <Windows.h>

const wchar_t *get_file_name(const wchar_t *path)
{
    const wchar_t *retval = path;
    for (; *path; ++path)
    {
        if ((*path == L'\\') || (*path == L'/'))
        {
            retval = path + 1U;
        }
    }
    return retval;
}

void check_executable_filename(void)
{
    wchar_t exe_path[MAX_PATH];
    if (GetModuleFileNameW(NULL, exe_path, MAX_PATH))
    {
        const wchar_t *const exe_name = get_file_name(exe_path);
        if (lstrcmpiW(exe_name, L"cheatengine-i386.exe") != 0)//RemoteDll32.exe  //cheatengine-i386.exe
        {
            __halt(); /* <-- DLL was loaded by a program other than "my_program.exe", so force termination! */
        }
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        check_executable_filename();
        break;
    /* ... */
    }
}
Topic archived. No new replies allowed.