Quantcast
Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
    1. Welcome to GTAForums!

    1. GTANet.com

    1. GTA Online

      1. The Cayo Perico Heist
      2. The Diamond Casino Heist
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Red Dead Online

      1. Frontier Pursuits
      2. Find Lobbies & Outlaws
      3. Help & Support
    3. Crews

    1. Red Dead Redemption 2

      1. PC
      2. Help & Support
    2. Red Dead Redemption

    1. Grand Theft Auto Series

    2. GTA VI

      1. St. Andrews Cathedral
    3. GTA V

      1. Guides & Strategies
      2. Help & Support
    4. GTA IV

      1. The Lost and Damned
      2. The Ballad of Gay Tony
      3. Guides & Strategies
      4. Help & Support
    5. GTA San Andreas

      1. Guides & Strategies
      2. Help & Support
    6. GTA Vice City

      1. Guides & Strategies
      2. Help & Support
    7. GTA III

      1. Guides & Strategies
      2. Help & Support
    8. Portable Games

      1. GTA Chinatown Wars
      2. GTA Vice City Stories
      3. GTA Liberty City Stories
    9. Top-Down Games

      1. GTA Advance
      2. GTA 2
      3. GTA
    1. GTA Mods

      1. GTA V
      2. GTA IV
      3. GTA III, VC & SA
      4. Tutorials
    2. Red Dead Mods

      1. Documentation
    3. Mod Showroom

      1. Scripts & Plugins
      2. Maps
      3. Total Conversions
      4. Vehicles
      5. Textures
      6. Characters
      7. Tools
      8. Other
      9. Workshop
    4. Featured Mods

      1. Design Your Own Mission
      2. OpenIV
      3. GTA: Underground
      4. GTA: Liberty City
      5. GTA: State of Liberty
    1. Rockstar Games

    2. Rockstar Collectors

    1. Off-Topic

      1. General Chat
      2. Gaming
      3. Technology
      4. Movies & TV
      5. Music
      6. Sports
      7. Vehicles
    2. Expression

      1. Graphics / Visual Arts
      2. GFX Requests & Tutorials
      3. Writers' Discussion
      4. Debates & Discussion
    3. Gangs

    1. Announcements

    2. Support

    3. Suggestions

Demarest

manipulating game memory for fun and profit

Recommended Posts

Demarest

For those of you that do not remember this, here are page 1 and page 2 of the original topic from Google cache (damn pruning grumble grumble). In my quest to maximize SCM usefulness, I decided I wanted to master this technique too. It's something I've been discussing with CyQ. At the time, he was okay with me digging the topic up. I thought I'd make this public so we can all have fun, especially now that I've made it work in MB. The code I'm about to post is for MB 0.22 and as of right now, the MB you use HAS to support DMA. Note: this is only possible on VC for now and possibly always. You will need to turn scm.ini off in MB by going to the Compiler menu and selecting disable custom IDs. Below is a stripped SCM. I'm sharing the code in this manner becuase since DMA is required and these slots are in use by original code. So this means no compatibility at this time. I've already tried moving the block--I originally tried starting with 0?? and so on and backing the addresses off the same 8 bytes, but the game crashed. Hopefully we will be able to move the block. If so, I will do what I can to incoporate it into savegame compatibility. Don't get your hopes up as I've already been told this isn't possible. I'm just stubborn and have been learning lately that there's no reason to accept no for an answer wink.gif

 

Anyways, go into your MB folder and open up scm.ini. BACK IT UP FIRST! Add the lines

0124=2,write_mem_address %1d% value %2d%0125=2,read_mem_address %1d% into %2d%

and save. These changes won't be usable in MB until the next time you launch it. And now the stripped SCM:

