Noob starting Script Search...

Ask for Help on Using the Language With Memory Hacking Software

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

Noob starting Script Search...

Postby WhiteHat » Tue Jun 26, 2007 11:04 pm

I've had enough with memory editing, and wanna start (for real) script searching, even tho my programming experience is very very limited...
Had myself into the MHS help file, and done a few things with Script Search tho, and here's what i've got...

I've put the 'Shell Code To Get You Started' from the helpfile to the Code Editor and compiled it... Anyway, allow me to put the shell code here, so
we don't have to open the helpfile... :

Code: Select all
const DWORD SIZE_OF_ITEM = sizeof( DWORD );
INT UserSearch( LPVOID lpvAddress, LPVOID lpvBuffer, INT iSize ) {
    // Cast to a standard DWORD value.  iSize  is always equal to SIZE_OF_ITEM here.
    DWORD dwThis = *(DWORD *)lpvBuffer;

    // Add your checks here to determine if the DWORD value should be added
    //  to the list.

    return 0;   // Value not added.
}

VOID UserDecoder( LPVOID lpvAddress, LPVOID lpvBuffer, DWORD dwLength, CHAR * pcReturn, INT iMaxLength ) {
    // Display a DWORD in decimal and hex.
    DWORD dwValue = *(DWORD *)lpvBuffer;

    SNPrintF( pcReturn, iMaxLength, "%u (%.8X)", dwValue , dwValue );
}

VOID UserSearchSetup( INT * piDataSize, INT * piAlign, CHAR ** ppcCallback, CHAR ** ppcDecoder ) {
    (*piDataSize) = SIZE_OF_ITEM;
    (*piAlign) = 4;
    (*ppcCallback) = "UserSearch";
    (*ppcDecoder) = "UserDecoder";
}

INT UserSubSearch( LPVOID lpvAddress, LPVOID lpvCur, DWORD dwCurSize, LPVOID lpvOld, DWORD dwOldSize ) {
    return 0;   // Item removed from the list.
}


Now... In my understanding, the UserSearch, UserDecoder, UserSearchSetup, UserSubSearch are all functions. Am i correct ?
If it is, what are each of their purpose(s) ?

Started the script search with minesweeper as the target, using the Basic mode, i set the 4 for Data Size, and UserDecoder for CallBack function.
I got these in result window:

Code: Select all
Address  | Value

00830000 | 03 00 00 00
00830004 | 80 4F 0A 00
00830008 | 10 00 83 00
0083000C | 00 00 00 00
...      | ...


My understanding is, this part of the script :
Code: Select all
VOID UserDecoder( LPVOID lpvAddress, LPVOID lpvBuffer, DWORD dwLength, CHAR * pcReturn, INT iMaxLength ) {
    // Display a DWORD in decimal and hex.
    DWORD dwValue = *(DWORD *)lpvBuffer;

    SNPrintF( pcReturn, iMaxLength, "%u (%.8X)", dwValue , dwValue );
}

is a decoder that reads every bytes in the memory, starting address 00830000 and put them as hex dumber in the result in 4 column, as i
enter 4 for the Data Size... Am i correct on this ?

So, now for the really questions:
1. How do i search the exact value of 500 in Long datatype with search scripts ?
2. How do i perform subsearch after the result 500 were found with the script ? Say i want to subsearch to the value of 300 ?
3. Why the result in my experiment started at 00830000 ?

I've trying to study the helpfile but it seems that i'm not capable enough to understand it clearly... But, hey, at least i've done something ...


Thank you very much in advance... Appreciate for any kind of help to get me really start with this feature...


:)
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby L. Spiro » Wed Jun 27, 2007 10:00 am

Now... In my understanding, the UserSearch, UserDecoder, UserSearchSetup, UserSubSearch are all functions. Am i correct ?

Yes.


If it is, what are each of their purpose(s) ?

