Quantcast

Jump to content

» «
Photo

How to mod GTA from C++ ?

18 replies to this topic
Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#1

Posted 31 October 2011 - 04:04 PM

Hy guys.
How can I make a simple script , like creat actor in map, but in C++ ???

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#2

Posted 31 October 2011 - 10:26 PM

Depends. Which GTA?

ThePrince
  • ThePrince

    Moroccan Modder

  • Members
  • Joined: 28 Oct 2011

#3

Posted 31 October 2011 - 10:29 PM

wrong section: go to III coding

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#4

Posted 01 November 2011 - 05:10 AM

I think he meant SA because he has asked solutions for problems that are mostly related to SA modding!
The actor can be created by using a SCM hook!! SCM hook is kind of running/calling the SCM code/function from an asi file by which the game automatically would load. Hooks are the redirection of game code to your own code.

Well that information is just in brief.

There might be some other complex ways too.

Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#5

Posted 01 November 2011 - 11:36 AM

QUOTE (Swoorup @ Tuesday, Nov 1 2011, 05:10)
I think he meant SA because he has asked solutions for problems that are mostly related to SA modding!
The actor can be created by using a SCM hook!! SCM hook is kind of running/calling the SCM code/function from an asi file by which the game automatically would load. Hooks are the redirection of game code to your own code.

Well that information is just in brief.

There might be some other complex ways too.

wait, but isn't .asi for Assambley ?????

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#6

Posted 01 November 2011 - 11:54 AM

No asi does not mean assembly.
Short form for Assembly is ASM actually.

And asi is a file extension, containing executable codes. Its just a renamed dll file actually

Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#7

Posted 01 November 2011 - 12:02 PM

QUOTE (Swoorup @ Tuesday, Nov 1 2011, 11:54)
No asi does not mean assembly.
Short form for Assembly is ASM actually.

And asi is a file extension, containing executable codes. Its just a renamed dll file actually

ok

coin-god
  • coin-god

    High Roller

  • $outh $ide Hoodz
  • Joined: 18 Mar 2007
  • None

#8

Posted 01 November 2011 - 02:15 PM

Do you even know C++?

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#9

Posted 01 November 2011 - 02:26 PM

Yeah I am sure he does, I saw him demonstrate a hello world cpp program

Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#10

Posted 01 November 2011 - 05:48 PM

QUOTE (goin-god @ Tuesday, Nov 1 2011, 14:15)
Do you even know C++?

Yeah, I read some books... But I need to learn more ofc...

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#11

Posted 01 November 2011 - 06:13 PM

One of the libraries that Vice City and San Andreas use for audio automatically loads additional libraries. For some reason, it expects these libraries to be named *.asi, even though they are normal DLL files. So if you compile a DLL file, rename it to something.asi, and stick it into the root directory of the game, it will get loaded, with the DllMain getting executed. Since the code within DLL will run in the same virtual memory space as the game, it will have access to all the functions and variables that the rest of the game has.

From there, things get a little more complicated. The DllMain will get called once, which lets you set up everything you need to set up, but then to have your code executed every time something happens, be it a key press, frame change, or a physics update, you need to add hooks. That's not straight forward and involves machine-level programming. Just C/C++ won't cut it. The easiest thing here is to look how other people have done it.

With GTAIV things are significantly easier because they used to be significantly harder. Since it doesn't automatically load libraries, people had to be clever. And since people were tired of implementing workarounds all the time, some tools have been written that make your life very easy. If you want to do GTA IV mods, all you really need is ScriptHook. It sets up everything you need to get your DLL file loaded into memory and provides you with callback functions. So all the hooks are in place by the time your code kicks in. The only tricky aspect of ScriptHook is that you need to understand how namespaces work, because it's written in proper C++ style.

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#12

Posted 01 November 2011 - 06:25 PM Edited by Swoorup, 01 November 2011 - 06:45 PM.

For starting out and simplicity, I recommend you learn this code closely. icon14.gif icon14.gif
Credits goes to K^2 by the way. Its for VC anyways, but I am sure with a bit of changing memory addresses and learning the SA internal functions, you could convert it to work with SA.

QUOTE (K^2 @ Oct 4 2011, 15:27)
Ok, here is a very simple code that utilizes a hook. Almost nothing to it. Note that I modified ChangeFunctionaCall code. The reason for that is that E8 turns out to be the call, rahter than jmp instruction like I thought. That means that function you call will return to finish the function you hooked into, but since you done some damage to it, it causes problems. I'm guessing squiddy had his reasons for that. I prefer a clean hook, so I added a C3 instruction, which is return. Now the function you replace with a hook is replaced completely.

Anyways, this little mod lets you kick peds out of their cars by hitting F5. (They think the car is upside down.) You'll have to hit F5 again to get into the car.

CODE
#include <windows.h>
#include <stdio.h>

int carFlipped=0;
HWND* hGameWnd     = (HWND*)0x7897A4;
WNDPROC hOldWndProc;


