CRAW now runs on Windows 7 too - the problem was that Windows 7 has moved some functi...
[craw.git] / craw / automap.cpp
blobae059c900aee28cd2c821b1fb9dc5d8364bc7111
1 /*
2 Command line arguments: python E:\Code\Python\ida\ida.py D2Client.dll B:\D2\D2Client.lst process_automap_unit automap_blobs E:\Code\craw_module\source\craw\automap.cpp
3 Time of generation: 2009-07-10 16:34:56
4 */
6 #include <string>
7 #include <windows.h>
8 #include <ail/string.hpp>
9 #include "d2_data.hpp"
10 #include "utility.hpp"
11 #include "python.hpp"
13 namespace
15 //Initialisation variables
17 char const * module_name = "D2Client.dll";
18 unsigned image_base = 0x6FAB0000;
19 unsigned module_base = 0;
21 unsigned get_y_coordinate = 0x6FABC214;
22 unsigned sub_6FACF710 = 0x6FACF710;
23 unsigned D2Common_10195 = 0x6FABC3D0;
24 unsigned D2Win_10132 = 0x6FABD354;
25 unsigned D2Lang_10005 = 0x6FABD1D4;
26 unsigned draw_text = 0x6FABD360;
27 unsigned sub_6FACF780 = 0x6FACF780;
28 unsigned get_unit_state = 0x6FABC21A;
29 unsigned D2Common_10860 = 0x6FABCA4E;
30 unsigned automap_unit_type_check = 0x6FAEF3D0;
31 unsigned sub_6FAEDE00 = 0x6FAEDE00;
32 unsigned D2Common_10350 = 0x6FABC3D6;
33 unsigned sub_6FAB2D40 = 0x6FAB2D40;
34 unsigned draw_cross = 0x6FAED0C0;
35 unsigned sub_6FACF3D0 = 0x6FACF3D0;
36 unsigned set_text_size = 0x6FABD36C;
37 unsigned get_x_coordinate = 0x6FABC208;
39 //Custom variables
41 unit * unit_pointer;
44 void automap_blobs_interrupt()
46 __asm
48 int 3
52 void __stdcall process_unit(int x, int y, uchar colour)
54 python::perform_automap_callback(*unit_pointer, x, y, colour);
57 void __declspec(naked) intercept_draw_cross()
59 __asm
61 pushad
62 push [esp + 32 + 4]
63 push eax
64 push ecx
65 call process_unit
66 popad
67 ret 4
71 void automap_blobs();
73 void __stdcall initialise_automap_blobs()
75 module_base = reinterpret_cast<unsigned>(GetModuleHandle(module_name));
76 if(module_base == 0)
77 automap_blobs_interrupt();
79 unsigned * call_addresses[] =
81 &get_y_coordinate,
82 &sub_6FACF710,
83 &D2Common_10195,
84 &D2Win_10132,
85 &D2Lang_10005,
86 &draw_text,
87 &sub_6FACF780,
88 &get_unit_state,
89 &D2Common_10860,
90 &automap_unit_type_check,
91 &sub_6FAEDE00,
92 &D2Common_10350,
93 &sub_6FAB2D40,
94 &draw_cross,
95 &sub_6FACF3D0,
96 &set_text_size,
97 &get_x_coordinate
100 unsigned linking_offset = module_base - image_base;
102 for(std::size_t i = 0; i < 17; i++)
104 unsigned & address = *call_addresses[i];
105 address += linking_offset;
108 bool success = false;
110 std::string const marker = "\x0f\x0b\x0f\x0b\x0f\x0b\x0f\x0b";
112 char * data_pointer = reinterpret_cast<char *>(&automap_blobs);
113 while(true)
115 std::string current_string(data_pointer, marker.size());
116 if(current_string == marker)
118 success = true;
119 break;
121 data_pointer++;
124 if(!success)
125 automap_blobs_interrupt();
127 data_pointer += marker.size();
129 for(unsigned i = 0; i < 19; i++)
131 char * label_pointer = *reinterpret_cast<char **>(data_pointer + 1);
132 unsigned * immediate_pointer = reinterpret_cast<unsigned *>(label_pointer - 4);
133 DWORD old_protection;
134 SIZE_T const patch_size = 4;
135 if(!VirtualProtect(immediate_pointer, patch_size, PAGE_EXECUTE_READWRITE, &old_protection))
136 automap_blobs_interrupt();
137 unsigned & address = *immediate_pointer;
138 address += linking_offset;
139 DWORD unused;
140 if(!VirtualProtect(immediate_pointer, patch_size, old_protection, &unused))
141 automap_blobs_interrupt();
142 data_pointer += 5;
146 void __declspec(naked) automap_blobs()
148 __asm
150 //Initialisation code:
152 cmp module_base, 0
153 jnz is_already_initialised
155 pushad
156 call initialise_automap_blobs
157 popad
159 is_already_initialised:
161 //store the unit pointer so we can restore it later if necessary
162 mov unit_pointer, esi
164 //Actual code starts here:
166 sub esp, 10h
167 push ebp
168 push esi
169 mov esi, eax
170 test esi, esi
171 mov ebp, 6
172 jz loc_6FAEF932
173 mov ebp, ds:[esi]
174 loc_6FAEF932:
175 test ebp, ebp
176 mov byte ptr ds:[esp + 18h - 10h], 0
177 jnz loc_6FAEF975
178 test dword ptr ds:[esi + 0C4h], 10000h
179 jnz loc_6FAEF965
180 mov eax, ds:[esi]
181 sub eax, ebp
182 mov ecx, ds:[esi + 10h]
183 jz loc_6FAEF95C
184 dec eax
185 jnz loc_6FAEF975
186 test ecx, ecx
187 jz loc_6FAEF965
188 cmp ecx, 0Ch
189 jmp loc_6FAEF963
190 loc_6FAEF95C:
191 test ecx, ecx
192 jz loc_6FAEF965
193 cmp ecx, 11h
194 loc_6FAEF963:
195 jnz loc_6FAEF975
196 loc_6FAEF965:
197 push 7
198 push esi
199 call get_unit_state
200 test eax, eax
201 jz loc_6FAEFC2C
202 loc_6FAEF975:
203 push ebx
204 lea ebx, ds:[esp + 1Ch - 10h]
207 mov eax, esi
208 call automap_unit_type_check
211 //<modification>
213 mov eax, esi
214 call automap_unit_type_check
216 //fix esi and always have the check pass, keep the colour around though
217 mov esi, unit_pointer
218 mov eax, 1
220 //</modification>
222 test eax, eax
223 jz dont_draw_unit
224 push edi
225 push esi
226 call get_x_coordinate
227 push esi
228 mov edi, eax
229 call get_y_coordinate
230 mov ebx, ds:[06FBA3B98h]
231 linker_address_0:
232 mov ecx, eax
233 mov eax, edi
235 idiv ebx
236 mov edx, ds:[06FBCC2E8h]
237 linker_address_1:
238 mov edi, eax
239 sub edi, edx
240 mov eax, ecx
242 idiv ebx
243 mov edx, ds:[06FBCC2ECh]
244 linker_address_2:
245 add edi, 8
246 mov ebx, eax
247 mov eax, ds:[06FBCC318h]
248 linker_address_3:
249 sub ebx, edx
250 sub ebx, 8
251 cmp edi, eax
252 jl loc_6FAEFC2A
253 cmp edi, ds:[06FBCC320h]
254 linker_address_4:
255 jg loc_6FAEFC2A
256 cmp ebx, ds:[06FBCC31Ch]
257 linker_address_5:
258 jl loc_6FAEFC2A
259 cmp ebx, ds:[06FBCC324h]
260 linker_address_6:
261 jg loc_6FAEFC2A
262 mov eax, ebp
263 sub eax, 0
264 jz loc_6FAEFBCD
265 dec eax
266 jz loc_6FAEFA80
267 dec eax
268 jnz loc_6FAEFC2A
269 mov eax, ds:[06FBA3BA4h]
270 linker_address_7:
271 test eax, eax
272 jz loc_6FAEFA6A
273 test esi, esi
274 jz loc_6FAEFA6A
275 cmp dword ptr ds:[esi + 4], 10Bh
276 jnz loc_6FAEFA6A
277 mov ecx, 6
278 call set_text_size
279 mov ecx, 0CF3h
280 mov ebp, eax
281 call D2Lang_10005
282 mov esi, eax
283 movzx eax, byte ptr ds:[esp + 20h - 10h]
284 push 0
285 push eax
286 add ebx, 0FFFFFFF6h
287 push ebx
288 mov ecx, esi
289 call D2Win_10132
291 sub eax, edx
292 sar eax, 1
293 mov edx, edi
294 sub edx, eax
295 mov ecx, esi
296 call draw_text
297 mov ecx, ebp
298 call set_text_size
299 pop edi
300 pop ebx
301 pop esi
302 pop ebp
303 add esp, 10h
304 retn
305 loc_6FAEFA6A:
306 mov ecx, ds:[esp + 20h - 10h]
307 push ecx
308 mov eax, ebx
309 mov ecx, edi
311 //call draw_cross
312 call intercept_draw_cross
314 pop edi
315 pop ebx
316 pop esi
317 pop ebp
318 add esp, 10h
319 retn
320 loc_6FAEFA80:
321 mov edx, ds:[esp + 20h - 10h]
322 push edx
323 mov eax, ebx
324 mov ecx, edi
326 //call draw_cross
327 call intercept_draw_cross
329 mov eax, ds:[06FBA3BA4h]
330 linker_address_8:
331 test eax, eax
332 jz loc_6FAEFC2A
333 test esi, esi
334 jnz loc_6FAEFAA4
335 or eax, 0FFFFFFFFh
336 jmp loc_6FAEFAA7
337 loc_6FAEFAA4:
338 mov eax, ds:[esi + 4]
339 loc_6FAEFAA7:
340 mov edx, 9
341 call sub_6FAB2D40
342 test eax, eax
343 jz loc_6FAEFAF4
344 mov ecx, 6
345 call set_text_size
346 mov ds:[esp + 20h - 10h], eax
347 mov eax, esi
348 call sub_6FACF3D0
349 push 0
350 mov ebp, eax
351 push 4
352 lea eax, ds:[ebx - 0Ah]
353 push eax
354 mov ecx, ebp
355 call D2Win_10132
357 sub eax, edx
358 sar eax, 1
359 mov edx, edi
360 sub edx, eax
361 mov ecx, ebp
362 call draw_text
363 mov ecx, ds:[esp + 20h - 10h]
364 call set_text_size
365 loc_6FAEFAF4:
366 mov eax, ds:[06FBA3BA4h]
367 linker_address_9:
368 test eax, eax
369 jz loc_6FAEFC2A
370 mov eax, ds:[06FBA3BA0h]
371 linker_address_10:
372 test eax, eax
373 jz loc_6FAEFC2A
374 test esi, esi
375 mov eax, 6
376 jz loc_6FAEFB19
377 mov eax, ds:[esi]
378 loc_6FAEFB19:
379 test esi, esi
380 mov ds:[esp + 20h - 10h], eax
381 jnz loc_6FAEFB26
382 or eax, 0FFFFFFFFh
383 jmp loc_6FAEFB29
384 loc_6FAEFB26:
385 mov eax, ds:[esi + 4]
386 loc_6FAEFB29:
387 test esi, esi
388 mov ds:[esp + 20h - 8], eax
389 jnz loc_6FAEFB35
390 xor eax, eax
391 jmp loc_6FAEFB38
392 loc_6FAEFB35:
393 mov eax, ds:[esi + 10h]
394 loc_6FAEFB38:
395 push 0A15h
396 push 06FB85D18h
397 linker_address_11:
398 lea ecx, ds:[esp + 28h - 0Ch]
399 push ecx
400 lea edx, ds:[esp + 2Ch - 8]
401 mov ds:[esp + 2Ch - 0Ch], eax
402 push edx
403 lea eax, ds:[esp + 30h - 10h]
404 push eax
405 push esi
406 call D2Common_10350
407 mov eax, ds:[esp + 20h - 10h]
408 test eax, eax
409 jnz loc_6FAEFC2A
410 push 25h
411 push esi
412 call D2Common_10195
413 test eax, eax
414 jz loc_6FAEFC2A
415 mov eax, esi
416 call sub_6FACF710
417 mov ebp, eax
418 test ebp, ebp
419 jz loc_6FAEFC2A
420 cmp dword ptr ds:[ebp + 0], 0
421 jnz loc_6FAEFC2A
422 mov eax, ds:[06FBCC3D0h]
423 linker_address_12:
424 call sub_6FACF780
425 cmp ax, 0FFFFh
426 mov ds:[esp + 20h - 4], eax
427 jz loc_6FAEFBB4
428 mov eax, esi
429 call sub_6FACF780
430 cmp word ptr ds:[esp + 20h - 4], ax
431 jz loc_6FAEFC2A
432 loc_6FAEFBB4:
433 push 1
434 push ebx
435 push edi
436 push ebp
437 call D2Common_10860
438 mov ebx, eax
439 call sub_6FAEDE00
440 pop edi
441 pop ebx
442 pop esi
443 pop ebp
444 add esp, 10h
445 retn
446 loc_6FAEFBCD:
447 mov eax, ds:[06FBA3BA0h]
448 linker_address_13:
449 test eax, eax
450 jnz loc_6FAEFBE2
451 mov cl, byte ptr ds:[esp + 20h - 10h]
452 cmp cl, ds:[06FBCC303h]
453 linker_address_14:
454 jz loc_6FAEFBF0
455 loc_6FAEFBE2:
456 mov edx, ds:[esp + 20h - 10h]
457 push edx
458 mov eax, ebx
459 mov ecx, edi
461 //call draw_cross
462 call intercept_draw_cross
464 loc_6FAEFBF0:
465 mov eax, ds:[06FBA3BA4h]
466 linker_address_15:
467 test eax, eax
468 jz loc_6FAEFC2A
469 mov eax, ds:[06FBA3BA0h]
470 linker_address_16:
471 test eax, eax
472 jz loc_6FAEFC2A
473 cmp esi, ds:[06FBCC3D0h]
474 linker_address_17:
475 jz loc_6FAEFC2A
476 mov al, ds:[06FBCC303h]
477 linker_address_18:
478 cmp byte ptr ds:[esp + 20h - 10h], al
479 jnz loc_6FAEFC19
480 push 2
481 jmp loc_6FAEFC1B
482 loc_6FAEFC19:
483 push 1
484 loc_6FAEFC1B:
485 push ebx
486 push edi
487 push esi
488 call D2Common_10860
489 mov ebx, eax
490 call sub_6FAEDE00
491 loc_6FAEFC2A:
492 pop edi
493 dont_draw_unit:
494 pop ebx
495 loc_6FAEFC2C:
496 pop esi
497 pop ebp
498 add esp, 10h
499 retn
501 //Instruction address table hack:
508 push linker_address_0
509 push linker_address_1
510 push linker_address_2
511 push linker_address_3
512 push linker_address_4
513 push linker_address_5
514 push linker_address_6
515 push linker_address_7
516 push linker_address_8
517 push linker_address_9
518 push linker_address_10
519 push linker_address_11
520 push linker_address_12
521 push linker_address_13
522 push linker_address_14
523 push linker_address_15
524 push linker_address_16
525 push linker_address_17
526 push linker_address_18