DEFINE VERSION VICE 0.220002: jump ��Label008620DEFINE MEMORY  97:Label0086200002: jump ��Label008644DEFINE OBJECTS  1DEFINE OBJECT (no name)                   \\ This is an unused object. You can put anything here.:Label0086440002: jump ��Label008658DEFINE MISSIONS  0;-------------MAIN---------------:Label008658016A: fade  0? ()  0? ms01F0: set_max_wanted_level_to  6?0111: set_wasted_busted_check_to  0? (disabled)00C0: set_current_time  12?  0?0007:  [email protected] = -444!  \\ floating-point values0007:  [email protected] = -486!  \\ floating-point values0007:  [email protected] =  10!  \\ floating-point values04E4: unknown_refresh_game_renderer_at  [email protected]  [email protected]: set_camera  [email protected]  [email protected]  [email protected]: $MYPLAYER_CHAR = create_player #NULL at  [email protected]  [email protected]  [email protected]: $MYPLAYER_ACTOR = create_emulated_actor_from_player $MYPLAYER_CHAR0001: wait  0? ms01B6: set_weather  0?0352: set_actor $MYPLAYER_ACTOR skin_to "PLAYER"038B: load_requested_models0353: refresh_actor $MYPLAYER_ACTOR016A: fade  1? (back)  1000& ms04BB: select_interiour  0?  \\ select render area01B4: set_player $MYPLAYER_CHAR frozen_state  1? (unfrozen)01B7: release_weather004F: create_thread ��LabelMEMHACKING:LabelMAIN30001: wait  5000& ms0002: jump ��LabelMAIN3:LabelMEMHACKING0004:  8?? = -1995422835&&0004:  12?? =  1342335705&&0004:  16?? = -1023575064&&0004:  20?? =  1949868543&&0004:  24?? =  495648893&&0004:  28?? =  8221756&&0004:  32?? = -1070589815&&0004:  36?? =  10011777&&0004:  40?? =  1599930368&&0004:  44?? =  79846238&&0004:  48?? =  272862464&&0004:  52?? =  23779721&&0004:  56?? = -44898224&&0004:  60?? =  950140866&&0004:  64?? = -1962902156&&0004:  68?? =  1949868800&&0004:  72?? =  1133314173&&0004:  76?? =  1792641296&&0004:  80?? =  2045267969&&0004:  84?? =  822067963&&0004:  88?? = -1731952192&&0004:  92?? =  1560281088&&0004:  96?? = -1034199457&&0004:  100?? =  4&&03FD: set_player -5035& handling_responsiveness  8524424&&0124: write_mem_address  6850752&& value  8524465&&:LabelMEMHACKINGTRAP0001: wait  5000& ms0002: jump ��LabelMEMHACKINGTRAP

 

Edited by Demarest

Share this post


Link to post
Share on other sites
Y_Less

As both Dem and I were working on this at the same time, talking as we did it, I have a few pieces of code to demonstrate it (nothing exciting, just some bits to mess up your radar). Add these as threads (note: they both use the same labels, im lazy, so one at once):

 

 

:Labelmemhack                                  03A4: name thread "RADAR"                         0007:  [email protected] = -0.01!  \\ floating-point values 0125: read_mem_address  6880572&& value  [email protected]  :labelmemloop 0001: wait  100? ms 0125: read_mem_address  6880572&& value  $radar 005f: $radar += [email protected]  \\ floating-point values (never used in VC or GTA 3) 0124: write_mem_address  6880572&& value  $radar  00D6: if  0?   0032:    0! >=  $radar  \\ floating-point values 004D: jump if false ££labelmemloop2 0007:  [email protected] = 0.01!  \\ floating-point values  :labelmemloop2 00D6: if  0?   0036:   $radar >= [email protected]  \\ floating-point values (never used in VC or GTA 3) 004D: jump if false ££labelmemloop3 0007:  [email protected] = -0.01!  \\ floating-point values                                     :labelmemloop3                                    0002: jump ££labelmemloop 

 

 

 

:Labelmemhack                                  03A4: name thread "RADAR"                         0007:  [email protected] = 0.01!  \\ floating-point values 0124: write_mem_address  6880572&& value  1000!   0125: read_mem_address  6880552&& value  [email protected]  :labelmemloop 0001: wait  10? ms 0125: read_mem_address  6880552&& value  $radar  0125: read_mem_address  6880564&& value  $radar2  005f: $radar += [email protected]  \\ floating-point values (never used in VC or GTA 3)  0013: [email protected] *= 200!  \\ floating-point values (never used in VC or GTA 3) 005f: $radar2 += [email protected]  \\ floating-point values (never used in VC or GTA 3) 0017: [email protected] /= 200!  \\ floating-point values (never used in VC or GTA 3) 0124: write_mem_address  6880552&& value  $radar 0124: write_mem_address  6880564&& value  $radar2  0011:  $radar *=  100!  \\ floating-point values 008C:  [email protected] = float_to_integer  $radar 0015:  $radar /=  100!  \\ floating-point values 01E4: text 1number lowpriority "HJ_IS"  [email protected]  2000& ms  1?   00D6: if  0?   8032:    1! >=  $radar  \\ floating-point values 004D: jump if false ££labelmemloop2 0007:  [email protected] = -0.01!  \\ floating-point values  :labelmemloop2 00D6: if  0?   8036:   $radar >= [email protected]  \\ floating-point values (never used in VC or GTA 3) 004D: jump if false ££labelmemloop3 0007:  [email protected] = 0.01!  \\ floating-point values                                     :labelmemloop3                                    0002: jump ££labelmemloop

 

