- Joined
- Oct 20, 2007
- Messages
- 28
- Reaction score
- 2
Hey guys,
first of all i dont open this thread to get answers like: use madknight's dll or learn c++, i want make my own .dll's and not just download finished ones..
i learning by doing and i wanted to use Keays Source code but anything wrong...if i start my client it dont use the fpslimiter <.<
and no i dont copy paste, i changed few functions to miney like "Core to Memory,.." included too all i need for it but it still not work -.-
no one wanted to help me or tryed... so i hope anyone of you can explain me what i did wrong :S
(its not the fully source of my dll, just the one for fpslimiter)
dllmain.cpp:
FpsLimiter.h
FpsLimiter.cpp
Memory.cpp (Just the Intercept Function):
Memory.h (Just the _I_Call & Intercept Function):
The Memory.cpp & Memory.h is from Cry.dll
so whats wrong, i dont understand lol... i looked now many times function for function but it should work oO or iam wrong?
pls help xD
greets dark
first of all i dont open this thread to get answers like: use madknight's dll or learn c++, i want make my own .dll's and not just download finished ones..
i learning by doing and i wanted to use Keays Source code but anything wrong...if i start my client it dont use the fpslimiter <.<
and no i dont copy paste, i changed few functions to miney like "Core to Memory,.." included too all i need for it but it still not work -.-
no one wanted to help me or tryed... so i hope anyone of you can explain me what i did wrong :S
(its not the fully source of my dll, just the one for fpslimiter)
dllmain.cpp:
PHP:
#include "FpsLimiter.h"
void IProtect::Boot(HMODULE hModule)
{
CTweaks Tweaks;
Tweaks.HookWorldRefresh();
}
FpsLimiter.h
PHP:
#include <iostream>
#include <Windows.h>
using namespace std;
class CTweaks
{
public:
CTweaks(); // Constructor
void HookWorldRefresh(); // World refreshing function hooker
private:
// This function has to be static, otherwise it wouldn't be possible to get a pointer to it.
static WPARAM __thiscall WorldRefresh(void*); // Engine World refreshing thread
typedef int (__cdecl *WREngineFunc)(void); // Unknown WorldRefresh function's prototype
typedef int (__thiscall *RefreshEntities)(void*); // Entity worldrefreshing function's prototype
DWORD WREngineFuncPtr; // Pointer to unknown worldrefreshing function
DWORD RefreshEntitiesPtr; // Pointer to entity worldrefreshing function
BYTE *WREngineActive; // Pointer to possible 'this' instance
int MaxFPS; // Maximum frames per second
int MaxTime; // Maximum milliseconds accepted to engage frame blocker
DWORD SleepTime; // Time to block the frame each round
};
extern CTweaks *Tweaks;
FpsLimiter.cpp
PHP:
#include "StdAfx.h"
#include "FpsLimiter.h"
#include "Memory.h"
// Only one single instance of this class is needed
// So there is no need to worry about where nor how we initialize it.
CTweaks *Tweaks = new CTweaks;
IMemory Memory;
CTweaks::CTweaks()
{
// Engine addresses pointers
this->WREngineFuncPtr = 0x004a73b0;
this->RefreshEntitiesPtr = 0x00425960;
this->WREngineActive = (BYTE*)0x006ddf58;
}
void CTweaks::HookWorldRefresh()
{
this->MaxFPS = 30;
// Right here it is possible to load the max fps from a configuration file, or what so ever.
// Example : this->MaxFPS = Config->Engine.FPSLimit;
// Two calls to our WorldRefresh function, only one of them is used, but the second one is just in case.
this->MaxTime = (1000/this->MaxFPS);
Memory.Intercept(Memory._I_CALL,(void*)0x00505869,(void*)this->WorldRefresh,5);
Memory.Intercept(Memory._I_CALL,(void*)0x00505bfc,(void*)this->WorldRefresh,5);
#ifndef SILENT_MODE
cout << "FPS Limiter installed." << endl;
#endif
}
WPARAM __thiscall CTweaks::WorldRefresh(void *thisPointer)
{
// Since this function is running as a thread, InixSoft had to declare it as static (just as done here)
// Therefore, since the 'this' instance can only be used with non-static member functions,
// The calling convention is not __thiscall anymore but __fastcall, and the 'this' pointer is passed as argument.
// EDIT: After some tests, I figured __thiscall is sometimes required, so try it like this.
// If it doesn't work out, change it back to __fastcall
// Default function vars
void *that;
char state;
struct tagMSG Msg;
HACCEL hAccel;
// Our variables
// We will be using high resolution timers
// <3 precision
int PerformanceTime;
unsigned __int64 lpFrequency;
unsigned __int64 lpPerformanceCount;
unsigned __int64 lpPerformanceStep;
// This > That. Ok ?
that = thisPointer;
// Checking for the CPU's frequency, unit is in Herz.
QueryPerformanceFrequency((LARGE_INTEGER*)&lpFrequency);
hAccel = LoadAcceleratorsA(NULL, (LPCSTR)0x71);
Msg.message = 0;
PeekMessageA(&Msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE);
while (Msg.message != 0x12)
{
// EXTREMELY important!!
// Since we call functions that weren't compiled with the same compiler (type, version, et cetera) as we use
// There are high chances that those functions modify, either the stack or the registers in a way OUR compiler would never expect.
// Such corruption is especially noticeable in loops, causing crashes in most cases.
// This is why it is critical to save the stack before and after those functions are executed.
__asm pushad
if (*((BYTE*)that+0x9d)) state = (!!PeekMessageA(&Msg, NULL, WM_NULL, WM_NULL, PM_REMOVE));
else state = (!!GetMessageA(&Msg, NULL, 0, 0));
if (state)
{
if ((!hAccel) || (!(*(DWORD*)that+0x38)) || (!TranslateAcceleratorA(*((HWND*)that+0x38), hAccel, &Msg)))
{
TranslateMessage(&Msg);
DispatchMessageA(&Msg);
}
// Not quite sure about what this function really does
// I know it's executed when the mouse is moved.
((WREngineFunc)Tweaks->WREngineFuncPtr)();
}
else
{
if ((*((BYTE*)that+0x9d)) && (*(BYTE*)Tweaks->WREngineActive))
{
// Querying the performance count before and after world refreshing function
QueryPerformanceCounter((LARGE_INTEGER*)&lpPerformanceCount);
// This function refreshes the whole kal world, including object movements in time, daytime, et cetera, well, pretty much everything.
// Could also be called rendering function.
int tmpActive = ((RefreshEntities)Tweaks->RefreshEntitiesPtr)(that);
QueryPerformanceCounter((LARGE_INTEGER*)&lpPerformanceStep);
if (tmpActive < 0) SendMessageA(*((HWND*)that+0x38), WM_COMMAND, 0x9C46, 0);
// From here on, we will calculate the difference between the two counters
// And base the time we'll need to block the frames from being displayed for on that amount.
PerformanceTime = (int)(lpFrequency / (lpPerformanceStep-lpPerformanceCount));
if (PerformanceTime) PerformanceTime = 1000 / PerformanceTime;
if (Tweaks->MaxTime > PerformanceTime)
{
// This var could be used as local variable, but let's rather keep it global.
Tweaks->SleepTime = (Tweaks->MaxTime - PerformanceTime);
Sleep(Tweaks->SleepTime);
}
}
}
// Restoring the stack.
__asm popad
}
if (hAccel) DestroyAcceleratorTable(hAccel);
return Msg.wParam;
}
Memory.cpp (Just the Intercept Function):
PHP:
unsigned long IMemory::Intercept(unsigned char instruction, void* source, void* destination, size_t length)
{
unsigned long realTarget;
LPBYTE buffer = new BYTE[length];
memset(buffer,0x90,length);
if (instruction != IMemory::_I_NOP && length >= 5)
{
buffer[(length-5)] = instruction;
unsigned long dwJMP = (unsigned long)destination - ((unsigned long)source + 5 + (length-5));
memcpy(&realTarget,(void*)((unsigned long)source+1),4);
realTarget = realTarget + (unsigned long)source + 5;
memcpy(buffer + 1 + (length - 5),&dwJMP,4);
}
if (instruction == IMemory::_I_JE_SHORT)
{
buffer[0] = instruction;
buffer[1] = (BYTE)destination;
}
if (instruction == 0x00)
buffer[0] = (BYTE)destination;
this->MemcpyExD(source, buffer, length);
delete[] buffer;
return realTarget;
}
Memory.h (Just the _I_Call & Intercept Function):
PHP:
_I_CALL = 0xe8,
virtual unsigned long Intercept(unsigned char instruction, void* source, void* destination, size_t length);
The Memory.cpp & Memory.h is from Cry.dll
so whats wrong, i dont understand lol... i looked now many times function for function but it should work oO or iam wrong?
pls help xD
greets dark