Core Function DLLStructCreate

From Sputnik Wiki
(Difference between revisions)
Jump to: navigation, search
(Example)
(Example)
 
(22 intermediate revisions by one user not shown)
Line 17: Line 17:
 
Success - Returns the DLLStruct.
 
Success - Returns the DLLStruct.
  
Failure - Returns 0 and most likely throws exception.
+
Failure - Returns null and most likely throws exception.
  
 
=== Remarks ===
 
=== Remarks ===
Line 36: Line 36:
  
 
An elementname can be added similar to a C-style declaration DllStructCreate("int n;char buffer[128]").
 
An elementname can be added similar to a C-style declaration DllStructCreate("int n;char buffer[128]").
 +
 +
If the definition begins with "union " you will create the struct the same as a C union type example:
 +
$a = DllStructCreate("union int a;float b");
  
 
def string settings
 
def string settings
 
<pre>
 
<pre>
 
[TYPE] [WHAT IT RETURNS WITH DLLSTRUCTGETDATA] [WHAT IS IT IN C++]
 
[TYPE] [WHAT IT RETURNS WITH DLLSTRUCTGETDATA] [WHAT IS IT IN C++]
ubyte unsigned 8 bit integer char
+
ubyte unsigned 8 bit integer unsigned char
 
byte signed 8 bit integer char
 
byte signed 8 bit integer char
 
char a single ASCII character char
 
char a single ASCII character char
 +
wchar a single UNICODE character wchar
 
short signed 16 bit integer short
 
short signed 16 bit integer short
 
int16 signed 16 bit integer short
 
int16 signed 16 bit integer short
Line 48: Line 52:
 
int32 signed 32 bit integer int
 
int32 signed 32 bit integer int
 
int64 signed 64 bit integer __int64
 
int64 signed 64 bit integer __int64
 +
long signed 64 bit integer __int64
 
ushort signed unsigned 16 bit integer unsigned short
 
ushort signed unsigned 16 bit integer unsigned short
 
uint16 signed unsigned 16 bit integer unsigned short
 
uint16 signed unsigned 16 bit integer unsigned short
Line 53: Line 58:
 
uint32 signed unsigned 32 bit integer unsigned int
 
uint32 signed unsigned 32 bit integer unsigned int
 
uint64 signed unsigned 64 bit integer unsigned __int64
 
uint64 signed unsigned 64 bit integer unsigned __int64
 +
ulong signed unsigned 64 bit integer unsigned __int64
 
float signed 32 bit floating point float
 
float signed 32 bit floating point float
 
double signed 64 bit floating point double
 
double signed 64 bit floating point double
 +
char* a pointer to an ASCII char array (string) char*
 +
wchar* a pointer to an UNICODE char array (string) wchar*
 +
ptr a pointer void*
 +
uptr a unsigned pointer unsigned void*
  
 
Note - There is no *string* type instead;
 
Note - There is no *string* type instead;
 
You must create an array of chars example "char mystring[500]"
 
You must create an array of chars example "char mystring[500]"
 
then you can use it like a string.
 
then you can use it like a string.
 +
 +
Or if you wish to use UNICODE its "wchar mystring[500]"
 +
 +
Warning - Remember to free() etc when your working with allocated memory and pointers.
 
</pre>
 
</pre>
  
 
=== Example ===
 
=== Example ===
 +
 +
Example of placing DLLStructs inside DLLStructs
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Define a POINT struc to include in our main struct
 +
DLLStructCreateDef("POINT", "int x;int y");
 +
 +
// Create the struct
 +
