Improved and moved the address conflict checking to CheckAddress.cpp/h

Added ddraw_CheckAddr.ini file to check conflicts properly.
Some code fixes/edits.
This commit is contained in:
NovaRain
2019-10-29 10:41:03 +08:00
parent 0570062123
commit 0d023c32db
14 changed files with 1014 additions and 67 deletions
+1 -2
View File
@@ -94,7 +94,7 @@ GPUBlt=0
Use32BitHeadGraphics=0 Use32BitHeadGraphics=0
;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies ;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies
;Requires graphics mode 4 or 5 ;Requires DX9 graphics mode 4 or 5
AllowDShowMovies=0 AllowDShowMovies=0
;Fade effect time percentage modifier ;Fade effect time percentage modifier
@@ -797,7 +797,6 @@ AlwaysFindScripts=0
Test_ForceFloats=0 Test_ForceFloats=0
;These options control what output is saved in the debug log (sfall-log.txt) ;These options control what output is saved in the debug log (sfall-log.txt)
;Prints messages duing sfall initialization ;Prints messages duing sfall initialization
Init=0 Init=0
;Prints messages relating to hook scripts ;Prints messages relating to hook scripts
+173
View File
@@ -0,0 +1,173 @@
#include "main.h"
#include "CheckAddress.h"
namespace sfall
{
#ifndef NDEBUG
std::multimap<long, long> writeAddress;
static std::vector<long> excludeAddr = {
0x42a14f,
0x42a178,
//0x43C77D, // for 0x43C77C
};
struct HackPair {
long addr;
long len;
HackPair(long addr, long len) : addr(addr), len(len) {}
};
static std::vector<HackPair> hackAddr = {
// scripting: Anims
{0x459C97, 1}, {0x459D4B, 1}, {0x459E3B, 1}, {0x459EEB, 1}, {0x459F9F, 1}, {0x45A053, 1}, {0x45A10B, 1}, {0x45AE53, 1},
// scripting: Misc
{0x495C50, 4}, {0x495C77, 6}, {0x495CEC, 6}, {0x495CFB, 1}, {0x495BF1, 5}, {0x4AFBC1, 1}, {0x4AFC1C, 2},
// scripting: Perks
{0x424AB6, 1}, {0x4AFAE2, 4},
{0x49687F, 1}, {0x496880, 4}, // hookcall
// scripting: Stats
{0x43C27A, 1}, {0x4AFABD, 5},
// scripting: Worldmap
{0x4C06D1, 5},
// module: AI
{0x4290B6, 5},
// module: BarBoxes
{0x461342, 5}, {0x461243, 5},
{0x461493, 5}, //{0x461495, 1},
{0x461513, 1}, {0x461718, 1}, {0x46170A, 1},
// module: Books
{0x49B9FB, 5},
// module: Combat
{0x478EC6, 1}, {0x478EC7, 4}, // hookcall
// module: CritterStats
{0x4AF761, 1}, {0x4AF762, 4}, // hookcall
// module: DamageMod
{0x4722DD, 1}, {0x4722DE, 4}, {0x472309, 1}, {0x47230A, 4}, // hookcalls
// module: Debug
{0x48007E, 1},
// module: Drugs
{0x479EEC, 5}, {0x43C15C, 5}, {0x47A5B8, 5}, {0x47A50C, 5},
{0x47A523, 4}, {0x47A527, 1}, {0x47A3A8, 1},
// module: Explosions
{0x49BCC7, 5}, {0x49BD56, 5}, {0x4A2865, 5}, {0x4737F2, 5}, {0x49C005, 5},
{0x411B54, 1}, {0x423C93, 1},
{0x411A19, 4}, {0x411A29, 4}, {0x411A35, 4}, {0x411A3C, 4},
{0x479183, 4}, {0x47918B, 4},
{0x411709, 1}, {0x4119FC, 1}, {0x411C08, 1}, {0x4517C1, 1}, {0x423BC8, 1}, {0x42381A, 1},
// module: ExtraSave
//{0x47B923, 6},
// module: Inventory
// module: LoadOrder
{0x43FA9F, 4}, {0x44EB5B, 4}, {0x48152E, 4},
//{0x480A95, 5}, (it in movies.cpp)
// module: MainMenu
{0x481753, 4}, {0x48175C, 4}, {0x481748, 4},
// module: Message
{0x484B18, 1}, {0x484B19, 4}, // hookcall
// module: Movies
{0x44E937, 1}, {0x44E938, 4}, {0x44E949, 1}, {0x44E94A, 4}, // hookcalls
//{0x4A378B, 5}, {0x4A36EC, 4}, {0x4A3747, 4}, {0x4A376A, 4},
// module: Objects
{0x4A364A, 5}, {0x4831D9, 1}, {0x4831DA, 1},
{0x4841D6, 1}, {0x4841D7, 4}, // hookcall
// module: PartyControl
{0x422BDE, 1}, {0x4229EC, 1},
{0x49EB09, 1}, {0x49EB0A, 4}, {0x458242, 1}, {0x458243, 4}, {0x458326, 1}, {0x458327, 4}, // hookcalls
// module: Perks
{0x43C77C, 1}, {0x43C77D, 4}, // hookcall
{0x478AC4, 1}, {0x478AC5, 4}, {0x496823, 5},
{0x496C2D, 1}, {0x496C2E, 4}, {0x496D11, 1}, {0x496D12, 4}, // hookcalls
// trait hookcalls
{0x4245E0, 1}, {0x4245E1, 4}, {0x4248F9, 1}, {0x4248FA, 4}, {0x478C8A, 1}, {0x478C8B, 4},
{0x478E70, 1}, {0x478E71, 4}, {0x410707, 1}, {0x410708, 4}, {0x42389F, 1}, {0x4238A0, 4},
{0x47A0CD, 1}, {0x47A0CE, 4}, {0x47A51A, 1}, {0x47A51B, 4}, {0x479BE1, 1}, {0x479BE2, 4},
{0x47A0DD, 1}, {0x47A0DE, 4}, {0x43C295, 1}, {0x43C296, 4}, {0x43C2F3, 1}, {0x43C2F4, 4},
{0x43C2A4, 1}, {0x43C2A5, 4}, {0x44272E, 1}, {0x44272F, 4},
// end
{0x4B3C7C, 5}, {0x4B40FC, 5},
{0x4B3A81, 4}, {0x4B3B80, 4}, {0x4B3AAE, 4}, {0x4B3BA0, 4}, {0x4B3BC0, 4},
{0x478E75, 5},
{0x42448E, 4}, {0x424489, 4}, {0x424474, 4},
{0x42465D, 1}, {0x424636, 1}, {0x4251CE, 1},
// module: Player model
{0x418B88, 4}, {0x418BAB, 4}, {0x418B50, 4}, {0x418B6D, 4},
// module: Skills
{0x4AA59D, 5}, {0x4AA738, 5}, {0x4AA940, 5},
{0x4AA9E1, 1}, {0x4AA9E2, 4}, {0x4AA9F1, 1}, {0x4AA9F2, 4}, {0x4AA9EC, 1}, {0x4AA9ED, 4}, // hookcalls
// module: Stats
{0x4AF6FC, 5},
// module: Worldmap
{0x4A33B8, 6}, {0x4A34EC, 1}, {0x4A3544, 1},
{0x42E57A, 1}, {0x42E57B, 4}, // hookcall
{0x4C2D9B, 4}, {0x499FDE, 4},
{0x49952C, 1}, {0x497557, 1}, {0x42E587, 1}, {0x42E588, 4}, {0x499FD4, 2}, {0x499E93, 2},
// module: MiscPatches
{0x460BB6, 4}, {0x41276A, 1}, {0x480AAA, 4}, {0x444BA5, 4}, {0x444BCA, 4},
};
//static std::vector<long> jumpAddr = {
//};
// Checking for conflicts requires all options in ddraw.ini to be enabled
void PrintAddrList() {
long level = iniGetInt("Debugging", "Enable", 0, ::sfall::ddrawIni);
if (level < 10) hackAddr.clear();
std::vector<HackPair> sortAddr(hackAddr);
for (const auto &wa : writeAddress) {
sortAddr.emplace_back(wa.first, wa.second);
}
std::sort(sortAddr.begin(), sortAddr.end(), [](const HackPair &a, const HackPair &b) {
return (a.addr != b.addr) ? a.addr < b.addr : a.len < b.len;
});
unsigned long pa = 0, pl = 0;
for (const auto &el : sortAddr)
{
unsigned long diff = (pa) ? (el.addr - pa) : -1; // length between two addresses
if (diff == 0) {
dlog_f("0x%x L:%d [Overwriting]\n", DL_MAIN, el.addr, el.len);
} else if (diff < pl) {
dlog_f("0x%x L:%d [Conflict] with 0x%x L:%d\n", DL_MAIN, el.addr, el.len, pa, pl);
MessageBoxA(0, "Conflict detected!", "", MB_TASKMODAL);
} else if (level >= 11 && diff == pl) {
dlog_f("0x%x L:%d [Warning] Hacking near:0x%x\n", DL_MAIN, el.addr, el.len, pa);
} else if (level >= 12) {
dlog_f("0x%x L:%d\n", DL_MAIN, el.addr, el.len);
}
pa = el.addr;
pl = el.len;
}
}
void CheckConflict(DWORD addr, long len) {
if (writeAddress.find(addr) != writeAddress.cend()) {
if (std::find(excludeAddr.cbegin(), excludeAddr.cend(), addr) != excludeAddr.cend()) return;
char buf[64];
sprintf_s(buf, "Memory overwriting at address 0x%x", addr);
MessageBoxA(0, buf, "", MB_TASKMODAL);
}
writeAddress.emplace(addr, len);
}
void AddrAddToList(DWORD addr, long len) {
writeAddress.emplace(addr, len);
}
#else
void PrintAddrList() {}
void CheckConflict(DWORD addr, long len) {}
void AddrAddToList(DWORD addr, long len) {}
#endif
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
namespace sfall
{
void PrintAddrList();
void CheckConflict(DWORD addr, long len);
void AddrAddToList(DWORD addr, long len);
}
+1 -1
View File
@@ -113,7 +113,7 @@ static void LoadElevators(const char* elevFile) {
for (int i = 0; i < vanillaElevatorCount; i++) elevatorType[i] = i; for (int i = 0; i < vanillaElevatorCount; i++) elevatorType[i] = i;
char section[4]; char section[4];
if (elevFile) { if (elevFile && GetFileAttributes(elevFile) != INVALID_FILE_ATTRIBUTES) {
for (int i = 0; i < elevatorCount; i++) { for (int i = 0; i < elevatorCount; i++) {
_itoa_s(i, section, 10); _itoa_s(i, section, 10);
int type = iniGetInt(section, "Image", elevatorType[i], elevFile); int type = iniGetInt(section, "Image", elevatorType[i], elevFile);
+2 -3
View File
@@ -162,9 +162,8 @@ static void __stdcall InitExtraPatches() {
patchFiles.shrink_to_fit(); patchFiles.shrink_to_fit();
} }
static void __fastcall game_init_databases_hook() { static void __fastcall game_init_databases_hook() { // eax = _master_db_handle
fo::PathNode* master_patches; fo::PathNode* master_patches = (fo::PathNode*)fo::var::master_db_handle;
__asm mov master_patches, eax; // eax = _master_db_handle
if (!patchFiles.empty()) InitExtraPatches(); if (!patchFiles.empty()) InitExtraPatches();
+2 -2
View File
@@ -184,7 +184,6 @@ static void ClearReadExtraGameMsgFiles() {
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) { for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
fo::func::message_exit(it->second.get()); fo::func::message_exit(it->second.get());
} }
//gExtraGameMsgLists.clear();
} }
void Message::init() { void Message::init() {
@@ -192,11 +191,12 @@ void Message::init() {
LoadGameHook::OnGameInit() += FallbackEnglishLoadMsgFiles; LoadGameHook::OnGameInit() += FallbackEnglishLoadMsgFiles;
LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles; LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles;
LoadGameHook::OnBeforeGameClose() += ClearReadExtraGameMsgFiles;
LoadGameHook::OnGameReset() += ClearScriptAddedExtraGameMsg; LoadGameHook::OnGameReset() += ClearScriptAddedExtraGameMsg;
} }
void Message::exit() { void Message::exit() {
ClearReadExtraGameMsgFiles(); //gExtraGameMsgLists.clear();
} }
} }
+7 -7
View File
@@ -858,10 +858,10 @@ static void PerkSetup() {
if (!perksReInit) { if (!perksReInit) {
// _perk_data // _perk_data
SafeWriteBatch<DWORD>((DWORD)perks, {0x496669, 0x496837, 0x496BAD, 0x496C41, 0x496D25}); SafeWriteBatch<DWORD>((DWORD)perks, {0x496669, 0x496837, 0x496BAD, 0x496C41, 0x496D25});
SafeWrite32(0x496696, (DWORD)perks + 4); SafeWrite32(0x496696, (DWORD)&perks[0].description);
SafeWrite32(0x496BD1, (DWORD)perks + 4); SafeWrite32(0x496BD1, (DWORD)&perks[0].description);
SafeWrite32(0x496BF5, (DWORD)perks + 8); SafeWrite32(0x496BF5, (DWORD)&perks[0].image);
SafeWrite32(0x496AD4, (DWORD)perks + 12); SafeWrite32(0x496AD4, (DWORD)&perks[0].ranks);
} }
memcpy(perks, var::perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data memcpy(perks, var::perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
@@ -1121,9 +1121,9 @@ static void TraitSetup() {
// _trait_data // _trait_data
SafeWrite32(0x4B3A81, (DWORD)traits); SafeWrite32(0x4B3A81, (DWORD)traits);
SafeWrite32(0x4B3B80, (DWORD)traits); SafeWrite32(0x4B3B80, (DWORD)traits);
SafeWrite32(0x4B3AAE, (DWORD)traits + 4); SafeWrite32(0x4B3AAE, (DWORD)&traits[0].description);
SafeWrite32(0x4B3BA0, (DWORD)traits + 4); SafeWrite32(0x4B3BA0, (DWORD)&traits[0].description);
SafeWrite32(0x4B3BC0, (DWORD)traits + 8); SafeWrite32(0x4B3BC0, (DWORD)&traits[0].image);
char buf[512], num[5] = {'t'}; char buf[512], num[5] = {'t'};
char* num2 = &num[1]; char* num2 = &num[1];
+1 -1
View File
@@ -46,7 +46,7 @@ void Premade::init() {
SafeWrite32(0x51C8D4, count); SafeWrite32(0x51C8D4, count);
SafeWrite32(0x4A7D76, (DWORD)premade); SafeWrite32(0x4A7D76, (DWORD)premade);
SafeWrite32(0x4A8B1E, (DWORD)premade); SafeWrite32(0x4A8B1E, (DWORD)premade);
SafeWrite32(0x4A7E2C, (DWORD)premade + 20); SafeWrite32(0x4A7E2C, (DWORD)&premade[0].fid);
strcpy((char*)0x50AF68, premade[0].path); strcpy((char*)0x50AF68, premade[0].path);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
+1 -41
View File
@@ -1,4 +1,5 @@
#include "main.h" #include "main.h"
#include "CheckAddress.h"
namespace sfall namespace sfall
{ {
@@ -9,47 +10,6 @@ enum CodeType : BYTE {
Nop = 0x90 Nop = 0x90
}; };
#ifndef NDEBUG
std::multimap<long, long> writeAddress;
/* Checking for conflicts requires all options in ddraw.ini to be enabled */
void PrintAddrList() {
bool level = (iniGetInt("Debugging", "Enable", 0, ::sfall::ddrawIni) > 1);
unsigned long pa = 0, pl = 0;
for (const auto &wa : writeAddress) {
unsigned long diff = (pa) ? (wa.first - pa) : -1; // length between two addresses
if (diff == 0) {
dlog_f("0x%x L:%d [Overwriting]\n", DL_MAIN, wa.first, wa.second);
} else if (diff < pl) {
dlog_f("0x%x L:%d [Conflict] with 0x%x L:%d\n", DL_MAIN, wa.first, wa.second, pa, pl);
} else if (level && diff == pl) {
dlog_f("0x%x L:%d [Warning] PL:%d\n", DL_MAIN, wa.first, wa.second, pl);
} else if (level) {
dlog_f("0x%x L:%d\n", DL_MAIN, wa.first, wa.second);
}
pa = wa.first;
pl = wa.second;
}
}
void CheckConflict(DWORD addr, long len) {
if (writeAddress.find(addr) != writeAddress.cend()) {
char buf[64];
sprintf_s(buf, "Memory writing conflict at address 0x%x.", addr);
//dlogr(buf, DL_MAIN);
MessageBoxA(0, buf, "", MB_TASKMODAL);
}
writeAddress.emplace(addr, len);
}
void AddrAddToList(DWORD addr, long len) {
writeAddress.emplace(addr, len);
}
#else
void CheckConflict(DWORD addr, long len) {}
void AddrAddToList(DWORD addr, long len) {}
#endif
static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) { static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) {
DWORD oldProtect, data = (DWORD)func - (addr + 5); DWORD oldProtect, data = (DWORD)func - (addr + 5);
+2 -7
View File
@@ -3,23 +3,18 @@
#include <initializer_list> #include <initializer_list>
#include <Windows.h> #include <Windows.h>
#include "CheckAddress.h"
namespace sfall namespace sfall
{ {
#ifndef NDEBUG
void AddrAddToList(DWORD addr, long len);
void PrintAddrList();
#endif
template<typename T> void _stdcall SafeWrite(DWORD addr, T data) { template<typename T> void _stdcall SafeWrite(DWORD addr, T data) {
DWORD oldProtect; DWORD oldProtect;
VirtualProtect((void*)addr, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect); VirtualProtect((void*)addr, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect);
*((T*)addr) = data; *((T*)addr) = data;
VirtualProtect((void*)addr, sizeof(T), oldProtect, &oldProtect); VirtualProtect((void*)addr, sizeof(T), oldProtect, &oldProtect);
#ifndef NDEBUG
AddrAddToList(addr, sizeof(T)); AddrAddToList(addr, sizeof(T));
#endif
} }
template <typename T, class ForwardIteratorType> template <typename T, class ForwardIteratorType>
+2 -1
View File
@@ -23,8 +23,9 @@ T SimplePatch(DWORD *addrs, int numAddrs, const char* iniSection, const char* in
} }
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Applying patch: %s = %d.", iniKey, value); _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Applying patch: %s = %d.", iniKey, value);
dlog((const char*)msg, DL_INIT); dlog((const char*)msg, DL_INIT);
for (int i = 0; i < numAddrs; i++) for (int i = 0; i < numAddrs; i++) {
SafeWrite<T>(addrs[i], (T)value); SafeWrite<T>(addrs[i], (T)value);
}
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
return value; return value;
+3 -1
View File
@@ -45,7 +45,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v141</PlatformToolset> <PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@@ -277,6 +277,7 @@
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="CheckAddress.h" />
<ClInclude Include="Delegate.h" /> <ClInclude Include="Delegate.h" />
<ClInclude Include="FalloutEngine\Enums.h" /> <ClInclude Include="FalloutEngine\Enums.h" />
<ClInclude Include="FalloutEngine\Fallout2.h" /> <ClInclude Include="FalloutEngine\Fallout2.h" />
@@ -376,6 +377,7 @@
<ClInclude Include="Modules\ExtraSaveSlots.h" /> <ClInclude Include="Modules\ExtraSaveSlots.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="CheckAddress.cpp" />
<ClCompile Include="FalloutEngine\EngineUtils.cpp" /> <ClCompile Include="FalloutEngine\EngineUtils.cpp" />
<ClCompile Include="FalloutEngine\FunctionOffsets.cpp" /> <ClCompile Include="FalloutEngine\FunctionOffsets.cpp" />
<ClCompile Include="FalloutEngine\Variables.cpp" /> <ClCompile Include="FalloutEngine\Variables.cpp" />
+2
View File
@@ -285,6 +285,7 @@
<Filter>Modules</Filter> <Filter>Modules</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CRC.h" /> <ClInclude Include="CRC.h" />
<ClInclude Include="CheckAddress.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
@@ -530,6 +531,7 @@
<Filter>Modules</Filter> <Filter>Modules</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CRC.cpp" /> <ClCompile Include="CRC.cpp" />
<ClCompile Include="CheckAddress.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="version.rc" /> <ResourceCompile Include="version.rc" />
File diff suppressed because it is too large Load Diff