HTTP requests (without sampfuncs)

Important: from 7/09/2020 update, "HTTP_GET" and "HTTP_POST" have additional parameter called "is_https", which allow it to use https (secure) protocol.
So number of parameters in HTTP_GET and HTTP_POST "0AB1: call_scm_func" opcode calls must be updated (now it's 4 for HTTP_GET instead of 3, and it's 5 instead of 4 for HTTP_POST). If you never used this snippet in the past, please ignore this message (because examples below are updated).


Code to put inside "Gta/cleo/includes/http_requests.txt":
Code:
/* Based on the work of:
    - legend2360 from BlastHack forum   https://blast.hk/threads/13410/page-214#post-54339
    - AhnMo from github                 https://gist.github.com/AhnMo/5cf37bbd9a6fa2567f99ac0528eaa185
*/

// 0AB1: call_scm_func @HTTP_GET 4 host 30@ file_path 29@ response_buffer 28@ is_https 27@ _ret_is_success 30@
:HTTP_GET
0AC8: 31@ = allocate_memory_size 4
0AD3: 31@ = format "GET"
059A:  return_false
0AB1: call_scm_func @HTTP_REQUEST 6 host 0@ file_path 1@ type 31@ response_buffer 2@ data 0 is_https 3@ _ret 30@
0AC9: free_allocated_memory 31@
0AB2: ret 1 30@

// 0AB1: call_scm_func @HTTP_POST 5 host 30@ file_path 29@ response_buffer 28@ data 27@ is_https 26@ _ret_is_success 30@
:HTTP_POST
0AC8: 31@ = allocate_memory_size 5
0AD3: 31@ = format "POST"
0AB1: call_scm_func @HTTP_REQUEST 6 url 0@ file_path 1@ type 31@ response_buffer 2@ data 3@ is_https 4@ _ret 30@
0AC9: free_allocated_memory 31@
0AB2: ret 1 30@


