Quantcast

Jump to content

» «
Photo

C++ .asi help

13 replies to this topic
ED-E
  • ED-E

    War. War never changes.

  • Members
  • Joined: 31 May 2010
  • None

#1

Posted 25 November 2013 - 11:29 AM Edited by ChopTheDog., 25 November 2013 - 11:33 AM.

#include <windows.h>
#include <detours.h>

BOOL WINAPI DLLMain(
	_In_  HINSTANCE hinstDLL,
	_In_  DWORD nReason,
	_In_  LPVOID lpvReserved
	)
{
	DWORD PlayerPointer = 0x94AD28;
	DWORD WantedLevelPointer = 0x5F4;
	DWORD WantedCounter = 0x0;
	DWORD WantedLevel = {1200}; // 4 stars
	HWND hWnd = FindWindow(NULL,L"GTA: Vice City");
	HANDLE phandle = NULL;
	DWORD pid;
	//-----------------------------------------
	//-----------------------------------------
	switch (nReason)
	{
	case DLL_PROCESS_ATTACH:
		if (hWnd != 0)
		{
			GetWindowThreadProcessId(hWnd, &pid);
			phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
			if (phandle != 0)
			{
				ReadProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &PlayerPointer, 4, 0);
				PlayerPointer = PlayerPointer + WantedLevelPointer;
				ReadProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &PlayerPointer, 4, 0);
				PlayerPointer = PlayerPointer + WantedCounter;
				WriteProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &WantedLevel, 4, 0);
			}
		}

	case DLL_PROCESS_DETACH:
		break;
		
    case DLL_THREAD_ATTACH:

    case DLL_THREAD_DETACH:
		break;
	}
	return TRUE;
}

Okay, so this code is meant to be compiled to a .asi file and placed inside my Vice City directory and then it should give the player a wanted level as soon as he has spawned.

 

For some reason though it doesn't work and I can't put my finger on it.

 

I was also told that Vice City doesn't require an ASI loader so I don't have one.

 

Any help is appreciated.


Bad.boy!
  • Bad.boy!

    SA modder

  • Feroci
  • Joined: 20 Jun 2010
  • None

#2

Posted 25 November 2013 - 04:47 PM

I'll quote myself on this one:
 

It doesn't work because your code is executed when the game starts. You need to hook a (in)game function, so that your code will be executed when the game is loaded. And in your hooked function you should force a pointer on the address you want to modify, instead of using ReadProcessMemory and WriteProcessMemory.

 

I assume that you're trying to learn how to create your own game mods in a real programming language. But it doesn't look like you know the programming language well. You should try to master the language before writing mods in it. Also cleo scripts are a better and easier way to write mods, ASI plugins don't offer much advantages unless you're rewriting bits/parts of the engine.

 

 

Also, it would be better if you posted this in your other topic in III-era coding.


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

#3

Posted 26 November 2013 - 03:02 PM

At the time that the ASI file is loaded, which is when DLLMain is called, the player object doesn't exist yet. So you can't alter the wanted level at that time.

  • ED-E likes this

ED-E
  • ED-E

    War. War never changes.

  • Members
  • Joined: 31 May 2010
  • None

#4

Posted 26 November 2013 - 04:47 PM Edited by ChopTheDog., 26 November 2013 - 04:47 PM.

At the time that the ASI file is loaded, which is when DLLMain is called, the player object doesn't exist yet. So you can't alter the wanted level at that time.

 

I don't know which function I should be looking to hook though (using Microsoft's Detours).

 

Is using ReadProcessMemory and WriteProcessMemory the correct way of editing memory values through a .asi file?

 

I've read/seen loads of different snippets using different code to edit memory 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

#5

Posted 27 November 2013 - 02:19 AM

I don't know which function I should be looking to hook though (using Microsoft's Detours).

What exactly are you trying to achieve? The easiest thing to hook into with Vice City is message processing, which is why most trainers have shortcut keys. It's easy to intercept key down messages. For pretty much anything else you either need to find a game's own function to hook or hook into the Direct 3D libraries. (E.g. if you want something done per-frame.)
 

Is using ReadProcessMemory and WriteProcessMemory the correct way of editing memory values through a .asi file?

Yeah. Your code for actually writing the value to the correct location looks good. You just need to figure out a good way to trigger it. Like I said, getting it to trigger on a key press is very easy. Getting it to trigger on other conditions is trickier.

ED-E
  • ED-E

    War. War never changes.

  • Members
  • Joined: 31 May 2010
  • None

#6

Posted 27 November 2013 - 09:05 AM

 

I don't know which function I should be looking to hook though (using Microsoft's Detours).

What exactly are you trying to achieve? The easiest thing to hook into with Vice City is message processing, which is why most trainers have shortcut keys. It's easy to intercept key down messages. For pretty much anything else you either need to find a game's own function to hook or hook into the Direct 3D libraries. (E.g. if you want something done per-frame.)
 

Is using ReadProcessMemory and WriteProcessMemory the correct way of editing memory values through a .asi file?

Yeah. Your code for actually writing the value to the correct location looks good. You just need to figure out a good way to trigger it. Like I said, getting it to trigger on a key press is very easy. Getting it to trigger on other conditions is trickier.

 

 

Well, all I want to achieve at this moment is to develop a .asi file and get it to set the wanted level when the game is started.

 

I would think that checking for key presses could cause problems since the user can click the mouse or press the space bar at any time before getting to the Menu and selecting an option?

 

