Skip to content

Commit

Permalink
- added CastSpellAtMouseover
Browse files Browse the repository at this point in the history
- added explanation to README
- bumped version to 1.2
  • Loading branch information
namreeb committed Jun 20, 2015
1 parent 86299e9 commit 1e2728b
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 15 deletions.
7 changes: 7 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ nampower

An auto stop-cast tool for World of Warcraft 1.12.1.5875 (for Windows)

To cast a spell at your current target using this tool, create a macro of the format
"/script CastSpellAtTarget(x)" where x is the numerical id of the spell you wish to cast.

To cast a spell at your current mouseover target using this tool, create a macro of the
format "/script CastSpellAtMouseover(x)" where x is the numerical id of the spell you
wish to cast.

Note that while this makes no malicious changes to the WoW client, it could easily be
mistaken as malicious by the primitive anticheats in use on most vanilla private
servers. This program contains absolutely no protection against anticheat software.
Expand Down
2 changes: 1 addition & 1 deletion loader/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/

#define NAME "nampower"
#define VERSION "v1.1"
#define VERSION "v1.2"

#include <iostream>
#include <vector>
Expand Down
25 changes: 25 additions & 0 deletions nampower/castspell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,30 @@ int CastSpellAtTarget(void *luaState)
packet.Send();
}

return 1;
}

int CastSpellAtMouseover(void *luaState)
{
if (const unsigned __int64 mouseoverGuid = *(const unsigned __int64 *)Offsets::gMouseoverGuid)
{
auto param = (DWORD)LuaToNumber(luaState, 1);

std::vector<BYTE> packedGuid;
BuildPackedGuid(mouseoverGuid, packedGuid);

CDataStore packet(10 + packedGuid.size());

packet.Write((DWORD)0x12E); // CMSG_CAST_SPELL
packet.Write((DWORD)param); // spell id
packet.Write((WORD)0x02); // TARGET_FLAG_UNIT
packet.Write(&packedGuid[0], packedGuid.size()); // packed target guid

packet.Send();
}
//if mouseover guid is empty, use target instead
else
CastSpellAtTarget(luaState);

return 1;
}
31 changes: 21 additions & 10 deletions nampower/lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,46 @@

double(__fastcall *LuaToNumber)(PVOID, unsigned int);

void RegisterLuaFunction()
void RegisterLuaFunctions()
{
// note: there are many suitable locations for this trampoline in the 1.12.1 client.
// this offset is what you would change if you care to use a different one.
const DWORD trampolineAddress = Offsets::gTrampoline;
// note: there are many suitable locations for these trampolines in the 1.12.1 client.
// these offsets are what you would change if you care to use different ones.
const hadesmem::Process process(::GetCurrentProcessId());
FrameScriptRegisterT frameScriptRegister = hadesmem::detail::AliasCast<decltype(frameScriptRegister)>(Offsets::FrameScript__Register);

std::vector<BYTE> patch(5);

patch[0] = 0xE9; // JMP

const DWORD castSpellLocation = hadesmem::detail::AliasCast<DWORD>(&CastSpellAtTarget);
const DWORD relativeJumpValue = castSpellLocation - trampolineAddress - 5;
// first trampoline
DWORD trampolineAddress = Offsets::gTrampoline1;
DWORD castSpellLocation = hadesmem::detail::AliasCast<DWORD>(&CastSpellAtTarget);
DWORD relativeJumpValue = castSpellLocation - trampolineAddress - 5;

memcpy(&patch[1], &relativeJumpValue, sizeof(DWORD));

// write JMP to wow's .text section so it can be registered with lua
auto trampoline = new hadesmem::PatchRaw(process, (PVOID)trampolineAddress, patch);
trampoline->Apply();
(new hadesmem::PatchRaw(process, (PVOID)trampolineAddress, patch))->Apply();

// register with lua
FrameScriptRegisterT frameScriptRegister = hadesmem::detail::AliasCast<decltype(frameScriptRegister)>(Offsets::FrameScript__Register);
frameScriptRegister("CastSpellAtTarget", trampolineAddress);

// second trampoline
trampolineAddress = Offsets::gTrampoline2;
castSpellLocation = hadesmem::detail::AliasCast<DWORD>(&CastSpellAtMouseover);
relativeJumpValue = castSpellLocation - trampolineAddress - 5;

memcpy(&patch[1], &relativeJumpValue, sizeof(DWORD));

(new hadesmem::PatchRaw(process, (PVOID)trampolineAddress, patch))->Apply();

frameScriptRegister("CastSpellAtMouseover", trampolineAddress);
}

void LuaLoadScripts(hadesmem::PatchDetourBase *detour)
{
LuaLoadScriptsT originalRegister = detour->GetTrampolineT<decltype(originalRegister)>();
(*originalRegister)();

RegisterLuaFunction();
RegisterLuaFunctions();
}
2 changes: 1 addition & 1 deletion nampower/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extern "C" HADESMEM_DETAIL_DLLEXPORT DWORD Load()
unsigned __int64(__stdcall *getPlayerGuid)() = (decltype(getPlayerGuid))(Offsets::GetPlayerGuid);

if ((*getPlayerGuid)())
RegisterLuaFunction();
RegisterLuaFunctions();

return EXIT_SUCCESS;
}
Expand Down
5 changes: 3 additions & 2 deletions nampower/misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ using LuaLoadScriptsT = void(__cdecl *)();
using FrameScriptRegisterT = void(__fastcall *)(const char *, DWORD);

extern double(__fastcall *LuaToNumber)(PVOID, unsigned int);
extern void RegisterLuaFunction();
extern void RegisterLuaFunctions();
extern void LuaLoadScripts(hadesmem::PatchDetourBase *);

extern int CastSpellAtTarget(void *luaState);
extern int CastSpellAtTarget(void *);
extern int CastSpellAtMouseover(void *);
4 changes: 3 additions & 1 deletion nampower/offsets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
enum Offsets : DWORD
{
gTargetGuid = 0xB4E2D8,
gMouseoverGuid = 0xB4E2C8,
gClientConnection = 0xC28128,
gTrampoline = 0x7FDF52, // must have at least five bytes of alignment (INT3/0xCC) space and be between 0x401000 and 0x7FEDAC
gTrampoline1 = 0x7FDF52, // must have at least five bytes of alignment (INT3/0xCC) space and be between 0x401000 and 0x7FEDAC
gTrampoline2 = 0x7FA606,
ClientConnection__SendPacket = 0x5379A0,
FrameScript__LoadWorldScripts = 0x490250,
FrameScript__Register = 0x704120,
Expand Down

0 comments on commit 1e2728b

Please sign in to comment.