Reverse engineering Diablo v1.09b (last patch)
#13
O.K! SO! This is now where I'm at in my journey towards trying to understand how Diablo loads items and deals with that 'magic' item header (definitely 4-bytes in length) + 4-bytes for an alternate item header (appears to affect both magic items and unique items).

Upon loading a game in Diablo (minus normal routines; which I need to do more research on), the jist of program flow goes like this:
  • Recursively call 'itemGeneration()' function 7-times (copying to a separate character/item buffer); "ActiveItems" (worn items)
  • Recursively call 'itemGeneration()' function 40-times (copying to a separate character/item buffer) "InactiveItems" (inventory items)
  • Recursively call 'itemGeneration()' function 8-times (copying to character/item buffer); "ActiveItems" (worn items) + belt(?)
  • Recursively call 'itemGeneration()' function 40-times (copying to character/item buffer) "InactiveItems" (inventory items)
END LIST

At this point: I am still completely lost as to how it's generating the affixes (prefixes/suffixes) for magical items.
I can definitively say that it is using some sort of linked-list structure of pointers to items (which are structures of pointers? with the item name (string) and respective static data for that type of item).

Hopefully I'll have an update later today.

The counter for these iterations is stored in the .data:
Code:
0018F7C4 = counter for looping

Beginning of epoch:
Code:
00448C44 | 8B 55 FC                 | mov     edx,dword ptr ss:[ebp-0x4]                | Pointer to empty data segment
00448C47 | 8B 4D 08                 | mov     ecx,dword ptr ss:[ebp+0x8]                | Pointer to empty data segment (item???)
00448C4A | E8 F9 00 00 00           | call    <diablo_copy.itemGenerationFromFile()>    |
00448C4F | 83 45 08 13              | add     dword ptr ss:[ebp+0x8],0x13               | Address of pointer to: ????
00448C53 | 01 5D FC                 | add     dword ptr ss:[ebp-0x4],ebx                | Address of pointer to: Item header (4 bytes)
00448C56 | FF 4D F8                 | dec     dword ptr ss:[ebp-0x8]                    |
00448C59 | 75 E9                    | jne     diablo_copy.448C44                        |

...

00448D48 | 56                       | push    esi                                       | itemGenerationFromFile()

As far as I understand: An individual item is 76 bytes in size; This appears to be circumstantial.
Worn items seem to be 0x170 (368 bytes) apart from one another. I am not sure why.

Code:
00448D48 | 56                       | push    esi                                       | -- EBX = 0x170 (368 bytes)
This coincides between the "no item" value of 0xFF 0xFF 0xFF 0xFF (which comes after the ~8 byte item header).

Code:
0x00686934: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF ; No item in the character's helm(?) slot

EDIT: WOW! Is all I can say.

Diablo is INCREDIBLY[I] horrible with dealing with writing data. Horrendously inefficient in terms of senselessly, constantly rechecking the [I]same value, then writing over it, then changing it right back again without reason, only to move forward...

Also: It's been about ~11hrs consecutive hours since I made this post.
THAT is how long it took me to step through the generation of only one item from a saved character file.

What did I learn regarding the item header? It'd appear (from everything I saw) to be 100% random.
Which flings back to the idea of 'unique item ID' and not prefix/suffix setter.

I am confused, yet again! Sad

Perhaps there were optional flag jumps that were skipped due to the item header being 0x00 0x00 0x00 0x00 and the 5th byte 0xCF ("of Crimson" suffix).

I did have some fun adding comments and documenting what these (inline, as far as I can tell) functions are though.

Code:
00469B10 | 83 EC 20                 | sub     esp,0x20                                  | ConvertTokensToStrings()
0046CF90 | 53                       | push    ebx                                       | CopyPointerStringToBuffer()
0042084A | 55                       | push    ebp                                       | SpawnItem()
0041FD98 | 53                       | push    ebx                                       | CreateItem()
0042254A | 55                       | push    ebp                                       | TempItemGeneration() (from player file)
0046B970 | 51                       | push    ecx                                       | ConvertToAllLowercase()
00448D48 | 56                       | push    esi                                       | ItemGenerationFromFile()
00405295 | 33 D2                    | xor     edx,edx                                   | WriteStringToBuffer()
00469D80 | 57                       | push    edi                                       | WriteString()
Reply


Messages In This Thread
RE: Reverse engineering Diablo v1.09b (last patch) - by TheKillerVortex - 02-02-2018, 09:45 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)