[Fixed] Problem - memory

Parazitas

Well-Known Member
Section Moderator
Joined
Jan 2, 2017
Messages
2,556
Likes
617
Points
163
Location
Lithuania
Website
discord.gg
30
#1
Hello.
So.., i have problem with Game Text address reading
0xBAACC0 + GameText_ID = GameText
With cheat engine works fine..

But when i tried read it in cleo it makes my game crash.
I think there's problem with check if return isn't null.

How it looks when game text exist

How it looks when game text not exist

Question :
There's any way to check when he not returning text?

I already tried:
KERNEL32.lstrlenA but return is always NULL
 
Last edited:

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
308
Likes
158
Points
48
Location
Pluto
#2
Hello.
So.., i have problem with Game Text address reading
0xBAACC0 + GameText_ID = GameText
With cheat engine works fine..

But when i tried read it in cleo it makes my game crash.
I think there's problem with check if return isn't null.

How it looks when game text exist

How it looks when game text not exist

Question :
There's any way to check when he not returning text?

I already tried:
KERNEL32.lstrlenA but return is always NULL
Looks like that pointer you are trying to read stores the address value of a certain string? And it might be returning address 0 I think.

Looking about info regarding base pointer 0xBAACC0, this website says something about:
0xBAACC0 - Center, Center, Orange, Black Outline+Medium+Fade Out+Cool FadeIn/Out Effect, "Mission Complete"
And within this base pointer needs an offset index with 0x80 in size. Im not sure yet I assume that The number of index depends on how many GXT you have been using in you GTA SA I think:
dwAddress := 0xBAACC0 + (GameText_Index - 1) * 0x80