Share this post


Link to post
Share on other sites
random_download

 

@0 = 8524416&&@0 += ££[email protected] += <bytesfromlabel>0124: write_mem_address  @0 value <code>

 

Would doing that be an easier way to do self-modifying code? Currently I think you store the modifing bit in global vars, then gosub to those, which is a little confusing tounge.gif

Share this post


Link to post
Share on other sites
Y_Less

Yes that would, but self modifying code was sort of developed (by me anyway - apparently CyQ thought of it long ago, but meh, he never released it) before we looked into this.

 

Edit: also note that Mission Builder likes to screw with certain DMA variables (the ones defined at the bottom of vicescm.ini). Dems way around was to rename $player_char (which is ALWAYS (even when custom ids are disabled on DECOMILE) COMPILED to 8??) to $myplayer_char. My way, which I much prefer, but its up to you, is to comment out all the global vars at the end of vicescm.ini (just put a semi-colon (wink.gif at the start of every line under "[variables]" (without the double quotes)).

Edited by Y_Less

Share this post


Link to post
Share on other sites
Demarest
you store the modifing bit in global vars, then gosub to those, which is a little confusing tounge.gif

Nah. MB doesn't allow DMA to anything that's not divisible by 4 and certainly not to anything outside the defined memory. The gosub initially jumps to this command

 

0084: 61973?? = 96??

 

...which MB won't touch. If however you store valued in globals that set the bytes to where it looks like that, MB won't know, the game will execute, and everybody lives happily ever after. cool.gif

Share this post


Link to post
Share on other sites
Un3462

ok. so. you want to move this around. it's possible, if you can find a block of 24 free variables. you could even split the two opcode handlers apart quite easily, requiring two separate blocks of only 11 and 13 free variables. (someone with x86 asm knowledge and a bit of time, could even optimize it for less variables, and variables which aren't in a single block.)

 

the key in moving them around is keeping the relative addressing and the hooking correct. relative addressing occurs in three places:

 

e8 7b-fd-c2-ff          call    CollectParameterse8 52-fd-c2-ff          call    CollectParameterse8 79-fb-c2-ff          call    StoreParameters

 

so if you want to move all the code 4 bytes higher, you simply need to subtract 4 from those values (they're negative, and you'd want them to point back 4 bytes further).

the first one for example (e8 is the call opcode, nearly equivalent to gosub in gta):

7b-fd-c2-ff -> ffc2fd7b -> in wincalc subtract 4 -> ffc2fd77 -> 77-fd-c2-ff, and you're done.

 

when you're done adjusting the addresses, you put all the bytes together again in groups of 4, and convert them to ints, like i did in my original post. then set those in the correct variables.

 

then you change the following:

 

set_player_handling_responsiveness -5035, 8524424; set opcode handler for 0124 at $00000000write_mem 6850752, 8524465; set opcode handler for 0125 at second byte of $0000000a

 

..by editing those two addresses (second param for each) accordingly. in this example, you'd simply add 4 to both.

Share this post


