From a4730efe4d381bafd464eba6fca68b3fc1e391d7 Mon Sep 17 00:00:00 2001 From: Hash Borgir Date: Fri, 12 Apr 2024 14:49:22 -0600 Subject: [PATCH] Working Copy. --- D2Patch.h | 219 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 159 insertions(+), 60 deletions(-) diff --git a/D2Patch.h b/D2Patch.h index 86bc74f..15853cb 100644 --- a/D2Patch.h +++ b/D2Patch.h @@ -15,10 +15,7 @@ #include #include #include - - -// Function to read settings from D2Mod.ini file -#include +#include // Function to read setting from the INI file and provide detailed information int ReadSettingFromIni(const char* section, const char* key, int defaultValue) { @@ -34,36 +31,35 @@ int ReadSettingFromIni(const char* section, const char* key, int defaultValue) { // Try to read the setting from the INI file int value = GetPrivateProfileIntA(section, key, defaultValue, filePath); - //DWORD lastError = GetLastError(); - //if (value == 0 && lastError != 0) { - // // Error occurred while reading from INI file - // char errorMessage[512]; - // sprintf(errorMessage, "Error reading setting from INI file:\n\n" - // "INI File Path: %s\n" - // "Section: %s\n" - // "Key: %s\n" - // "Default Value: %d\n" - // "Error Code: %d\n\n" - // "Ensure that the section and key exist in the INI file and the file is accessible.", - // filePath, section, key, defaultValue, lastError); - // MessageBoxA(NULL, errorMessage, "INI File Error", MB_OK | MB_ICONERROR); - //} - //else { - // // Successfully read the setting - // char successMessage[256]; - // sprintf(successMessage, "Setting read from INI file:\n\n" - // "INI File Path: %s\n" - // "Section: %s\n" - // "Key: %s\n" - // "Value: %d", filePath, section, key, value); - // MessageBoxA(NULL, successMessage, "INI File Success", MB_OK | MB_ICONINFORMATION); - //} - + { + //DWORD lastError = GetLastError(); + //if (value == 0 && lastError != 0) { + // // Error occurred while reading from INI file + // char errorMessage[512]; + // sprintf(errorMessage, "Error reading setting from INI file:\n\n" + // "INI File Path: %s\n" + // "Section: %s\n" + // "Key: %s\n" + // "Default Value: %d\n" + // "Error Code: %d\n\n" + // "Ensure that the section and key exist in the INI file and the file is accessible.", + // filePath, section, key, defaultValue, lastError); + // MessageBoxA(NULL, errorMessage, "INI File Error", MB_OK | MB_ICONERROR); + //} + //else { + // // Successfully read the setting + // char successMessage[256]; + // sprintf(successMessage, "Setting read from INI file:\n\n" + // "INI File Path: %s\n" + // "Section: %s\n" + // "Key: %s\n" + // "Value: %d", filePath, section, key, value); + // MessageBoxA(NULL, successMessage, "INI File Success", MB_OK | MB_ICONINFORMATION); + //} + } return value; } - - // Function to calculate relative offset (D2COMMON base address is 0x6F600000) DWORD calculateRelativeOffsetD2Common(DWORD offset) { return offset - 0x6F600000; @@ -93,16 +89,134 @@ uint32_t reverseHexBytes(uint32_t hexNumber) { return reversedHex; } +/* +CPU Disasm +Address Hex dump Command Comments +6F68D570 > \85C0 TEST EAX,EAX +6F68D572 . 75 03 JNE SHORT 6F68D577 +6F68D574 . C2 0800 RETN 8 ; return FALSE if reqs are not met +6F68D577 > 8B44E4 04 MOV EAX,DWORD PTR SS:[ESP+4] ; pItem +6F68D57B . 8B40 2C MOV EAX,DWORD PTR DS:[EAX+2C] ; pitem->pPath +6F68D57E . 8378 0C 05 CMP DWORD PTR DS:[EAX+0C],5 ; pPath->posX, 5 == leftBorder +6F68D582 . 72 1A JB SHORT 6F68D59E +6F68D584 . 8378 0C 07 CMP DWORD PTR DS:[EAX+0C],7 ; pPath->posX, 7 == rightBorder +6F68D588 . 77 14 JA SHORT 6F68D59E +6F68D58A . 8378 10 03 CMP DWORD PTR DS:[EAX+10],3 ; pPath->posY, 3 == topBorder +6F68D58E . 72 0E JB SHORT 6F68D59E +6F68D590 . 8378 10 04 CMP DWORD PTR DS:[EAX+10],4 ; pPath->posY, 4 == botomBorder +6F68D594 . 77 08 JA SHORT 6F68D59E +6F68D596 . B8 01000000 MOV EAX,1 ; return TRUE +6F68D59B . C2 0800 RETN 8 +6F68D59E > 31C0 XOR EAX,EAX ; return FALSE +6F68D5A0 . C2 0800 RETN 8 +*/ + +__declspec(naked) void customD2CommonASM() { + __asm { + TEST EAX, EAX + JE NOT_IN_CHARM_ZONE + + // Load parameters + MOV EAX, DWORD PTR SS : [ESP + 0x04] + MOV EAX, DWORD PTR DS : [EAX + 0x2C] + + // Load border values into 8-bit registers + MOV CH, leftBorder + MOV CL, rightBorder + MOV DH, topBorder + MOV DL, bottomBorder + + // Check if within charm zone boundaries + CMP BYTE PTR DS : [EAX + 0x0C] , CH + JB NOT_IN_CHARM_ZONE + + CMP BYTE PTR DS : [EAX + 0x0C] , CL + JA NOT_IN_CHARM_ZONE + + CMP BYTE PTR DS : [EAX + 0x10] , DH + JB NOT_IN_CHARM_ZONE + + CMP BYTE PTR DS : [EAX + 0x10] , DL + JA NOT_IN_CHARM_ZONE + + // Return 1 if within charm zone + MOV EAX, 1 + RETN 8 + + // Return 0 otherwise + NOT_IN_CHARM_ZONE : + XOR EAX, EAX + RETN 8 + } +} + +/* + +6FAE118F /E9 6CB30800 JMP 6FB6C500 +6FAE1194 |90 NOP +6FAE1195 |90 NOP +6FAE1196 |90 NOP + +CPU Disasm +Address Hex dump Command Comments +6FB6C500 > \85C0 TEST EAX,EAX +6FB6C502 .^ 0F84 7B4DF7FF JE 6FAE1283 ; item reqs not met +6FB6C508 . 6A 0D PUSH 0D ; /Arg2 = 0D, 0xD == ITEMTYPE_CHARM +6FB6C50A . 56 PUSH ESI ; |Arg1, pItem +6FB6C50B . E8 10E7FFFF CALL ; \D2Common.#10731, IsItemOfItemType (CALL 6FB6AC20) +6FB6C510 . 85C0 TEST EAX,EAX +6FB6C512 .^ 0F84 7F4CF7FF JE 6FAE1197 ; no charm, so don't continue checking the charm zone +6FB6C518 . 8B44E4 20 MOV EAX,DWORD PTR SS:[ESP+20] ; pUnit +6FB6C51C . 50 PUSH EAX ; /Arg2, pUnit +6FB6C51D . 56 PUSH ESI ; |Arg1, pItem +6FB6C51E . E8 19EFFFFF CALL ; \D2Common.#10840, AreCharmReqsMet (CALL 6FB6B43C) +6FB6C523 . 85C0 TEST EAX,EAX +6FB6C525 .^ 0F84 584DF7FF JE 6FAE1283 ; charm reqs not met +6FB6C52B .^ E9 674CF7FF JMP 6FAE1197 ; charm reqs met + +*/ + +//D2Common.0x6FD9DCE0 (#10731) +D2FUNC(D2COMMON, 10731, BOOL, __stdcall, (const D2UnitStrc* pItem, int nItemType), -10731) + +//D2Common.0x6FD9FE70 (#10840) +D2FUNC(D2COMMON, 10840, BOOL, __stdcall, (D2UnitStrc* pItem, D2UnitStrc* pPlayer), -10840) + +// Currently not working as expected +__declspec(naked) void customD2ClientASM() { + __asm { + TEST EAX, EAX + JE lbl_not_found + PUSH 0xD + PUSH ESI + CALL D2COMMON_10731 + TEST EAX, EAX + JE lbl_not_found + MOV EAX, DWORD PTR SS : [ESP + 0x20] + PUSH EAX + PUSH ESI + CALL D2COMMON_10840 + TEST EAX, EAX + JE lbl_not_found + JMP lbl_found + lbl_not_found : + JMP lbl_not_found_address + lbl_found : + RET + + lbl_not_found_address : + MOV EAX, 0x6FAE1197 + JMP EAX + } +} + static const DLLPatchStrc gptTemplatePatches[] = { - ////////////////////////////// - // // - // D2COMMON PATCHES // - // // - ////////////////////////////// - {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F65FEF4), (DWORD)PATCH_JMP, FALSE, 0x01}, - {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F65FEF5), (DWORD)reverseHexBytes(0x77D60200), FALSE, 0x00}, - + // D2COMMON PATCHES + {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F65FEF4), (DWORD)(0xE9), FALSE, 0x01}, + {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F65FEF5), (DWORD)customD2CommonASM, TRUE, 0x00}, + + /* // Patching TEST EAX, EAX at address 0x6F68D570 {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F68D570), (DWORD)(0xC085), FALSE, 0x00}, // Patching JNE SHORT 6F68D577 at address 0x6F68D572 @@ -148,40 +262,32 @@ static const DLLPatchStrc gptTemplatePatches[] = {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F68D59E), (DWORD)(0xC031), FALSE, 0x0}, // Patching RETN 8 at address 0x6F68D5A0 {D2DLL_D2COMMON, calculateRelativeOffsetD2Common(0x6F68D5A0), (DWORD)(0x0008C2), FALSE, 0x0}, + */ - ////////////////////////////// - // // - // D2CLIENT PATCHES // - // // - ////////////////////////////// - - {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE118F), (DWORD)PATCH_JMP, FALSE, 0x00}, + // D2CLIENT PATCHES + // Patching JMP at address 0x6FAE118F + {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE118F), (DWORD)PATCH_JMP, FALSE, 0x01}, + //{D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE1190), (DWORD)customD2ClientASM, TRUE, 0x00}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE1190), (DWORD)reverseHexBytes(0x6CB30800), FALSE, 0x00}, - {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE1194), (DWORD)0x90, FALSE, 0x03}, + {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FAE1194), (DWORD)0x90, FALSE, 0x03}, // Patching TEST EAX,EAX at address 0x6FB6C500 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C500), (DWORD)(0xC085), FALSE, 0x00}, - // Patching JE 6FAE1283 at address 0x6FB6C502 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C502), (DWORD)(0x840F), FALSE, 0x00}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C504), (DWORD)reverseHexBytes(0x7B4DF7FF), FALSE, 0x00}, - // Patching PUSH 0D at address 0x6FB6C508 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C508), (DWORD)(0x0D6A), FALSE, 0x00}, - // Patching PUSH ESI at address 0x6FB6C50A {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C50A), (DWORD)(0x56), FALSE, 0x00}, - // Patching CALL at address 0x6FB6C50B {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C50B), (DWORD)(0xE8), FALSE, 0x01}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C50C), (DWORD)reverseHexBytes(0x10E7FFFF), FALSE, 0x00}, - // Patching TEST EAX,EAX at address 0x6FB6C510 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C510), (DWORD)(0xC085), FALSE, 0x00}, // Patching JE 6FAE1197 at address 0x6FB6C512 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C512), (DWORD)(0x840F), FALSE, 0x00}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C514), (DWORD)reverseHexBytes(0x7F4CF7FF), FALSE, 0x00}, - // Patching MOV EAX,DWORD PTR SS:[ESP+20] at address 0x6FB6C518 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C518), (DWORD)reverseHexBytes(0x8B44E420), FALSE, 0x00}, // Patching PUSH EAX at address 0x6FB6C51C @@ -191,22 +297,15 @@ static const DLLPatchStrc gptTemplatePatches[] = // Patching CALL at address 0x6FB6C51E {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C51E), (DWORD)(0xE8), FALSE, 0x01}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C51F), (DWORD)reverseHexBytes(0x19EFFFFF), FALSE, 0x00}, - - // Patching TEST EAX,EAX at address 0x6FB6C523 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C523), (DWORD)(0xC085), FALSE, 0x00}, - // Patching JE 6FAE1283 at address 0x6FB6C525 {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C525), (DWORD)(0x840F), FALSE, 0x00}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C527), (DWORD)reverseHexBytes(0x584DF7FF), FALSE, 0x00}, - // Patching JMP 6FAE1197 at address 0x6FB6C52B {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C52B), (DWORD)(0xE9), FALSE, 0x01}, {D2DLL_D2CLIENT, calculateRelativeOffsetD2Client(0x6FB6C52C), (DWORD)reverseHexBytes(0x674CF7FF), FALSE, 0x00}, - - - {D2DLL_INVALID} // this must be the last entry in the array! };