my $Struct = DLLStructCreate( // Of course @"" makes producing the struct almost identical to C/C++
 +
@"
 +
int i;
 +
char* name;
 +
char* pass;
 +
char* id[3];
 +
POINT loc;
 +
POINT lastLoc;
 +
int j;
 +
");
 +
 +
// Write the data
 +
DLLStructSetData($Struct, "i", 100);
 +
DLLStructSetData($Struct, "j", 200);
 +
DLLStructSetData($Struct, "name", "Testy");
 +
DLLStructSetData($Struct, "pass", "Another Testy");
 +
DLLStructSetData($Struct, "id", "This is ID 0", 0);
 +
DLLStructSetData($Struct, "id", "This is ID 1", 1);
 +
DLLStructSetData($Struct, "id", "This is ID 2", 2);
 +
DLLStructSetData($Struct, "loc->x", 50);
 +
DLLStructSetData($Struct, "loc->y", 70);
 +
DLLStructSetData($Struct, "lastLoc->x", 11);
 +
DLLStructSetData($Struct, "lastLoc->y", 22);
 +
 +
// Print the data
 +
println( "I = " . DLLStructGetData($Struct, "i") );
 +
println( "J = " . DLLStructGetData($Struct, "j") );
 +
println( "Name = " . DLLStructGetData($Struct, "name") );
 +
println( "Pass = " . DLLStructGetData($Struct, "pass") );
 +
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
 +
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
 +
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
 +
println( "Loc->x = " . DLLStructGetData($Struct, "loc->x") );
 +
println( "Loc->y = " . DLLStructGetData($Struct, "loc->y") );
 +
println( "lastLoc->x = " . DLLStructGetData($Struct, "lastLoc->x") );
 +
println( "lastLoc->y = " . DLLStructGetData($Struct, "lastLoc->y") );
 +
</syntaxhighlight>
 +
 +
Same as above but with more structs inside structs
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Define a SIZE struc to include in the POINT struct
 +
DLLStructCreateDef("SIZE", "int width;int height");
 +
// Define a POINT struc to include in our main struct
 +
DLLStructCreateDef("POINT", "int x;int y;SIZE s");
 +
 +
// Create the struct
 +
my $Struct = DLLStructCreate( // Of course @"" makes producing the struct almost identical to C/C++
 +
@"
 +
int i;
 +
char* name;
 +
char* pass;
 +
char* id[3];
 +
POINT loc;
 +
POINT lastLoc;
 +
int j;
 +
");
 +
 +
// Write the data
 +
DLLStructSetData($Struct, "i", 100);
 +
DLLStructSetData($Struct, "j", 200);
 +
DLLStructSetData($Struct, "name", "Testy");
 +
DLLStructSetData($Struct, "pass", "Another Testy");
 +
DLLStructSetData($Struct, "id", "This is ID 0", 0);
 +
DLLStructSetData($Struct, "id", "This is ID 1", 1);
 +
DLLStructSetData($Struct, "id", "This is ID 2", 2);
 +
DLLStructSetData($Struct, "loc->x", 50);
 +
DLLStructSetData($Struct, "loc->y", 70);
 +
DLLStructSetData($Struct, "loc->s->width", 800);
 +
DLLStructSetData($Struct, "loc->s->height", 600);
 +
DLLStructSetData($Struct, "lastLoc->x", 11);
 +
DLLStructSetData($Struct, "lastLoc->y", 22);
 +
DLLStructSetData($Struct, "lastLoc->s->width", 640);
 +
DLLStructSetData($Struct, "lastLoc->s->height", 480);
 +
 +
// Print the data
 +
println( "I = " . DLLStructGetData($Struct, "i") );
 +
println( "J = " . DLLStructGetData($Struct, "j") );
 +
println( "Name = " . DLLStructGetData($Struct, "name") );
 +
println( "Pass = " . DLLStructGetData($Struct, "pass") );
 +
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
 +
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
 +
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
 +
println( "Loc->x = " . DLLStructGetData($Struct, "loc->x") );
 +
println( "Loc->y = " . DLLStructGetData($Struct, "loc->y") );
 +
println( "Loc->s->width = " . DLLStructGetData($Struct, "Loc->s->width") );
 +
println( "Loc->s->height = " . DLLStructGetData($Struct, "Loc->s->height") );
 +
println( "lastLoc->x = " . DLLStructGetData($Struct, "lastLoc->x") );
 +
println( "lastLoc->y = " . DLLStructGetData($Struct, "lastLoc->y") );
 +
println( "lastLoc->s->width = " . DLLStructGetData($Struct, "lastLoc->s->width") );
 +
println( "lastLoc->s->height = " . DLLStructGetData($Struct, "lastLoc->s->height") );
 +
</syntaxhighlight>
 +
 +
Example of placing DLLStructs inside DLLStructs inside DLLStructs and so on
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Create a POINT struct
 +
DLLStructCreateDef("POINT", "int x;int y");
 +
 +
// Create a RECT struct that contains POINT structs
 +
DLLStructCreateDef("RECT", "POINT pos;POINT size");
 +
 +
// Create the main struct that will incluyde a RECT struct
 +
my $Struct = DLLStructCreate( // Of course @"" makes producing the struct almost identical to C/C++
 +
@"
 +
int i;
 +
char* name;
 +
char* pass;
 +
char* id[3];
 +
RECT r;
 +
int j;
 +
");
 +
 +
// Write the data
 +
DLLStructSetData($Struct, "i", 100);
 +
DLLStructSetData($Struct, "j", 200);
 +
DLLStructSetData($Struct, "name", "Testy");
 +
DLLStructSetData($Struct, "pass", "Another Testy");
 +
DLLStructSetData($Struct, "id", "This is ID 0", 0);
 +
DLLStructSetData($Struct, "id", "This is ID 1", 1);
 +
DLLStructSetData($Struct, "id", "This is ID 2", 2);
 +
DLLStructSetData($Struct, "r->pos->x", 50);
 +
DLLStructSetData($Struct, "r->pos->y", 70);
 +
DLLStructSetData($Struct, "r->size->x", 11);
 +
DLLStructSetData($Struct, "r->size->y", 22);
 +
 +
// Print the data
 +
println( "I = " . DLLStructGetData($Struct, "i") );
 +
println( "J = " . DLLStructGetData($Struct, "j") );
 +
println( "Name = " . DLLStructGetData($Struct, "name") );
 +
println( "Pass = " . DLLStructGetData($Struct, "pass") );
 +
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
 +
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
 +
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
 +
println( "r->pos->x = " . DLLStructGetData($Struct, "r->pos->x") );
 +
println( "r->pos->y = " . DLLStructGetData($Struct, "r->pos->y") );
 +
println( "r->size->x = " . DLLStructGetData($Struct, "r->size->x") );
 +
println( "r->size->y = " . DLLStructGetData($Struct, "r->size->y") );
 +
</syntaxhighlight>
 +
 +
An example on using the struct with char* and even char* [] array
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Create the struct
 +
my $Struct = DLLStructCreate( // Of course @"" makes producing the struct almost identical to C/C++
 +
@"
 +
int i;
 +
char* name;
 +
char* pass;
 +
char* id[3];
 +
int j;
 +
");
 +
 +
// Write the data
 +
DLLStructSetData($Struct, "i", 100);
 +
DLLStructSetData($Struct, "j", 200);
 +
DLLStructSetData($Struct, "name", "Testy");
 +
DLLStructSetData($Struct, "pass", "Another Testy");
 +
DLLStructSetData($Struct, "id", "This is ID 0", 0);
 +
DLLStructSetData($Struct, "id", "This is ID 1", 1);
 +
DLLStructSetData($Struct, "id", "This is ID 2", 2);
 +
 +
// Print the data
 +
println( "I = " . DLLStructGetData($Struct, "i") );
 +
println( "J = " . DLLStructGetData($Struct, "j") );
 +
println( "Name = " . DLLStructGetData($Struct, "name") );
 +
println( "Pass = " . DLLStructGetData($Struct, "pass") );
 +
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
 +
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
 +
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
 +
</syntaxhighlight>
 +
 +
Another example
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
Line 118: Line 313:
  
 
// Call "GetCursorPos" API and send the struct to it using the "t" param
 
// Call "GetCursorPos" API and send the struct to it using the "t" param
$ret = DLLCall("", "GetCursorPos", "Int32", "t", $a);
+
$ret = DLLCall("User32.dll", "GetCursorPos", "Int32", "t", "Ansi", $a);
  
 
if($ret)
 
if($ret)
Line 148: Line 343:
 
   
 
   
 
// Call a few apis
 
// Call a few apis
DLLCall("", "wsprintf", "", "tpii", DLLStructGetPtr($a, "x"), "Number is '%d' in hex '%x'", 100, 200);
+
DLLCall("user32.dll", "wsprintf", "", "tpii", "Ansi", DLLStructGetPtr($a, "x"), "Number is '%d' in hex '%x'", 100, 200);
DLLCall("", "wsprintf", "", "tpii", DLLStructGetPtr($a, "y"), "Number is '%d' in hex '%x'", 1337, 4242);
+
DLLCall("user32.dll", "wsprintf", "", "tpii", "Ansi", DLLStructGetPtr($a, "y"), "Number is '%d' in hex '%x'", 1337, 4242);
DLLCall("", "wsprintf", "", "tpp", DLLStructGetPtr($a, "z"), "STR '%s'", DLLStructGetData($a, "x"));
+
DLLCall("user32.dll", "wsprintf", "", "tpp", "Ansi", DLLStructGetPtr($a, "z"), "STR '%s'", DLLStructGetData($a, "x"));
 
// This time lets use lstrcat to append text to our strings
 
// This time lets use lstrcat to append text to our strings
DLLCall("", "lstrcat", "", "tp", DLLStructGetPtr($a, "z"), " | Added to string");
+
DLLCall("kernel32.dll", "lstrcat", "", "tp", "Ansi", DLLStructGetPtr($a, "z"), " | Added to string");
DLLCall("", "lstrcat", "", "tp", DLLStructGetPtr($a, "z"), "; Also added...");
+
DLLCall("kernel32.dll", "lstrcat", "", "tp", "Ansi", DLLStructGetPtr($a, "z"), "; Also added...");
 
   
 
   
 
// Print it
 
// Print it
Line 159: Line 354:
 
println(  DLLStructGetData($a, "y")  );
 
println(  DLLStructGetData($a, "y")  );
 
println(  DLLStructGetData($a, "z")  );
 
println(  DLLStructGetData($a, "z")  );
println(  "Length of X is: " . DLLCall("", "lstrlen", "Int32", "t", DLLStructGetPtr($a, "x"))  );
+
println(  "Length of X is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "x"))  );
println(  "Length of Y is: " . DLLCall("", "lstrlen", "Int32", "t", DLLStructGetPtr($a, "y"))  );
+
println(  "Length of Y is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "y"))  );
println(  "Length of Z is: " . DLLCall("", "lstrlen", "Int32", "t", DLLStructGetPtr($a, "z"))  );
+
println(  "Length of Z is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "z"))  );
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Yet Another DLLStruct example
+
A very large DLLCall + DLLStruct example using C function sprintf :
 
+
This time 2 ToolTips just around the screen randomly
+
 
+
<syntaxhighlight lang="sputnik">
+
// Spawn 2 tooltips
+
$a = ToolTip("Hello World!!!!");
+
$b = ToolTip("Hello World!!!! FROM ME TOO!!!");
+
 
+
// Create a struct to handle a GetWindowRect api call
+
$Rect = DLLStructCreate("int left; int top; int right; int bottom");
+
 
+
// Infinite loop
+
while(true)
+
{
+
// Move the first tooltip
+
DLLCall("", "GetWindowRect", "", "tt", $a, $Rect);
+
$Width = DLLStructGetData($Rect, "right") - DLLStructGetData($Rect, "left");
+
$Height = DLLStructGetData($Rect, "bottom") - DLLStructGetData($Rect, "top");
+
$NewX = Random(1, @DesktopWidth);
+
$NewY = Random(1, @DesktopHeight);
+
DLLCall("", "MoveWindow", "", "tiiiii", $a, $NewX, $NewY, $Width, $Height, 1);
+
+
// Move the first second
+
DLLCall("", "GetWindowRect", "", "tt", $b, $Rect);
+
$Width = DLLStructGetData($Rect, "right") - DLLStructGetData($Rect, "left");
+
$Height = DLLStructGetData($Rect, "bottom") - DLLStructGetData($Rect, "top");
+
$NewX = Random(1, @DesktopWidth);
+
$NewY = Random(1, @DesktopHeight);
+
DLLCall("", "MoveWindow", "", "tiiiii", $b, $NewX, $NewY, $Width, $Height, 1);
+
+
// Sleep a little
+
sleep(500);
+
}
+
</syntaxhighlight>
+
 
+
A very large DLLCall + DLLStruct example :
+
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
 
$myString = WSPrintf('Testing "%c%c%c" %d | %u hehe %d....%s %f', 'A', 'B', 'B', 12, 131, 200, "omg", 133.77);
 
$myString = WSPrintf('Testing "%c%c%c" %d | %u hehe %d....%s %f', 'A', 'B', 'B', 12, 131, 200, "omg", 133.77);
 
println($myString);
 
println($myString);
 
+
 
// Use the sprintf from msvcrt as an example for DLLCall
 
// Use the sprintf from msvcrt as an example for DLLCall
 
// Havent added uint64/int64 support yet
 
// Havent added uint64/int64 support yet
Line 211: Line 370:
 
// but that wouldnt be using dll then would it?
 
// but that wouldnt be using dll then would it?
 
// Also this demonstrates the Eval() function to dynamically create Sputnik code
 
// Also this demonstrates the Eval() function to dynamically create Sputnik code
 +
[Args("true")] // Allow the @args variable to be made (we will use it)
 
Function WSPrintf( $Format )
 
Function WSPrintf( $Format )
 
{
 
{
Line 227: Line 387:
 
case '%':
 
case '%':
 
{
 
{
if($LastC == "\\") break;
+
if($LastC == "\\")
 +
break;
 
$i++;
 
$i++;
 
if($i >= $Len)
 
if($i >= $Len)
 
{
 
{
throw("Format string is invalid");
+
throw new exception("Format string is invalid");
 
return 0;
 
return 0;
 
}
 
}
Line 252: Line 413:
 
$EstMaxLen += 2;
 
$EstMaxLen += 2;
 
$DLLParDef .= "b";
 
$DLLParDef .= "b";
$DLLPars .= ", (Char)@args[$j]";
+
$DLLPars .= ', (Char)@args[' . $j . ']';
 
$j++;
 
$j++;
 
$b64Bit = false;
 
$b64Bit = false;
Line 266: Line 427:
 
$EstMaxLen += 20;
 
$EstMaxLen += 20;
 
$DLLParDef .= "l";
 
$DLLParDef .= "l";
$DLLPars .= ", (Int64)@args[$j]";
+
$DLLPars .= ', (Int64)@args[' . $j . ']';
 
}
 
}
 
else
 
else
Line 272: Line 433:
 
$EstMaxLen += 11;
 
$EstMaxLen += 11;
 
$DLLParDef .= "i";
 
$DLLParDef .= "i";
$DLLPars .= ", (Int32)@args[$j]";
+
$DLLPars .= ', (Int32)@args[' . $j . ']';
 
}
 
}
 
$j++;
 
$j++;
Line 287: Line 448:
 
$EstMaxLen += 20;
 
$EstMaxLen += 20;
 
$DLLParDef .= "L";
 
$DLLParDef .= "L";
$DLLPars .= ", (UInt64)@args[$j]";
+
$DLLPars .= ', (UInt64)@args[' . $j . ']';
 
}
 
}
 
else
 
else
Line 293: Line 454:
 
$EstMaxLen += 11;
 
$EstMaxLen += 11;
 
$DLLParDef .= "I";
 
$DLLParDef .= "I";
$DLLPars .= ", (UInt32)@args[$j]";
+
$DLLPars .= ', (UInt32)@args[' . $j . ']';
 
}
 
}
 
$j++;
 
$j++;
Line 306: Line 467:
 
$EstMaxLen += 20;
 
$EstMaxLen += 20;
 
$DLLParDef .= "d";
 
$DLLParDef .= "d";
$DLLPars .= ", (double)@args[$j]";
+
$DLLPars .= ', (double)@args[' . $j . ']';
 
$j++;
 
$j++;
 
$b64Bit = false;
 
$b64Bit = false;
Line 315: Line 476:
 
$EstMaxLen += StrLen(@Args[$j] + 1);
 
$EstMaxLen += StrLen(@Args[$j] + 1);
 
$DLLParDef .= "p";
 
$DLLParDef .= "p";
$DLLPars .= ", (string)@args[$j]";
+
$DLLPars .= ', (string)@args[' . $j . ']';
 
$j++;
 
$j++;
 
$b64Bit = false;
 
$b64Bit = false;
Line 322: Line 483:
 
default:
 
default:
 
{
 
{
throw("Invalid specifier '$char'");
+
throw new exception("Invalid specifier '$char'");
 
return 0;
 
return 0;
 
}
 
}
Line 331: Line 492:
 
}
 
}
 
$LastC = $char;
 
$LastC = $char;
}
+
}
 
