I'm tremendously impressed with the capabilities of MHS, but I'm having trouble with something I'm trying to accomplish, which may be rather odd. I'll start out with my first step.
In the game in question, all values that I need to adjust are stored in a structure. This structure is always a DWORD of value 2 followed by a 32-bit float with the value I seek. (If I just seek the float itself I'll get >100 results, with the 2, usually 1-2 results. You'll see below why I can't change the value and subsearch.) Using the following script I can easily accomplish this:
- Code: Select all
INT CustomSearchIZ3 (LPVOID lpvAddress, LPVOID lpvBuffer, INT iSize)
{
if ((DWORD)lpvAddress % 0x4 == 0)
{
if (iSize >= sizeof(FLOAT))
{
DWORD *lpdwTwo = (DWORD *)(LPVOID)((DWORD)lpvBuffer - 4);
FLOAT *lpfValue = (FLOAT *)(LPVOID)((DWORD)lpvBuffer);
if (*lpdwTwo == 2)
{
if ((*lpfValue >= g_fWanted) && (*lpfValue < (g_fWanted + 1.000)))
{
return sizeof (FLOAT);
}
}
}
}
return 0;
}
This works fine and returns to me the current location of the float to adjust. However, this is not the end result I need. The structure holding this value moves every time it is changed with a "fixed" pointer located elsewhere. It is the location of this pointer that I'm after.
Right now I can just take the result of the above script and then search for a DWORD (or pointer) containing that value in a separate step, but I really want to determine the location of that pointer using one operation. I've tried to write scripts to accomplish this, but they all end up CTDing MHS.
I still don't entirely understand the relationship between lpvAddress and lpvBuffer. I'm guessing that the former is the true address in the program and the latter is a separate address space containing the same data as in lpvAddress but directly accessible from the Script. Thinking this I tried a bunch of different methods including this:
- Code: Select all
DWORD dwOffsetBuffer = ((DWORD)(lpvBuffer));
DWORD dwOffsetAddress = ((DWORD)(lpvAddress));
long lOffsetDelta = dwOffsetBuffer - dwOffsetAddress;
DWORD dwOffsetAddressPointsTo = *((DWORD *)(lpvBuffer));
if ((dwOffsetAddressPointsTo < 0x00400000) || (dwOffsetAddressPointsTo > 0x7FFFE000))
return (0);
DWORD dwOffsetBufferPointsTo = dwOffsetAddressPointsTo + lOffsetDelta;
if ((dwOffsetBufferPointsTo < 0x00400000) || (dwOffsetBufferPointsTo > 0x7FFFE000))
return (0);
struct structSought
{
DWORD iTwo;
FLOAT fValue;
};
structSought* soughtData = (LPVOID)dwOffsetBufferPointsTo;
Is there a way to do this?
To be clear, I'm looking for:
The location of a pointer that points to a 8 byte structure with the first 4 bytes being (DWORD)2 and the second 4 bytes being a (FLOAT)X where X is the number I input.
Thank you for any assistance you can provide,
G
Edit: I know I can optimize my code in the first sample more, but I was just experimenting. Once I get a working solution, I'll tweak for performance. Also, sorry for the non-descriptive Subject, I found it hard to sum up this issue in a few words.