/*================================================================= File created by Yohann NICOLAS. Add support 1.13d by L'Autour. Add support 1.14d by haxifix. Changing the current save path. =================================================================*/ #include "savePath.h" #include "common.h" char* savePath = NULL; bool active_changingSavePath = false; FCT_ASM( changeSavePath ) PUSH EDI PUSH EDX PUSH ESI MOV EDI,DWORD PTR DS:[savePath] XOR AL,AL CLD OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] NOT ECX SUB EDI,ECX XCHG EDI,ESI CMP BYTE PTR [ESI+1],':' JE END_CHANGESP //RELATIVE_PATH: MOV EDX,ECX OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] DEC EDI CMP BYTE PTR [EDI-1],'\\' JE NEXT MOV BYTE PTR [EDI],'\\' INC EDI NEXT: MOV ECX,EDX END_CHANGESP: REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] POP ESI POP EDX POP EDI PUSH ESI CALL EBP CMP EAX,-1 RETN }} FCT_ASM( changeSavePath_114 ) PUSH EAX PUSH EDI PUSH EDX PUSH ESI MOV ESI, EBX MOV EDI,DWORD PTR DS:[savePath] XOR AL,AL CLD OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] NOT ECX SUB EDI,ECX XCHG EDI,ESI CMP BYTE PTR [ESI+1],':' JE END_CHANGESP //RELATIVE_PATH: MOV EDX,ECX OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] DEC EDI CMP BYTE PTR [EDI-1],'\\' JE NEXT MOV BYTE PTR [EDI],'\\' INC EDI NEXT: MOV ECX,EDX END_CHANGESP: REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] POP ESI POP EDX POP EDI POP EAX PUSH EBX CALL DWORD PTR[GetFileAttributesA] CMP EAX,-1 JE DONOT_JMP ADD DWORD PTR SS:[ESP],0x5 RETN DONOT_JMP: ADD DWORD PTR SS:[ESP],0x1D RETN }} FCT_ASM( changeSavePath_111 ) PUSH EAX PUSH EDI PUSH EDX PUSH ESI MOV EDI,DWORD PTR DS:[savePath] XOR AL,AL CLD OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] NOT ECX SUB EDI,ECX XCHG EDI,ESI CMP BYTE PTR [ESI+1],':' JE END_CHANGESP //RELATIVE_PATH: MOV EDX,ECX OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] DEC EDI CMP BYTE PTR [EDI-1],'\\' JE NEXT MOV BYTE PTR [EDI],'\\' INC EDI NEXT: MOV ECX,EDX END_CHANGESP: REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] POP ESI POP EDX POP EDI POP EAX CMP EAX,-1 JE DONOT_JMP ADD DWORD PTR SS:[ESP],5 DONOT_JMP: RETN }} FCT_ASM ( forCreateSavePath ) PUSH EDI MOV EDI,DWORD PTR DS:[savePath] MOV ECX,EDI CMP BYTE PTR DS:[EDI+1],':' JNZ END_CREATESP PUSH ESI XOR AL,AL CLD OR ECX,0xFFFFFFFF REPNE SCAS BYTE PTR ES:[EDI] NOT ECX SUB EDI,ECX XCHG EDI,ESI REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] POP ESI END_CREATESP: POP EDI MOV DWORD PTR SS:[ESP+8],ECX JMP D2Storm503 }} void Install_ChangingSavePath() { static int isInstalled = false; if (isInstalled) return; log_msg("Patch Fog for change the save path. (changingSavePath)\n"); if (version_Fog >= V111) { // Call funtion to manage subfolder mem_seek R8(Fog, 000, 000, 000, 185F6, 1C106, 1F086, 17F86, 1E146, 71A6); memt_byte( 0x83 ,0xE8); // CALL changeSavePath MEMT_REF4( 0x0575FFF8, version_Fog == V114d ? changeSavePath_114 : changeSavePath_111); //6FF685F6 . 83F8 FF CMP EAX,-1 //6FF685F9 . 75 05 JNZ SHORT fog.6FF68600 //6FF6C106 . 83F8 FF CMP EAX,-1 //6FF6C109 . 75 05 JNZ SHORT fog.6FF6C110 //6FF6F086 . 83F8 FF CMP EAX,-1 //6FF6F089 . 75 05 JNZ SHORT Fog.6FF6F090 //6FF67F86 . 83F8 FF CMP EAX,-1 //6FF67F89 . 75 05 JNZ SHORT Fog.6FF67F90 //6FF6E146 . 83F8 FF CMP EAX,-1 //6FF6E149 . 75 05 JNZ SHORT Fog.6FF50F64 //004071A6 |. 83F8 FF CMP EAX,-1 //004071A9 |. 75 05 JNZ SHORT Game.004071B0 // Create the right save path if (version_Fog < V114a) { mem_seek R8(Fog, 000, 000, 000, 18616, 1C126, 1F0A6, 17FA6, 1E166, 71CA); MEMJ_REF4( D2Storm503, forCreateSavePath); //6FF68615 . E8 A246FFFF CALL //6FF6C125 . E8 C20BFFFF CALL //6FF6F0A5 . E8 34DDFEFF CALL //6FF67FA5 . E8 504EFFFF CALL //6FF6E165 . E8 6AEBFEFF CALL //004071C9 |. E8 82C50000 CALL Game.00413750 ; \Game.00413750 } // Remove registry update mem_seek R8(Fog, 000, 000, 000, 1861A, 1C12A, 1F0AA, 17FAA, 1E16A, 71E9); memt_byte( version_Fog == V114d ? 0x53 : 0x56 ,0xEB); // JMP SHORT fog.6FF6862C memt_byte( 0x6A ,0x10); // memt_byte( version_Fog == V114d ? 0x01 : 0x00 ,0x90); // NOP //6FF6861A . 56 PUSH ESI //6FF6861B . 6A 00 PUSH 0 //6FF6861D . 68 7C7BF76F PUSH fog.6FF77B7C ; ASCII "Save Path" //6FF68622 . 68 2876F76F PUSH fog.6FF77628 ; ASCII "Diablo II" //6FF68627 . E8 1A47FFFF CALL //6FF6C12A . 56 PUSH ESI //6FF6C12B . 6A 00 PUSH 0 //6FF6C12D . 68 BC73F76F PUSH fog.6FF773BC ; ASCII "Save Path" //6FF6C132 . 68 C873F76F PUSH fog.6FF773C8 ; ASCII "Diablo II" //6FF6C137 . E8 E60BFFFF CALL //6FF6F0AA . 56 PUSH ESI //6FF6F0AB . 6A 00 PUSH 0 //6FF6F0AD . 68 D466F76F PUSH Fog.6FF766D4 ; ASCII "Save Path" //6FF6F0B2 . 68 E066F76F PUSH Fog.6FF766E0 ; ASCII "Diablo II" //6FF6F0B7 . E8 58DDFEFF CALL //6FF67FAA . 56 PUSH ESI //6FF67FAB . 6A 00 PUSH 0 //6FF6E16A . 56 PUSH ESI //6FF6E16B . 6A 00 PUSH 0 //004071E9 |> 53 PUSH EBX ; /Arg4 //004071EA |. 6A 01 PUSH 1 ; |Arg3 = 00000001 } else { // Call funtion to manage subfolder mem_seek( (DWORD)D2FogGetSavePath + 0x28);//6FF61928-6FF50000 memt_byte( 0x56 ,0x90); // NOP memt_byte( 0xFF ,0xE8); // CALL changeSavePath MEMT_REF4( 0xFFF883D5, changeSavePath); //6FF61928 56 PUSH ESI //6FF61929 FFD5 CALL EBP //6FF6192B 83F8 FF CMP EAX,-1 // Create the right save path mem_seek( (DWORD)D2FogGetSavePath + 0xBD);//6FF619BC MEMJ_REF4( D2Storm503, forCreateSavePath); //6FF619BC . E8 5D2A0000 CALL // Remove registry update mem_seek( (DWORD)D2FogGetSavePath + 0xC1);//6FF619C1-6FF50000 memt_byte( 0x56 ,0xEB); // JMP SHORT FOG.6FF619D2 memt_byte( 0x53 ,0x0F); //6FF619C3-6FF619D2 //6FF619C1 56 PUSH ESI //6FF619C2 53 PUSH EBX //6FF619C3 68 A877F76F PUSH Fog.6FF777A8 ; ASCII "Save Path" //6FF619C8 68 9068F76F PUSH Fog.6FF76890 ; ASCII "Diablo II" //6FF619CD E8 AC2A0000 CALL } log_msg("\n"); isInstalled = true; } /*================================= END OF FILE =================================*/