// Create the correct size struct which will hold the newly made string
 
// Create the correct size struct which will hold the newly made string
 
// It should have been calculated to a good degree of accuracy so we
 
// It should have been calculated to a good degree of accuracy so we
Line 337: Line 498:
 
$Struct = DLLStructCreate("char buf[$EstMaxLen];");
 
$Struct = DLLStructCreate("char buf[$EstMaxLen];");
 
// Create the DLL call string
 
// Create the DLL call string
$CallString = 'DLLCall("msvcrt.dll", "sprintf", "cdecl Int32", "tp' . $DLLParDef . '", $Struct, $Format' . $DLLPars . ');';
+
$CallString = 'DLLCall("msvcrt.dll", "sprintf", "Int32", "tp' . $DLLParDef . '", "Ansi:cdecl", $Struct, $Format' . $DLLPars . ');';
 
$RetVal = Eval($CallString); // Dynamically call the dll using the string as if it was physical Sputnik code
 
$RetVal = Eval($CallString); // Dynamically call the dll using the string as if it was physical Sputnik code
 +
if(Eval($CallString) == 0)
 +
{
 +
unset($Struct); // Cleanup the Struct
 +
return 0;
 +
}
 +
$newStr = DLLStructGetData($Struct, "buf");
 +
unset($Struct); // Cleanup the Struct
 +
