国外CE使用

All .exe and .dll files when loaded into memory are referred to as "modules".

When adding addresses to your Cheat Engine table, and especially when using pointers you will often find the address listed like this:

 

Or maybe like this:
server.dll + 004EE83

This is using relative offset from the address of a module. Too see if an address is offset from a certain module make sure you enable this:

 

Then in memory viewer use "Go To Address" to the address. Regardless of if it is data or code, this will tell you what module it is offset from.

To view all the modules loaded by the process in Cheat Engine and view their addresses do this:

 

Also you can use Dissect PE Headers to view relative information:


MZ-Start is the address of the module as it is currently loaded into memory. Preferred ImageBase is parsed straight from the PE Header and is the location that it prefers to be loaded into. If this memory address is already taken, it will relocate.

When an .exe is executed, the windows loader create a process for it and give it it's own virtual memory space. The loader loads the executable into memory and then any .dlls that are called by the process. The PE header for the .dll defines a ImageBase address. The windows loader will try to load the .dll into the virtual memory space of the process that requires it. If that space is already occupied, it will be loaded into a different location. If this happens hardcodes addresses in our hacks will not work.

Now let's say we have a pointer:
ac_client.exe + 109B74

Now the ImageBase pulled from the PE header of ac_client.exe is "00400000"
We can only have one executable for each process which is an empty memory space until ac_client.exe is loaded. There is nothing blocking ac_client.exe from loading into it's ImageBase. So the base address of a .exe is always the same.

The ONLY time when a .exe isn't loaded into the imagebase stored in the PE headers is when ASLR(Address Space Layout Randomization) is enabled on the OS and the DynamicBase flag is set to enable the OS to randomize virtual address of the module.

We can just evaluate this before placing it in the code.
ac_client.exe + 109B74
00400000 + 109B74
509B74

This is the definition of a static address, it may be relative to the base address of an executable in the binary on disk, but it is always static in memory after relocations have occured.

But for .DLL's that can be relocated:

"server.dll + 004EE83" works in Cheat Engine because Cheat Engine evaluates the address of server.dll. CE will get the address of server.dll and replace it with the adress that the module is loaded.
So lets say the address of module server.dll is 0x10000000, cheat Engine will evaluate:

server.dll + 004EE83
0x10000000 + 004EE83
1004EE83

The above evaluation is done by cheat engine while the program is running.

But when you are trying to use this in an external trainer you need to evaluate "server.dll" + 004EE83 yourself. There are multiple ways of doing this and we will discuss one of them now.

To do this externally you can use this function that has been widely used named dwGetModuleBaseAddress.

Basically it uses the windows API CreateToolhelp32Snapshot to get a snapshot of all loaded modules for the given process, it then iterates through all the loaded modules and finds the module with the module name you give it. It returns a uintptr_t to the module address. You input the ProcessID and the name of the module and it ouputs the address of the module.

Includes:

C++:Copy to clipboard
//Place these with your other includes
#include <tlhelp32.h>
#include <tchar.h>

Function Prototype:

C++:Copy to clipboard
//Place this in the global namespace anywhere before the function is defined and called.
uintptr_t GetModuleBaseAddress(DWORD dwProcID, const TCHAR *szModuleName)

Function Definition:

C++:Copy to clipboard
//Place this anywhere in the global namespace
uintptr_t GetModuleBaseAddress(DWORD dwProcID, const TCHAR *szModuleName)
{
    uintptr_t ModuleBaseAddress = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 ModuleEntry32;
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &ModuleEntry32))
        {
            do
            {
                if (_tcsicmp(ModuleEntry32.szModule, szModuleName) == 0)
                {
                    ModuleBaseAddress = (uintptr_t)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }
    return ModuleBaseAddress;
}

The Function Call

C++:Copy to clipboard
uintptr_t serverdllBaseAddress = 0;
serverdllBaseAddress = GetModuleBaseAddress(dwProcId, _T("server.dll"));

猜你喜欢

转载自blog.csdn.net/aa80303857/article/details/84924218
ce
今日推荐