I have seen an example in AHK format :
Code:
; Autohotkey Function
getGameText() {
if (!checkHandles())
return ""
Loop, 7 {
dwAddress := 0xBAACC0 + (A_Index - 1) * 0x80
gameText := readString(hGTA, dwAddress, 128)
if (ErrorLevel)
return ""
if (gameText != "")
break
}
He is inspecting 7 gametext, and you just need the 6th index I think. This is my function based on this(untested yet since I Don't have PC with me):
Code:
{$CLEO .cs}
0000: gxt examiner

wait 10000 // not necessary

while true
    wait 0
    if 04B1: @getgxt 1 _gxt_index 5 _return_string 1@ // gets gametext 0x200
    then 0ACD: show_text_highpriority 1@ time 1000
    else 0ACD: show_text_highpriority "no string found" time 1000
    end
end

:getgxt // 04B1: @getgxt 1 _gxt_index 0@ _return_string 31@ // index starts at 0(0 to n)
0@ *= 0x80 // size per index
0@ += 0xBAACC0 // base pointer for Center, Center, Orange, Black Outline+Medium+Fade Out+Cool FadeIn/Out Effect, "Mission Complete"
31@ = -1 // supporting value in case that the read memory fails
0A8D: 31@ = read_memory 0@ size 0x80 virtual_protect 0 // turn virtual protect to 1 if crashing
if 31@ > 0 // if there is a string, this will return the address of the gxt
then 0485:  return_true
else 059A:  return_false // returns -1 or 0 if there is no string or if it fails
end
ret 1 31@ // return the gxt pointer
 

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
308
Likes
158
Points
48
Location
Pluto
#4
Stupid cleo makes any time crash...
You might be crashing because the string you have scanned does not have a NULL terminator? reading a whole 240 bytes might not have a null terminator at the end. Maybe its safe to read "~y~KIMBA!!!~n~SPAUSKITE ~r~[MOUSE1]." as a 37 bytes string instead of 240 bytes or with CE inspect the size that has a null terminator at the end of that string at pointer (0xBAACC0 + 200) .

What is the server IP anyway? If you are just trying to detect if that message pop up you can just read pointer 0xBAACC0 like:
Some Test, when the message "~y~KIMBA!!!~n~SPAUSKITE ~r~[MOUSE1]." pops up, 0xBAACC0 is overwritten by that message:
Code:
{$CLEO .cs}
0000: gxt examiner

while true
    wait 0
    0@ = 0xBAACC0
    0@ += 0x0 // GTA SA default center pop up pointer offset
    0ACD: show_text_highpriority 0@ time 100 // this opcode can show 60 characters, above that makes it crash I think. but pointer 0xBAACC0 is exactly 240 bytes in size
end
 
Last edited:
OP
OP
Parazitas

Parazitas

Well-Known Member
Section Moderator
Joined
Jan 2, 2017
Messages
2,556
Likes
617
Points
163
Location
Lithuania
Website
discord.gg
30
#5
You might be crashing because the string you have scanned does not have a NULL terminator? reading a whole 240 bytes might not have a null terminator at the end. Maybe its safe to read "~y~KIMBA!!!~n~SPAUSKITE ~r~[MOUSE1]." as a 37 bytes string instead of 240 bytes or with CE inspect the size that has a null terminator at the end of that string at pointer (0xBAACC0 + 200) .

What is the server IP anyway? If you are just trying to detect if that message pop up you can just read pointer 0xBAACC0 like:
Some Test, when the message "~y~KIMBA!!!~n~SPAUSKITE ~r~[MOUSE1]." pops up, 0xBAACC0 is overwritten by that message:
Code:
{$CLEO .cs}
0000: gxt examiner

while true
    wait 0
    0@ = 0xBAACC0
    0@ += 0x0 // GTA SA default center pop up pointer offset
    0ACD: show_text_highpriority 0@ time 100 // this opcode can show 60 characters, above that makes it crash I think. but pointer 0xBAACC0 is exactly 240 bytes in size
end
I found addchatwnd offset so now i can use chatmsg snippet, instead of 0AD1:
 

monday

Well-Known Member
Joined
Jun 23, 2014
Messages
1,105
Likes
142
Points
208
#8
The first thing I'd check is what is stored at 0xBAACC0+GameText_ID when the "GameText" is not shown.
In cheat engine it shows empty space when "string" is selected in the combo box, I'd change that "string" to "Byte" and see if "0" stored at that location.
This way you could either:
- read a single byte and check if it's 0
- read whatever the number of bytes you typically read from there and see if the 1st byte is 0

Btw, in the code posted by ajom, "04B1" is used as if it was "0AB1"
 
OP
OP
Parazitas

Parazitas

Well-Known Member
Section Moderator
Joined
Jan 2, 2017
Messages
2,556
Likes
617
Points
163
Location
Lithuania
Website
discord.gg
30
#9
The first thing I'd check is what is stored at 0xBAACC0+GameText_ID when the "GameText" is not shown.
In cheat engine it shows empty space when "string" is selected in the combo box, I'd change that "string" to "Byte" and see if "0" stored at that location.
This way you could either:
- read a single byte and check if it's 0
- read whatever the number of bytes you typically read from there and see if the 1st byte is 0

Btw, in the code posted by ajom, "04B1" is used as if it was "0AB1"
Works only when i checking if text exist then code return exist...
But when i tried read existing text it always makes crash...

PHP:
{$CLEO .cs}

0000:

wait 10000 // not necessary

while true
    wait 0
  
if 0AB1: @getgxt 1 _gxt_index 5 _return_string 1@
then
    0ACD: show_text_highpriority "string found" time 50
    //0AD1: show_formatted_text_highpriority "%s" time 50 1@
else
    0ACD: show_text_highpriority "no string found" time 50
end

end

:getgxt // 04B1: @getgxt 1 _gxt_index 0@ _return_string 31@ // index starts at 0(0 to n)
0@ *= 0x80 // size per index
0@ += 0xBAACC0 // base pointer
0A8D: 31@ = read_memory 0@ size 1 virtual_protect 0 // turn virtual protect to 1 if crashing
if 31@ > 0 // if exist then
then
    //0A8D: 30@ = read_memory 0@ size 4 virtual_protect 0 // read to get string , but somehow makes crash
    0485:  return_true
else
    059A:  return_false
end
0AB2: ret 1 30@
 
Last edited:

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
308
Likes
158
Points
48
Location
Pluto
#10
Works only when i checking if text exist then code return exist...
But when i tried read existing text it always makes crash...
What do you use to read existing text? This following opcodes is limited to 127 characters:
Code:
0ACC: show_text_lowpriority "im limited to 127 characters" time 1000
0ACD: show_text_highpriority "im limited to 127 characters" time 1000
0AD0: show_formatted_text_lowpriority "im limited to %d characters" time 2000 127
0AD1: show_formatted_text_highpriority "im limited to %d characters" time 2000 127
With SAMPFUNCS if it was just troubleshooting I will show the message in the chatbox since SAMPFUNCS opcode 0AF8 and 0C8F automatically trims the message to 127 characters.
Code:
say "im safe to use :)"
0AF8: samp add_message_to_chat "im safe to use :)" color 0xFF00FF00

I made tests on how many characters some opcodes can show so that Im confident on my statements above:
Code:
{$CLEO .cs}
0000: gxt examiner

alloc 31@ 1024

while true

    // empty message
    0085: 30@ = 31@ // store the 240 allocated bytes pointer
    for 0@ = 1 to 256
        0A8C: write_memory 30@ size 4 value 0 virtual_protect 0
        30@ += 4
    end
    //

    0085: 30@ = 31@ // store the 240 allocated bytes pointer
    for 0@ = 1 to 1023
        wait 50
        0A8C: write_memory 30@ size 1 value 97 virtual_protect 0 // acii a
        30@++
        0ACD: show_text_highpriority 31@ time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0ACC: show_text_lowpriority 31@ time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD1: show_formatted_text_highpriority "%s" time 250 31@ // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD0: show_formatted_text_lowpriority "%s" time 250 31@ // can show max of 127 characters // crashes when reaching 128 characters
        // 0AF8: samp add_message_to_chat 31@ color -1 // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        // say 31@  // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        0AD1: show_formatted_text_highpriority "showed Char Count: %d" time 250 0@
    end

end
You can try it to see how it behaves.
 
OP
OP
Parazitas

Parazitas

Well-Known Member
Section Moderator
Joined
Jan 2, 2017
Messages
2,556
Likes
617
Points
163
Location
Lithuania
Website
discord.gg
30
#11
What do you use to read existing text? This following opcodes is limited to 127 characters:
Code:
0ACC: show_text_lowpriority "im limited to 127 characters" time 1000
0ACD: show_text_highpriority "im limited to 127 characters" time 1000
0AD0: show_formatted_text_lowpriority "im limited to %d characters" time 2000 127
0AD1: show_formatted_text_highpriority "im limited to %d characters" time 2000 127
With SAMPFUNCS if it was just troubleshooting I will show the message in the chatbox since SAMPFUNCS opcode 0AF8 and 0C8F automatically trims the message to 127 characters.
Code:
say "im safe to use :)"
0AF8: samp add_message_to_chat "im safe to use :)" color 0xFF00FF00

I made tests on how many characters some opcodes can show so that Im confident on my statements above:
Code:
{$CLEO .cs}
0000: gxt examiner

alloc 31@ 1024

while true

    // empty message
    0085: 30@ = 31@ // store the 240 allocated bytes pointer
    for 0@ = 1 to 256
        0A8C: write_memory 30@ size 4 value 0 virtual_protect 0
        30@ += 4
    end
    //

    0085: 30@ = 31@ // store the 240 allocated bytes pointer
    for 0@ = 1 to 1023
        wait 50
        0A8C: write_memory 30@ size 1 value 97 virtual_protect 0 // acii a
        30@++
        0ACD: show_text_highpriority 31@ time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0ACC: show_text_lowpriority 31@ time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD1: show_formatted_text_highpriority "%s" time 250 31@ // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD0: show_formatted_text_lowpriority "%s" time 250 31@ // can show max of 127 characters // crashes when reaching 128 characters
        // 0AF8: samp add_message_to_chat 31@ color -1 // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        // say 31@  // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        0AD1: show_formatted_text_highpriority "showed Char Count: %d" time 250 0@
    end

end
You can try it to see how it behaves.
I use chatmsg snippet also, but it is still same.
PHP:
:Chatmsg
{
    0AB1: @Chatmsg 2 color 0xFF00FF00 text 0@
    0.3.7 - R4
}
IF 0AA2: 2@ = "samp.dll"
THEN
    0085: 3@ = 2@
    3@ += 0x26E9F8
    0A8D: 3@ = readMem 3@ sz 4 vp 1
    0085: 4@ = 2@
    4@ += 0x67BA0
    0AA6: call 4@ struct 3@ num_params 5 pop 0 params 0 0@ 0 1@ 8
END
0AB2: 0
 

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
308
Likes
158
Points
48
Location
Pluto
#12
I use chatmsg snippet also, but it is still same.
PHP:
:Chatmsg
{
    0AB1: @Chatmsg 2 color 0xFF00FF00 text 0@
    0.3.7 - R4
}
IF 0AA2: 2@ = "samp.dll"
THEN
    0085: 3@ = 2@
    3@ += 0x26E9F8
    0A8D: 3@ = readMem 3@ sz 4 vp 1
    0085: 4@ = 2@
    4@ += 0x67BA0
    0AA6: call 4@ struct 3@ num_params 5 pop 0 params 0 0@ 0 1@ 8
END
0AB2: 0
Strange, can you try experimenting this script using your own pointers at R4, I don't have R4 currently:
Code:
{$CLEO .cs}
0000: gxt examiner

alloc 31@ 1024
wait 5000

while true

    // empty message
    0085: 30@ = 31@ // store the 1024 allocated bytes pointer
    for 0@ = 1 to 256
        0A8C: write_memory 30@ size 4 value 0 virtual_protect 0
        30@ += 4
    end
    0AB1: @ChatMsg 2 0xFF00FF00 31@
    0ACD: show_text_highpriority "showed Char Count: 1" time 250
    //

    0085: 30@ = 31@ // store the 1024 allocated bytes pointer
    for 0@ = 1 to 1023
        wait 100
        0A8C: write_memory 30@ size 1 value 97 virtual_protect 0 // acii a
        30@++
        0AB1: @ChatMsg 2 0xFF00FF00 31@
        0AD1: show_formatted_text_highpriority "showed Char Count: %d" time 250 0@
    end

end

const
    // R1 0.3.7
    SAMP_CHAT_INFO_OFFSET = 0x21A0E4
    FUNC_ADDTOCHATWND = 0x64010
    FUNC_SAY = 0x57F0
end

:ChatMsg
IF 0AA2: 2@ = "samp.dll"
THEN
    0085: 3@ = 2@
    3@ += SAMP_CHAT_INFO_OFFSET
    0A8D: 3@ = readMem 3@ sz 4 vp 1
    0085: 4@ = 2@
    4@ += FUNC_ADDTOCHATWND
    0AA6: call 4@ struct 3@ num_params 5 pop 0 params 0 0@ 0 1@ 8
END
0AB2: 0
That script should not crash even when showing 1023 characters. I tried experimenting this script on mine and it does not crash. If it crashes to you the moment it was executed, then the R4 offset pointers you used might be wrong.
 
OP
OP
Parazitas

Parazitas

Well-Known Member
Section Moderator
Joined
Jan 2, 2017
Messages
2,556
Likes
617
Points
163
Location
Lithuania
Website
discord.gg
30
#13

Working example with cleo...
PHP:
{$CLEO .cs}

0000:

wait 8500 // not necessary

while true
wait 0
for 0@ = 0 to 7
    if 0AB1: @getgxt 1 _gxt_index 0@ _return_string 1@
    then
        0AB1: @Chatmsg 2 text 1@ color 0xFF00FF00
    end
end

end

:getgxt
// 0AB1: @getgxt 1 _gxt_index 0@ _return_string 1@ // index starts at 0(0 to n)
0@ *= 0x80 // size per index
0@ += 0xBAACC0 // base pointer
0A8D: 31@ = read_memory 0@ size 1 virtual_protect 0
if 31@ > 0 // if exist then
then                                                         
    0A8C: write_memory 0@ size 0 value 0 virtual_protect 0  // anti crash - clear unknown shit i guess
    0485:  return_true
    0AC8: 30@ = allocate_memory_size 260
    0AD3: 30@ = format "%s" 0@
    0AB2: ret 1 30@
else
    059A:  return_false
end
0AB2: ret 0

:Chatmsg
{
    0AB1: @Chatmsg 2 text 0@ color 0xFF00FF00
    0.3.7 - R4
}
IF 0AA2: 2@ = "samp.dll"
THEN
    0085: 3@ = 2@
    3@ += 0x26E9F8
    0A8D: 3@ = readMem 3@ sz 4 vp 1
    0085: 4@ = 2@
    4@ += 0x67BA0
    0AA6: call 4@ struct 3@ num_params 5 pop 0 params 0 1@ 0 0@ 8
END
0AB2: 0


With c++ it was much easier...
C++:
std::string getGameText()
{
  if(!checkHandles())
    return "";

  DWORD dwAddress = 0;
  std::string gameText;
  for(int i = 0; i < 7; i++)
  {
    DWORD dwAddress +=  0xBAACC0 + (i * 0x80);
    gameText += readString(hGTA, dwAddress, 128);
  }
}

Good job @monday and @ajom .
 
Top