UserSearch: Is checked against each value in RAM to allow you to run checks that determine if the value should be added to the list or not.
UserDecoder: After the search is over, they must appear in the Found Address list. This function allows you to decode each result into text for displaying in the Found Address list.
UserSearchSetup: Allows you to set up the Script Search without having to fill out the entire dialog each time. In the dialog, select Programmatic and put this function there; your function sets the 4 parameters itself.
UserSubSearch: Same thing as UserSearch but on Sub Searches instead.


and UserDecoder for CallBack

This function is meant to decode items into text for displaying in the Found Address list. It goes into the Result-Display function slot.
UserSearch goes into Callback.



is a decoder that reads every bytes in the memory, starting address 00830000 and put them as hex dumber in the result in 4 column, as i enter 4 for the Data Size... Am i correct on this ?

No.
The text you saw in the Found Address list is the default decoder that applies when you did not specify a Result-Display function.
Which you didn’t, since you put this into Callback instead.
If you use this decoder, it will read the 4-byte returns from the result list and decode them as:
Code: Select all
00830000 | 3 (00000003)
00830004 | 675712 (000A4F80)
00830008 | 8585232 (00830010)
0083000C | 0 (00000000)




1. How do i search the exact value of 500 in Long datatype with search scripts ?

Code: Select all
INT UserSearch( LPVOID lpvAddress, LPVOID lpvBuffer, INT iSize ) {
    // Cast to a standard DWORD value.  iSize  is always equal to SIZE_OF_ITEM here.
    DWORD dwThis = *(DWORD *)lpvBuffer;
 
    if ( dwThis == 500 ) { return SIZE_OF_ITEM; } // Value added. 
    return 0;   // Value not added.
}




2. How do i perform subsearch after the result 500 were found with the script ? Say i want to subsearch to the value of 300 ?

After the Script Search perform a Sub Search and enter the UserSubSearch function. And it must look like this:
Code: Select all
INT UserSubSearch( LPVOID lpvAddress, LPVOID lpvCur, DWORD dwCurSize, LPVOID lpvOld, DWORD dwOldSize ) {
    if ( (*(DWORD *)lpvCur) == 300 ) { return SIZE_OF_ITEM; } // Item remains.
    return 0;   // Item removed from the list.
}




3. Why the result in my experiment started at 00830000 ?

Because that is the first readable address in the range you specified.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby WhiteHat » Wed Jun 27, 2007 12:35 pm

As i've expected, a fast reply has posted... Thank you very much L.Spiro... ;)

The helpfile is indeed clear enough, but as english is not my first language, it takes me double time to understand it better. But, i've found an example that is match to my needs: the FF7 script search regard Accessories and Player stats... It is awesome !

I planned to do similar things for WC3TFT DOTA for i've found plenty addresses... So i hope i can move along with it... (and maybe need quite helps about it... :D)

However, there is a slight difference between FF7 and WC3TFT: The data structure in FF7 seems located next to each other, while in WC3TFT the address of, for example, HP & MaxHP and SP & MaxSP are quite far separated... (I'll post some screenshots about this later on...)

So, would that be a problem anyway ? I mean, was i correct to say that 'there is a slight difference' ? Should the later script woud be similar or totally different ?

Also, can i expect that with this kind of 'structured script search' then i would never need to find the pointer for each of the address ?

Thank you very much in advance... Gotta go to dig up the script now !...


:)
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby L. Spiro » Wed Jun 27, 2007 9:34 pm

So, would that be a problem anyway ?

Typically not.


Should the later script woud be similar or totally different ?

The only difference is you add data between the known values to fill the spaces between them.


Also, can i expect that with this kind of 'structured script search' then i would never need to find the pointer for each of the address ?

If you always want to search for them.
You really should find the pointers after your searches are complete.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby WhiteHat » Thu Jun 28, 2007 1:12 pm

Finally i've done some exact value with script search... It wasn't that hard after all !... So i move to the next step, which is searching structured data. This is what i've been trying to do since quite a while.

The target is WC3 The Frozen Throne, and for the first step i'll try searching Heroes Health Point.

I found that the structure as follows:
- Float Current HP
- Float HP Regeneration Rate
- Dword NULL -> always 00 00 00 00
- Float Maximum HP

