01-28-2018, 06:04 AM
Hello.
Does anyone here have a compiled list of any sort of data regarding Diablo? It does not have to be 'of interest' (which is relative from person-to-person).
For instance:
This entire function pertains to spell casting, but this is before(?) the "in-town" check is performed AFAIK.
You can manually edit the EAX register for the one-time-call on Charged Bolt (0x34), then modify the actual function call in the loop (push XX). The loop counter is directly affected by the level of the Charged Bolt (which is 'protected' I believe (the value is constantly written to in two different locations)).
You can in essence create a multi-shot Firebolt (spawn 15+ Firebolts that are all stacked). It'll "pierce" through a target (visual effect) and hit the next target and so on and so forth. The movzx is what sets the EAX register to 0x34, which is read inside the function (0045764E | E8 87 5D FD FF | call <diablo_copy.sub_42D3DA>).
If you are new to reverse engineering or are simply interested in learning: Feel free to ask questions and I will provide as many in-depth explanations as I can.
If you are very familiar with reverse engineering Diablo: I'd love to pick your brain on a few topics of how Diablo was written.
Thanks in advance!
Does anyone here have a compiled list of any sort of data regarding Diablo? It does not have to be 'of interest' (which is relative from person-to-person).
For instance:
Code:
004575D5 | 55 | push ebp | Spell-casting related
004575D6 | 8B EC | mov ebp,esp |
004575D8 | 51 | push ecx |
004575D9 | 51 | push ecx |
004575DA | 8B 45 18 | mov eax,dword ptr ss:[ebp+0x18] |
004575DD | 53 | push ebx |
004575DE | 33 DB | xor ebx,ebx |
004575E0 | 56 | push esi |
004575E1 | 2B C3 | sub eax,ebx |
004575E3 | 89 4D FC | mov dword ptr ss:[ebp-0x4],ecx |
004575E6 | 74 11 | je diablo_copy.4575F9 |
004575E8 | 48 | dec eax |
004575E9 | 75 30 | jne diablo_copy.45761B |
004575EB | 69 C9 E4 00 00 00 | imul ecx,ecx,0xE4 |
004575F1 | 8B 81 78 D3 64 00 | mov eax,dword ptr ds:[ecx+0x64D378] |
004575F7 | EB 1F | jmp diablo_copy.457618 |
004575F9 | 8B C1 | mov eax,ecx |
004575FB | 89 5D 18 | mov dword ptr ss:[ebp+0x18],ebx | ebp+18:LocalFree
004575FE | 69 C0 D8 54 00 00 | imul eax,eax,0x54D8 | Setting EDX here modifies the casted spell
00457604 | 83 FA 06 | cmp edx,0x6 | EDX = Spell index
00457607 | 8B 88 B8 64 68 00 | mov ecx,dword ptr ds:[eax+0x6864B8] | ECX = Position in relation to the character
0045760D | 89 4D F8 | mov dword ptr ss:[ebp-0x8],ecx |
00457610 | 75 09 | jne diablo_copy.45761B |
00457612 | 8B 80 24 66 68 00 | mov eax,dword ptr ds:[eax+0x686624] | Special case: Firewall only
00457618 | 89 45 F8 | mov dword ptr ss:[ebp-0x8],eax |
0045761B | 6B D2 38 | imul edx,edx,0x38 | Multiplies EDX by 0x38
0045761E | 57 | push edi |
0045761F | 33 FF | xor edi,edi | edi:PeekMessageA
00457621 | 8D B2 E9 23 4A 00 | lea esi,dword ptr ds:[edx+0x4A23E9] |
00457627 | 38 1E | cmp byte ptr ds:[esi],bl |
00457629 | 74 2E | je diablo_copy.457659 | Prevents spell casting (JMP)
0045762B | 83 FF 03 | cmp edi,0x3 | EDX is the spell index?
0045762E | 7D 29 | jge diablo_copy.457659 | Prevents spells from having any effect (minus audio/character "spell animation")
00457630 | FF 75 1C | push dword ptr ss:[ebp+0x1C] | "In-town check" not received yet
00457633 | 8B 55 0C | mov edx,dword ptr ss:[ebp+0xC] |
00457636 | 0F B6 04 3E | movzx eax,byte ptr ds:[esi+edi] | Loads Charged Bolt?
0045763A | 53 | push ebx |
0045763B | 8B 4D 08 | mov ecx,dword ptr ss:[ebp+0x8] |
0045763E | FF 75 FC | push dword ptr ss:[ebp-0x4] |
00457641 | FF 75 18 | push dword ptr ss:[ebp+0x18] | ebp+18:LocalFree
00457644 | 50 | push eax |
00457645 | FF 75 F8 | push dword ptr ss:[ebp-0x8] |
00457648 | FF 75 14 | push dword ptr ss:[ebp+0x14] |
0045764B | FF 75 10 | push dword ptr ss:[ebp+0x10] |
0045764E | E8 87 5D FD FF | call <diablo_copy.sub_42D3DA> | Spell animation / Casting
00457653 | 47 | inc edi | edi:PeekMessageA
00457654 | 38 1C 3E | cmp byte ptr ds:[esi+edi],bl |
00457657 | 75 D2 | jne diablo_copy.45762B |
00457659 | 80 3E 0A | cmp byte ptr ds:[esi],0xA | A:'\n'
0045765C | 5F | pop edi | edi:PeekMessageA
0045765D | 75 0B | jne diablo_copy.45766A | ECX holds spell index
0045765F | 8B 4D FC | mov ecx,dword ptr ss:[ebp-0x4] |
00457662 | 6A 07 | push 0x7 |
00457664 | 5A | pop edx | EDX holds spell index again
00457665 | E8 D0 FE FF FF | call <diablo_copy.sub_45753A> |
0045766A | 80 3E 34 | cmp byte ptr ds:[esi],0x34 | 34:'4'
0045766D | 75 3C | jne diablo_copy.4576AB |
0045766F | 8B 4D FC | mov ecx,dword ptr ss:[ebp-0x4] | Special case: Charged Bolt
00457672 | 6A 1E | push 0x1E | Charged Bolt spell index (1E)
00457674 | 5A | pop edx | push/pop set EDX to Charged Bolt spell index (1E)
00457675 | E8 C0 FE FF FF | call <diablo_copy.sub_45753A> |
0045767A | 8B 45 1C | mov eax,dword ptr ss:[ebp+0x1C] |
0045767D | D1 F8 | sar eax,0x1 |
0045767F | 83 C0 03 | add eax,0x3 | Sets EAX = 10, then copies to ESI
00457682 | 3B C3 | cmp eax,ebx |
00457684 | 7E 25 | jle diablo_copy.4576AB | JMP = 1x1 Charged Bolt
00457686 | 8B F0 | mov esi,eax |
00457688 | FF 75 1C | push dword ptr ss:[ebp+0x1C] |
0045768B | 8B 55 0C | mov edx,dword ptr ss:[ebp+0xC] |
0045768E | 8B 4D 08 | mov ecx,dword ptr ss:[ebp+0x8] |
00457691 | 53 | push ebx |
00457692 | FF 75 FC | push dword ptr ss:[ebp-0x4] |
00457695 | FF 75 18 | push dword ptr ss:[ebp+0x18] |
00457698 | 6A 06 | push 0x6 | Flag for Charged Bolt?
0045769A | FF 75 F8 | push dword ptr ss:[ebp-0x8] |
0045769D | FF 75 14 | push dword ptr ss:[ebp+0x14] |
004576A0 | FF 75 10 | push dword ptr ss:[ebp+0x10] |
004576A3 | E8 32 5D FD FF | call <diablo_copy.sub_42D3DA> |
004576A8 | 4E | dec esi |
004576A9 | 75 DD | jne diablo_copy.457688 | ESI = Loop counter (# of Charged Bolts?)
004576AB | 5E | pop esi |
004576AC | 5B | pop ebx |
004576AD | C9 | leave |
004576AE | C2 18 00 | ret 0x18 |
This entire function pertains to spell casting, but this is before(?) the "in-town" check is performed AFAIK.
You can manually edit the EAX register for the one-time-call on Charged Bolt (0x34), then modify the actual function call in the loop (push XX). The loop counter is directly affected by the level of the Charged Bolt (which is 'protected' I believe (the value is constantly written to in two different locations)).
You can in essence create a multi-shot Firebolt (spawn 15+ Firebolts that are all stacked). It'll "pierce" through a target (visual effect) and hit the next target and so on and so forth. The movzx is what sets the EAX register to 0x34, which is read inside the function (0045764E | E8 87 5D FD FF | call <diablo_copy.sub_42D3DA>).
If you are new to reverse engineering or are simply interested in learning: Feel free to ask questions and I will provide as many in-depth explanations as I can.
If you are very familiar with reverse engineering Diablo: I'd love to pick your brain on a few topics of how Diablo was written.
Thanks in advance!