return $newStr;
 +
}
 +
</syntaxhighlight>
 +
 +
A very large DLLCall + DLLStruct example using C function sprintf :
 +
 +
This time we will use a cache to store the DLL imported functions in a buffer and execute it again without having to recompile it each time the function is called.
 +
 +
The way it will work is it will remember your param defs such as "ippi" if the defs are the same when you call the function again it will use the previously compiled and cached function instead of creating a new one.
 +
 +
The benefit of this is amazing speed improvement by up to 10 fold.
 +
 +
<syntaxhighlight lang="sputnik">
 +
Global $CallArray = array(); // Store imported DLL functions
 +
 +
// Print 10,000 items very rapidly
 +
my $Tick = TickCount();
 +
for(my $i = 0; $i < 10000; $i++)
 +
{
 +
$var = CSPrintf("The value is '%d'\n", $i);
 +
print("Returned: $var");
 +
}
 +
say("Final (in seconds): " . (TickCount($Tick) / 1000.0));
 +
 +
[Args("true")] // Allow the @args variable to be made (we will use it)
 +
Function CSPrintf( $Format )
 +
{
 +
$Args = array();
 +
$Len = StrLen($Format);
 +
$EstMaxLen = $Len;
 +
$LastC = '';
 +
$DLLParDef = "";
 +
$DLLPars = "";
 +
$b64Bit = false;
 +
for(my $i = 0, my $j = 1; $i < $Len; $i++)
 +
{
 +
$char = $Format[$i];
 +
switch ($char)
 +
{
 +
case '%':
 +
{
 +
if($LastC == "\\")
 +
break;
 +
$i++;
 +
if($i >= $Len)
 +
{
 +
throw new exception("Format string is invalid");
 +
return 0;
 +
}
 +
$char = $Format[$i];
 +
switch ($char)
 +
{
 +
case '%':
 +
$b64Bit = false;
 +
break;
 +
case 'l':
 +
case 'L':
 +
$b64Bit = true;
 +
break;
 +
case 'c':
 +
$EstMaxLen += 2;
 +
$DLLParDef .= "b";
 +
$DLLPars .= ', (Char)@args[' . $j . ']';
 +
$j++;
 +
$b64Bit = false;
 +
break;
 +
case 'd':
 +
case 'i':
 +
case 'o':
 +
case 'p':
 +
if($b64Bit)
 +
{
 +
$EstMaxLen += 20;
 +
$DLLParDef .= "l";
 +
$DLLPars .= ', (Int64)@args[' . $j . ']';
 +
}
 +
else
 +
{
 +
$EstMaxLen += 11;
 +
$DLLParDef .= "i";
 +
$DLLPars .= ', (Int32)@args[' . $j . ']';
 +
}
 +
$j++;
 +
$b64Bit = false;
 +
break;
 +
case 'o':
 +
case 'u':
 +
case 'x':
 +
case 'X':
 +
if($b64Bit)
 +
{
 +
$EstMaxLen += 20;
 +
$DLLParDef .= "L";
 +
$DLLPars .= ', (UInt64)@args[' . $j . ']';
 +
}
 +
else
 +
{
 +
$EstMaxLen += 11;
 +
$DLLParDef .= "I";
 +
$DLLPars .= ', (UInt32)@args[' . $j . ']';
 +
}
 +
$j++;
 +
$b64Bit = false;
 +
break;
 +
case 'f':
 +
case 'g':
 +
case 'e':
 +
case 'E':
 +
$EstMaxLen += 20;
 +
$DLLParDef .= "d";
 +
$DLLPars .= ', (double)@args[' . $j . ']';
 +
$j++;
 +
$b64Bit = false;
 +
break;
 +
case 's':
 +
$EstMaxLen += StrLen(@Args[$j] + 1);
 +
$DLLParDef .= "p";
 +
$DLLPars .= ', (string)@args[' . $j . ']';
 +
$j++;
 +
$b64Bit = false;
 +
break;
 +
default:
 +
throw new exception("Invalid specifier '$char'");
 +
return 0;
 +
break;
 +
}
 +
}
 +
break;
 +
}
 +
$LastC = $char;
 +
}
 +
// Create a unique hash that will be the same for everything that calls this function with the same definition
 +
// but allow for unique parameters to be passed of course
 +
my $Hash = 'sprintf' . Hash('p' . $DLLParDef);
 +
if((!IsKeySet($CallArray, $Hash)))
 +
{
 +
my $RandName = "sprintf_" . RandStr(10); // Generate name for new function (must be unique)
 +
$CallArray[$Hash] = $RandName; // Insert the function name into array
 +
// Create the function by importing it form the DLL
 +
DLLImport("msvcrt.dll", "sprintf:$RandName", "Int32", "tp$DLLParDef", "Ansi:cdecl");
 +
 +
}
 +
// Get function name from array so we can call it
 +
my $FuncName = $CallArray[$Hash];
 +
// Create the correct size struct which will hold the newly made string
 +
// It should have been calculated to a good degree of accuracy so we
 +
// Dont really expect any buffer overflows here
 +
$Struct = DLLStructCreate("char buf[$EstMaxLen];");
 +
// Build a string to execute as Sputnik code
 +
$CallString = $FuncName . '($Struct, $Format' . $DLLPars . ');';
 +
// Call it
 
if(Eval($CallString) == 0)
 
if(Eval($CallString) == 0)
 
{
 
{

Latest revision as of 07:12, 22 September 2015

DLLStructCreate( <def string> )

Contents

Description

Creates a C/C++ style structure to be used with DLLCall

Parameters

def string

A string representing the structure to create (See Remarks).

Return Value

Success - Returns the DLLStruct.

Failure - Returns null and most likely throws exception.

Remarks

To delete a DLLStruct you must unset it example:

unset( $dllStruct );

Note - If you do not unset the DLLStruct and instead just change the value of the variable then the garbage collector will deal with the DLLStruct *evenutally* but that could be today, tomorrow you never know so always unset() the struct when your finished with it.

DEFS

Each data type must be separated by a semi-colon ';'.

Create arrays by adding '[size]' after the data type.

DllStructCreate("int;char[128]").

An elementname can be added similar to a C-style declaration DllStructCreate("int n;char buffer[128]").

If the definition begins with "union " you will create the struct the same as a C union type example: $a = DllStructCreate("union int a;float b");

def string settings

[TYPE]		[WHAT IT RETURNS WITH DLLSTRUCTGETDATA]		[WHAT IS IT IN C++]
ubyte		unsigned 8 bit integer				unsigned char
byte		signed 8 bit integer				char
char		a single ASCII character			char
wchar		a single UNICODE character			wchar
short		signed 16 bit integer				short
int16		signed 16 bit integer				short
int		signed 32 bit integer				int
int32		signed 32 bit integer				int
int64		signed 64 bit integer				__int64
long		signed 64 bit integer				__int64
ushort		signed unsigned 16 bit integer			unsigned short
uint16		signed unsigned 16 bit integer			unsigned short
uint		signed unsigned 32 bit integer			unsigned int
uint32		signed unsigned 32 bit integer			unsigned int
uint64		signed unsigned 64 bit integer			unsigned __int64
ulong		signed unsigned 64 bit integer			unsigned __int64
float		signed 32 bit floating point			float
double		signed 64 bit floating point			double
char*		a pointer to an ASCII char array (string)	char*
wchar*		a pointer to an UNICODE char array (string)	wchar*
ptr		a pointer					void*
uptr		a unsigned pointer				unsigned void*

Note - There is no *string* type instead;
You must create an array of chars example "char mystring[500]"
then you can use it like a string.

Or if you wish to use UNICODE its "wchar mystring[500]"

Warning - Remember to free() etc when your working with allocated memory and pointers.

Example

Example of placing DLLStructs inside DLLStructs

// Define a POINT struc to include in our main struct
DLLStructCreateDef("POINT", "int x;int y");
 
// Create the struct
my $Struct = DLLStructCreate(	// Of course @"" makes producing the struct almost identical to C/C++
				@"
				int i;
				char* name;
				char* pass;
				char* id[3];
				POINT loc;
				POINT lastLoc;
				int j;
				");
 
// Write the data
DLLStructSetData($Struct, "i", 100);
DLLStructSetData($Struct, "j", 200);
DLLStructSetData($Struct, "name", "Testy");
DLLStructSetData($Struct, "pass", "Another Testy");
DLLStructSetData($Struct, "id", "This is ID 0", 0);
DLLStructSetData($Struct, "id", "This is ID 1", 1);
DLLStructSetData($Struct, "id", "This is ID 2", 2);
DLLStructSetData($Struct, "loc->x", 50);
DLLStructSetData($Struct, "loc->y", 70);
DLLStructSetData($Struct, "lastLoc->x", 11);
DLLStructSetData($Struct, "lastLoc->y", 22);
 
// Print the data
println( "I = " . DLLStructGetData($Struct, "i") );
println( "J = " . DLLStructGetData($Struct, "j") );
println( "Name = " . DLLStructGetData($Struct, "name") );
println( "Pass = " . DLLStructGetData($Struct, "pass") );
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
println( "Loc->x = " . DLLStructGetData($Struct, "loc->x") );
println( "Loc->y = " . DLLStructGetData($Struct, "loc->y") );
println( "lastLoc->x = " . DLLStructGetData($Struct, "lastLoc->x") );
println( "lastLoc->y = " . DLLStructGetData($Struct, "lastLoc->y") );

Same as above but with more structs inside structs

// Define a SIZE struc to include in the POINT struct
DLLStructCreateDef("SIZE", "int width;int height");
// Define a POINT struc to include in our main struct
DLLStructCreateDef("POINT", "int x;int y;SIZE s");
 
// Create the struct
my $Struct = DLLStructCreate(	// Of course @"" makes producing the struct almost identical to C/C++
				@"
				int i;
				char* name;
				char* pass;
				char* id[3];
				POINT loc;
				POINT lastLoc;
				int j;
				");
 
// Write the data
DLLStructSetData($Struct, "i", 100);
DLLStructSetData($Struct, "j", 200);
DLLStructSetData($Struct, "name", "Testy");
DLLStructSetData($Struct, "pass", "Another Testy");
DLLStructSetData($Struct, "id", "This is ID 0", 0);
DLLStructSetData($Struct, "id", "This is ID 1", 1);
DLLStructSetData($Struct, "id", "This is ID 2", 2);
DLLStructSetData($Struct, "loc->x", 50);
DLLStructSetData($Struct, "loc->y", 70);
DLLStructSetData($Struct, "loc->s->width", 800);
DLLStructSetData($Struct, "loc->s->height", 600);
DLLStructSetData($Struct, "lastLoc->x", 11);
DLLStructSetData($Struct, "lastLoc->y", 22);
DLLStructSetData($Struct, "lastLoc->s->width", 640);
DLLStructSetData($Struct, "lastLoc->s->height", 480);
 
// Print the data
println( "I = " . DLLStructGetData($Struct, "i") );
println( "J = " . DLLStructGetData($Struct, "j") );
println( "Name = " . DLLStructGetData($Struct, "name") );
println( "Pass = " . DLLStructGetData($Struct, "pass") );
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
println( "Loc->x = " . DLLStructGetData($Struct, "loc->x") );
println( "Loc->y = " . DLLStructGetData($Struct, "loc->y") );
println( "Loc->s->width = " . DLLStructGetData($Struct, "Loc->s->width") );
println( "Loc->s->height = " . DLLStructGetData($Struct, "Loc->s->height") );
println( "lastLoc->x = " . DLLStructGetData($Struct, "lastLoc->x") );
println( "lastLoc->y = " . DLLStructGetData($Struct, "lastLoc->y") );
println( "lastLoc->s->width = " . DLLStructGetData($Struct, "lastLoc->s->width") );
println( "lastLoc->s->height = " . DLLStructGetData($Struct, "lastLoc->s->height") );

Example of placing DLLStructs inside DLLStructs inside DLLStructs and so on

// Create a POINT struct
DLLStructCreateDef("POINT", "int x;int y");
 
// Create a RECT struct that contains POINT structs
DLLStructCreateDef("RECT", "POINT pos;POINT size");
 
// Create the main struct that will incluyde a RECT struct
my $Struct = DLLStructCreate(	// Of course @"" makes producing the struct almost identical to C/C++
				@"
				int i;
				char* name;
				char* pass;
				char* id[3];
				RECT r;
				int j;
				");
 
// Write the data
DLLStructSetData($Struct, "i", 100);
DLLStructSetData($Struct, "j", 200);
DLLStructSetData($Struct, "name", "Testy");
DLLStructSetData($Struct, "pass", "Another Testy");
DLLStructSetData($Struct, "id", "This is ID 0", 0);
DLLStructSetData($Struct, "id", "This is ID 1", 1);
DLLStructSetData($Struct, "id", "This is ID 2", 2);
DLLStructSetData($Struct, "r->pos->x", 50);
DLLStructSetData($Struct, "r->pos->y", 70);
DLLStructSetData($Struct, "r->size->x", 11);
DLLStructSetData($Struct, "r->size->y", 22);
 
// Print the data
println( "I = " . DLLStructGetData($Struct, "i") );
println( "J = " . DLLStructGetData($Struct, "j") );
println( "Name = " . DLLStructGetData($Struct, "name") );
println( "Pass = " . DLLStructGetData($Struct, "pass") );
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );
println( "r->pos->x = " . DLLStructGetData($Struct, "r->pos->x") );
println( "r->pos->y = " . DLLStructGetData($Struct, "r->pos->y") );
println( "r->size->x = " . DLLStructGetData($Struct, "r->size->x") );
println( "r->size->y = " . DLLStructGetData($Struct, "r->size->y") );

An example on using the struct with char* and even char* [] array

// Create the struct
my $Struct = DLLStructCreate(	// Of course @"" makes producing the struct almost identical to C/C++
				@"
				int i;
				char* name;
				char* pass;
				char* id[3];
				int j;
				");
 
// Write the data
DLLStructSetData($Struct, "i", 100);
DLLStructSetData($Struct, "j", 200);
DLLStructSetData($Struct, "name", "Testy");
DLLStructSetData($Struct, "pass", "Another Testy");
DLLStructSetData($Struct, "id", "This is ID 0", 0);
DLLStructSetData($Struct, "id", "This is ID 1", 1);
DLLStructSetData($Struct, "id", "This is ID 2", 2);
 
// Print the data
println( "I = " . DLLStructGetData($Struct, "i") );
println( "J = " . DLLStructGetData($Struct, "j") );
println( "Name = " . DLLStructGetData($Struct, "name") );
println( "Pass = " . DLLStructGetData($Struct, "pass") );
println( "ID 0 = " . DLLStructGetData($Struct, "id", 0) );
println( "ID 1 = " . DLLStructGetData($Struct, "id", 1) );
println( "ID 2 = " . DLLStructGetData($Struct, "id", 2) );

Another example

/*=========================================================
   Create the struct
   struct {
       int             var1;
       unsigned char   var2;
       unsigned int    var3;
       char            var4[128];
   }
=========================================================*/
 
$str		= "int var1;ubyte var2;uint var3;char var4[128]";
$a			= DllStructCreate($str);
if ( !$a )
{
	MsgBox("Error in DllStructCreate");
	exit();
}
 
/*=========================================================
	Set data in the struct
	struct.var1	= -1;
	struct.var2	= 255;
	struct.var3	= 777;
	strcpy(struct.var4,"Hello");
	struct.var4[0]	= 'h';
=========================================================*/
DllStructSetData($a,"var1",-1);
DllStructSetData($a,"var2",255);
DllStructSetData($a,"var3",777);
DllStructSetData($a,"var4","Hello");
DllStructSetData($a,"var4","G",0);
 
/*=========================================================
	Display info in the struct
;=========================================================*/
MsgBox("Struct Size: " . DllStructGetSize($a) . @CRLF .
		"Struct pointer: " . DllStructGetPtr($a) . @CRLF .
		"Data:" . @CRLF .
		DllStructGetData($a,"var1") . @CRLF .
		DllStructGetData($a,"var2") . @CRLF .
		DllStructGetData($a,"var3") . @CRLF .
		DllStructGetData($a,"var4"),
		"DllStruct");

Heres an example of using DLLStruct

// Create the struct
$a = DLLStructCreate("int x; int y");
// Print its info just for sake of it
println( "DLLStruct info: " . $a );
 
// Call "GetCursorPos" API and send the struct to it using the "t" param
$ret = DLLCall("User32.dll", "GetCursorPos", "Int32", "t", "Ansi", $a);
 
if($ret)
{
	// Get the X and Y from the struct
	$x = DLLStructGetData($a, "x");
	$y = DLLStructGetData($a, "y");
	// Print it
	println("X '$x' Y '$y'");
}
else
{
	println("GetCursorPos() api failed...");
}

Another DLLStruct example

// Create the struct
$a = DLLStructCreate("char x[500]; char y[500]; char z[500]");
// Print its info just for sake of it
println( "DLLStruct info: " . $a );
 
// Zero term the strings just to be sure
DLLStructSetData($a, "x", "\0", 0);
DLLStructSetData($a, "y", "\0", 0);
DLLStructSetData($a, "z", "\0", 0);
 
// Call a few apis
DLLCall("user32.dll", "wsprintf", "", "tpii", "Ansi", DLLStructGetPtr($a, "x"), "Number is '%d' in hex '%x'", 100, 200);
DLLCall("user32.dll", "wsprintf", "", "tpii", "Ansi", DLLStructGetPtr($a, "y"), "Number is '%d' in hex '%x'", 1337, 4242);
DLLCall("user32.dll", "wsprintf", "", "tpp", "Ansi", DLLStructGetPtr($a, "z"), "STR '%s'", DLLStructGetData($a, "x"));
// This time lets use lstrcat to append text to our strings
DLLCall("kernel32.dll", "lstrcat", "", "tp", "Ansi", DLLStructGetPtr($a, "z"), " | Added to string");
DLLCall("kernel32.dll", "lstrcat", "", "tp", "Ansi", DLLStructGetPtr($a, "z"), "; Also added...");
 
// Print it
println(   DLLStructGetData($a, "x")   );
println(   DLLStructGetData($a, "y")   );
println(   DLLStructGetData($a, "z")   );
println(   "Length of X is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "x"))   );
println(   "Length of Y is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "y"))   );
println(   "Length of Z is: " . DLLCall("kernel32.dll", "lstrlen", "Int32", "t", "Ansi", DLLStructGetPtr($a, "z"))   );

A very large DLLCall + DLLStruct example using C function sprintf :

$myString = WSPrintf('Testing "%c%c%c" %d | %u hehe %d....%s %f', 'A', 'B', 'B', 12, 131, 200, "omg", 133.77);
println($myString);
 
// Use the sprintf from msvcrt as an example for DLLCall
// Havent added uint64/int64 support yet
// Of course we could have just built the new string as we found params
// but that wouldnt be using dll then would it?
// Also this demonstrates the Eval() function to dynamically create Sputnik code
[Args("true")] // Allow the @args variable to be made (we will use it)
Function WSPrintf( $Format )
{
	$Args = array();
	$Len = StrLen($Format);
	$EstMaxLen = $Len;
	$LastC = '';
	$DLLParDef = "";
	$DLLPars = "";
	$b64Bit = false;
	for(my $i = 0, my $j = 1; $i < $Len; $i++)
	{
		$char = $Format[$i];
		switch ($char)
		{
			case '%':
			{
				if($LastC == "\\")
					break;
				$i++;
				if($i >= $Len)
				{
					throw new exception("Format string is invalid");
					return 0;
				}
				$char = $Format[$i];
				switch ($char)
				{
					case '%':
						{
							$b64Bit = false;
						}
						break;
					case 'l':
					case 'L':
						{
							$b64Bit = true;							
						}
						break;
					case 'c':
						{
							$EstMaxLen += 2;
							$DLLParDef .= "b";
							$DLLPars .= ', (Char)@args[' . $j . ']';
							$j++;
							$b64Bit = false;
						}
						break;
					case 'd':
					case 'i':
					case 'o':
					case 'p':
						{
							if($b64Bit)
							{
								$EstMaxLen += 20;
								$DLLParDef .= "l";
								$DLLPars .= ', (Int64)@args[' . $j . ']';
							}
							else
							{
								$EstMaxLen += 11;
								$DLLParDef .= "i";
								$DLLPars .= ', (Int32)@args[' . $j . ']';
							}
							$j++;
							$b64Bit = false;
						}
						break;
					case 'o':
					case 'u':
					case 'x':
					case 'X':
						{
							if($b64Bit)
							{
								$EstMaxLen += 20;
								$DLLParDef .= "L";
								$DLLPars .= ', (UInt64)@args[' . $j . ']';
							}
							else
							{
								$EstMaxLen += 11;
								$DLLParDef .= "I";
								$DLLPars .= ', (UInt32)@args[' . $j . ']';
							}
							$j++;
							$b64Bit = false;
						}
						break;
					case 'f':
					case 'g':
					case 'e':
					case 'E':
						{
							$EstMaxLen += 20;
							$DLLParDef .= "d";
							$DLLPars .= ', (double)@args[' . $j . ']';
							$j++;
							$b64Bit = false;
						}
						break;
					case 's':
						{
							$EstMaxLen += StrLen(@Args[$j] + 1);
							$DLLParDef .= "p";
							$DLLPars .= ', (string)@args[' . $j . ']';
							$j++;
							$b64Bit = false;
						}
						break;
					default:
						{
							throw new exception("Invalid specifier '$char'");
							return 0;
						}
					break;
				}
			}
			break;
		}
		$LastC = $char;
	}
	// Create the correct size struct which will hold the newly made string
	// It should have been calculated to a good degree of accuracy so we
	// Dont really expect any buffer overflows here
	$Struct = DLLStructCreate("char buf[$EstMaxLen];");
	// Create the DLL call string
	$CallString = 'DLLCall("msvcrt.dll", "sprintf", "Int32", "tp' . $DLLParDef . '", "Ansi:cdecl", $Struct, $Format' . $DLLPars . ');';
	$RetVal = Eval($CallString); // Dynamically call the dll using the string as if it was physical Sputnik code
	if(Eval($CallString) == 0)
	{
		unset($Struct); // Cleanup the Struct
		return 0;
	}
	$newStr = DLLStructGetData($Struct, "buf");
	unset($Struct); // Cleanup the Struct
	return $newStr;
}

A very large DLLCall + DLLStruct example using C function sprintf :

This time we will use a cache to store the DLL imported functions in a buffer and execute it again without having to recompile it each time the function is called.

The way it will work is it will remember your param defs such as "ippi" if the defs are the same when you call the function again it will use the previously compiled and cached function instead of creating a new one.

The benefit of this is amazing speed improvement by up to 10 fold.

Global $CallArray = array(); // Store imported DLL functions
 
// Print 10,000 items very rapidly
my $Tick = TickCount();
for(my $i = 0; $i < 10000; $i++)
{
	$var = CSPrintf("The value is '%d'\n", $i);
	print("Returned: $var");
}
say("Final (in seconds): " . (TickCount($Tick) / 1000.0));
 
[Args("true")] // Allow the @args variable to be made (we will use it)
Function CSPrintf( $Format )
{
	$Args = array();
	$Len = StrLen($Format);
	$EstMaxLen = $Len;
	$LastC = '';
	$DLLParDef = "";
	$DLLPars = "";
	$b64Bit = false;
	for(my $i = 0, my $j = 1; $i < $Len; $i++)
	{
		$char = $Format[$i];
		switch ($char)
		{
			case '%':
			{
				if($LastC == "\\")
					break;
				$i++;
				if($i >= $Len)
				{
					throw new exception("Format string is invalid");
					return 0;
				}
				$char = $Format[$i];
				switch ($char)
				{
					case '%':
						$b64Bit = false;
						break;
					case 'l':
					case 'L':
						$b64Bit = true;	
						break;
					case 'c':
						$EstMaxLen += 2;
						$DLLParDef .= "b";
						$DLLPars .= ', (Char)@args[' . $j . ']';
						$j++;
						$b64Bit = false;
						break;
					case 'd':
					case 'i':
					case 'o':
					case 'p':
						if($b64Bit)
						{
							$EstMaxLen += 20;
							$DLLParDef .= "l";
							$DLLPars .= ', (Int64)@args[' . $j . ']';
						}
						else
						{
							$EstMaxLen += 11;
							$DLLParDef .= "i";
							$DLLPars .= ', (Int32)@args[' . $j . ']';
						}
						$j++;
						$b64Bit = false;
						break;
					case 'o':
					case 'u':
					case 'x':
					case 'X':
						if($b64Bit)
						{
							$EstMaxLen += 20;
							$DLLParDef .= "L";
							$DLLPars .= ', (UInt64)@args[' . $j . ']';
						}
						else
						{
							$EstMaxLen += 11;
							$DLLParDef .= "I";
							$DLLPars .= ', (UInt32)@args[' . $j . ']';
						}
						$j++;
						$b64Bit = false;
						break;
					case 'f':
					case 'g':
					case 'e':
					case 'E':
						$EstMaxLen += 20;
						$DLLParDef .= "d";
						$DLLPars .= ', (double)@args[' . $j . ']';
						$j++;
						$b64Bit = false;
						break;
					case 's':
						$EstMaxLen += StrLen(@Args[$j] + 1);
						$DLLParDef .= "p";
						$DLLPars .= ', (string)@args[' . $j . ']';
						$j++;
						$b64Bit = false;
						break;
					default:
						throw new exception("Invalid specifier '$char'");
						return 0;
					break;
				}
			}
			break;
		}
		$LastC = $char;
	}
	// Create a unique hash that will be the same for everything that calls this function with the same definition
	// but allow for unique parameters to be passed of course
	my $Hash = 'sprintf' . Hash('p' . $DLLParDef);
	if((!IsKeySet($CallArray, $Hash)))
	{
		my $RandName = "sprintf_" . RandStr(10); // Generate name for new function (must be unique)
		$CallArray[$Hash] = $RandName; // Insert the function name into array
		// Create the function by importing it form the DLL
		DLLImport("msvcrt.dll", "sprintf:$RandName", "Int32", "tp$DLLParDef", "Ansi:cdecl");
 
	}
	// Get function name from array so we can call it
	my $FuncName = $CallArray[$Hash];
	// Create the correct size struct which will hold the newly made string
	// It should have been calculated to a good degree of accuracy so we
	// Dont really expect any buffer overflows here
	$Struct = DLLStructCreate("char buf[$EstMaxLen];");
	// Build a string to execute as Sputnik code
	$CallString = $FuncName . '($Struct, $Format' . $DLLPars . ');';
	// Call it
	if(Eval($CallString) == 0)
	{
		unset($Struct); // Cleanup the Struct
		return 0;
	}
	$newStr = DLLStructGetData($Struct, "buf");
	unset($Struct); // Cleanup the Struct
	return $newStr;
}
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox