Skip to content

Commit

Permalink
Implemented code restoration for Trampoline
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-fadely committed Apr 22, 2016
1 parent 8bf2f4d commit a916fb7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 54 deletions.
4 changes: 2 additions & 2 deletions SADXModLoader/AutoMipmap.cpp
Expand Up @@ -797,7 +797,7 @@ namespace mipmap

// This has something to do with dynamic texture generation. It's used for videos and menus.
static Sint32 __cdecl sub_77FA10_hook(Uint32 gbix, void* a2);
static Trampoline sub_77FA10_trampoline(0x0077FA10, 0x0077FA16, (DetourFunction)sub_77FA10_hook);
static Trampoline sub_77FA10_trampoline(0x0077FA10, 0x0077FA16, sub_77FA10_hook);
static Sint32 __cdecl sub_77FA10_hook(Uint32 gbix, void* a2)
{
blacklisted = true;
Expand All @@ -812,7 +812,7 @@ namespace mipmap
// This one seems to be related to text.
// On first call, it generates a new texture maybe. From that point on, it calls the above function.
static void sub_40D2A0_hook(void* a1);
static Trampoline sub_40D2A0_trampoline(0x0040D2A0, 0x0040D2A8, (DetourFunction)sub_40D2A0_hook);
static Trampoline sub_40D2A0_trampoline(0x0040D2A0, 0x0040D2A8, sub_40D2A0_hook);
static void sub_40D2A0_hook(void* a1)
{
blacklisted = true;
Expand Down
2 changes: 1 addition & 1 deletion SADXModLoader/Events.cpp
Expand Up @@ -7,7 +7,7 @@ std::vector<ModEvent> modInputEvents;
std::vector<ModEvent> modControlEvents;
std::vector<ModEvent> modExitEvents;

Trampoline exitDetour((size_t)0x0064672F, 0x00646736, (DetourFunction)OnExit);
Trampoline exitDetour((size_t)0x0064672F, 0x00646736, OnExit);

/**
* Registers an event to the specified event list.
Expand Down
76 changes: 38 additions & 38 deletions SADXModLoader/HudScale.cpp
Expand Up @@ -16,8 +16,8 @@ using std::vector;
static void __cdecl Draw2DSpriteHax(NJS_SPRITE* sp, Int n, Float pri, Uint32 attr, char zfunc_type);
void __cdecl njDrawSprite2D_4_Hax(NJS_SPRITE *sp, Int n, Float pri, Uint32 attr);

Trampoline drawSprite(0x00404660, 0x00404666, (DetourFunction)Draw2DSpriteHax);
Trampoline drawSpriteWrapper(0x004070A0, 0x004070A5, (DetourFunction)njDrawSprite2D_4_Hax);
Trampoline drawSprite(0x00404660, 0x00404666, Draw2DSpriteHax);
Trampoline drawSpriteWrapper(0x004070A0, 0x004070A5, njDrawSprite2D_4_Hax);

// TODO: Give Trampoline a default constructor and stuff
static Trampoline* drawObjects;
Expand Down Expand Up @@ -466,44 +466,44 @@ void SetupHudScale()
scale = min(last_h, last_v);
WriteJump((void*)0x0042BEE0, ScaleResultScreen);

drawObjects = new Trampoline(0x0040B540, 0x0040B546, (DetourFunction)DrawAllObjectsHax);
drawObjects = new Trampoline(0x0040B540, 0x0040B546, DrawAllObjectsHax);
WriteCall((void*)((size_t)drawObjects->Target() + 1), (void*)0x004128F0);

missionScreen = new Trampoline(0x00590E60, 0x00590E65, (DetourFunction)FixMissionScreen);
missionScreen = new Trampoline(0x00590E60, 0x00590E65, FixMissionScreen);

scaleRingLife = new Trampoline(0x00425F90, 0x00425F95, (DetourFunction)ScaleA);
scaleScoreTime = new Trampoline(0x00427F50, 0x00427F55, (DetourFunction)ScaleB);
scaleStageMission = new Trampoline(0x00457120, 0x00457126, (DetourFunction)ScaleStageMission);
scaleRingLife = new Trampoline(0x00425F90, 0x00425F95, ScaleA);
scaleScoreTime = new Trampoline(0x00427F50, 0x00427F55, ScaleB);
scaleStageMission = new Trampoline(0x00457120, 0x00457126, ScaleStageMission);

scalePause = new Trampoline(0x00415420, 0x00415425, (DetourFunction)ScalePauseMenu);
scalePause = new Trampoline(0x00415420, 0x00415425, ScalePauseMenu);
WriteCall(scalePause->Target(), (void*)0x40FDC0);

scaleTargetLifeGague = new Trampoline(0x004B3830, 0x004B3837, (DetourFunction)ScaleTargetLifeGague);
scaleTargetLifeGague = new Trampoline(0x004B3830, 0x004B3837, ScaleTargetLifeGague);

scaleScoreA = new Trampoline(0x00628330, 0x00628335, (DetourFunction)ScaleScoreA);
scaleScoreA = new Trampoline(0x00628330, 0x00628335, ScaleScoreA);

WriteData((const float**)0x006288C2, &patch_dummy);
scaleTornadoHP = new Trampoline(0x00628490, 0x00628496, (DetourFunction)ScaleTornadoHP);
scaleTornadoHP = new Trampoline(0x00628490, 0x00628496, ScaleTornadoHP);

// TODO: Consider tracking down the individual functions so that they can be individually aligned.
scaleTwinkleCircuitHUD = new Trampoline(0x004DB5E0, 0x004DB5E5, (DetourFunction)ScaleTwinkleCircuitHUD);
scaleTwinkleCircuitHUD = new Trampoline(0x004DB5E0, 0x004DB5E5, ScaleTwinkleCircuitHUD);
WriteCall(scaleTwinkleCircuitHUD->Target(), (void*)0x590620);

// Rod scaling disabled.
// TODO: Figure out how gauge is drawn (it doesn't appear to use the texture).
//scaleReel = new Trampoline(0x0046C9F0, 0x0046C9F5, (DetourFunction)ScaleReel);
//scaleRod = new Trampoline(0x0046CAB0, 0x0046CAB9, (DetourFunction)ScaleRod);
//scaleRodMeters = new Trampoline(0x0046CC70, 0x0046CC75, (DetourFunction)ScaleRodMeters);
scaleFishingHit = new Trampoline(0x0046C920, 0x0046C926, (DetourFunction)ScaleFishingHit);
scaleBigHud = new Trampoline(0x0046FB00, 0x0046FB05, (DetourFunction)ScaleBigHud);
//scaleReel = new Trampoline(0x0046C9F0, 0x0046C9F5, ScaleReel);
//scaleRod = new Trampoline(0x0046CAB0, 0x0046CAB9, ScaleRod);
//scaleRodMeters = new Trampoline(0x0046CC70, 0x0046CC75, ScaleRodMeters);
scaleFishingHit = new Trampoline(0x0046C920, 0x0046C926, ScaleFishingHit);
scaleBigHud = new Trampoline(0x0046FB00, 0x0046FB05, ScaleBigHud);

scaleAnimalPickup = new Trampoline(0x0046B330, 0x0046B335, (DetourFunction)ScaleAnimalPickup);
scaleAnimalPickup = new Trampoline(0x0046B330, 0x0046B335, ScaleAnimalPickup);

scaleItemBoxSprite = new Trampoline(0x004C0790, 0x004C0795, (DetourFunction)ScaleItemBoxSprite);
scaleItemBoxSprite = new Trampoline(0x004C0790, 0x004C0795, ScaleItemBoxSprite);

scaleBalls = new Trampoline(0x005C0B70, 0x005C0B75, (DetourFunction)ScaleBalls);
scaleBalls = new Trampoline(0x005C0B70, 0x005C0B75, ScaleBalls);

scaleCheckpointTime = new Trampoline(0x004BABE0, 0x004BABE5, (DetourFunction)ScaleCheckpointTime);
scaleCheckpointTime = new Trampoline(0x004BABE0, 0x004BABE5, ScaleCheckpointTime);
WriteData((const float**)0x0044F2E1, &patch_dummy);
WriteData((const float**)0x0044F30B, &patch_dummy);
WriteData((const float**)0x00476742, &patch_dummy);
Expand All @@ -515,36 +515,36 @@ void SetupHudScale()
// Emerald get
WriteData((const float**)0x00477E8E, &patch_dummy);
WriteData((const float**)0x00477EC0, &patch_dummy);
scaleEmeraldRadarA = new Trampoline(0x00475A70, 0x00475A75, (DetourFunction)ScaleEmeraldRadarA);
scaleEmeraldRadarB = new Trampoline(0x00475E50, 0x00475E55, (DetourFunction)ScaleEmeraldRadarB);
scaleEmeraldRadar_Grab = new Trampoline(0x00475D50, 0x00475D55, (DetourFunction)ScaleEmeraldRadar_Grab);
scaleEmeraldRadarA = new Trampoline(0x00475A70, 0x00475A75, ScaleEmeraldRadarA);
scaleEmeraldRadarB = new Trampoline(0x00475E50, 0x00475E55, ScaleEmeraldRadarB);
scaleEmeraldRadar_Grab = new Trampoline(0x00475D50, 0x00475D55, ScaleEmeraldRadar_Grab);

scaleSandHillMultiplier = new Trampoline(0x005991A0, 0x005991A6, (DetourFunction)ScaleSandHillMultiplier);
scaleIceCapMultiplier = new Trampoline(0x004EC120, 0x004EC125, (DetourFunction)ScaleIceCapMultiplier);
scaleSandHillMultiplier = new Trampoline(0x005991A0, 0x005991A6, ScaleSandHillMultiplier);
scaleIceCapMultiplier = new Trampoline(0x004EC120, 0x004EC125, ScaleIceCapMultiplier);

WriteData((const float**)0x0049FF70, &patch_dummy);
WriteData((const float**)0x004A005B, &patch_dummy);
WriteData((const float**)0x004A0067, &patch_dummy);
scaleGammaTimeAddHud = new Trampoline(0x0049FDA0, 0x0049FDA5, (DetourFunction)ScaleGammaTimeAddHud);
scaleGammaTimeRemaining = new Trampoline(0x004C51D0, 0x004C51D7, (DetourFunction)ScaleGammaTimeRemaining);
scaleGammaTimeAddHud = new Trampoline(0x0049FDA0, 0x0049FDA5, ScaleGammaTimeAddHud);
scaleGammaTimeRemaining = new Trampoline(0x004C51D0, 0x004C51D7, ScaleGammaTimeRemaining);

WriteData((float**)0x004B4470, &last_h);
WriteData((float**)0x004B444E, &last_v);
scaleEmblemScreen = new Trampoline(0x004B4200, 0x004B4205, (DetourFunction)ScaleEmblemScreen);
scaleEmblemScreen = new Trampoline(0x004B4200, 0x004B4205, ScaleEmblemScreen);

scaleBossName = new Trampoline(0x004B33D0, 0x004B33D5, (DetourFunction)ScaleBossName);
scaleBossName = new Trampoline(0x004B33D0, 0x004B33D5, ScaleBossName);

scaleNightsCards = new Trampoline(0x005D73F0, 0x005D73F5, (DetourFunction)ScaleNightsCards);
scaleNightsCards = new Trampoline(0x005D73F0, 0x005D73F5, ScaleNightsCards);
WriteData((float**)0x005D701B, &last_h);
scaleNightsJackpot = new Trampoline(0x005D6E60, 0x005D6E67, (DetourFunction)ScaleNightsJackpot);
scaleNightsJackpot = new Trampoline(0x005D6E60, 0x005D6E67, ScaleNightsJackpot);

scaleMissionStartClear = new Trampoline(0x00591260, 0x00591268, (DetourFunction)ScaleMissionStartClear);
scaleMissionStartClear = new Trampoline(0x00591260, 0x00591268, ScaleMissionStartClear);

scaleMissionTimer = new Trampoline(0x00592D50, 0x00592D59, (DetourFunction)ScaleMissionTimer);
scaleMissionCounter = new Trampoline(0x00592A60, 0x00592A68, (DetourFunction)ScaleMissionCounter);
scaleMissionTimer = new Trampoline(0x00592D50, 0x00592D59, ScaleMissionTimer);
scaleMissionCounter = new Trampoline(0x00592A60, 0x00592A68, ScaleMissionCounter);

scaleTailsWinLose = new Trampoline(0x0047C480, 0x0047C485, (DetourFunction)ScaleTailsWinLose);
scaleTailsOtherThing = new Trampoline(0x0047C260, 0x0047C267, (DetourFunction)ScaleTailsOtherThing);
scaleTailsWinLose = new Trampoline(0x0047C480, 0x0047C485, ScaleTailsWinLose);
scaleTailsOtherThing = new Trampoline(0x0047C260, 0x0047C267, ScaleTailsOtherThing);

scaleDemoPressStart = new Trampoline(0x00457D30, 0x00457D36, (DetourFunction)ScaleDemoPressStart);
scaleDemoPressStart = new Trampoline(0x00457D30, 0x00457D36, ScaleDemoPressStart);
}
17 changes: 8 additions & 9 deletions libmodutils/Trampoline.cpp
Expand Up @@ -7,14 +7,8 @@
#include <ninja.h> // for typedefs
#include <ModLoader/MemAccess.h>

/// <summary>
/// Initializes a new <see cref="Trampoline" />, allowing you to replace functions and still call the original code.
/// </summary>
/// <param name="start">Start offset (address of function).</param>
/// <param name="end">End offset.</param>
/// <param name="func">Your detour function.</param>
Trampoline::Trampoline(size_t start, size_t end, DetourFunction func) :
target(nullptr), detour(nullptr), codeData(nullptr), originalSize(0), codeSize(0)
Trampoline::Trampoline(size_t start, size_t end, void* func, bool destructRevert) :
target(nullptr), detour(nullptr), codeData(nullptr), originalSize(0), codeSize(0), revert(destructRevert)
{
if (start > end)
throw std::exception("Start address cannot exceed end address.");
Expand All @@ -30,7 +24,7 @@ Trampoline::Trampoline(size_t start, size_t end, DetourFunction func) :
// Copy original instructions
codeData = VirtualAlloc(nullptr, codeSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (codeData == nullptr)
throw std::exception("VirtualAlloc failure");
throw std::exception("VirtualAlloc failure.");

// ReadProcessMemory maybe?
memcpy(codeData, target, originalSize);
Expand All @@ -49,5 +43,10 @@ Trampoline::Trampoline(size_t start, size_t end, DetourFunction func) :
Trampoline::~Trampoline()
{
if (codeData)
{
if (revert)
WriteData(target, codeData, originalSize);

VirtualFree(codeData, codeSize, MEM_DECOMMIT);
}
}
10 changes: 6 additions & 4 deletions libmodutils/Trampoline.h
Expand Up @@ -2,8 +2,6 @@

#include <wtypes.h>

typedef void(*DetourFunction)(void);

// TODO: Better documentation
// TODO: Clearer member names
// TODO: Code restoration
Expand All @@ -12,10 +10,11 @@ class Trampoline
{
private:
void* target;
DetourFunction detour;
void* detour;
LPVOID codeData;
size_t originalSize;
size_t codeSize;
const bool revert;

public:
/// <summary>
Expand All @@ -24,7 +23,10 @@ class Trampoline
/// <param name="start">Start offset (address of function).</param>
/// <param name="end">End offset.</param>
/// <param name="func">Your detour function.</param>
Trampoline(size_t start, size_t end, DetourFunction func);
/// <param name="destructRevert">If <c>true</c>, code changes will be reverted when this instance is destroyed.</param>
/// <remarks>If there's a relative jump or call within the range of <see cref="start" /> and <see cref="end" />,
/// they need to be replaced with absolute offsets before instantiating a <see cref="Trampoline" />.</remarks>
Trampoline(size_t start, size_t end, void* func, bool destructRevert = true);
~Trampoline();

// Pointer to original code.
Expand Down

0 comments on commit a916fb7

Please sign in to comment.