After studying your tutorial about FF7 script search (excellent tut !) about structured data script search, i write this code:

Code: Select all
INT WC3HeroesHPSearchF ( LPVOID lpvAddress, LPVOID lpvBuffer, INT iSize )
{
   struct WC3HeroesHP
   {
      FLOAT      fHPNow;
      FLOAT      fHPRegen;
      DWORD      dwNULL;
      FLOAT      fHPMax;
    }   * pWC3HeroesHP = lpvBuffer;

   if ( iSize < sizeof( WC3HeroesHP ) )
      { return 0; }
   if ( pWC3HeroesHP->dwNULL != 0 )
      { return 0; }
   if ( pWC3HeroesHP->fHPMax != 454 )
      { return 0; }
   
    return sizeof ( WC3HeroesHP );
}

VOID WC3HeroesHPSearchSetupF
(
   INT * piDataSize,
   INT * piAlign,
   CHAR ** ppcCallback,
   CHAR ** ppcDecoder
)

{
    (*piDataSize) = sizeof( WC3HeroesHP );
    (*piAlign) = 4;
    (*ppcCallback) = "WC3HeroesHPSearchF";
}


Save the code, add it to the script list, n compile... I used Programmatic script search and found these result, which were far of my expectation:

Image

On above result, looks like the value 454 was in long datatype and not in float datatype ( 454 = 0x01C6, that is the rightmost values in the tabble) ... >.< ... How did this happened ?


Still won't give up, i decided to modify my code and change the float datatype into dword. And after manually convert 454 float into 1138950144 long, i wrote this:

Code: Select all
INT WC3HeroesHPSearch ( LPVOID lpvAddress, LPVOID lpvBuffer, INT iSize )
{
   struct WC3HeroesHP
   {
      DWORD      dwHPNow;
      FLOAT      fHPRegen;
      DWORD      dwNULL;
      DWORD      dwHPMax;
    }   * pWC3HeroesHP = lpvBuffer;

   if ( iSize < sizeof( WC3HeroesHP ) )
      { return 0; }
   if ( pWC3HeroesHP->dwNULL != 0 )
      { return 0; }
   if ( pWC3HeroesHP->dwHPMax != 1138950144 )            // 454.0000 float = 1138950144 Long
      { return 0; }
   if ( pWC3HeroesHP->dwHPMax != pWC3HeroesHP->dwHPNow ) // Search heroes with full health...
      { return 0; }   
   
    return sizeof ( WC3HeroesHP );
}

VOID WC3HeroesHPSearchSetup
(
   INT * piDataSize,
   INT * piAlign,
   CHAR ** ppcCallback,
   CHAR ** ppcDecoder
)

{
    (*piDataSize) = sizeof( WC3HeroesHP );
    (*piAlign) = 4;
    (*ppcCallback) = "WC3HeroesHPSearch";
}


The results were exactly as i wanted:

Image

Found 3 heroes that MaxHp values is 454 float, and they are at full health (CurrentHP=MaxHP)...

But i'm sure i don't have to do this all the time, i mean converting the float into dword datatype manually... So, What's really going on here ?

Did i make a mistake about the float search code ?
Or there is a bug here ?


Thank you very much in advance... :)
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby WhiteHat » Thu Jun 28, 2007 1:19 pm

Ahh... sorry for double post... Forgot to reply your previous post:

L. Spiro wrote:
So, would that be a problem anyway ?

Typically not.

That's great !


L. Spiro wrote:
Should the later script woud be similar or totally different ?

The only difference is you add data between the known values to fill the spaces between them.

Understood clearly...


L. Spiro wrote:
Also, can i expect that with this kind of 'structured script search' then i would never need to find the pointer for each of the address ?

If you always want to search for them.
You really should find the pointers after your searches are complete.

Huh ?.. Still don't understand why i should find the pointers...
Would you please give me an example, some cases maybe ?


Thank you very much in advance ... :)
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby L. Spiro » Fri Jun 29, 2007 12:13 am

On above result, looks like the value 454 was in long datatype and not in float datatype ( 454 = 0x01C6, that is the rightmost values in the tabble) ... >.< ... How did this happened ?