void HandleKeyPress(int bKey)
{
if(bKey==VK_F5)carFlipped=1-carFlipped;

if(bKey==VK_F9)*(DWORD*)(0x9B48F0) = 1;
}

LRESULT APIENTRY NewWndProc( HWND hwnd,UINT uMsg, WPARAM wParam,LPARAM lParam )
{
switch(uMsg) {
 case WM_KEYDOWN:
  HandleKeyPress((int)wParam);
  break;
}
return CallWindowProc(hOldWndProc, *hGameWnd, uMsg, wParam, lParam);
}

bool IsFlipped(void)
{
return carFlipped;
}

void ChangeFunctionCall(DWORD dwAddress, DWORD dwCallTarget, DWORD dwNopBytes)
{
DWORD dwProt;
VirtualProtect((void*)dwAddress, 5, PAGE_EXECUTE_READWRITE, &dwProt);
*(BYTE*)dwAddress = 0xE8;
*(DWORD*)(dwAddress+1) = dwCallTarget-dwAddress-0x5;
*(BYTE*)(dwAddress+5) = 0xC3;
memset((void*)(dwAddress+6), 0x90, dwNopBytes);
VirtualProtect((void*)dwAddress, 5, dwProt, &dwProt);
}

void Initialization()
{
ChangeFunctionCall(0x5B84F0, (DWORD)&IsFlipped, 0); //CVehicle::IsUpsideDown ((void))

hOldWndProc = (WNDPROC)GetWindowLong(*hGameWnd, GWL_WNDPROC);
SetWindowLong(*hGameWnd, GWL_WNDPROC, (LONG)NewWndProc);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                      DWORD  dwReason,
                      LPVOID lpReserved
     )
{
switch (dwReason)
{
 case DLL_PROCESS_ATTACH:
 {
  DisableThreadLibraryCalls((HMODULE) hModule);

  Initialization();
 }

 case DLL_PROCESS_DETACH:
 {
 }
}

   return TRUE;
}


This also demonstrates the bare minimum of code you need to make it all work. Hope that helps.

Oh, and your DLL gets loaded whenever the MSS library gets to start looking for .asi files. Memory is requested somewhere in RAM for the DLL to be loaded into. There is no telling where it will end up being physically, but virtual addresses are probably going to be in the same general address ranges as addresses for executable itself.


EDIT: THE dllMain is the first function that gets loaded by the game. After that if the dll is attached within the virtual address of the game the initialization function gets called which is where we perform our hacks.

In the initialization function, the user-defined function changefunction modifies the game code at address 0x5F84F0 and it patches with the call to our own function. The 0xE8 is the ASM call function and then it is followed by memory address of start of our own function IsFlipped.

From there on I thinks its pretty easy to understand. The VC internal function which checks for whether the car is fliped is replaced by a short and simple IsFlipped function, which returns true on pressing F5. Ignore the F9 key, It simply causes a crash. He used it because it would exit the game fast. And also after this head on to learn SCM hook. Honestly, never played with hooks on SA, but if you can get hands on Squiddy's SA HUD source, its easier.

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#13

Posted 01 November 2011 - 06:42 PM

K^2 correct me if I am wrong though! Whatever you say, you say it that it later on becomes very easy to understand icon14.gif
Hope I did'not create a mess in the post!

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#14

Posted 02 November 2011 - 12:27 AM

Credit actually goes to squiddy for writing the hook. I only made small modifications to it.

No ASM is used here, by the way. It's pure machine language at this stage. If you aren't familiar with machine codes, you might need to refer to an x86 manual.

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#15

Posted 02 November 2011 - 07:32 AM Edited by Swoorup, 02 November 2011 - 07:35 AM.

K^2 I download the Intel x86 manual, but its too much of information for beginners. I just look up the bytes codes in a debugger (Cheat engine) and then copy them into my code as an array!!!

Like this one here:
CODE

BYTE ASMHeatgain[]=
{
0xA1,0x28, 0xAD, 0x94, 0x00, 0x8B, 0x80, 0xF4, 0x05,
0x00, 0x00, 0x0F, 0xB6, 0x40, 0x20, 0x85, 0xC0, 0x75,
0x07, 0xB8, 0xAB, 0x91, 0x55, 0x00, 0xFF, 0xE0, 0xB8,
0x40, 0x10, 0x55, 0x00, 0xFF, 0xD0, 0xB8, 0xAB, 0x91,
0x55, 0x00, 0xFF, 0xE0
};


To make Wanted stars visible only if there is at least a wanted level for VC


Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#16

Posted 02 November 2011 - 01:20 PM

QUOTE (Swoorup @ Tuesday, Nov 1 2011, 18:25)
For starting out and simplicity, I recommend you learn this code closely. icon14.gif icon14.gif
Credits goes to K^2 by the way. Its for VC anyways, but I am sure with a bit of changing memory addresses and learning the SA internal functions, you could convert it to work with SA.

