[Tutorial] Using functions from Windows libraries

monday

Well-Known Member
Joined
Jun 23, 2014
Messages
919
Likes
4
Points
18
#1
Using windows libraries brings a lot of functionality to cleo. For example it allows to create an accurate FPS counter which wouldn't be possible using CLEO timers. Or things like setting the position and size of the GTA window, producing a beeping sound, retrieving current time and date. Potentially even executing a file (which I could never get to work properly).

How to call such functions in CLEO
If the function returns some value (0AA7):
Code:
0AA2: [email protected] = load_library "kernel32.dll" 
    if 0AA4: [email protected] = get_proc_address "GetTickCount" library [email protected] 
    then
    0AA7: call_function [email protected] num_params 0 pop 0 [email protected]  
If the function doesn't return any value (0AA5):
Code:
0AA2: [email protected] = load_library "kernel32.dll" 
    if 0AA4: [email protected] = get_proc_address "GetTickCount" library [email protected] 
    then
    0AA5: call [email protected] num_params 0 pop 0
GetTickCount doesn't require any input parameters but if it required it would look like this:
0AA7: ADDRESS_TO_CALL - PARAM_NUM - POP_NUM - SECOND_PARAM - FIRST_PARAM - RETURNED_VALUE
(The parameters passed should be in reverse order)
0AA7 - Opcode database
0AA7 - In depth explanation

For functions that do not return any value (e.g. "void SomeFunction(){}") it would look like:
0AA5: ADDRESS_TO_CALL - PARAM_NUM - POP_NUM - SECOND_PARAM - FIRST_PARAM
(The parameters passed should be in reverse order)
0AA5 - Opcode database

How to use push/pop parameter
Push - stands for number of arguments passed to function
Pop - without going into detail: if you know that it's WINAPI (stdcall) then set it to 0, if it's cdecl then set it to the same value as "push" parameter

Some functions take care themselves of "cleaning" parameters from stack, some functions don't take care of it and it has to be done outside of function after its return, that's what "pop" is doing.