I will check my compiler again; my suspicion is that it cast the float to int since the 454 on the right is an int, but if either side is a float it should have cast to that instead.
I have no doubts there are a few of these minor details lingering about still but they are very minor.

So to work around it, ensure it is casting to float by typing 454.0f instead of just 454.




Still don't understand why i should find the pointers...

Because pointers tell you where objects are in RAM instantly, without having to waste seconds searching for them.
But if your objects are already static, you do not need pointers to them.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby WhiteHat » Fri Jun 29, 2007 11:00 am

Thanks for your attention...

L. Spiro wrote:So to work around it, ensure it is casting to float by typing 454.0f instead of just 454.

I'll try this as soon as i get home...


L. Spiro wrote:Because pointers tell you where objects are in RAM instantly, without having to waste seconds searching for them.
But if your objects are already static, you do not need pointers to them.

So the issue is time efficiency. I understand this and will try to do so...


:)
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby WhiteHat » Sun Jul 01, 2007 10:45 am

L. Spiro wrote:So to work around it, ensure it is casting to float by typing 454.0f instead of just 454.

I've tried above method, changed the search value to 454.0f but the result was the same as if i use 454... That'is the value is indeed 454, but instead of they were in float data type, they came in Long data type...

:(
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby L. Spiro » Sun Jul 01, 2007 11:37 am

I will investigate the problem after my Japanese exam today.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby L. Spiro » Sun Jul 01, 2007 8:56 pm

My investigation reveals nothing wrong.
After trying my own examples and getting no strange behavior I copied and pasted your code directly and got one return on MSN. The return was normal, using 00 00 E3 43.

Ensure you are using the most up-to-date version, and that implies redownloading from the download page because I uploaded several versions over it to fix some small problems earlier.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby WhiteHat » Fri Jul 06, 2007 8:34 am

L. Spiro wrote:... I copied and pasted your code directly and got one return on MSN. The return was normal, using 00 00 E3 43.

Taking the bright-side of it: my script code works !.. Personally, i’m really proud of it... :lol:
I even tried a simple float Exact search for 434.00 and the return address are the same...
Guess i have to try with games other then WarCraft3 later then... >.<


L. Spiro wrote:... Ensure you are using the most up-to-date version, and that implies redownloading from the download page because I uploaded several versions over it to fix some small problems earlier.

I was using MHS Pre-Final up until now...
Did you upload the same Pre-Final but different version ? Well, that didn't seem noticable...
However, i'm gonna re-download it now...

Anyway, about the problem that occured to my computer, what could possibly wrong ?
Is it my processor ? My RAM ? The Operating System ?
Or is it because it is WarCraft3 ?

Thanks in advance...
User avatar
WhiteHat
Elang Djawa
 
Posts: 1059
Joined: Fri Jul 21, 2006 12:49 pm
Location: Away for a while...

Postby L. Spiro » Fri Jul 06, 2007 3:07 pm

Yes I have uploaded new versions of MHS PreFinal over the existing one.

I compile MHS with a precise floating-point model, which disables intrinsics and uses the standard run-time libraries instead.
Apparently this is causing a problem on your computer.


I have recompiled it using a fast floating-point model, which I guess should improve speed and compliance, but is not as accurate.
You should download MHS_PreFinal.rar once again.


L. Spiro
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Um

Postby abysusslynx » Sat Jan 19, 2008 8:41 am

I cannot hacked anything at all without a tutuorial...Could any1 recommend some sites or books or some type of refrence that will help me understand all this stuff? (Codes, how 2 find address...etc....)
Everything is just very overwelming and ive been trying 2 learn all this stuff, but all i c is a bunch of numbers and letters =((
Legends of ares i am asad 2 say is dead, but wolfteam and soldierfront r great, so c'mon hack hack hack
User avatar
abysusslynx
Hackleberry Fin
 
Posts: 26
Joined: Fri Jan 18, 2008 6:10 am
Location: USA,Florida


Return to Help

Who is online

Users browsing this forum: No registered users and 0 guests