QUOTE (K^2 @ Oct 4 2011, 15:27)
Ok, here is a very simple code that utilizes a hook. Almost nothing to it. Note that I modified ChangeFunctionaCall code. The reason for that is that E8 turns out to be the call, rahter than jmp instruction like I thought. That means that function you call will return to finish the function you hooked into, but since you done some damage to it, it causes problems. I'm guessing squiddy had his reasons for that. I prefer a clean hook, so I added a C3 instruction, which is return. Now the function you replace with a hook is replaced completely.

Anyways, this little mod lets you kick peds out of their cars by hitting F5. (They think the car is upside down.) You'll have to hit F5 again to get into the car.

CODE
#include <windows.h>
#include <stdio.h>

int carFlipped=0;
HWND* hGameWnd     = (HWND*)0x7897A4;
WNDPROC hOldWndProc;


void HandleKeyPress(int bKey)
{
if(bKey==VK_F5)carFlipped=1-carFlipped;

if(bKey==VK_F9)*(DWORD*)(0x9B48F0) = 1;
}

LRESULT APIENTRY NewWndProc( HWND hwnd,UINT uMsg, WPARAM wParam,LPARAM lParam )
{
switch(uMsg) {
 case WM_KEYDOWN:
  HandleKeyPress((int)wParam);
  break;
}
return CallWindowProc(hOldWndProc, *hGameWnd, uMsg, wParam, lParam);
}

bool IsFlipped(void)
{
return carFlipped;
}

void ChangeFunctionCall(DWORD dwAddress, DWORD dwCallTarget, DWORD dwNopBytes)
{
DWORD dwProt;
VirtualProtect((void*)dwAddress, 5, PAGE_EXECUTE_READWRITE, &dwProt);
*(BYTE*)dwAddress = 0xE8;
*(DWORD*)(dwAddress+1) = dwCallTarget-dwAddress-0x5;
*(BYTE*)(dwAddress+5) = 0xC3;
memset((void*)(dwAddress+6), 0x90, dwNopBytes);
VirtualProtect((void*)dwAddress, 5, dwProt, &dwProt);
}

void Initialization()
{
ChangeFunctionCall(0x5B84F0, (DWORD)&IsFlipped, 0); //CVehicle::IsUpsideDown ((void))

hOldWndProc = (WNDPROC)GetWindowLong(*hGameWnd, GWL_WNDPROC);
SetWindowLong(*hGameWnd, GWL_WNDPROC, (LONG)NewWndProc);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                      DWORD  dwReason,
                      LPVOID lpReserved
     )
{
switch (dwReason)
{
 case DLL_PROCESS_ATTACH:
 {
  DisableThreadLibraryCalls((HMODULE) hModule);

  Initialization();
 }

 case DLL_PROCESS_DETACH:
 {
 }
}

   return TRUE;
}


This also demonstrates the bare minimum of code you need to make it all work. Hope that helps.

Oh, and your DLL gets loaded whenever the MSS library gets to start looking for .asi files. Memory is requested somewhere in RAM for the DLL to be loaded into. There is no telling where it will end up being physically, but virtual addresses are probably going to be in the same general address ranges as addresses for executable itself.


EDIT: THE dllMain is the first function that gets loaded by the game. After that if the dll is attached within the virtual address of the game the initialization function gets called which is where we perform our hacks.

In the initialization function, the user-defined function changefunction modifies the game code at address 0x5F84F0 and it patches with the call to our own function. The 0xE8 is the ASM call function and then it is followed by memory address of start of our own function IsFlipped.

From there on I thinks its pretty easy to understand. The VC internal function which checks for whether the car is fliped is replaced by a short and simple IsFlipped function, which returns true on pressing F5. Ignore the F9 key, It simply causes a crash. He used it because it would exit the game fast. And also after this head on to learn SCM hook. Honestly, never played with hooks on SA, but if you can get hands on Squiddy's SA HUD source, its easier.

Yeah, I opened some files in C++ ,and I saw that code (This is SCM Hook, am I right ?)

Swoorup
  • Swoorup

    innovator

  • Feroci
  • Joined: 28 Oct 2008
  • Nepal

#17

Posted 02 November 2011 - 02:28 PM

SCM hook involves calling the scm opcodes that you use in SCM coding. No SCM opcodes is used here!

Ify24
  • Ify24

    0x00000000 --> invisible

  • Members
  • Joined: 17 Aug 2011

#18

Posted 02 November 2011 - 08:06 PM

QUOTE (Swoorup @ Wednesday, Nov 2 2011, 14:28)
SCM hook involves calling the scm opcodes that you use in SCM coding. No SCM opcodes is used here!

Ofc... I didn't say that you can use SCm opcodes in C++

EDIT: I meant on .ccp, .h files in SCM hook

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#19

Posted 04 November 2011 - 07:40 AM

In principle, this will hook into anything you have an address for. In practice, this hooks into functions that are used by SCM parser because that's what we have addresses for, but many of these functions are utilized by other parts of the game's engine. So on one hand, it gives you more control over what's going on in the game than you could ever achieve with SCM script, on the other, you have to be extra careful not to break something.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users