forked from igroglaz/a2mgr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug.cpp
358 lines (312 loc) · 6.43 KB
/
debug.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
#include <windows.h>
#include "utils.h"
#include "debug.h"
#include "zxmgr.h"
#define MGR_DEBUG
void log_str(char* string, unsigned long ref)
{
log_format("string: \"%s\"; return address 0x%08X\n", string, ref);
}
void __declspec(naked) DBG_logStrings()
{
__asm
{
push ebp
mov ebp, esp
push ecx
mov [ebp-0x04], ecx
mov eax, [ecx+0x0C]
add eax, [ebp+0x08]
push eax
mov ecx, 0x0062C7C8
mov edx, 0x00421580
call edx
mov eax, [eax]
#ifdef MGR_DEBUG
mov [ebp-0x04], eax
push [ebp+0x04]
push eax
call log_str
mov eax, [ebp-0x04]
#endif
mov esp, ebp
pop ebp
retn 0x0004
}
}
DWORD exc_handler_run(struct _EXCEPTION_POINTERS *info)
{
__try
{
// dump info
log_format("EXCEPTION DUMP:\neax=%08Xh,ebx=%08Xh,ecx=%08Xh,edx=%08Xh,\nesp=%08Xh,ebp=%08Xh,esi=%08Xh,edi=%08Xh;\neip=%08Xh;\naddr=%08Xh,code=%08Xh,flags=%08Xh\n",
info->ContextRecord->Eax,
info->ContextRecord->Ebx,
info->ContextRecord->Ecx,
info->ContextRecord->Edx,
info->ContextRecord->Esp,
info->ContextRecord->Ebp,
info->ContextRecord->Esi,
info->ContextRecord->Edi,
info->ContextRecord->Eip,
info->ExceptionRecord->ExceptionAddress,
info->ExceptionRecord->ExceptionCode,
info->ExceptionRecord->ExceptionFlags);
log_format("BEGIN STACK TRACE: %08Xh [%08Xh] <= ", info->ExceptionRecord->ExceptionAddress, *(unsigned long*)(info->ContextRecord->Esp));
unsigned long stebp = *(unsigned long*)(info->ContextRecord->Ebp);
while(true)
{
bool bad_ebp = false;
if(stebp & 3) bad_ebp = true;
if(!bad_ebp || IsBadReadPtr((void*)stebp, 8)) bad_ebp = true;
if(bad_ebp) /* ? */ break;
log_format2("%08Xh <= ", *(unsigned long*)(stebp+4));
stebp = *(unsigned long*)(stebp); // o_O
}
log_format2("END STACK TRACE\n");
log_format("a2mgr crashed.\n\n");
//if(_LOG_FILE.is_open()) _LOG_FILE.close();
TerminateProcess(GetCurrentProcess(), 1); // ãàðàíòèðîâàííî ¸áíåò
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
log_format("a2mgr crashed TWICE.\n\n");
TerminateProcess(GetCurrentProcess(), 1);
}
// will not get to this point
// but compiler requires that to be written
return EXCEPTION_EXECUTE_HANDLER;
}
void setup_handler()
{
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&exc_handler_run);
}
/*void _stdcall log_retn(unsigned ww, char* str)
{
log_format("log_retn: %08X, %s\n", ww, str);
}
void __declspec(naked) DBG_tempS()
{
__asm
{
push ebp
mov ebp, esp
push ecx
mov [ebp-0x04], ecx
push [ebp+0x10]
push [ebp+4]
call log_retn
mov eax, 0x004627FD
jmp eax
}
}*/
void __declspec(naked) DBG_tempS()
{
__asm
{
push 0x20
push 0x10
lea ecx, [ebp-0x14]
mov edx, 0x0042ABF0
call edx
mov edx, 0x004741CC
jmp edx
}
}
// THE ULTIMATE "DRAWN-FROM"
#include <map>
#include <string>
std::map<unsigned long, std::string> d_strings;
void _stdcall D_AddAddr(unsigned long addr, char* string)
{
d_strings[addr] = std::string(string);
}
void _stdcall D_LogAddr(unsigned long addr, unsigned long addr2)
{
log_format("drawn sprite: %s; at: %08X\n", d_strings[addr].c_str(), addr2);
}
void __declspec(naked) dbg_16a_addaddrstring()
{
__asm
{
//42A71B
push ebp
mov ebp, esp
push ecx
mov [ebp-0x04], ecx
push [ebp+0x08]
push ecx
call D_AddAddr
mov edx, 0x0042A722
jmp edx
}
}
void __declspec(naked) dbg_16a_readaddrstring()
{
__asm
{
//42A740
push ebp
mov ebp, esp
sub esp, 0x0C
mov [ebp-0x0C], ecx
push [ebp+4]
push ecx
call D_LogAddr
mov edx, 0x0042A749
jmp edx
}
}
void _stdcall logVision(char* struc, char* unit)
{
unsigned short vis = *(unsigned short*)(unit + 0x10A);
unsigned long shift = *(unsigned long*)(struc + 0x3F50);
unsigned short vis2 = (1 << (shift - 1)) + (vis >> (8 - shift));
log_format("vis = %u (%04X); shift = %u; vis2 = %u (%04X)\n", vis, vis, shift, vis2, vis2);
}
void __declspec(naked) dbg_logVision()
{
__asm
{
push ebp
mov ebp, esp
sub esp, 0x28
mov [ebp-0x28], ecx
push [ebp+0x08]
push ecx
call logVision
mov edx, 0x00403D50
jmp edx
}
}
void _stdcall logSectionLoaded(char* what)
{
}
// 4F7B90
void __declspec(naked) DBG_logSectionLoaded()
{
__asm
{
push 0x00674620
call logSectionLoaded
mov eax, [ebp+0x1C]
mov dword ptr [eax], 0x00674620
mov edx, 0x004F7BA2
jmp edx
}
}
#include <map>
std::map<const char*, std::string> Names;
void _stdcall _load256(const char* name, const char* pthis)
{
if(!name || !pthis) return;
Names[pthis] = name;
}
// 426DA9
void __declspec(naked) DBG_load256()
{
__asm
{
push ebp
mov ebp, esp
push 0xFFFFFFFF
push 0x005C5232
mov eax, fs:[0]
push eax
mov fs:[0], esp
sub esp, 0x138
mov [ebp-0x144], ecx
push ecx
push [ebp+0x08]
call _load256
mov edx, 0x00426DCD
jmp edx
}
}
void _stdcall _disp256(const char* pthis, unsigned long retaddr)
{
std::string fname = "N/A";
for(std::map<const char*, std::string>::iterator it = Names.begin();
it != Names.end(); ++it)
{
if(it->first == pthis)
{
fname = it->second;
break;
}
}
log_format(".256 displayed (\"%s\", [ebp+4]=%08Xh)\n", fname.c_str(), retaddr);
}
// 427014
void __declspec(naked) DBG_disp256()
{
__asm
{
push ebp
mov ebp, esp
sub esp, 0x08
mov [ebp-0x08], ecx
push [ebp+4]
push ecx
call _disp256
mov edx, 0x0042701D
jmp edx
}
}
// 427140
void __declspec(naked) DBG_di2p256()
{
__asm
{
push ebp
mov ebp, esp
sub esp, 0x08
mov [ebp-0x08], ecx
push [ebp+4]
push ecx
call _disp256
mov edx, 0x00427149
jmp edx
}
}
// 4271D0
void __declspec(naked) DBG_di3p256()
{
__asm
{
push ebp
mov ebp, esp
sub esp, 0x08
mov [ebp-0x08], ecx
push [ebp+4]
push ecx
call _disp256
mov edx, 0x004271D9
jmp edx
}
}
void _stdcall _decideState(unsigned long num)
{
log_format("idle: frame: %u\n", num);
}
// 4688CF
void __declspec(naked) DBG_decideState()
{
__asm
{
mov eax, [ebp-0x90]
test eax, eax
jz dds_skip
push [eax+0x74]
call _decideState
dds_skip:
mov eax, [ebp-0x50]
cmp dword ptr [eax+0x28], 0
jz loc_4688D6
mov edx, 0x004688DC
jmp edx
loc_4688D6:
mov edx, 0x004688D6
jmp edx
}
}