Raised This Month: $99 Target: $400
 24% 

[INC] valist.inc Variable arguments function


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 08-12-2017 , 10:46   [INC] valist.inc Variable arguments function
Reply With Quote #1

Attention!
Not working since sourcepawn "Disallow negative indices in all array access patterns" (d7743c3) update.

Used a few tricks i created functions for variable arguments access.

This workable only with non-array variables for now.

Instruction:
1) Include valist.inc in plugin with #include directive.
2) Call va_start(int param_n) first in variable argument function, where param_n number of argument with ..., counting of arguments start with 1.
It's important call va_start before any variable will declared. Overwise, it'll work not correct.
3) For getting next argument use va_arg(). In case if no more arguments to get, it'll throw error.
You can use va_args() for getting count of params passed in function and va_more() to check if all arguments getted.
4) When you no more needed to get arguments, you must call va_end(). Overwise, memory leaks.

Offtop: Please, if you see any grammar mistakes, notice me about it. I'm not going well in English.

Plugin example:
PHP Code:
//  Maxim "Kailo" Telezhenko, 2017

#pragma newdecls required
#pragma semicolon 1

#include <valist>

public void OnPluginStart()
{
    
RegConsoleCmd("sm_nums"Cmd_Nums);
}

public 
Action Cmd_Nums(int clientint args)
{
    
ReplyToCommand(client"Sum: %i"Sum(104050, -3080));

    return 
Plugin_Handled;
}

int Sum(int ...)
{
    
va_start(1);
    
PrintToServer("args: %i"va_args());
    
int sum 0;
    while (
va_more())
        
sum += va_arg();
    
va_end();
    return 
sum;

valist.inc code


How i did this: (tricks)
1) Unchecked memory access
Then you pass array as param, plugin know only address
PHP Code:
{
    
int array[1];
    
int var1 50;
    
PrintToServer("%i %i"Fn(array), var1);
}

int Fn(int[] array)
{
    return array[
1]; // will return var1 value

2) Variable index of array
PHP Code:
int Fn(int[] array)
{
    return array[-
1]; // will throw error
}

int Fn(int[] array)
{
    
int a = -1;
    return array[
a]; // workable code

3) Knowledge of SourcePawn virtual machine
Plugin memory сonsists of DAT (globals, statics, consts), heap, stack (order as i wrote).
When functions calls:
1) Pass arguments in reverse order
2) Pass num of arguments
3) pass old frame address
4) pass 0
Using sipmle trick i can dump stack
PHP Code:
void Fn()
{
    
int a[1] = {777};
    
dumpstack(a);
}

stock void dumpstack(int[] anchor)
{
    for (
int a = -15<= 15a++)
        
PrintToServer("%i: %i"aanchor[a]);

Using this in process of writing include i got:
Code:
etc.
-8: 2220   // unused memory
-7: 20780 // unused memory
-6: 20776 // unused memory
-5: -5       // value of a
-4: 0        // just 0
-3: 20804 // old frame // for example look at {1}
-2: 1        // param count
-1: 20800 // 1st param; address of a // Here is started vm_start() call
0: 666     // a[1] = {666} // address of this array is 20800
/// {1} Here beging frame of vm_start(), here address is 20804
1: 0        // just 0
2: 20824 // old frame
3: 1        // param count
4: 1        // 1st param // Here is started vm_start() call
5: 0        // Valist VALIST variable
6: 0        // just 0
7: 20856 // old frame
8: 5        // arg count in Sum call
9: 2264   // 1st param
10: 2260 // 2nd param
11: 2256 // 3rd param
12: 2252 // 4th param
13: 2248 // 5th param // Here is started Sum() call; All 5 params is heap address
14: 2236 // this heap addr of where will stored result of Sum() for call ReplyToCommand in future
15: 20876  // this  addr of "Sum: %i" for call ReplyToCommand in future
All addresses is local for plugin memory.
Also as we see stack reversed in memory.
memory: DAT-start ... DAT-end, heap-start ... heap-end, stack-end ... stack-start;
4) pseudo-class based on methodmap + ArrayList
5) Some macros for good looking code
Attached Files
File Type: inc valist.inc (2.0 KB, 15 views)

Last edited by Kailo; 09-11-2017 at 02:22.
Kailo is offline
Deathknife
Senior Member
Join Date: Aug 2014
Old 08-13-2017 , 13:27   Re: [INC] valist.inc Variable arguments function
Reply With Quote #2

This is awesome!
__________________
Deathknife is offline
zipcore
Veteran Member
Join Date: Mar 2010
Location: m_flZipcore
Old 08-14-2017 , 06:37   Re: [INC] valist.inc Variable arguments function
Reply With Quote #3

Yay n1
__________________
zipcore is offline
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 09-11-2017 , 02:21   Re: [INC] valist.inc Variable arguments function
Reply With Quote #4

Not working since sourcepawn "Disallow negative indices in all array access patterns" (d7743c3) update.
Kailo is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 22:50.


Powered by vBulletin®
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Theme made by Freecode