(idk exactly how to find out the calling convention of specific function, would be good if someone clarified that and I'd update this section, link to theory)

Resources for finding functions
I don't know if there's a list of all useful libraries with their most useful functions but you could check the following links:
-user32.dll
-shell32.dll (ShellExecute function is interesting, if anyone manages to make it work and posts it here it would be cool)
-kernel32.dll

Anyway I'd like to present a practical approach on how to effectively find and use them. Here's the example of what could be done to apply some function to solve FPS counter issue:
-type in google: "how to get tick count c++"
-notice the function "GetTickCount()" documented on msdn.microsoft.com Link
-notice the part of MSDN page which says: "Library Kernel32.lib", that's how to know which library to use in 0AA2 opcode
-notice the number and data type of parameters and returns to know how to call the function using 0AA7 opcode
-sometimes the return variable can't be null so it's important to read any remarks on the MSDN site

GetTickCount visualisation:


MoveWindow visualisation:



Examples of usage
Make beep - by Opcode.eXe
Code:
//0AB1: @MAKE_BEEP 2 FREQUENCY 0x25 TIME 1000
:MAKE_BEEP
IF
0AA2: [email protected] = load_library "kernel32.dll"
THEN
    IF
    0AA4: [email protected] = get_proc_address "Beep" library [email protected]
    THEN
        0AA5: _CALL_ [email protected] num_params 2 pop 0 [email protected] [email protected]
    END
    0AA3: free_library [email protected]
END
0AB2: 0
Set window position and size - by Opcode.eXe
Code:
0AB1: @SET_WINDOW_POS_AND_SIZE 4 pos_x 50 pos_y 40 width 400 width 400
:SET_WINDOW_POS_AND_SIZE
0A8D: [email protected] = 0xC9C060 4 0
IF
[email protected] == TRUE
THEN
      0AA2: [email protected] = load_library "User32.dll"
      0AA4: [email protected] = get_proc_address "MoveWindow" library [email protected]
      0A8D: [email protected] = 0xC97C1C 4 0
      0AA7: call_function [email protected] params 6 pop 0 TRUE [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] 
END
0AB2: 0

Get date and time
Code:
{$CLEO .cs}
0000:
repeat
wait 500
until 0AFA:  is_samp_available

alloc [email protected] 256
call @Get_Date_Time 0 [email protected]
chatmsg [email protected] -1
free [email protected]

0A93: end_custom_thread




:Get_Date_Time
alloc [email protected] 30
alloc [email protected] 256
0AD3: [email protected] = format "nodatefound"
0AA2: [email protected] = load_library "kernel32.dll" // IF and SET
   if 0AA4: [email protected] = get_proc_address "GetLocalTime" library [email protected]
   then
   0A8C: write_memory [email protected] size 2 value 1 virtual_protect 1
   0AA5: call_function [email protected] num_params 1 pop 0 [email protected]
   //0AC7: [email protected] = var [email protected] offset
   0085: [email protected] = [email protected] // (int)

   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   [email protected] += 2
   0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 1
   //printf "%d %d %d %d %d %d %d" 2000 [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
   0AD3: [email protected] = format "Day=%d Month=%d Year=%d Hour=%d Minute=%d Second=%d" [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
   end
0AA3: free_library [email protected]
free [email protected]
0AB2: ret 1 [email protected]

Time measurement
Code:
:halfSecondPassed
0AA2: [email protected] = load_library "kernel32.dll" // IF and SET
    if 0AA4: [email protected] = get_proc_address "GetTickCount" library [email protected] 
    then
    0AA7: call_function [email protected] num_params 0 pop 0 [email protected]    
    [email protected] = 0
    0085: [email protected] = [email protected] //
    0062: [email protected] -= [email protected]  //
        if 0019:   [email protected] >= 500
        then
        0085: [email protected] = [email protected]
        0485:  return_true
        else
        059A:  return_false
        end
    else
    059A:  return_false
    end
0AA3: free_library [email protected]
0AB2: ret 1 [email protected]
 

0x32789

Well-Known Member
Joined
May 26, 2014
Messages
766
Likes
1
Points
18
Location
teknickal suprot
#4
Opcode.eXe said:
When you use: "Beep" with 1000ms beep time your gta_sa will also freeze for the duration of it.
Thats one of the bad sideeffects of the functions :X
I thought its multi threaded?
 

springfield

Well-Known Member
Staff member
Joined
Feb 18, 2005
Messages
2,931
Likes
6
Points
38
Website
www.ugbase.eu
#5
Joined
Jan 26, 2017
Messages
15
Likes
0
Points
1
#6
hey, i tried this but i don't know why it doesn't work....
{$CLEO}
0000:
repeat
wait 0
until 0afa:
0b63: "fileinfo"
0b34: "fileinfo" @fileinfo
while true
wait 0
end
:fileinfo
0b35: [email protected]
[email protected] = File.Open([email protected], "rt")
/*

BOOL WINAPI GetFileTime(
_In_ HANDLE hFile,
_Out_opt_ LPFILETIME lpCreationTime,
_Out_opt_ LPFILETIME lpLastAccessTime,
_Out_opt_ LPFILETIME lpLastWriteTime
);
*/
alloc [email protected] 260
alloc [email protected] 260
alloc [email protected] 260
alloc [email protected] 260
call @getFileInfo 1 fileHandle [email protected] results-> lpCreationTime [email protected] lpLastAccesTime [email protected] lpLastWriteTime [email protected]
format [email protected] "lpCreationTime %s lpLastAccesTime %s lpLastWriteTime %s" [email protected] [email protected] [email protected]
chatmsg [email protected] -1
File.Close([email protected])
cmdret



:getFileInfo
0AA2: [email protected] = load_library "kernel32.dll" // IF and SET
if 0AA4: [email protected] = get_proc_address "GetFileTime" library [email protected]
then
0AA7: call_function [email protected] num_params 1 pop 0 [email protected] [email protected] [email protected] [email protected]
end
0AA3: free_library [email protected]
0AB2: ret 3 [email protected] [email protected] [email protected]


@monday can u help me please?
 

shanker

Well-Known Member
Joined
Sep 18, 2016
Messages
225
Likes
0
Points
16
Location
Romania
#7
springfield said:
Nice. Here's ShellExecute example.

[shcode=cpp]
0AA2: [email protected] = "shell32.dll"
IF 0AA4: [email protected] = "ShellExecuteA" [email protected]
THEN
   0AA7: [email protected] push 6 pop 1 params 1 0 0 "www.ugbase.eu" 0 0 error_code [email protected]
   IF [email protected] <= 32
   THEN PRINTF "FAILURE: %d" 1000 [email protected]
   END
END
[/shcode]
can you tell me why this version[v1] don't give any avertisment of crassh and that one[v2] do

[v1]
[shcode=cpp]
{$CLEO}

0000:

repeat
wait 0
until 0AFA:

0B34: "Test" to @TEST

while true
   wait 0
end

:TEST
0AA2: [email protected] = "shell32.dll"
IF 0AA4: [email protected] = "ShellExecuteA" [email protected]
THEN
  0AA7: [email protected] push 6 pop 1 params 1 0 0 "www.ugbase.eu" 0 0 error_code [email protected]
  IF [email protected] <= 32
  THEN PRINTF "FAILURE: %d" 1000 [email protected]
  END
END
cmdret
// it don't give me warnings
[/shcode]

[v2]
[shcode=cpp]
{$CLEO}

0000:

repeat
wait 0
until 0AFA:


0AB1: @TEST 0  // or gosub but stil gives crash, happening same if i just add the source to be readed without any jump funcs

while true
wait 0
end

:TEST
0AA2: [email protected] = "shell32.dll"
IF 0AA4: [email protected] = "ShellExecuteA" [email protected]
THEN
  0AA7: [email protected] push 6 pop 1 params 1 0 0 "www.ugbase.eu" 0 0 error_code [email protected]
  IF [email protected] <= 32
  THEN PRINTF "FAILURE: %d" 1000 [email protected]
  END
END
ret 0
// this mdfk give warning
[/shcode]
 
Top