-
Notifications
You must be signed in to change notification settings - Fork 2
/
Logging.cpp
172 lines (147 loc) · 5.3 KB
/
Logging.cpp
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "Logging.h"
#include "Menu_Log.hpp"
#include <cstdint>
#include <cstdio>
#include <string>
using namespace CATHODE::Logging;
void Logger::printFormattedMessage(const char* formatted_message)
{
if (!formatted_message || formatted_message == nullptr)
{
logger.AddLog("[Logger] Error - Someone attempted to log a message with a null pointer!\n");
}
else
{
logger.AddLog("%s\n", formatted_message);
}
}
void Logger::formatAndPrintFormattedMessage(char* buffer, const char* format, const char* arg)
{
// Check if we have been provided with a valid buffer to write the result into.
if (buffer && buffer != nullptr)
{
sprintf_s(buffer, 256, format, arg);
printFormattedMessage(buffer);
}
else
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, format, arg);
printFormattedMessage(formatBuffer);
}
}
// Because we are hooking in the middle of a function, we need to do some extra work to preserve the state of the registers to avoid access violations.
// We save the return address for the hijacked call to our function, and restore it at the end so the program returns back to the correct place.
// We preserve the state of the volatile registers with PUSHAD, and we restore them in our custom function epilogue with POPAD.
// We also preserve the state of the EFLAGS with PUSHFD, and restore them with POPFD.
// __declspec(naked) instructs the compiler that we do not need it to autogenerate a function prologue and epilogue in assembly, as we will write our own.
long returnAddress;
__declspec(naked)
void HavokLogger::hijackedPrint(char* /*buffer*/, const char* format, const char* havok_physics_object)
{
// Our custom prologue.
__asm {
// Save the return address to our variable.
mov eax, [ebp+4]
mov returnAddress, eax
// Save the stack pointer, all general registers and EFLAGS.
push ebp
mov ebp, esp
pushad
pushfd
}
formatAndPrintFormattedMessage(nullptr, format, havok_physics_object);
// Our custom epilogue.
__asm {
// Restore all EFLAGS, general registers and the stack pointer.
popfd
popad
mov esp, ebp
pop ebp
}
__asm {
// Restore the return address and return to fully restore the stack back to its original condition.
mov eax, [returnAddress]
mov [ebp+4], eax
ret
}
}
void MusicControllerLogger::hijackedPrint_MusicController(char* buffer, const char* format, double* rtpc_value)
{
sprintf_s(buffer, 256, format, rtpc_value);
printFormattedMessage(buffer);
}
void MusicControllerLogger::hijackedPrint_MusicEvent(char* buffer, const char* format, const char* event_name,
double* rtpc_value)
{
sprintf_s(buffer, 256, format, event_name, rtpc_value);
printFormattedMessage(buffer);
}
void AnimationCommandLogger::hijackedPrint(char* buffer, const char* format, const char* command_type,
const char* command_name)
{
sprintf_s(buffer, 256, format, command_type, command_name);
printFormattedMessage(buffer);
}
void AnimationDataLogger::hijackedPrint(const char* animation_data_set, const char* format,
const char* animation_data_label)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, format, animation_data_set, animation_data_label);
printFormattedMessage(formatBuffer);
}
void DoorLogger::hijackedPrint(void* this_ptr, bool do_not_log, const char* format)
{
if (!do_not_log)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, "{Entity: 0x%p} %s", this_ptr, format);
printFormattedMessage(formatBuffer);
}
/*else
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, "{Entity: 0x%p} Warning - Ignoring DoorLogger print due to \"do_not_log\" being %d.", this_ptr, do_not_log);
printFormattedMessage(formatBuffer);
}*/
}
void AnimationLogger::hijackedPrint(char* /*unknown_1*/, char* /*unknown_2*/, const char* format)
{
formatAndPrintFormattedMessage(nullptr, format, "");
}
void CharacterNodeLogger::hijackedPrint(char* /*unknown_1*/, char* /*unknown_2*/, const char* format, char* node_name)
{
formatAndPrintFormattedMessage(nullptr, format, node_name);
}
void ZoneLogger::hijackedPrint(void* this_ptr, bool /*do_not_log*/, const char* format)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, "{Entity: 0x%p} %s", this_ptr, format);
printFormattedMessage(formatBuffer);
}
void SpeechLogger::hijackedPrint_RequestPriority(char* /*unknown_1*/, const char* format, char* unknown_str_1, char* priority, double* timeout)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, format, unknown_str_1, priority, timeout);
printFormattedMessage(formatBuffer);
}
void SpeechLogger::hijackedPrint_SpeechSize(char* /*unknown_1*/, const char* format, unsigned* size)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, format, size);
printFormattedMessage(formatBuffer);
}
void SpeechLogger::hijackedPrint_SpacialAudioType(char* /*unknown_1*/, const char* format, char* unknown_str_1, char* spacial_audio_type)
{
char formatBuffer[256] = {};
sprintf_s(formatBuffer, 256, format, unknown_str_1, spacial_audio_type);
printFormattedMessage(formatBuffer);
}
void SpeechLogger::hijackedPrint_SpeechEntity(char* this_ptr, const char* format, char* speech_name)
{
formatAndPrintFormattedMessage(nullptr, format, speech_name);
}
void SpeechLogger::hijackedPrint(char* /*unknown_1*/, const char* format)
{
formatAndPrintFormattedMessage(nullptr, format, "");
}