:HTTP_REQUEST
{   
Parematers:
    0@ = host       (e.g. http://example.com)
    1@ = file_path  (e.g. index.php)
    2@ = type       (e.g. GET, POST, PUT)
    3@ = response buffer
    4@ = data       (for POST, PUT requests)
}

16@ = false
0AA2: 31@ = load_library "wininet.dll"
0AA4: 30@ = get_proc_address "InternetCloseHandle" library 31@ 
0AA4: 29@ = get_proc_address "InternetOpenA" library 31@
0AA7: call_function 29@ num_params 5 pop 0 flags 0 proxy_bypass "" proxy "" access_type 0 user_agent "CLEO" _returned 28@
if 28@ <> 0
then
    0AA4: 27@ = get_proc_address "InternetConnectA" library 31@
    
{    void InternetConnectA(
  HINTERNET     hInternet,
  LPCSTR        lpszServerName,
  INTERNET_PORT nServerPort,
  LPCSTR        lpszUserName,
  LPCSTR        lpszPassword,
  DWORD         dwService,
  DWORD         dwFlags,
  DWORD_PTR     dwContext
);
}
    // 3 = INTERNET_SERVICE_HTTP
    if 5@ == true 
    then
        // https
        0AA7: call_function 27@ num_params 8 pop 0 0 0 3 "" "" port 443 host 0@ connection_handle 28@ _returned 26@
    else
        // http
        0AA7: call_function 27@ num_params 8 pop 0 0 0 3 "" "" port 80 host 0@ connection_handle 28@ _returned 26@
    end
    
    if 26@ <> 0
    then
        0AA4: 25@ = get_proc_address "HttpOpenRequestA" library 31@
        
        /*  0x80400100 is a set of flags:
            0x80000000 - INTERNET_FLAG_RELOAD
              
              0x800000 - INTERNET_FLAG_SECURE
              0x400000 - INTERNET_FLAG_KEEP_CONNECTION (both these flags result in 12, so "c" in hexadecimal)
              
                 0x100 - INTERNET_FLAG_PRAGMA_NOCACHE 
            Reference: https://docs.microsoft.com/en-us/windows/win32/wininet/api-flags   */
        if 5@ == true 
        then
            // https
            0AA7: call_function 25@ num_params 8 pop 0 dwContext 0 dwFlags 0x80c00100 accept_types 0 referrer "" version "HTTP/1.1" file_path 1@ request_type 2@ connection_handle 26@ _returned 24@
        else
            0AA7: call_function 25@ num_params 8 pop 0 dwContext 0 dwFlags 0x80400100 accept_types 0 referrer "" version "HTTP/1.1" file_path 1@ request_type 2@ connection_handle 26@ _returned 24@
        end
        
        if 24@ <> 0
        then
            if 4@ == 0
            then
                17@ = 0
            else                       
                0AB1: call_scm_func @http_requests_unique_strlen 1 4@ _returned 17@
            end
 
            0AA4: 22@ = get_proc_address "HttpSendRequestA" library 31@
            
            // content and content_length can be 0 if there's no data to send (e.g. in GET request)
            0AA7: call_function 22@ num_params 5 pop 0  content_length 17@ content 4@ headers_length 47 headers "Content-Type: application/x-www-form-urlencoded" request_handle 24@ _returned 21@


            0AA4: 20@ = get_proc_address "InternetReadFile" library 31@
            
            18@ = 1
            0AC7: 19@ = var 18@ offset
            while 18@ > 0                
                wait 0
                0AA5: call_function 20@ num_params 4 pop 0 ptr_to_number_of_bytes_read 19@ number_of_bytes_to_receive 31 receive_data_buffer 3@ file_handle 24@
                005A: 3@ += 18@
                16@ = true
            end
            0A8C: write_memory 3@ size 1 value 0 virtual_protect 0
            0AA5: call_function 30@ num_params 1 pop 0 24@
        end
 
        0AA5: call_function 30@ num_params 1 pop 0 26@
    end
 
    0AA5: call_function 30@ num_params 1 pop 0 28@
end
 
0AA3: free_library 31@

{ it just doesn't work properly (idk why)
if 16@ == true
then
    0485:  return_true
else
    059A:  return_false
end}
0AB2: ret 1 16@

:http_requests_unique_strlen // called like that to avoid coliding with strlen (if someone has it in their code)
8@ = 0
0A8D: 9@ = read_memory 0@ size 1 virtual_protect 0
while 9@ <> 0
    8@++
    0@++
    0A8D: 9@ = read_memory 0@ size 1 virtual_protect 0    
end
0AB2: ret 1 8@

Example usage:
Code:
{$CLEO}                                
0000:

0AC8: 30@ = allocate_memory_size 260
0AD3: 30@ = format "localhost"   // can be replaced with sometihng like: 0AD3: 30@ = format "mywebsite.000webhostapp.com" 47

0AC8: 29@ = allocate_memory_size 260
0AD3: 29@ = format "add.php"

0AC8: 28@ = allocate_memory_size 1500

// Data for the POST request
0AC8: 27@ = allocate_memory_size 260
0AD3: 27@ = format "key=val&another_key=another_val"

while true
wait 0
    if 0ADC:   test_cheat "x"
    then
        // 0AB1: call_scm_func @HTTP_GET 4 host 30@ file_path 29@ response_buffer 28@ is_https false _ret_is_success 30@
        0AB1: call_scm_func @HTTP_POST 5 host 30@ file_path 29@ response_buffer 28@ data 27@ is_https true _ret_is_success 31@
        if 31@ == true
        then
            0AD1: show_formatted_text_highpriority "response = %s" time 2000 28@
        else
            0AD1: show_formatted_text_highpriority "Request failed" time 2000
        end
    end
end

{$INCLUDE includes/http_requests.txt}
 
Last edited:

GeorgeMor

Member
Joined
Apr 15, 2020
Messages
9
Reaction score
0
Location
Scotland
I get this error while running the script:

(I have launched a working http server on localhost but it's not receiving any request)


[23:06:09] Warning(s007): Exception 0xC0000005 at 0x0
[23:06:09] Warning(s007): Exception 0xC0000005 at 0x0

How can I troubleshoot them?

(I have latest cleo version and samp 0.3dl)
 
Last edited:

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
151
I tested it with cleo 4.1, maybe that's the reason but I don't know to be honest
 

Parazitas

God
Joined
Jan 2, 2017
Messages
3,104
Solutions
5
Reaction score
882
Location
Lithuania
I get this error while running the script:

(I have launched a working http server on localhost but it's not receiving any request)


[23:06:09] Warning(s007): Exception 0xC0000005 at 0x0
[23:06:09] Warning(s007): Exception 0xC0000005 at 0x0

How can I troubleshoot them?

(I have latest cleo version and samp 0.3dl)
Show code.
 

GeorgeMor

Member
Joined
Apr 15, 2020
Messages
9
Reaction score
0
Location
Scotland
Show code.
Exactly the same of monday, I didn't change anything.

I created a http_requests.txt in GTA-SanAndreas\CLEO\includes and put

Code:
/* Based on the work of:
    - legend2360 from BlastHack forum   https://blast.hk/threads/13410/page-214#post-54339
    - AhnMo from github                 https://gist.github.com/AhnMo/5cf37bbd9a6fa2567f99ac0528eaa185
*/

// 0AB1: call_scm_func @HTTP_GET 3 host 30@ file_path 29@ response_buffer 28@ _ret_is_success 30@
:HTTP_GET
0AC8: 31@ = allocate_memory_size 4
0AD3: 31@ = format "GET"
059A:  return_false
0AB1: call_scm_func @HTTP_REQUEST 5 host 0@ file_path 1@ type 31@ response_buffer 2@ data 0 _ret 30@
0AC9: free_allocated_memory 31@
0AB2: ret 1 30@

// 0AB1: call_scm_func @HTTP_POST 4 host 30@ file_path 29@ response_buffer 28@ data 27@ _ret_is_success 30@
:HTTP_POST
0AC8: 31@ = allocate_memory_size 5
0AD3: 31@ = format "POST"
0AB1: call_scm_func @HTTP_REQUEST 5 url 0@ file_path 1@ type 31@ response_buffer 2@ data 3@ _ret 30@
0AC9: free_allocated_memory 31@
0AB2: ret 1 30@


:HTTP_REQUEST
{   
Parematers:
    0@ = host       (e.g. http://example.com)
    1@ = file_path  (e.g. index.php)
    2@ = type       (e.g. GET, POST, PUT)
    3@ = response buffer
    4@ = data       (for POST, PUT requests)
}

16@ = false
0AA2: 31@ = load_library "wininet.dll"
0AA4: 30@ = get_proc_address "InternetCloseHandle" library 31@
0AA4: 29@ = get_proc_address "InternetOpenA" library 31@
0AA7: call_function 29@ num_params 5 pop 0 flags 0 proxy_bypass "" proxy "" access_type 0 user_agent "CLEO" _returned 28@
if 28@ <> 0
then
    0AA4: 27@ = get_proc_address "InternetConnectA" library 31@
    
    // 3 = INTERNET_SERVICE_HTTP
    0AA7: call_function 27@ num_params 8 pop 0 0 0 3 "" "" port 80 host 0@ connection_handle 28@ _returned 26@
    if 26@ <> 0
    then
        0AA4: 25@ = get_proc_address "HttpOpenRequestA" library 31@
        
        /*  0x80400100 is a set of flags:
            0x80000000 - INTERNET_FLAG_RELOAD
              0x400000 - INTERNET_FLAG_KEEP_CONNECTION
                 0x100 - INTERNET_FLAG_PRAGMA_NOCACHE
            Reference: https://docs.microsoft.com/en-us/windows/win32/wininet/api-flags   */
        0AA7: call_function 25@ num_params 8 pop 0 dwContext 0 dwFlags 0x80400100 accept_types 0 referrer "" version "HTTP/1.1" file_path 1@ request_type 2@ connection_handle 26@ _returned 24@
        if 24@ <> 0
        then
            if 4@ == 0
            then
                17@ = 0
            else                       
                0AB1: call_scm_func @http_requests_unique_strlen 1 4@ _returned 17@
            end
 
            0AA4: 22@ = get_proc_address "HttpSendRequestA" library 31@
            
            // content and content_length can be 0 if there's no data to send (e.g. in GET request)
            0AA7: call_function 22@ num_params 5 pop 0  content_length 17@ content 4@ headers_length 47 headers "Content-Type: application/x-www-form-urlencoded" request_handle 24@ _returned 21@


            0AA4: 20@ = get_proc_address "InternetReadFile" library 31@
            
            18@ = 1
            0AC7: 19@ = var 18@ offset
            while 18@ > 0               
                wait 0
                0AA5: call_function 20@ num_params 4 pop 0 ptr_to_number_of_bytes_read 19@ number_of_bytes_to_receive 31 receive_data_buffer 3@ file_handle 24@
                005A: 3@ += 18@
                16@ = true
            end
            0A8C: write_memory 3@ size 1 value 0 virtual_protect 0
            0AA5: call_function 30@ num_params 1 pop 0 24@
        end
 
        0AA5: call_function 30@ num_params 1 pop 0 26@
    end
 
    0AA5: call_function 30@ num_params 1 pop 0 28@
end
 
0AA3: free_library 31@

{ it just doesn't work properly (idk why)
if 16@ == true
then
    0485:  return_true
else
    059A:  return_false
end}
0AB2: ret 1 16@

:http_requests_unique_strlen // called like that to avoid coliding with strlen (if someone has it in their code)
8@ = 0
0A8D: 9@ = read_memory 0@ size 1 virtual_protect 0
while 9@ <> 0
    8@++
    0@++
    0A8D: 9@ = read_memory 0@ size 1 virtual_protect 0   
end
0AB2: ret 1 8@

and this file .cs
Code:
{$CLEO}                                 
0000:

0AC8: 30@ = allocate_memory_size 260
0AD3: 30@ = format "localhost"   // can be replaced with sometihng like: 0AD3: 30@ = format "http:%c/mywebsite.000webhostapp.com" 47

0AC8: 29@ = allocate_memory_size 260
0AD3: 29@ = format "add.php"

0AC8: 28@ = allocate_memory_size 1500

// Data for the POST request
0AC8: 27@ = allocate_memory_size 260
0AD3: 27@ = format "key=val&another_key=another_val"

while true
wait 0
    if 0ADC:   test_cheat "x"
    then
        // 0AB1: call_scm_func @HTTP_GET 3 host 30@ file_path 29@ response_buffer 28@ _ret_is_success 30@
        0AB1: call_scm_func @HTTP_POST 4 host 30@ file_path 29@ response_buffer 28@ data 27@ _ret_is_success 31@
        if 31@ == true
        then
            0AD1: show_formatted_text_highpriority "response = %s" time 2000 28@
        else
            0AD1: show_formatted_text_highpriority "Request failed" time 2000
        end
    end
end

{$INCLUDE includes/http_requests.txt}
 

0x_

Wtf I'm not new....
Administrator
Joined
Feb 18, 2013
Messages
1,116
Reaction score
167
Nice snippet, never liked the idea of external closed source plug-ins like SAMPFUNCS it set's everything on one card.
 

mpol77

Active member
Joined
Oct 24, 2018
Messages
66
Reaction score
6
:/
 

Attachments

  • 1606014051306.png
    1606014051306.png
    51.8 KB · Views: 64

dphome

Well-known member
Joined
Mar 21, 2020
Messages
456
Solutions
9
Reaction score
165
Location
Poland
Great. It works wonderfully. I tested it on 0.3.DL-R1.

add.php, config.ini to YourSite.com/samp-test and chmod 777
Script.cs to GTA\CLEO.
nq4NjPa.png

y6GlReB.png

Script.cs
PHP:
{$CLEO .cs}
0000:

WHILE TRUE
WAIT 0

IF 0ADC:   test_cheat "1"
THEN
    0AC8: 30@ = allocate_memory_size 1024
    0AD3: 30@ = format "dphome.cba.pl"
    0AC8: 29@ = allocate_memory_size 1024
    0AD3: 29@ = format "samp-test/add.php"    
    0AC8: 28@ = allocate_memory_size 1024    
    0AC8: 27@ = allocate_memory_size 1024
    0AD3: 27@ = format "nick=Eripe&message=Chuj, nie bragga"    
    
    0AB1: @HTTP_POST 5 host 30@ file_path 29@ response_buffer 28@ data 27@ is_https 26@ _ret_is_success 30@
    IF 30@ == TRUE
    THEN 0AD1: "~g~%s" time 3000 28@
    ELSE 0AD1: "~r~ERROR" time 3000
    END
END

END
0A93: terminate_this_custom_script
add.php
PHP:
<?php
// Pobranie danych przesłanych w żądaniu POST
$nick = $_POST['nick'] ?? '';
$message = $_POST['message'] ?? '';

// Sprawdzenie, czy dane są poprawne
if (!empty($nick) && !empty($message)) {
    // Otwarcie pliku config.ini w trybie do zapisu
    $configFilePath = 'config.ini';
    $configContent = parse_ini_file($configFilePath);
    
    if ($configContent === false) {
        die("Error: Unable to read config.ini");
    }
    
    // Dodanie nowego wpisu do pliku konfiguracyjnego
    $entry = "[Entry]\n";
    $entry .= "nick = \"$nick\"\n";
    $entry .= "message = \"$message\"\n\n";
    
    // Dodanie wpisu do istniejącej zawartości pliku konfiguracyjnego
    file_put_contents($configFilePath, $entry, FILE_APPEND);
    
    $response = "Success: Entry added to config.ini.";
} else {
    $response = "Error: Invalid data.";
}

// Wysłanie odpowiedzi z powrotem do żądającego skrypt
echo $response;
?>
 

Attachments

  • Files.zip
    9.7 KB · Views: 8
Top