-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdllmain.cpp
More file actions
117 lines (89 loc) · 4.3 KB
/
dllmain.cpp
File metadata and controls
117 lines (89 loc) · 4.3 KB
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
#include <thread>
#include <string>
HMODULE UnityPlayerHandle = nullptr;
using UnityMainFunc = int(*)(HINSTANCE, HINSTANCE, LPSTR, int);
UnityMainFunc UnityMainOriginal = nullptr;
typedef void* (__cdecl* mono_get_root_domain_t)();
typedef void(__cdecl* mono_thread_attach_t)(void* monoDomain);
typedef void* (__cdecl* mono_assembly_open_t)(const char* assemblyPath, void* monoImageOpenStatus);
typedef void* (__cdecl* mono_assembly_get_image_t)(void* monoAssembly);
typedef void* (__cdecl* mono_class_from_name_t)(void* monoImage, const char* namespaceName, const char* className);
typedef void* (__cdecl* mono_class_get_method_from_name_t)(void* monoClass, const char* methodName, int paramCount);
typedef void* (__cdecl* mono_runtime_invoke_t)(void* monoMethod, void* obj, void** params, void** exc);
void InjectDoki(HMODULE monoHandle) {
auto mono_get_root_domain = (mono_get_root_domain_t)GetProcAddress(monoHandle, "mono_get_root_domain");
auto mono_thread_attach = (mono_thread_attach_t)GetProcAddress(monoHandle, "mono_thread_attach");
auto mono_assembly_open = (mono_assembly_open_t)GetProcAddress(monoHandle, "mono_assembly_open");
auto mono_assembly_get_image = (mono_assembly_get_image_t)GetProcAddress(monoHandle, "mono_assembly_get_image");
auto mono_class_from_name = (mono_class_from_name_t)GetProcAddress(monoHandle, "mono_class_from_name");
auto mono_class_get_method_from_name = (mono_class_get_method_from_name_t)GetProcAddress(monoHandle, "mono_class_get_method_from_name");
auto mono_runtime_invoke = (mono_runtime_invoke_t)GetProcAddress(monoHandle, "mono_runtime_invoke");
auto domain = mono_get_root_domain();
if (domain == nullptr) {
MessageBoxA(nullptr, "Couldn't get mono domain", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
mono_thread_attach(domain);
auto assembly = mono_assembly_open("Doki.dll", nullptr);
if (assembly == nullptr) {
MessageBoxA(nullptr, "Couldn't get mono assembly", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
auto image = mono_assembly_get_image(assembly);
if (image == nullptr) {
MessageBoxA(nullptr, "Couldn't get mono image", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
auto klass = mono_class_from_name(image, "Doki", "BootLoader");
if (klass == nullptr) {
MessageBoxA(nullptr, "Couldn't find Doki.BootLoader!", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
auto method = mono_class_get_method_from_name(klass, "Load", 0);
if (method == nullptr) {
MessageBoxA(nullptr, "Couldn't find Doki.BootLoader -> Load()!", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
mono_runtime_invoke(method, nullptr, nullptr, nullptr);
}
void WaitForInjection() {
HMODULE monoHandle = nullptr;
for (int x = 0; x < 100; x++) {
monoHandle = GetModuleHandleA("mono-2.0-bdwgc.dll");
if (monoHandle) {
break;
}
Sleep(100);
}
if (!monoHandle) {
MessageBoxA(nullptr, "Couldn't get a handle to mono!", "Doki Proxy UnityPlayer.dll", MB_OK);
return;
}
InjectDoki(monoHandle);
}
extern "C" __declspec(dllexport)
int UnityMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
if (!UnityMainOriginal) {
UnityPlayerHandle = LoadLibraryA("UnityPlayer_Original.dll");
if (!UnityPlayerHandle) {
MessageBoxA(nullptr, "Couldn't find UnityPlayer_Original.dll! Try re-installing the game & Doki.", "Doki Proxy UnityPlayer.dll", MB_OK);
return -1;
}
UnityMainOriginal = (UnityMainFunc)GetProcAddress(UnityPlayerHandle, "UnityMain");
if (!UnityMainOriginal) {
MessageBoxA(nullptr, "Couldn't find UnityMain original export! Try re-installing the game.", "Doki Proxy UnityPlayer.dll", MB_OK);
return -1;
}
std::thread(WaitForInjection).detach();
}
return UnityMainOriginal(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
}
return TRUE;
}