Sorry for these annoying newbie questions I'm still wrapping my head around this, although I do prefer to be thrown into the deep end because I actually learn, but that's just me.


Bad.boy!
  • Bad.boy!

    SA modder

  • Feroci
  • Joined: 20 Jun 2010
  • None

#7

Posted 27 November 2013 - 04:30 PM Edited by Bad.boy!, 27 November 2013 - 04:31 PM.

Yeah. Your code for actually writing the value to the correct location looks good.

It works, but it isn't efficient at all. The code is executed in the same virtual memory, so he won't have to use any api calls to alter memory (as you probably already know).

 

The most reliable way to execute your function on game load is to hook a function which is often used in-game. When the code is called you simply set the wanted level and remove the 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

#8

Posted 29 November 2013 - 02:15 AM

Like Bad.boy! said, you need to hook into one of the functions. This is much easier to do if you understand a bit of x86 machine language, but you can find pretty good tutorials for GTA III era.
 
Depending on the order in which these things are called, hooking into CPed::Initialise might work. If you can hook it at the function exit, call your own code, check if the pointer to CPed matches pointer to player, and if so, modify wanted level, it should work flawlessly. Unless, of course, the init code is called before player pointer is set. But I doubt that's the case. I would guess that the game calls constructor, sets player pointer, and then calls the init code, making it the perfect place for the hook.

WBaker
  • WBaker

    Acatalepsis

  • Members
  • Joined: 18 Sep 2013
  • United-States

#9

Posted 29 November 2013 - 04:24 AM

This made me wonder... would hooking int 8 (rtc) bog down the game too much?

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

#10

Posted 29 November 2013 - 05:05 AM

This made me wonder... would hooking int 8 (rtc) bog down the game too much?

This isn't DOS. Are you going to root the system just so you can hook an interrupt?
  • WBaker likes this

WBaker
  • WBaker

    Acatalepsis

  • Members
  • Joined: 18 Sep 2013
  • United-States

#11

Posted 29 November 2013 - 06:13 AM

This made me wonder... would hooking int 8 (rtc) bog down the game too much?

This isn't DOS. Are you going to root the system just so you can hook an interrupt?

As a matter of fact, the last time I hooked an interrupt it was DOS.

Thanks for the answer.

ED-E
  • ED-E

    War. War never changes.

  • Members
  • Joined: 31 May 2010
  • None

#12

Posted 29 November 2013 - 12:57 PM Edited by ChopTheDog., 29 November 2013 - 06:05 PM.

Like Bad.boy! said, you need to hook into one of the functions. This is much easier to do if you understand a bit of x86 machine language, but you can find pretty good tutorials for GTA III era.
 
Depending on the order in which these things are called, hooking into CPed::Initialise might work. If you can hook it at the function exit, call your own code, check if the pointer to CPed matches pointer to player, and if so, modify wanted level, it should work flawlessly. Unless, of course, the init code is called before player pointer is set. But I doubt that's the case. I would guess that the game calls constructor, sets player pointer, and then calls the init code, making it the perfect place for the hook.

 

Here's the function I pulled from IDA starting at 0x50D9F0 (This is where CPed::Initialize starts)

 

bUbZ2P8.png

 

So I looked up a basic hooking tutorial and after editing I got this code:

 

#define StartOfCPED 0x50D9F0
double (__cdecl* originalFunction) (double);

This should define and point to the original function, right?

 

So in the DLLmain I wrote (using Detours 1.5):

 

BOOL WINAPI DLLMAIN(HANDLE hHandle,DWORD nReason,LPVOID lpReserved )
{
switch (nReason)
{
case DLL_PROCESS_ATTACH:
originalFunction = (double(__cdecl*)(double))DetourFunction((PBYTE)(StartOfCPED), (PBYTE)Hook);
break;


case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

This calls (I think) my Hook function which is:

double Hook(double a)
{
GetWindowThreadProcessId(hWnd, &pid);
phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
ReadProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &PlayerPointer, 4, 0);
PlayerPointer = PlayerPointer + WantedLevelPointer;
ReadProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &PlayerPointer, 4, 0);
PlayerPointer = PlayerPointer + WantedCounter;
WriteProcessMemory(phandle, (LPVOID)PlayerPointer, (LPVOID) &WantedLevel, 4, 0);
return originalFunction (a);
}

The game loads without crashing (thankfully) but nothing happens.

 

Just for the record, I'm trying to hook VC and I am not using an ASI Loader.

 

You might look at this and laugh at how noobish it is.  :sui:

 

EDIT: Unless, like K^2 stated, CPed::Initialize is called before the Player pointer 

is set and my code is still behind it.

 

EDIT 2: 

 

I also tried hooking on game load at 0x61A700 but again, I failed, it must be my Detours code or the pointer to the original function causing the problem.

 

qNv5YEK.png


sharpie_eastern
  • sharpie_eastern

    Do it thyself

  • Members
  • Joined: 25 Oct 2008
  • United-States

#13

Posted 30 November 2013 - 07:02 AM

You could do it via SCM. I just tried it
 

010D: set_player $PLAYER_CHAR wanted_level_to 4

ED-E
  • ED-E

    War. War never changes.

  • Members
  • Joined: 31 May 2010
  • None

#14

Posted 30 November 2013 - 03:02 PM

 

You could do it via SCM. I just tried it
 

010D: set_player $PLAYER_CHAR wanted_level_to 4

 

I already knew that bro.

 

I've been an SCM scripter for 3 years.  :p 

  • TommyCJFaann likes this




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users