Add project files.
This commit is contained in:
34
L2BotDll/Common/Common.cpp
Normal file
34
L2BotDll/Common/Common.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "pch.h"
|
||||
#include "Common.h"
|
||||
#include <Rpc.h>
|
||||
#pragma comment(lib, "Rpcrt4.lib")
|
||||
|
||||
std::string ConvertFromWideChar(const wchar_t* str)
|
||||
{
|
||||
std::wstring ws(str);
|
||||
std::string result(ws.begin(), ws.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string GenerateUUID()
|
||||
{
|
||||
UUID uuid;
|
||||
::ZeroMemory(&uuid, sizeof(UUID));
|
||||
|
||||
::UuidCreate(&uuid);
|
||||
|
||||
WCHAR* wszUuid = NULL;
|
||||
::UuidToStringW(&uuid, (RPC_WSTR*)&wszUuid);
|
||||
|
||||
if (wszUuid == NULL)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::wstring ws = wszUuid;
|
||||
|
||||
::RpcStringFree((RPC_WSTR*)&wszUuid);
|
||||
wszUuid = NULL;
|
||||
|
||||
return std::string(ws.begin(), ws.end());
|
||||
}
|
6
L2BotDll/Common/Common.h
Normal file
6
L2BotDll/Common/Common.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string ConvertFromWideChar(const wchar_t* str);
|
||||
std::string GenerateUUID();
|
81
L2BotDll/Common/TimerMap.h
Normal file
81
L2BotDll/Common/TimerMap.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
class TimerMap
|
||||
{
|
||||
public:
|
||||
TimerMap() = default;
|
||||
virtual ~TimerMap()
|
||||
{
|
||||
StopAll();
|
||||
}
|
||||
|
||||
void StartTimer(const uint32_t key, const uint32_t milliseconds, const std::function<void(uint32_t)> callback)
|
||||
{
|
||||
StopTimer(key);
|
||||
|
||||
m_Timers[key].Start(milliseconds, callback, key);
|
||||
}
|
||||
|
||||
void StopTimer(uint32_t key)
|
||||
{
|
||||
if (m_Timers.find(key) != m_Timers.end())
|
||||
{
|
||||
m_Timers[key].Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void StopAll()
|
||||
{
|
||||
m_Timers.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
void Start(const uint32_t milliseconds, const std::function<void(uint32_t)> callback, const uint32_t data)
|
||||
{
|
||||
m_Terminate = false;
|
||||
m_Thread = std::thread([this, milliseconds, callback, data] {
|
||||
std::unique_lock<std::mutex> lk(m_Mutex);
|
||||
|
||||
if (!m_Condition.wait_for(lk, std::chrono::milliseconds(milliseconds), [this]() { return m_Terminate == true; }))
|
||||
{
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_Terminate = true;
|
||||
m_Condition.notify_all();
|
||||
if (m_Thread.joinable())
|
||||
{
|
||||
m_Thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
Timer() = default;
|
||||
virtual ~Timer()
|
||||
{
|
||||
Stop();
|
||||
|
||||
}
|
||||
private:
|
||||
std::condition_variable m_Condition;
|
||||
std::mutex m_Mutex;
|
||||
std::atomic_bool m_Terminate = false;
|
||||
std::thread m_Thread;
|
||||
};
|
||||
|
||||
std::map<uint32_t, Timer> m_Timers;
|
||||
};
|
75
L2BotDll/Common/apihook.cpp
Normal file
75
L2BotDll/Common/apihook.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "pch.h"
|
||||
#include "apihook.h"
|
||||
#include "Trampoline.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct CallJmpInstr
|
||||
{
|
||||
BYTE opcode;
|
||||
DWORD rel32;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#pragma pack(push, 1)
|
||||
struct SavedFunction
|
||||
{
|
||||
DWORD originalAddress;
|
||||
BYTE size;
|
||||
BYTE oldCode[5];
|
||||
CallJmpInstr* jumpInstruction;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> jump (0xe9), <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void recalculateRel32IfIsJump(void* dest, void* source)
|
||||
{
|
||||
CallJmpInstr* mayBeJump = (CallJmpInstr*)dest;
|
||||
if (mayBeJump->opcode == 0xe9)
|
||||
{
|
||||
mayBeJump->rel32 = (DWORD)source - (DWORD)dest + mayBeJump->rel32;
|
||||
}
|
||||
}
|
||||
|
||||
BYTE saveOldFunction(void* proc, void* old)
|
||||
{
|
||||
CopyMemory(old, proc, 5);
|
||||
recalculateRel32IfIsJump(old, proc);
|
||||
CallJmpInstr* instr = (CallJmpInstr*)((BYTE*)old + 5);
|
||||
instr->opcode = 0xe9;
|
||||
instr->rel32 = (DWORD)((BYTE*)proc - (BYTE*)old - 5);
|
||||
return 5;
|
||||
}
|
||||
|
||||
void* splice(void* splicedFunctionAddress, void* hookFunction)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((DWORD*)splicedFunctionAddress, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
void* oldFunction = malloc(255);
|
||||
*(DWORD*)oldFunction = (DWORD)splicedFunctionAddress;
|
||||
*((BYTE*)oldFunction + 4) = saveOldFunction((DWORD*)((BYTE*)splicedFunctionAddress), (DWORD*)((BYTE*)oldFunction + 5));
|
||||
CallJmpInstr* instr = (CallJmpInstr*)((BYTE*)splicedFunctionAddress);
|
||||
instr->opcode = 0xe9;
|
||||
instr->rel32 = (DWORD)hookFunction - (DWORD)splicedFunctionAddress - 5;
|
||||
VirtualProtect((DWORD*)splicedFunctionAddress, 5, oldProtect, &oldProtect);
|
||||
|
||||
return (DWORD*)((BYTE*)oldFunction + 5);
|
||||
}
|
||||
|
||||
BOOL restore(void*& oldProc)
|
||||
{
|
||||
if (oldProc != 0 && *((BYTE*)(*(DWORD*)((BYTE*)oldProc - 5))) == 0xe9) {
|
||||
void* proc = (DWORD*)(*(DWORD*)((BYTE*)oldProc - 5));
|
||||
DWORD size = (BYTE)(*(DWORD*)((BYTE*)oldProc - 1));
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(proc, size, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
CopyMemory(proc, oldProc, size);
|
||||
recalculateRel32IfIsJump(proc, oldProc);
|
||||
VirtualProtect(proc, size, oldProtect, &oldProtect);
|
||||
free((DWORD*)((BYTE*)oldProc - 5));
|
||||
oldProc = 0;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
5
L2BotDll/Common/apihook.h
Normal file
5
L2BotDll/Common/apihook.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
void* splice(void* splicedFunctionAddress, void* hookFunction);
|
||||
BOOL restore(void*& oldProc);
|
Reference in New Issue
Block a user