Hello Alain and everyone in this thread.
I got a bit of question regarding EAL.
I've been porting this function from the EAL source to C#
[Only registered and activated users can see links. Click Here To Register...]
This is my finnished port
[Only registered and activated users can see links. Click Here To Register...]
And you basically use it like this
Code:
static void Main(string[] args)
{
if (!Mem.Attach("game.bin")) return;
Constants.ProcModule main = Mem.FindProcessModule("game.bin");
var GET_LOCAL_PLAYER = Mem.FindPattern(main, "C0 89 87 04 01", -5, 2, Constants.MemoryType.RT_REL_ADDRESS);
var INVENTORY_ACCESS_FUNCTION = Mem.FindPattern(main, "FF 5E 5D C2 14", -13, 2, Constants.MemoryType.RT_REL_ADDRESS);
var TARGETING_COLLECTIONS_BASE = Mem.FindPattern(main, "68 50 06 00 00", 30, 1, Constants.MemoryType.RT_ADDRESS);
var WND_INTERFACE_BASE = Mem.FindPattern(main, "4E 24 83 B9 B0", 31, 1, Constants.MemoryType.RT_ADDRESS);
var EUDEMON_GETEUDEMON_FUNCTION = Mem.FindPattern(main, "DB 0F 84 5E 01", -7, 1, Constants.MemoryType.RT_REL_ADDRESS);
var EUDEMON_SENDCOMMAND_FUNCTION = Mem.FindPattern(main, "6A 04 6A 00 52", 6, 1, Constants.MemoryType.RT_REL_ADDRESS);
var EUDEMON_SELECT_FUNCTION = Mem.FindPattern(main, "FB FF 56 8B F1", -33, 1, Constants.MemoryType.RT_LOCATION);
var EUDEMON_ISMEDITATING_FUNCTION = Mem.FindPattern(main, "3B 01 7D 1A 0F", -17, 1, Constants.MemoryType.RT_LOCATION);
var EUDEMON_HASGIFT_FUNCTION = Mem.FindPattern(main, "3B 01 7D 1A 0F", -17, 2, Constants.MemoryType.RT_LOCATION);
var CURRENT_MAP_BASE = Mem.FindPattern(main, "C0 74 0D 83 3D", -10, 1, Constants.MemoryType.RT_ADDRESS);
var DETOUR_MAIN_LOOP_OFFSET = Mem.FindPattern(main, "FF 80 BE 08 01", 1, 1, Constants.MemoryType.RT_LOCATION, true, "80 BE 08 01 00 00 00");
var DETOUR_CRASH_HANDLER_OFFSET = Mem.FindPattern(main, "4D EC 51 6A 05", -86, 1, Constants.MemoryType.RT_LOCATION, true, "64 A1 00 00 00 00");
Mem.Detach(true);
Console.ReadLine();
}
It seems to "work" but when I for an example try to execute these mnemonics (from Alains source, function GetLocalPlayer)
Code:
__asm
{
mov eax, lpBase;
mov ecx, ds:[eax];
test ecx, ecx;
jz Finnish;
call lpFunction;
mov localPlayer, eax;
Finnish:
}
I get a crash, this is how I try to execute them in the game (Creating a remote thread and writing assembled bytes into a cave etc)
Code:
static void Main(string[] args)
{
if (!Mem.Attach("game.bin"))
{
Environment.Exit(-1);
}
var localPlayer = Mem.AllocateMemory(4); // Allocate 4 bytes inside process where the Localplayer will be stored within the executable
var TARGETING_COLLECTIONS_BASE = Mem.FindPattern(main, "68 50 06 00 00", 30, 1, Constants.MemoryType.RT_ADDRESS);
var GET_LOCAL_PLAYER = Mem.FindPattern(main, "C0 89 87 04 01", -5, 2, Constants.MemoryType.RT_REL_ADDRESS);
string[] array = new string[]
{
"use32",
$"mov eax,{TARGETING_COLLECTIONS_BASE}",
"mov ecx, [ds:eax]",
"test ecx,ecx",
"jz .Finnish"
$"call {GET_LOCAL_PLAYER}", // This could be an issue with relative instruction, can I just move this into lets say ebx or something and do call ebx instead of address directly?
$"mov {localPlayer.Pointer},eax" // Move contents of EAX into our allocated space so we can read from it
".Finnish:",
// "retn",
}
RemoteAllocatedMemory alloc = AllocateMemory(0x10000, MemoryProtection.ExecuteReadWrite, AllocationType.Commit); // Allocate some space to write our assembly code into
byte[] assembled = Assemble(mnemonics); // Using FASM assembler to assemble mnemonics into bytes
WriteBytes(alloc.Pointer.ToInt32(), assembled); // Write assembled bytes into our little code cave location
IntPtr hThread = Native.CreateRemoteThread(MiniMem.AttachedProcess.ProcessHandle,
IntPtr.Zero,
IntPtr.Zero,
alloc.Pointer, // Start of code cave
IntPtr.Zero /* LP PARAMETER */,
(uint) ThreadCreationFlags.Run,
IntPtr.Zero);
// Here here is the crash happening
// Here here is the crash happening
// Here here is the crash happening
if (hThread == IntPtr.Zero)
{
FreeMemory(alloc);
return;
}
WaitForSingleObject(hThread, 0xFFFFFFFF);
CloseHandle(hThread);
// Remote thread has finnished, read the value from
var localPlayerReadResult = Mem.Read<int>(localPlayer.Pointer.ToInt64());
// Do something with localPlayerReadResult here
} // End of Main()
What could I be doing wrong? My pattern scans do return something, but maybe they return the wrong addresses, I dont know how to compare the addresses with the results the EAL function RetrieveAddresses() gets
Sorry for wall of text, but if anyone has a clue and feel like helping out please do :)
RIP skandia :handsdown: (I am "Ohm" or "Ohmnicient" from skandia forums)
EDIT:
Here is an image of example addresses I get from my pattern scans (if it is to any help)