Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Asiern committed Feb 2, 2021
1 parent b7cfb22 commit 1290f6a
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 49 deletions.
16 changes: 16 additions & 0 deletions Source/ConsoleApplication1/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <iostream>
#include <thread>
#include "NierHook.hpp"
using namespace std;

//Function used to exit the program
void ENDPressed(NieRHook* hook) {
Expand All @@ -24,16 +25,31 @@ void ENDPressed(NieRHook* hook) {
*/
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//Look for memory leaks

NieRHook hook;
cout << "Hooking..." << endl;
//Hook to process
while (!hook.isHooked()) {
hook.start();
}
cout << "Hooked" << endl;

//Enable some cheats
hook.InfiniteDoubleJump(true);
hook.IgnoreUpgradeMaterials(true);

//Add some items
//For ID reference please visit github.com/Asiern/NieRHook Readme
hook.addItem(510, 80); //Beast Hide ID => 510
hook.addItem(0, 10); //Small Recovery => ID 0
hook.addItem(721, 1); //Data chip B => ID 721
hook.addItem(400, 99); //E-Drug => ID 400

//Add some weapons
hook.addWeapon(0x4D8, 1); //Type-40 Blade => ID 0x4D8
hook.addWeapon(0x41A, 1); //Type-40 Sword => ID 0x41A

//Create a thread to exit when the 'END' button is pressed
std::thread exitThread(ENDPressed, &hook);

Expand Down
171 changes: 124 additions & 47 deletions Source/ConsoleApplication1/NierHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
void NieRHook::_hook(void)
{
DWORD ID = this->_pID;
uintptr_t entityAddress = 0;
while (ID <= 0) {
while (ID <= 0)
{
ID = this->_getProcessID();
}
this->_pID = ID;
Expand Down Expand Up @@ -47,8 +47,8 @@ DWORD NieRHook::_getProcessID(void)
//return if game window not found
return 0;
}
DWORD pID; //Process ID
GetWindowThreadProcessId(hwnd, &pID); //Get Process ID
DWORD pID; //Process ID
GetWindowThreadProcessId(hwnd, &pID); //Get Process ID
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); //Open process
if (pHandle == INVALID_HANDLE_VALUE)
{
Expand All @@ -58,7 +58,7 @@ DWORD NieRHook::_getProcessID(void)
return pID;
}
//Find modules in NieR:Automata process returns: memory address of module
uintptr_t NieRHook::_getModuleBaseAddress(DWORD procId, const wchar_t* modName)
uintptr_t NieRHook::_getModuleBaseAddress(DWORD procId, const wchar_t *modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
Expand Down Expand Up @@ -147,26 +147,16 @@ void NieRHook::_updateEXP(void)
CloseHandle(pHandle); //Close handle to prevent memory leaks
this->EXP = exp;
}
bool NieRHook::_isCurrentPos(float X, float Y, float Z)
{
int cX = (int)this->getXPosition();
int cY = (int)this->getYPosition();
int cZ = (int)this->getZPosition();
if ((cX != (int)X) || (cY != (int)Y) || (cZ != (int)Z)) {
return false;
}
return true;
}
//Fill memory with no Operations
void NieRHook::Nop(BYTE* destination, unsigned int size, HANDLE hProcess)
void NieRHook::Nop(BYTE *destination, unsigned int size, HANDLE hProcess)
{
BYTE* nopArray = new BYTE[size];
BYTE *nopArray = new BYTE[size];
memset(nopArray, 0x90, size);
Patch(destination, nopArray, size, hProcess);
delete[] nopArray;
}
//Fill memory with custom values
void NieRHook::Patch(BYTE* destination, BYTE* src, unsigned int size, HANDLE hProcess)
void NieRHook::Patch(BYTE *destination, BYTE *src, unsigned int size, HANDLE hProcess)
{
DWORD oldprotection;
VirtualProtectEx(hProcess, destination, size, PAGE_EXECUTE_READWRITE, &oldprotection);
Expand All @@ -176,7 +166,8 @@ void NieRHook::Patch(BYTE* destination, BYTE* src, unsigned int size, HANDLE hPr

void NieRHook::hookStatus(void)
{
if (this->_pID != this->_getProcessID()) {
if (this->_pID != this->_getProcessID())
{
this->_unHook();
}
}
Expand Down Expand Up @@ -224,10 +215,6 @@ void NieRHook::setPosition(float X, float Y, float Z)
WriteProcessMemory(pHandle, (LPVOID)(this->_entityAddress + 0x50), &X, sizeof(X), NULL);
WriteProcessMemory(pHandle, (LPVOID)(this->_entityAddress + 0x54), &Y, sizeof(Y), NULL);
WriteProcessMemory(pHandle, (LPVOID)(this->_entityAddress + 0x58), &Z, sizeof(Z), NULL);
//See if player has finished teleporting
while (!_isCurrentPos(X, Y, Z)) {
//TODO test
}
Sleep(500);
NoCLip(false); //Disable noclip
CloseHandle(pHandle);
Expand All @@ -252,13 +239,15 @@ void NieRHook::setGameSpeed(float speed)
void NieRHook::NoCooldown(bool enabled)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
if (enabled) {//Enable No cooldown
if (enabled)
{ //Enable No cooldown
//Set memory at offset 0x23821F = 90 90 90 90
Nop((BYTE*)(this->_baseAddress + 0x23821F), 9, pHandle);
Nop((BYTE *)(this->_baseAddress + 0x23821F), 9, pHandle);
}
else {//Disable No cooldown
else
{ //Disable No cooldown
//Set memory at offsets 0x1354B1 & 0x135758 = previous values
Patch((BYTE*)(this->_baseAddress + 0x23821F), (BYTE*)"\xF3\x0F\x11\x84\xC3\x24\x6A\x01\x00", 9, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x23821F), (BYTE *)"\xF3\x0F\x11\x84\xC3\x24\x6A\x01\x00", 9, pHandle);
}
CloseHandle(pHandle);
}
Expand All @@ -267,57 +256,141 @@ void NieRHook::InfiniteAirDash(bool enabled)
{

HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
if (enabled) {//Enable Inf Air Dash
if (enabled)
{ //Enable Inf Air Dash
//Set memory at offset 0x1E2E5D = 90 90 90 90 90 90 90 90 90 90
Nop((BYTE*)(this->_baseAddress + 0x1E2E89), 10, pHandle);
Nop((BYTE *)(this->_baseAddress + 0x1E2E89), 10, pHandle);
}
else {//Disable Inf Air Dash
else
{ //Disable Inf Air Dash
//Set memory at offset 0x1E2E5D = previous values
Patch((BYTE*)(this->_baseAddress + 0x1E2E89), (BYTE*)"\xC7\x83\x88\x0A\x01\x00\x01\x00\x00\x00", 10, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x1E2E89), (BYTE *)"\xC7\x83\x88\x0A\x01\x00\x01\x00\x00\x00", 10, pHandle);
}
CloseHandle(pHandle);
}

void NieRHook::IgnoreUpgradeMaterials(bool enabled)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
if (enabled) {//Enable Ignore Upgrade Materials
//Set memory at offset 0x5EE5CE = 90 90 90
Nop((BYTE*)(this->_baseAddress + 0x5EE5CE), 3, pHandle);
if (enabled)
{ //Enable Ignore Upgrade Materials
//Set memory at offset 0x5EE5CE = 90 90 90
Nop((BYTE *)(this->_baseAddress + 0x5EE5CE), 3, pHandle);
}
else {//Disable Ignore Upgrade Materials
else
{ //Disable Ignore Upgrade Materials
//Set memory at offset 0x5EE5CE = previous values
Patch((BYTE*)(this->_baseAddress + 0x5EE5CE), (BYTE*)"\x41\x3B\xC2\x7C\x31", 5, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x5EE5CE), (BYTE *)"\x41\x3B\xC2\x7C\x31", 5, pHandle);
}
CloseHandle(pHandle);
}
/*
Add item to inventory
If Item is not in the inventory, Creates a new Item on memory
returns: true if successful and false if not
*/
bool NieRHook::addItem(int ID, int number)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
uintptr_t Address = this->_baseAddress + 0x197C4C4;
uintptr_t emptySlot = 0;
unsigned int currentID;
if (!this->_hooked)
{
return false;
}
while (Address <= this->_baseAddress + 0x197CE18)
{
ReadProcessMemory(pHandle, (LPVOID)Address, &currentID, sizeof(currentID), NULL);
if (ID == currentID)
{ //Item found on memory
WriteProcessMemory(pHandle, (LPVOID)(Address + 0x8), &number, sizeof(number), NULL); //Set level
return true;
}
else if (emptySlot == 0 && currentID == 0xffffffff)
{ //Get empty slot address
emptySlot = Address;
}
Address += 0xC; //Go to the next slot
}
if (emptySlot == 0)
{ //empty slot == 0 => no free slots on memory
return false;
}
//Item not found on memory, create on empty slot
WriteProcessMemory(pHandle, (LPVOID)(emptySlot), &ID, sizeof(ID), NULL); //Set level
WriteProcessMemory(pHandle, (LPVOID)(emptySlot + 0x8), &number, sizeof(number), NULL); //Set level
CloseHandle(pHandle);
}

/*
Add weapon to memory by ID
returns: true if successful and false if not
*/
bool NieRHook::addWeapon(int ID, int level)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
uintptr_t Address = this->_baseAddress + 0x197DCC4;
uintptr_t emptySlot = 0;
unsigned int currentID;
if (!this->_hooked)
{
return false; //Return if not hooked
}
while (Address <= this->_baseAddress + 0x197DFBC)
{
ReadProcessMemory(pHandle, (LPVOID)Address, &currentID, sizeof(currentID), NULL);
if (ID == currentID)
{ //Weapon found on memory
WriteProcessMemory(pHandle, (LPVOID)(Address + 0x4), &level, sizeof(level), NULL); //Set level
return true;
}
if (emptySlot == 0 && currentID == 0xffffffff)
{ //Get empty slot address
emptySlot = Address;
}
Address += 0x14; //Go to the next slot
}
if (emptySlot == 0)
{ //empty slot == 0 => no free slots on memory
return false;
}
//Weapon not found on memory
WriteProcessMemory(pHandle, (LPVOID)(emptySlot), &ID, sizeof(ID), NULL); //Set Weapon ID
WriteProcessMemory(pHandle, (LPVOID)(emptySlot + 0x4), &level, sizeof(level), NULL); //Set level, level at offset 0x4 from ID
CloseHandle(pHandle);
}

void NieRHook::NoCLip(bool enabled)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
if (enabled) {//Enable noclip
if (enabled)
{ //Enable noclip
//Set memory at offsets 0x1354B1 & 0x135758 = 90 90 90 90
Nop((BYTE*)(this->_baseAddress + 0x1354B1), 4, pHandle);
Nop((BYTE*)(this->_baseAddress + 0x135758), 4, pHandle);
Nop((BYTE *)(this->_baseAddress + 0x1354B1), 4, pHandle);
Nop((BYTE *)(this->_baseAddress + 0x135758), 4, pHandle);
}
else {//Disable noclip
else
{ //Disable noclip
//Set memory at offsets 0x1354B1 & 0x135758 = previous values
Patch((BYTE*)(this->_baseAddress + 0x1354B1), (BYTE*)"\x0F\x29\x42\x50", 4, pHandle);
Patch((BYTE*)(this->_baseAddress + 0x135758), (BYTE*)"\x0F\x29\x43\x50", 4, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x1354B1), (BYTE *)"\x0F\x29\x42\x50", 4, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x135758), (BYTE *)"\x0F\x29\x43\x50", 4, pHandle);
}
CloseHandle(pHandle);
}

void NieRHook::InfiniteDoubleJump(bool enabled)
{
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->_pID);
if (enabled) {
if (enabled)
{
//Write FF 0f 8c to enable
Patch((BYTE*)(this->_baseAddress + 0x1E2D4C), (BYTE*)"\xFF\x0F\x8C", 3, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x1E2D4C), (BYTE *)"\xFF\x0F\x8C", 3, pHandle);
}
else {
else
{
//Write 02 0F 8D to disable
Patch((BYTE*)(this->_baseAddress + 0x1E2D4C), (BYTE*)"\x02\x0f\x8D", 3, pHandle);
Patch((BYTE *)(this->_baseAddress + 0x1E2D4C), (BYTE *)"\x02\x0f\x8D", 3, pHandle);
}
CloseHandle(pHandle);
}
Expand All @@ -338,9 +411,13 @@ NieRHook::NieRHook()
this->Level = 0;
}

NieRHook::~NieRHook()
{
}

void NieRHook::start(void)
{
this->_hook();//Hook
this->_hook(); //Hook
this->_updateEntity();
}

Expand Down
12 changes: 10 additions & 2 deletions Source/ConsoleApplication1/NierHook.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifndef NIERHOOK_H
#define NIERHOOK_H
class NieRHook;
class NieRHook {
private:
Expand Down Expand Up @@ -28,12 +30,12 @@ class NieRHook {
void _updateLevel(void);
void _updateFunds(void);
void _updateEXP(void);
bool _isCurrentPos(float X, float Y, float Z);
void Nop(BYTE* destination, unsigned int size, HANDLE hProcess);
void Patch(BYTE* destination, BYTE* src, unsigned int size, HANDLE hProcess);

public:
NieRHook();
~NieRHook();
void start(void); //Start hook
void stop(void); //Reset hook
bool isHooked(void);
Expand Down Expand Up @@ -64,4 +66,10 @@ class NieRHook {
void NoCooldown(bool enabled);
void InfiniteAirDash(bool enabled);
void IgnoreUpgradeMaterials(bool enabled);
};

//Inventory
bool addItem(int ID, int number);
bool addWeapon(int ID, int level);
};

#endif

0 comments on commit 1290f6a

Please sign in to comment.