Link to post
Share on other sites
Y_Less
Ahh, I had thought the problem was due to relative addressings (can't you use absolutes for those though?).

Share this post


Link to post
Share on other sites
Un3462

i don't think so, actually (x86 opcodes are confusing). you might be able to do "mov eax, absaddress / call eax". but relative is how gta does calls to near functions, so i just used that.

 

small correction to the above: if you split the opcode handlers apart, you need 14 vars for read_mem.

Share this post


Link to post
Share on other sites
Y_Less

Fair enought then. People interested in this may be interesed in THIS (Im sure CyQ already has something like it, but useful for others. Just enter your HEX string in the top box (with spaces between each byte) and it will generate a load of 32 bit integers for use in your code. I tested it on the start of the code CyQ wrote and it worked fine. One known bug though is that sometimes it adds an extra 0 to the bottom of the list, I know why this is but I can't get rid of it (as you may have entered 00 00 at the end which may end up on a separate needed string, so I cant just not display if the string equals 0 (but thats my problem not yours).

 

Edit: I also displays 8 numbers a line (assuming 1 space between) in IE, but it displays 9 in FF until you fill the box and the scroll bar appears, filling the box slightly, and then it displays 8 correctly, for one of the first times ever I made my code run better on IE than FF (although if I did it right on FF, it would be wrong on IE AND FF if you had too many, so this is actually better, but anyway).

 

Edit 2: I THINK I've solved the random extra 0's problem (I set a variable to tell the code that actual numbers have been processed, not just empty spaces (the error occured when you had trailing spaces after a 4 byte boundary, so there should have been data, but wasn't, therefore no data = 0)). But be careful, if you see it again, please tell me (this way WILL display 0 if the last bits entered are 00s, so should technically have a 0 to enter the data.

Edited by Y_Less

Share this post


Link to post
Share on other sites
Demarest

inlove.gif CyQ! I was just about to prod you for this since it had been a bit. Thank you.

 

And now a second can of worms. From what I've seen, I'm assuming that your method HAS to write 4 bytes at a time. And I would also assume that your code was made to do exactly that. Fair enough. Keep in mind that the rest of this post is based on those assumptions being true...

 

I would like a way to be able to write a byte at a time as some memory addresses contain one byte switches/values. I've actually tried a read_mem $var, $var -= 1, write_mem $var and it crashed. I'm assuming that the other 3 bytes I'm involving while trying to change the 1 are the ones crashing either because I'm trying to write to read-onlys or that the data in them move that quickly. Most likely I'm wrong and I'm just implimenting it wrong since mem-hacking is new to me. If this is the case, indulge me if you will for the sake of education/discussion.

 

I've noticed that quite a few on/off options in the pause menu have one byte switches assigned to them. When you consider an opcode such as 02A3 toggle_widescreen $int, I would assume the opcode handler code for it is something along the lines of "write_mem address value" where address is the memory address tied to the widescreen option being on and off. If all of the above is true, I'm assuming we could "borrow" that opcode for single byte writing by use of write_mem (address of 02A3's target address) (one byte address we'd like to write to), toggle_widescreen (0-255), write_mem (address of 02A3's target address) (original value), eh? I apologize if this is ambiguous in any way. Of course if you know of an easier way to write to a single byte at a time, please share. Or if you're certain that the continuous nature of my failed attempt above is in fact my own misapplication, feel free to say so.

Share this post


Link to post
Share on other sites
Un3462

the write-only values are called that because the game will mostly ignore them if you change them, not because it would crash or anything. gta is not multithreaded, so things changing inbetween your opcodes shouldn't be a problem either. so, in theory, your approach should work (as long as the value doesn't over- or underflow).

 

i can sort of see what you're trying to do with the toggle thing, but that really isn't necessary. and indeed, it's possible (likely even, imo) that there's something else you're not quite doing right. it might help to post full code, or some info on the memory value you're trying to manipulate.

Share this post


Link to post
Share on other sites
Y_Less

Right, this comes from my masses of work recently (I REALLY should be revising for exams but aren't), I have made this darkpact compatible (I just shifted it over a load of variables only used in mission 0 (this overwrites references to things like pickups but they still work):

 

 

0004: 8288?? = -1995422835&&0004: 8292?? = 1342335705&&0004: 8296?? = -1025694744&&0004: 8300?? = 1949868543&&0004: 8304?? = 495648893&&0004: 8308?? = 8221756&&0004: 8312?? = -1070589815&&0004: 8316?? = 10011777&&0004: 8320?? = 1599930368&&0004: 8324?? = 79846238&&0004: 8328?? = 272862464&&0004: 8332?? = 23779721&&0004: 8336?? = -587536304&&0004: 8340?? = 950140866&&0004: 8344?? = -1962902156&&0004: 8348?? = 1949868800&&0004: 8352?? = 1133314173&&0004: 8356?? = 1792641296&&0004: 8360?? = 568872961&&0004: 8364?? = 822067931&&0004: 8368?? = -1731952192&&0004: 8372?? = 1560281088&&0004: 8376?? = -1034199457&&0004: 8380?? = 4&&     03FD: set_player -5035& handling_responsiveness  8532704&&0124: write_mem_address  6850752&& value  8532745&&

 

 

Thats it, just use that instead of the original.

Share this post


Link to post
Share on other sites
Demarest
Thank you, sir. I personally wouldn't have reused pickups for good measure, but that's what I get for not getting off my own lazy ass, eh? cool.gif

Share this post


Link to post
Share on other sites
Y_Less

Err, I've been looking through the disassembly of my copy of the 1.1 EXE and unless I'm very much mistaken (i.e. the EXE I have is not 1.1) the pointers for both 0124 and 0125 are at the same point, so there is no problem using this in VC.

Share this post


Link to post
Share on other sites
chaosislife

a quick note; the 'page 1' and 'page 2' links are inactive,Perhaps google pruned them as well?

Share this post


Link to post
Share on other sites
Y_Less

Hmm, I'll have to see if I have my local copies still and host them somewhere.

Share this post


Link to post
Share on other sites
random_download

Is there something that stops you writing to addresses in the opcode jump tables in San Andreas? Writing to one through the scm caused the game to crash, even if the value was the same as the original.

Share this post


Link to post
Share on other sites
Y_Less

I don't know, I was experimenting with it before, using some OpCode in the 500s (IIRC) that fell on a boundary in SA but I could never get it to even write the address (and now I don't have a decompiled version of the EXE).

Share this post


Link to post
Share on other sites
random_download

I was going for the address 0x466D68 (opcode 0046) by writing -5DBD. Did your game crash when you tried or just didn't write the address? I can't find any reason why it does, the handling_responsiveness opcode does almost exactly the same thing as in VC, as does the CollectParameters function. I have no idea why it doesn't work :s

Share this post


Link to post
Share on other sites
Y_Less

Bump.

 

This is an old post from elsewhere but I never finished it and having only just seen randoms post I thought I'd post here in the hope someone better saw it:

 

The offset for OpCode 03FD in SA is:

 

 

param1*134h+B73458h+74h

 

 

Based on the code at 489731h (handler for the opcode) but it doesn't seem to work although SA has 'unk_B73458' (unknown type) as opposed to 'word_7DBCB0' so it could be unsigned.

 

The problem is, even when I set the command to set_player 1, which should produce an address of B73600h and set the value to 2, it still appears as 0 in memory. However some positive values seem to correctly modify the correct memory addresses, which leads me to believe the formula is correct, but others don't, and no negative numbers I've tried do.

 

Also, based on that formula, I found OpCode 05DF which is unused and on a correct boundary (using -23414 in the OpCode) and 05E0 which is unused to redirect the read_mem OpCode but when I use -23414, the game crashes.

 

Finally (this is just extra as I've not got this far yet without the game crashing) could someone check my modified ASM for SA style OpCodes please (note the jump at the end goes to what appears to be a common OpCode end for 1500 range OpCodes), I've never done ASM before:

 

 

Based on CyQs VC write_mem code and existing SA OpCodes:6a 02   push 2; num pars8B CE   mov ecx, esi; get ptr to threadstructE8 0f-a7-a1-ff  call CollectParmeters; (-6183153)a1 78-3c-a4-00          mov eax, ds:ScriptParams; get address8b 1d 7c-3c-a4-00       mov ebx, ds:ScriptParams+4; get value89 18                   mov [eax], ebx; write memE9 0d-91-a4-ff  jmp 0x492AA4; end OpCoderead_mem:6a 01   push 1; num pars8B CE   mov ecx, esi; get ptr to threadstructE8 f4-a6-a1-ff  call CollectParmeters; (-6183180)a1 78-3c-a4-00  mov eax, ds:ScriptParams; get address8b 00   mov eax, [eax]; read mema3 78-3c-a4-00  mov ds:ScriptParams, eax; store value8B CE   mov ecx, esi; get ptr to threadstruct6a 01   push 1; num pars50   push eaxE8 ce-a9-a1-ff  call StoreParmeters; (-6182450)E9 36-91-a4-ff  jmp 0x492AA4; end OpCode 

 

 

Any help would be much appreciated.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.