![]() ![]() |
![]() Post #1 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | As you might have noticed I am trying to learn some things about memory. And I have some questions: In the get all actors example, the actors are just numbers. Are they? And if so, what are cars for kind of number? And let's say I am creating an actor outside a thread, in a dll. If I create a ped, is it just an int? Will there be any conflicts with other peds? How is it done in viligant justice, as pure memory or is it a directly injected script? And my final question, 0xB6F5F0 is the player pointer, what about other peds how to get their struct (without cleo)? And there was a link to the source code of an old version of cleo, does anyone have it? |
![]() Post #2 | |
![]() Coding like a Rockstar! ![]() Posts: 1,468 From: ??? Joined: 28-May 09 ![]() | CLEO source: http://sannybuilder.com/dev/cleo.txt Everything in a computer is numbers. The values in vara are always numbers, even ped handles. No exception to the rule. Knowing that, we could just go through every number that possible with 4 bytes and we wouldn't just end up having every ped handle possible, but every other kind of handle, every possible float, every penguin... But of course going through all those numbers will take a lot of processing time. On a more helpful note, the handles for peds, vehicles and objects are actually the address with some math applied. But as I said before, I dont have IDA and my memory would make a really bad IDB. I think the address is simply bit shifted 8 bits I think. It makes the number smaller by losing some of the bits. But doesnt lose so much that there is risk of collision. You should be able to find the function that makes this conversion in the IDB. Opcodes that use handles convert it the other way. CLEO uses that func to get the address of entities. And if you create a ped in a dll... Well, you dont create a ped. There is no C++ command to create a ped ![]() ![]() -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
![]() Post #3 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | About the numbers of peds, I see some similarities: CODE Hex: 01 00 01 03 01 04 01 05 01 06 01 07 01 08 01 09 01 0A 02 0D 01 12 Output: 1 769 1025 1281 1537 1793 2049 2305 2561 3330 4609 [quote]You should be able to find the function that makes this conversion in the IDB.[/qoute] How to find functions? I've created a script to convert the handling of a car into a boat when it hits the water. But I don't know what the size is of the addresses, 4 crashed the game and 8 didn't work. The game doesn't crash but starts a new regular game (maybe I've hit something intresting?). What values should I use? EDIT: No more page stretching This post has been edited by badboy: Jun 12 2012, 02:43 PM |
![]() Post #4 | |
![]() Coding like a Rockstar! ![]() Posts: 1,468 From: ??? Joined: 28-May 09 ![]() | Floats are 4 bytes. Press Ctrl+L in IDA to open up the functions window and Alt+T to start a search. Enter "atHandle" and you should find the function. -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
![]() Post #5 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | Doesn't exist, and after looking over link2012's post: can I download a good version of SA idb somewhere? |
![]() Post #6 | |
Trained Newbie Posts: 21 Joined: 19-February 12 ![]() | CODE TransmissionData_nDriveType - Front = 70, Rear = 82, 4WD = 52 TransmissionData_nEngineType - Petrol = 80, Diesel = 68, Electric = 69 and this is my script. i hope this would help ![]() CODE 03C0: 0@ = actor $PLAYER_ACTOR car 0A97: 31@ = car 0@ struct 31@ += 0x384 //fMass 0A8D: 30@ = read_memory 31@ size 4 virtual_protect 0 30@ += 0x4 0A8C: write_memory 30@ size 4 value 1700.0 virtual_protect 0 |
![]() Post #7 | |
![]() I will kill you Posts: 126 Joined: 13-May 11 ![]() | Doesn't exist, and after looking over link2012's post: can I download a good version of SA idb somewhere? http://public.sannybuilder.com/gtasa_exe_idb/ Here you have a III and SA idb, good to start your work. (I think you already have this?) This post has been edited by LINK2012: Jun 12 2012, 02:26 PM |
![]() Post #8 | |
![]() Coding like a Rockstar! ![]() Posts: 1,468 From: ??? Joined: 28-May 09 ![]() | Use the 'Last modified' link to get the latest version. -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
![]() Post #9 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | Thanks, I found it now ![]() |
![]() Post #10 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | I'm trying to make a small asi file and I want to know if this will work. And I've got some questions. Is "CPed +0x46F" BYTE, WORD or DWORD? My code is wrong if it's not DWORD. CODE // DWORD * CPed = (DWORD*)0xB6F5F0; bool IsStanding(DWORD * CPed) { CPed += 0x46F; if (*CPed == 128) return true; else return false; } Would this work (as a check), and what is CPed for the player? Is it 0xB6F5F0 or 0xB7CD98. And how come the memory addresses are always the same. Shouldn't they be different on each runtime? |
![]() Post #11 | |
![]() The Assistant Posts: 84 From: Matera, IT Joined: 16-June 11 ![]() | CPed + 0x46C is a 4-byte flag. To check if the player is in stand position, do (untested): CODE bool IsPedStanding = (*(unsigned int *)(CPed + 0x46C) & 0x80000000) != 0; 0xB6F5F0 points to a CCamera member which contains a direct pointer to player's CPed. 0xB7CD98 is a array of 2 CPlayer, whose first member contains a direct pointer to player's CPed, use this instead. Note that I said these static memory addresses contain a dynamic pointer, the needed one. This post has been edited by Wesser: Jun 19 2012, 04:55 PM |
![]() Post #12 | |
![]() I will kill you Posts: 126 Joined: 13-May 11 ![]() | This will not work properly because a DWORD pointer + 1 is equal to moving the pointer 4 bytes ahead. Pointer += 10 is basically Pointer += sizeof(*Pointer) * 10 What you can do is cast it to a byte during the addition. Properly function CODE bool IsStanding(DWORD* CPed) { (BYTE*)CPed += 0x46F; // Now moved right 0x46F ahead. return (*CPed & 0x80000000) != 0; } Properly Wesser's version: CODE bool IsPedStanding = (*(unsigned int *)((BYTE*)CPed + 0x46C) & 0x80000000) != 0; This post has been edited by LINK2012: Jun 21 2012, 05:14 PM |
![]() Post #13 | |
![]() The Assistant Posts: 84 From: Matera, IT Joined: 16-June 11 ![]() | I was uncertain when posting but Visual Studio's ASM listing gave the same answer. ![]() |
![]() Post #14 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | Thanks for all the help. I can't test if it works because I haven't finished my code. Anyway, I want to keep running my code. And I need to hook a function (or is there another way?). I've searched but I can only find function hooks which use Detours 1.5, but that one is outdated and visual studio keeps giving me error's when compiling. Later versions of detours don't have the function that I need to use. Does anyone have an example of a hook, or know relatively easy articles about it? |
![]() Post #15 | |
![]() I will kill you Posts: 126 Joined: 13-May 11 ![]() | Are you trying to hook a function from a attached dll or a fully separated process? What you should do is unprotect the memory region, insert a jmp or call to the hook in the region to hook, and then restore the old region protection. If is not clear yet, you can take a look at the source of: http://www.gtaforums.com/index.php?showtopic=514465 Is a very simple code, very easy to understand. (Note that I did the hooks code entirely in ASM, but it's is not necessary, is relative); Don't know if is the samething for separated process because GTA acessing other process memory will cause a exception, right? This post has been edited by LINK2012: Jun 24 2012, 09:24 PM |
![]() Post #16 | |
![]() Coding like a Rockstar! ![]() Posts: 1,468 From: ??? Joined: 28-May 09 ![]() | In IDA, you will find calls like this: CODE call sub_421000 The call bytecode is E8, and the function address will be 0x421000. Thid means the assembled code looks like this in hex: CODE E8 00 10 42 00 So if we get the address of the start of the call function, we just have to add 1 byte to the address and we have a pointer to the function address, 0x421000. All we have to do is unprotect those 4 bytes, write our own function address and call the function address we wrote over in our function. Protecting again is entirely optional. -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
![]() Post #17 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | I need my hook te be executed at every new frame, so I chose _RpWorldRender (0x74F570) is this a good function to hook? Next thing I unprotected the memory. Using this address "void* pAddress = (void*)_RpWorldRender;". How to add 1 to this? Do I need to add one here already? And now I'm stuck at the next part. Do I need to replace it with a jump to my function (+1?) and the rest just 0's? And at the end of my function I need to insert my code and then the rest of the original function? This post has been edited by badboy: Jun 27 2012, 06:15 PM |
![]() Post #18 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | Deleted (again) This post has been edited by badboy: Jul 2 2012, 04:25 PM |
![]() Post #19 | |
![]() Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 ![]() | Here is my latest attempt (triple post yeey), I've came to the conclusion that I was wrong again. I wanted to replace the whole func, but as you told me that's not what I should have done. Anyway I did things the easy way this time and copy paste link2012 code (the hook thing). Everything went fine, but when I start the game (when finished loading) I got a game crash. It's not that I really modded any thing, I just replaced a call with a call to my hook and in my hook I placed a call to the original func. And now I'm 100% sure that the call is the problem. Can anyone help me out? Code (shorter is better I suppose): CODE #include "stdafx.h" #include "Hooks.h" #include "Injector.h" void* getPlayerCoords; DEFINE_HOOKER( hook ) { ASM { call getPlayerCoords } } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: getPlayerCoords = (void*)0x0056E010; MAKE_CALL(0x00423F26, &hook); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } I've also edited LINK2012's code a bit, I added a call func (maybe that's where everything went wrong?). @LINK2012 I hope you don't mind me posting your code, just say it and I'll remove it. Injector.h CODE extern void WriteMemory(void* Address, void* value, size_t size, bool vp = false); extern BYTE jmp_Jz; extern BYTE call; // Mine extern WORD ja_Jz; #define MEM_ADDRESS(mem) (void*)(mem) #define MAKE_JMP(at, dest) {\ WriteMemory(MEM_ADDRESS(at), &jmp_Jz, 1u, true);\ WriteMemory(MEM_ADDRESS(at+1), (DWORD)((BYTE*)dest - (at+1+4)), true);\ } // Mine #define MAKE_CALL(at, dest) WriteMemory(MEM_ADDRESS(at), &call, 1u, true);\ WriteMemory(MEM_ADDRESS(at+1), (DWORD)((BYTE*)dest - (at+1+4)), true);\ } #define MAKE_JA(at, dest) {\ WriteMemory(MEM_ADDRESS(at), &ja_Jz, 2u, true);\ WriteMemory(MEM_ADDRESS(at+2), (DWORD)((BYTE*)dest - (at+2+4)), true);\ } inline void UnprotectMemory(void* Address, int size, DWORD* oldProtect) { if(!VirtualProtect(Address, size, PAGE_EXECUTE_READWRITE, oldProtect)) MessageBoxA(NULL, "FAIL1", "FAIL1", NULL); } inline void ProtectMemory(void* Address, int size, DWORD Protect) { DWORD buf; if(!VirtualProtect(Address, size, Protect, &buf)) MessageBoxA(NULL, "FAIL1", "FAIL1", NULL); } inline void WriteMemory(void* Address, DWORD value, bool vp) { WriteMemory(Address, &value, 4, vp); } injector.ccp CODE #include "stdafx.h" #include "Injector.h" BYTE jmp_Jz = 0xE9; BYTE call = 0xE8; // Mine WORD ja_Jz = 0x870F; void WriteMemory(void* Address, void* value, size_t size, bool vp) { DWORD oldProtect; if(vp) UnprotectMemory(Address, size, &oldProtect); memcpy(Address, value, size); if(vp) VirtualProtect(Address, size, oldProtect, &oldProtect); } |
![]() Post #20 | |
![]() I will kill you Posts: 126 Joined: 13-May 11 ![]() | The MAKE_CALL macro is fine, is not the problem, the problem is the second call... The original call: CODE push 0FFFFFFFFh ; playerIndex push ecx ; outPoint call _getPlayerCoords The problem is, when you do a call another thing goes to the stack, that is the current ip, so the ret know where it must go... _getPlayerCoords expects that the stack is as follow when called: CODE [esp+0] = return code pointer (pushed by the CALL instruction in 0x423F26) [esp+4] = pointer to a RwV3D struct to return the results [esp+8] = player index But, in your call to _getPlayerCoords, the stack will be like this: CODE [esp+0] = return code pointer (pushed by the CALL instruction in your hook) [esp+4] = return code pointer (pushed by the CALL instruction in 0x423F26) [esp+8] = pointer to a RwV3D struct to return the results [esp+12] = player index Now you can see what's wrong right? To fix the problem, you can use a jmp instead of a call in your hook, jmps don't push anything. CODE DEFINE_HOOKER( hook ) { ASM { mov eax, 0x56E010 // jmp eax // absolute jump, so we don't have to do calculations of relative address... } } Another way to do a absolute jmp CODE DEFINE_HOOKER( hook ) { ASM { push 0x56E010 ret } } Yes, we pushed a new return point to the return instruction ![]() QUOTE @LINK2012 I hope you don't mind me posting your code, just say it and I'll remove it. No problem. This post has been edited by LINK2012: Jul 2 2012, 05:19 PM |
![]() ![]() |