Jump to content
francoiste

UINT - unsigned integer

Recommended Posts

francoiste

i have not found any built-in methods that allow to read values as unsigned integer.

all of the following return negative "-393216". but when read as unsigned the value actually is positive "4294574080".

#include <AutoItConstants.au3>

ConsoleWrite("value: " & 0xFFFA0000 & @CRLF)

ConsoleWrite("value: " & Int(0xFFFA0000, $NUMBER_AUTO) & @CRLF)
ConsoleWrite("value: " & Int(0xFFFA0000, $NUMBER_32BIT) & @CRLF)
ConsoleWrite("value: " & Int(0xFFFA0000, $NUMBER_64BIT) & @CRLF)

ConsoleWrite("value: " & Int("0xFFFA0000", $NUMBER_AUTO) & @CRLF)
ConsoleWrite("value: " & Int("0xFFFA0000", $NUMBER_32BIT) & @CRLF)
ConsoleWrite("value: " & Int("0xFFFA0000", $NUMBER_64BIT) & @CRLF)

ConsoleWrite("value: " & Ptr(0xFFFA0000) & @CRLF)
ConsoleWrite("value: " & Ptr("0xFFFA0000") & @CRLF)

 

so as workaround i'm currently doing:

  • convert the value to string (e.g. a pointer value i'm interested in)
  • then do some custom parsing of that hex value to calculate the decimal value myself

with the decimal value i can then do some arithmetic comparison and pointer logic.

is there no smarter support for UINT and UINT_PTR?

PS:
related trac ticket: https://www.autoitscript.com/trac/autoit/ticket/3245

Share this post


Link to post
Share on other sites
Danyfirex

You can make your own function.

 

#include <AutoItConstants.au3>

ConsoleWrite("value: " & 0xFFFA0000 & @CRLF)
ConsoleWrite("value: " & Int(0xFFFA0000, $NUMBER_AUTO) & @CRLF)
ConsoleWrite("value: " & _UINT(0xFFFA0000) & @CRLF)

Func _UINT($INT)
    Local $tUINT = DllStructCreate("UINT")
    DllStructSetData($tUINT, 1, $INT)
    Return DllStructGetData($tUINT, 1)
EndFunc   ;==>_UINT

Saludos

Share this post


Link to post
Share on other sites
jchd

AutoIt integers are signed (pointers are of course unsigned by definition), so have you tried:

#include <AutoItConstants.au3>

ConsoleWrite("value: " & 0x0FFFA0000 & @CRLF)

ConsoleWrite("value: " & Int(0x0FFFA0000, $NUMBER_AUTO) & @CRLF)
ConsoleWrite("value: " & Int(0x0FFFA0000, $NUMBER_32BIT) & @CRLF)
ConsoleWrite("value: " & Int(0x0FFFA0000, $NUMBER_64BIT) & @CRLF)

ConsoleWrite("value: " & Int("0x0FFFA0000", $NUMBER_AUTO) & @CRLF)
ConsoleWrite("value: " & Int("0x0FFFA0000", $NUMBER_32BIT) & @CRLF)
ConsoleWrite("value: " & Int("0x0FFFA0000", $NUMBER_64BIT) & @CRLF)

ConsoleWrite("value: " & Ptr(0xFFFA0000) & @CRLF)
ConsoleWrite("value: " & Ptr("0xFFFA0000") & @CRLF)

 


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
francoiste

let me give another example (that more closely matches the actual problem i am facing):

#include <Memory.au3>
#include <AutoItConstants.au3>
#include <StringConstants.au3>

Local $iAddress = _MemVirtualAlloc(0, 1024, $MEM_RESERVE + $MEM_TOP_DOWN, $PAGE_READWRITE)
ConsoleWrite("allocation address: " & $iAddress & " - VarType: " & VarGetType($iAddress) & @CRLF)

Local $iNumericAddress = Int ($iAddress)
ConsoleWrite("numeric address: " & $iNumericAddress & @CRLF)

If $iNumericAddress < 0 Then
    ConsoleWrite("ERROR: signed / unsigned mismatch - NEGATIVE memory address!" & @CRLF)
EndIf

If $iNumericAddress > 2^16 Then
    ConsoleWrite("do something ..." & @CRLF)
EndIf


;# where "_MemVirtualAlloc" is defined in the standard included file "Memory.au3" as follows:
;~ Func _MemVirtualAlloc($pAddress, $iSize, $iAllocation, $iProtect)
;~  Local $aResult = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", $pAddress, "ulong_ptr", $iSize, "dword", $iAllocation, "dword", $iProtect)

;~  If @error Then Return SetError(@error, @extended, 0)
;~  Return $aResult[0]
;~ EndFunc

there seems to bug in the int conversion "Int()":

the "VarGetType()" states that we are dealing with a "Ptr". but after the int conversion it carries a negative value.

---

there is another side-observation:

the standard "_MemVirtualAlloc()" is defined to be returning "ptr".

but actually the return type is of "uint_ptr". so i try my custom implementation:

Func CustomVirtualAlloc($pAddress, $iSize, $iAllocation, $iProtect)
    Local $aResult = DllCall("kernel32.dll", "uint_ptr", "VirtualAlloc", "uint_ptr", $pAddress, "ulong_ptr", $iSize, "dword", $iAllocation, "dword", $iProtect)

    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc

but now "VarGetType()" incorrectly states it was of type "Int32". in turn the int conversion will also give wrong results in this case.

it seems as if AutoIt wasn't fully aware of the datatype "uint_ptr", at all?

the UINT_PTR is being mentioned in the documentation, though:

DllCall(...)

 

Edited by francoiste

Share this post


Link to post
Share on other sites
jchd

A pointer is a pointer, not a signed integer. If you convert a pointer to an integer you're violating it's semantic, period. Don't do that and you'll be fine.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
francoiste
31 minutes ago, jchd said:

A pointer is a pointer, not a signed integer.

If you convert a pointer to an integer you're violating it's semantic, period.

Don't do that and you'll be fine.

thanks for your reply.
it seems you are having a complete different understanding of the context, though.


i'm doing a lot with VirtualAlloc / VirtualAllocEx / VirtualQuery / VirtualQueryEx.
and for those i need a numeric representation of the location in the virtual address space of the process.
period.

in post #4 i have added a more meaningful example.

i (again) classify the current behaviour as "bug":
the int conversion is giving wrong results.

as stated earlier: i'm currently using a workaround to do custom hex parsing of that address (interpreting it as "unsigned").
but a permanent fix would be desirable.

Share this post


Link to post
Share on other sites
jchd

Again, don't convert a pointer to an signed integer!

3 hours ago, francoiste said:

i need a numeric representation of the location in the virtual address space of the process.

A pointer is a numeric representation of an address, no need to convert it. If you feel the need to compare its magnitude to a given numerical limit, make the limit a pointer.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
francoiste

thanks for the advice on what to do and what better not to do.

facts are: i do need the decimal value of that pointer (i.e. the address).
my examples given above are limited to some simple repro code, only.
i have a couple of other scenarios that are more complex.

now let's get back to where i think a bug exists in AutoIt.

as with many other programming languages you can do various conversions. for example:

$test = String(99)
$test = Int("99")
$test = Hex(99)
$test = Ptr(99)
$test = Dec("0x63")

now, as you can see in the following repro code it gives wrong results for pointers greater than 2^31:

ConsoleWrite("1st round: 2^16 -1" & @CRLF)
Local $myInt = 2 ^ 16 - 1
Local $myPtr = Ptr($myInt)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite("Ptr: " & $myPtr & @CRLF)
$myInt = Int($myPtr)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("2nd round: 2^24 -1" & @CRLF)
$myInt = 2 ^ 24 - 1
$myPtr = Ptr($myInt)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite("Ptr: " & $myPtr & @CRLF)
$myInt = Int($myPtr)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("3rd round: 2^31 -1" & @CRLF)
$myInt = 2 ^ 31 - 1
$myPtr = Ptr($myInt)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite("Ptr: " & $myPtr & @CRLF)
$myInt = Int($myPtr)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("4th round: 2^32 -1" & @CRLF)
$myInt = 2 ^ 32 - 1
$myPtr = Ptr($myInt)
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite("Ptr: " & $myPtr & @CRLF)
$myInt = Int($myPtr) ;# <------ this is where the bug hits! <<<<<
ConsoleWrite("Int: " & $myInt & @CRLF)
ConsoleWrite(@CRLF)

 

and as you are saying "yes, pointers are of course unsigned by definition" then obviously there is a bug in the current int conversion:
for VarType "Ptr" it must return the value by reading it as unsigned int.

Edited by francoiste

Share this post


Link to post
Share on other sites
jchd

Can you please understand that there is NO unsigned integer datatype in AutoIt. Hence no AutoIt integer can reliably hold a pointer and display it unsigned.

Why do you need the decimal value of a pointer? Isn't the pointer value as stored good enough for processing? Decimal display is only a convenience for human reading, it has nothing to do with the processing capabilities. Anyway, you can still get it if you insist enough:

Local $p = Ptr(0x12345678)
ConsoleWrite($p & ' ' & VarGetType($p) & @LF)
Local $pp = $p + 9048701
ConsoleWrite($pp & ' ' & VarGetType($pp) & @LF)

$p = Ptr(0xFFFF0123)
ConsoleWrite($p & ' ' & VarGetType($p) & @LF)
Local $pp = $p + 0x4444
ConsoleWrite($pp & ' ' & VarGetType($pp) & @LF)

; if you insist on displaying the decimal value of a pointer
ConsoleWrite(StringFormat("0x%X = %u\n", $pp, $pp))

If $pp > 2^16 Then ConsoleWrite("Never do a Ptr comparison this way!" & @LF)
If $pp > Ptr(2^16) Then ConsoleWrite("Pointer > 2^16" & @LF)
If $pp < Ptr(0) Then ConsoleWrite("Should never show up" & @LF)

 

Edited by jchd
  • Like 1

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.