Open cacodemonx opened 10 years ago
this is a direct translation from C# to C++
(Switch memcpy() to appropriate calls if remote)
http://www.privatepaste.com/63b204048a
ShowName() will display your character's name (the first entity)
Thanks a lot! I got it working, it seems I did forget the struct alignment after all, kinda silly of me.
Just one last question, do you know where the camera stuff is stored? like the pitch, yaw etc? I want to try make a function where it simply takes you forward or even up depending on where you are looking. From what I saw bolter does not seem to have that kindof feature yet.
I haven't disassembled the cam stuff yet, I have found the location, just haven't decoded the structures. There are some cam adjustment functions in the Entity and Entity->subStruct, that move the cam, mostly up and down though.
For further inquiries, email here http://address-protector.com/5IvCCCijPea3dCida12ntYmrqfa2W3GNKRiEGLu2aMq3XMu-rq3fD9BzdzQhkNO9
Reopened because github doesn't have PMs. the camera structure pointer is the first member in the target struct. (now should be called the player info?) Still decoding it, but here is the full structure (in C#)
public struct Camera
{
private fixed byte Unknown0[0x40];
public float UnknownCam0; //offset 0x40
public float UnknownCam1; //offset 0x44
public float UnknownCam2; //offset 0x48
private fixed byte Unknown3[0x24];
public float UnknownCam3; //offset 0x70
public float UnknownCam4; //offset 0x74
public float UnknownCam5; //offset 0x78
private fixed byte Unknown6[0x4];
public float UnknownCam6; //offset 0x80
public float UnknownCam7; //offset 0x84
public float UnknownCam8; //offset 0x88
private fixed byte Unknown9[0x4];
public float UnknownCam9; //offset 0x90
public float UnknownCam10; //offset 0x94
public float UnknownCam11; //offset 0x98
private fixed byte Unknown12[0x8];
public float UnknownCam12; //offset 0xA4
public float UnknownCam13; //offset 0xA8
private fixed byte Unknown14[0x4];
public float UnknownCam14; //offset 0xB0
public float UnknownCam15; //offset 0xB4
public float UnknownCam16; //offset 0xB8
private fixed byte Unknown17[0x4];
public float UnknownCam17; //offset 0xC0
public float UnknownCam18; //offset 0xC4
public float UnknownCam19; //offset 0xC8
private fixed byte Unknown20[0x1C];
public float Zoom; //offset 0xE8
private fixed byte Unknown21[0x14];
public float UnknownCam21; //offset 0x100
public float UnknownCam22; //offset 0x104
private fixed byte Unknown23[0x38];
public float Zoom2; //offset 0x140
private fixed byte Unknown24[0x1C];
public float UnknownCam24; //offset 0x160
public float UnknownCam25; //offset 0x164
public float UnknownCam26; //offset 0x168
private fixed byte Unknown27[0x4];
public float UnknownCam27; //offset 0x170
public float UnknownCam28; //offset 0x174
public float UnknownCam29; //offset 0x178
private fixed byte Unknown30[0x4];
public float UnknownCam30; //offset 0x180
public float UnknownCam31; //offset 0x184
public float UnknownCam32; //offset 0x188
private fixed byte Unknown33[0x44];
public float UnknownCam33; //offset 0x1D0
public float UnknownCam34; //offset 0x1D4
public float UnknownCam35; //offset 0x1D8
private fixed byte Unknown36[0xC];
public float UnknownCam36; //offset 0x1E8
private fixed byte Unknown37[0x44];
public float UnknownCam37; //offset 0x230
public float UnknownCam38; //offset 0x234
public float UnknownCam39; //offset 0x238
}
Thanks! how are you finding these structs so quickly? I want to learn! my ida skills are not very good. Also the masterptr player and subplayer structs have changed in last patch? I forgot to write down the previous values and not struggling to update the structs :(
I'll commit the fixed version, the sig for MasterPtr only had one byte changed, and the structure shifted 12 bytes. playerstruct got changed around a lot. Making some major changes to the code, so pls excuse the layout lol. but GameStructs.h has the new structure layouts in C/C++.
Ahh awsome! thanks a lot for updating it, it all now works again. I am really curious as how you get those structs so precise, I always struggle with things like that, is there some trick to it or just lots and lots of analysis?
Mixture of both, it depends on how much I already know about the structure. To find them from scratch, I use a combination of IDA and CE, CE I use for finding a value that may be in the structure, and then with IDA, I find the function writing to that member, and walk the routine call path backwards, until I discover where the pointer is being created. once I find the pointer, I take an assumed size based on allocation of that memory block, and begin analysis on each member (varies greatly on what I'm looking for), I then pull all the members of interest into CE's address table, and save it. I use a C# app to convert the .CT file into a structure, adds the unknown spacers and formatting etc.
generally I name the members of interest appropriately, but I haven't worked with cam stuff much. so I didn't want to give the members inappropriate names, I do know XIV lays axes out X,Z,Y. so that should help me out some.
Thanks I will start reading up on it, Have you any idea where the health values are in the PCMobStruct? and any idea where the skillbar data is located with skill info?
HP/MP etc was at 16A0 before the update. they have shifted, but I can't recall the new offsets, I'll get back to you when I have time to look over it. The values are stored exactly how they are shown, so you could use CE to find the changing values, and scan for your exact HP, then change classes/gear etc, and rescan with your new HP. (using max HP is probably best, to not get messed up by regen)
I managed to get flying to work but because the ASM movement block thing the other entities are not updated either, like the other players and enemies, is there any way to just block my movement while allowing the other entities?
you would have to hook the entire movement block, and add a cmp, to the register that holds your character's entity pointer
ex. If eax stores the entity pointer
cmp eax,[your entity] //compare your entity pointer against the current iteration
v----je // redirect flow to nops, if the above is true.
v (update X) // these fire if the above cmp was false
v (update Z)
v (update Y)
v-->nop
flying seems cool, so, I'll write the hook for you when I get time, if you don't before hand.
Ah thanks that would be great, I still have not implemented that hook, kinda getting advanced for me.
For my flying control this works good:
float Scale = 0.0f;
float Up = 0.0f;
if(KEYDOWN(0x57) || (KEYDOWN(VK_LBUTTON) && KEYDOWN(VK_RBUTTON)))Scale = 0.05f * Delta; //W
if(KEYDOWN(0x53))Scale = -0.05f * Delta; //S
if(KEYDOWN(VK_SPACE))Up = 0.05f * Delta; //Space
if(KEYDOWN(VK_CONTROL))Up = -0.05f * Delta; //Control
float Heading = Entities[0].Heading;
Entities[0].ServerPos.x += Scale * sinf(Heading);
Entities[0].ServerPos.z += Up;
Entities[0].ServerPos.y += Scale * cosf(Heading);
http://www.privatepaste.com/0d9f035a53 this is the movement interception. I have example calls at the top, (sorry for the casting galore, wrote this quickly). but the MovementIntercept struct lays out what is all going on.
wow thanks a lot! will implement this asap and let you know.
It's going to need a bit of working, if you're doing things with WPM/RPM i.e
jmp dword ptr [CliMovePtr]
CliMovePtr is a pointer to the location in executable memory to go back to, to give the game back control. and since this means effectively, it's a pointer of a pointer. it needs to be allocated locally. you can append it to the Initialization VirtualAlloc(Ex)() if you'd like.
I am kinda struggling with this concept, since I am using an external method I had to change some things, can you tell me if I am on the right track?
// pCliMov: Pointer to the instruction at the beginning of the CliMovmentAsm
// pServMov: Pointer to the instruction at the beginning of the ServMovmentAsm
// pEntity: Pointer to your characters entity (also the beginning of the PC/Mob Entities)
void AllocateASMMemory(DWORD ClientASMFirstInstruction, DWORD ServerASMFirstInstruction, DWORD PlayerEntityPtr)
{
//Allocate a memory block for the ASM
DWORD CustomASMStart = (DWORD)VirtualAllocEx(Hook.ProcessHandle, 0, sizeof(MoveIntercept), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //Allocate some memory in the process
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)CustomASMStart, InterceptASMBytes, sizeof(MoveIntercept), 0); //Write to that memory our custom ASM bytes
//
//Fill in custom ASM variables
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, EntityPtr)), &PlayerEntityPtr, sizeof(DWORD), 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, EntityPtr2)), &PlayerEntityPtr, sizeof(DWORD), 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CXFunc)), ClientBytesX, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CZFunc)), ClientBytesZ, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CYFunc)), ClientBytesY, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CXFunc2)), Null5, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CZFunc2)), Null5, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, CYFunc2)), Null5, 5, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SXFunc)), ServerBytesX, 8, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SZFunc)), ServerBytesZ, 8, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SYFunc)), ServerBytesY, 8, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SXFunc2)), Null8, 8, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SZFunc2)), Null8, 8, 0);
WriteProcessMemory(Hook.ProcessHandle, (LPVOID)(CustomASMStart + offsetof(MoveIntercept, SYFunc2)), Null8, 8, 0);
//
}
As fas as I understand this allocates a memory block anywhere in the process and then I have to modify the game's asm to go to my new code block? How do I allocate the jmp dword ptr [CliMovePtr] stuff?
Thanks
http://www.privatepaste.com/9d0f48e5c2 CliMovePtr needs to point to the instruction that comes right after all the movss, in the original game asm. (same for ServMovePtr) The above paste adds some comments, and shows you can use the end of the MoveIntercept struct, to hold those pointers.
this part CliMovementPtr = pCliMov + 30; ServMovementPtr = pServMov + 39;
is me getting the addresses of the instruction that comes right after all the movss
Just to clarify, on this question ~"As fas as I understand this allocates a memory block anywhere in the process and then I have to modify the game's asm to go to my new code block? "~ Yes once the asm is allocated. the jmpptr/2 will be written at the top of the original game movss's and from there on, every movement update will be redirected to your custom asm. which now has full control of who should not get an update.
If you are still having trouble, someone suggested something to me, that may make it easier on you. you can use the "naked" keyword, to write asm out in c++. DWORD nulljmpptr = INFINITE; http://www.privatepaste.com/f94148a2fd
some of the offsets are off,you can verify them against the game's movement.
but basically, VirtualAllocEX sizeof(The entire asm) + 14 copy naked asm over. WriteProccessMemory to (base of asm + sizeof(The entire asm)), the address we need to return to for client movement. WriteProccessMemory to (base of asm + sizeof(The entire asm) + 4), the address we need to return to for server movement .WriteProccessMemory to (base of asm + sizeof(The entire asm) + 8), the address to our client entity cmp instruction. WriteProccessMemory to (base of asm + sizeof(The entire asm) + 12), the address to our server entity cmp instruction. WriteProccessMemory: turn both "7FFFFFEh" into our entity. WriteProccessMemory: turn the first "nulljmpptr" into (base of asm + sizeof(The entire asm)) WriteProccessMemory: turn the second "nulljmpptr" into (base of asm + sizeof(The entire asm) + 4) This is how it looks in memory (before writes). http://i842.photobucket.com/albums/zz348/usagiuke/memass_zpsb9915fb5.png
the jmp DWORD PTR nulljmpptr make two of those, and change nulljmpptr to (base of asm + sizeof(The entire asm) + 8) 1st (base of asm + sizeof(The entire asm) + 12) 2nd
.WriteProccessMemory to Top of client game movement, our jmp DWORD PTR (base of asm + sizeof(The entire asm) + 8) .WriteProccessMemory to Top of server game movement, our jmp DWORD PTR (base of asm + sizeof(The entire asm) + 12)
if all done correctly, the game should be hopping to our custom assembly, then hopping back when done.
Ah very cool, you say to VirtualAllocEX sizeof(The entire asm) + 14, how can I get the size of a naked function? or do you count the bytes manually?
Also how can I view my created assembly in cheat engine? VirtualAllocEx returns a dword but if I click memory view and go to that address there is a bunch of jmp commands, nothing resembling the asm that is defined in the naked function.
depending on the compiler flags. the naked asm will either be a jmp or the raw assembly. It sounds like you have the jump case. look at the &nakedasm in memory view. If it's a jmp, right click and press "follow" That will show the naked assembly. to get that address from your code. you will have to do something like this
DWORD jmpadrress = (DWORD)&NakedAsm;
DWORD jmpsize = *(DWORD*)(jmpadrress + 1)
LPVOID RawAsm = (LPVOID)(jmpadrress + jmpsize + 5);
Hi, I have been following this project for a while while trying to code a similar thing in C++ for training purposes. I got the movement block (asm) thing working just fine but the pointer I get for MasterPointer seems correct but it has no valid data inside once I cast it to a struct. The target is null and player struct seem's to contain all bogus data. I am just wondering if the code is even correct as of now? The sigPoints[8] + 0x30 thing is the weird thing to me. Sorry if I posted in wrong place, I can't seem to send you a pm anywhere.
//ASM Pos Changers ReadProcessMemory(Hook.ProcessHandle, (LPCVOID)(sigPoints[3] + 36), (LPVOID)&ServerPosStruct, sizeof(ServerPosAsm), 0); //Function that modifies pos NOP it! ReadProcessMemory(Hook.ProcessHandle, (LPCVOID)(sigPoints[2] + 11), (LPVOID)&ClientPosStruct, sizeof(ClientPosAsm), 0); //Function that modifies pos NOP it! memcpy(&OriginalServerPosStruct, &ServerPosStruct, sizeof(ServerPosAsm)); //Backup the original code memcpy(&OriginalClientPosStruct, &ClientPosStruct, sizeof(ClientPosAsm)); //Backup the original code //