mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
+1
-2
@@ -94,7 +94,7 @@ GPUBlt=0
|
||||
Use32BitHeadGraphics=0
|
||||
|
||||
;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
|
||||
|
||||
;Fade effect time percentage modifier
|
||||
@@ -797,7 +797,6 @@ AlwaysFindScripts=0
|
||||
Test_ForceFloats=0
|
||||
|
||||
;These options control what output is saved in the debug log (sfall-log.txt)
|
||||
|
||||
;Prints messages duing sfall initialization
|
||||
Init=0
|
||||
;Prints messages relating to hook scripts
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
void PrintAddrList();
|
||||
void CheckConflict(DWORD addr, long len);
|
||||
void AddrAddToList(DWORD addr, long len);
|
||||
|
||||
}
|
||||
@@ -113,7 +113,7 @@ static void LoadElevators(const char* elevFile) {
|
||||
for (int i = 0; i < vanillaElevatorCount; i++) elevatorType[i] = i;
|
||||
|
||||
char section[4];
|
||||
if (elevFile) {
|
||||
if (elevFile && GetFileAttributes(elevFile) != INVALID_FILE_ATTRIBUTES) {
|
||||
for (int i = 0; i < elevatorCount; i++) {
|
||||
_itoa_s(i, section, 10);
|
||||
int type = iniGetInt(section, "Image", elevatorType[i], elevFile);
|
||||
|
||||
@@ -162,9 +162,8 @@ static void __stdcall InitExtraPatches() {
|
||||
patchFiles.shrink_to_fit();
|
||||
}
|
||||
|
||||
static void __fastcall game_init_databases_hook() {
|
||||
fo::PathNode* master_patches;
|
||||
__asm mov master_patches, eax; // eax = _master_db_handle
|
||||
static void __fastcall game_init_databases_hook() { // eax = _master_db_handle
|
||||
fo::PathNode* master_patches = (fo::PathNode*)fo::var::master_db_handle;
|
||||
|
||||
if (!patchFiles.empty()) InitExtraPatches();
|
||||
|
||||
|
||||
@@ -184,7 +184,6 @@ static void ClearReadExtraGameMsgFiles() {
|
||||
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
|
||||
fo::func::message_exit(it->second.get());
|
||||
}
|
||||
//gExtraGameMsgLists.clear();
|
||||
}
|
||||
|
||||
void Message::init() {
|
||||
@@ -192,11 +191,12 @@ void Message::init() {
|
||||
|
||||
LoadGameHook::OnGameInit() += FallbackEnglishLoadMsgFiles;
|
||||
LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles;
|
||||
LoadGameHook::OnBeforeGameClose() += ClearReadExtraGameMsgFiles;
|
||||
LoadGameHook::OnGameReset() += ClearScriptAddedExtraGameMsg;
|
||||
}
|
||||
|
||||
void Message::exit() {
|
||||
ClearReadExtraGameMsgFiles();
|
||||
//gExtraGameMsgLists.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -858,10 +858,10 @@ static void PerkSetup() {
|
||||
if (!perksReInit) {
|
||||
// _perk_data
|
||||
SafeWriteBatch<DWORD>((DWORD)perks, {0x496669, 0x496837, 0x496BAD, 0x496C41, 0x496D25});
|
||||
SafeWrite32(0x496696, (DWORD)perks + 4);
|
||||
SafeWrite32(0x496BD1, (DWORD)perks + 4);
|
||||
SafeWrite32(0x496BF5, (DWORD)perks + 8);
|
||||
SafeWrite32(0x496AD4, (DWORD)perks + 12);
|
||||
SafeWrite32(0x496696, (DWORD)&perks[0].description);
|
||||
SafeWrite32(0x496BD1, (DWORD)&perks[0].description);
|
||||
SafeWrite32(0x496BF5, (DWORD)&perks[0].image);
|
||||
SafeWrite32(0x496AD4, (DWORD)&perks[0].ranks);
|
||||
}
|
||||
memcpy(perks, var::perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
|
||||
|
||||
@@ -1121,9 +1121,9 @@ static void TraitSetup() {
|
||||
// _trait_data
|
||||
SafeWrite32(0x4B3A81, (DWORD)traits);
|
||||
SafeWrite32(0x4B3B80, (DWORD)traits);
|
||||
SafeWrite32(0x4B3AAE, (DWORD)traits + 4);
|
||||
SafeWrite32(0x4B3BA0, (DWORD)traits + 4);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)traits + 8);
|
||||
SafeWrite32(0x4B3AAE, (DWORD)&traits[0].description);
|
||||
SafeWrite32(0x4B3BA0, (DWORD)&traits[0].description);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)&traits[0].image);
|
||||
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
|
||||
@@ -46,7 +46,7 @@ void Premade::init() {
|
||||
SafeWrite32(0x51C8D4, count);
|
||||
SafeWrite32(0x4A7D76, (DWORD)premade);
|
||||
SafeWrite32(0x4A8B1E, (DWORD)premade);
|
||||
SafeWrite32(0x4A7E2C, (DWORD)premade + 20);
|
||||
SafeWrite32(0x4A7E2C, (DWORD)&premade[0].fid);
|
||||
strcpy((char*)0x50AF68, premade[0].path);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
+1
-41
@@ -1,4 +1,5 @@
|
||||
#include "main.h"
|
||||
#include "CheckAddress.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
@@ -9,47 +10,6 @@ enum CodeType : BYTE {
|
||||
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) {
|
||||
DWORD oldProtect, data = (DWORD)func - (addr + 5);
|
||||
|
||||
|
||||
+2
-7
@@ -3,23 +3,18 @@
|
||||
#include <initializer_list>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "CheckAddress.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
#ifndef NDEBUG
|
||||
void AddrAddToList(DWORD addr, long len);
|
||||
void PrintAddrList();
|
||||
#endif
|
||||
|
||||
template<typename T> void _stdcall SafeWrite(DWORD addr, T data) {
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)addr, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((T*)addr) = data;
|
||||
VirtualProtect((void*)addr, sizeof(T), oldProtect, &oldProtect);
|
||||
|
||||
#ifndef NDEBUG
|
||||
AddrAddToList(addr, sizeof(T));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, class ForwardIteratorType>
|
||||
|
||||
+2
-1
@@ -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);
|
||||
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);
|
||||
}
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
return value;
|
||||
|
||||
+3
-1
@@ -45,7 +45,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -277,6 +277,7 @@
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CheckAddress.h" />
|
||||
<ClInclude Include="Delegate.h" />
|
||||
<ClInclude Include="FalloutEngine\Enums.h" />
|
||||
<ClInclude Include="FalloutEngine\Fallout2.h" />
|
||||
@@ -376,6 +377,7 @@
|
||||
<ClInclude Include="Modules\ExtraSaveSlots.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CheckAddress.cpp" />
|
||||
<ClCompile Include="FalloutEngine\EngineUtils.cpp" />
|
||||
<ClCompile Include="FalloutEngine\FunctionOffsets.cpp" />
|
||||
<ClCompile Include="FalloutEngine\Variables.cpp" />
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
<Filter>Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CRC.h" />
|
||||
<ClInclude Include="CheckAddress.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
@@ -530,6 +531,7 @@
|
||||
<Filter>Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CRC.cpp" />
|
||||
<ClCompile Include="CheckAddress.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="version.rc" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user