[Fixed] Problem - memory

Parazitas

Well-Known Member
Joined
Jan 2, 2017
Messages
2,229
Likes
420
Points
113
Location
Lithuania
Website
ugbase.eu
20
#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
150
Likes
72
Points
28
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 [email protected] // gets gametext 0x200
    then 0ACD: show_text_highpriority [email protected] time 1000
    else 0ACD: show_text_highpriority "no string found" time 1000
    end
end

:getgxt // 04B1: @getgxt 1 _gxt_index [email protected] _return_string [email protected] // index starts at 0(0 to n)
[email protected] *= 0x80 // size per index
[email protected] += 0xBAACC0 // base pointer for Center, Center, Orange, Black Outline+Medium+Fade Out+Cool FadeIn/Out Effect, "Mission Complete"
[email protected] = -1 // supporting value in case that the read memory fails
0A8D: [email protected] = read_memory [email protected] size 0x80 virtual_protect 0 // turn virtual protect to 1 if crashing
if [email protected] > 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 [email protected] // return the gxt pointer
 

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
150
Likes
72
Points
28
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
    [email protected] = 0xBAACC0
    [email protected] += 0x0 // GTA SA default center pop up pointer offset
    0ACD: show_text_highpriority [email protected] 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
Joined
Jan 2, 2017
Messages
2,229
Likes
420
Points
113
Location
Lithuania
Website
ugbase.eu
20
#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
    [email protected] = 0xBAACC0
    [email protected] += 0x0 // GTA SA default center pop up pointer offset
    0ACD: show_text_highpriority [email protected] 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,090
Likes
135
Points
168
#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
Joined
Jan 2, 2017
Messages
2,229
Likes
420
Points
113
Location
Lithuania
Website
ugbase.eu
20
#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 [email protected]
then
    0ACD: show_text_highpriority "string found" time 50
    //0AD1: show_formatted_text_highpriority "%s" time 50 [email protected]
else
    0ACD: show_text_highpriority "no string found" time 50
end

end

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

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
150
Likes
72
Points
28
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 [email protected] 1024

while true

    // empty message
    0085: [email protected] = [email protected] // store the 240 allocated bytes pointer
    for [email protected] = 1 to 256
        0A8C: write_memory [email protected] size 4 value 0 virtual_protect 0
        [email protected] += 4
    end
    //

    0085: [email protected] = [email protected] // store the 240 allocated bytes pointer
    for [email protected] = 1 to 1023
        wait 50
        0A8C: write_memory [email protected] size 1 value 97 virtual_protect 0 // acii a
        [email protected]++
        0ACD: show_text_highpriority [email protected] time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0ACC: show_text_lowpriority [email protected] time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD1: show_formatted_text_highpriority "%s" time 250 [email protected] // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD0: show_formatted_text_lowpriority "%s" time 250 [email protected] // can show max of 127 characters // crashes when reaching 128 characters
        // 0AF8: samp add_message_to_chat [email protected] color -1 // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        // say [email protected]  // 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 [email protected]
    end

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

Parazitas

Well-Known Member
Joined
Jan 2, 2017
Messages
2,229
Likes
420
Points
113
Location
Lithuania
Website
ugbase.eu
20
#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 [email protected] 1024

while true

    // empty message
    0085: [email protected] = [email protected] // store the 240 allocated bytes pointer
    for [email protected] = 1 to 256
        0A8C: write_memory [email protected] size 4 value 0 virtual_protect 0
        [email protected] += 4
    end
    //

    0085: [email protected] = [email protected] // store the 240 allocated bytes pointer
    for [email protected] = 1 to 1023
        wait 50
        0A8C: write_memory [email protected] size 1 value 97 virtual_protect 0 // acii a
        [email protected]++
        0ACD: show_text_highpriority [email protected] time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0ACC: show_text_lowpriority [email protected] time 250 // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD1: show_formatted_text_highpriority "%s" time 250 [email protected] // can show max of 127 characters // crashes when reaching 128 characters
        // 0AD0: show_formatted_text_lowpriority "%s" time 250 [email protected] // can show max of 127 characters // crashes when reaching 128 characters
        // 0AF8: samp add_message_to_chat [email protected] color -1 // does not crash even trying to show 1024 number of characters, that explains because the message was trimmed into 127 characters
        // say [email protected]  // 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 [email protected]
    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 [email protected]
    0.3.7 - R4
}
IF 0AA2: [email protected] = "samp.dll"
THEN
    0085: [email protected] = [email protected]
    [email protected] += 0x26E9F8
    0A8D: [email protected] = readMem [email protected] sz 4 vp 1
    0085: [email protected] = [email protected]
    [email protected] += 0x67BA0
    0AA6: call [email protected] struct [email protected] num_params 5 pop 0 params 0 [email protected] 0 [email protected] 8
END
0AB2: 0
 

ajom

Well-Known Member
Joined
Apr 14, 2020
Messages
150
Likes
72
Points
28
Location
Pluto
#12
I use chatmsg snippet also, but it is still same.
PHP:
:Chatmsg
{
    0AB1: @Chatmsg 2 color 0xFF00FF00 text [email protected]
    0.3.7 - R4
}
IF 0AA2: [email protected] = "samp.dll"
THEN
    0085: [email protected] = [email protected]
    [email protected] += 0x26E9F8
    0A8D: [email protected] = readMem [email protected] sz 4 vp 1
    0085: [email protected] = [email protected]
    [email protected] += 0x67BA0
    0AA6: call [email protected] struct [email protected] num_params 5 pop 0 params 0 [email protected] 0 [email protected] 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 [email protected] 1024
wait 5000

while true

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

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

end

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

:ChatMsg
IF 0AA2: [email protected] = "samp.dll"
THEN
    0085: [email protected] = [email protected]
    [email protected] += SAMP_CHAT_INFO_OFFSET
    0A8D: [email protected] = readMem [email protected] sz 4 vp 1
    0085: [email protected] = [email protected]
    [email protected] += FUNC_ADDTOCHATWND
    0AA6: call [email protected] struct [email protected] num_params 5 pop 0 params 0 [email protected] 0 [email protected] 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
Joined
Jan 2, 2017
Messages
2,229
Likes
420
Points
113
Location
Lithuania
Website
ugbase.eu
20
#13

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

0000:

wait 8500 // not necessary

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

end

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

:Chatmsg
{
    0AB1: @Chatmsg 2 text [email protected] color 0xFF00FF00
    0.3.7 - R4
}
IF 0AA2: [email protected] = "samp.dll"
THEN
    0085: [email protected] = [email protected]
    [email protected] += 0x26E9F8
    0A8D: [email protected] = readMem [email protected] sz 4 vp 1
    0085: [email protected] = [email protected]
    [email protected] += 0x67BA0
    0AA6: call [email protected] struct [email protected] num_params 5 pop 0 params 0 [email protected] 0 [email protected] 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