Edit 17.06.2015:
This is the best solution, ready to use for everybody:
Thx to all posters below and big Thx to HotKeyIt!
How to use: Just download it and copy the first part to your script
Code: Select all
; Big Thx to HotKeyIt
; Source: http://www.autohotkey.com/board/topic/87068-binrun-run-binary-executable-from-memory-eg-resource/page-2
; ************************ Howto use ************************
; copy this to your script and modify exe-name and parameters
;~ #Include ExeRun.ahk
;~ If 0
;~ FileInstall,MyExe.exe,-
;~ Parameters = -o"Path" -y -p"Password" ; Example for 7zip-Installer
;~ cmdLineScript = ; AHK Script-Code if used to create & execute code while running
;~ Hide = 0 ; Show/Hide the executed Window
;~ ExeToUse = ; if not specified, self is used
;~ Process_ID := BinRun("MyExe.exe", Parameters, cmdLineScript, Hide, ExeToUse)
;~ Process, Wait, %Process_ID%, 5 ; wait for process to start
;~ Process, WaitClose, %Process_ID%, 300 ; same as RunWait
; ************************ Source-Code ************************
; -- sizeof.ahk --
;: Title: sizeof function by HotKeyIt
;
; Function: sizeof
; Description:
; sizeof() is based on AHK_L Objects and supports both, ANSI and UNICODE version, so to use it you will require <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>Lexikos AutoHotkey_L.exe</a> or other versions based on it that supports objects.<br><br>nsizeof is used to calculate the size of structures or data types. <br>Visit <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>sizeof at AutoHotkey</a> forum, any feedback is welcome.
; Syntax: size:= sizeof(Structure_Definition or Structure_Object)
; Parameters:
; Field types - All AutoHotkey and Windows Data Types are supported<br>AutoHotkey Data Types<br> Int, Uint, Int64, UInt64, Char, UChar, Short, UShort, Fload and Double.<br>Windows Data Types<br> - note, TCHAR UCHAR and CHAR return actual character rather than the value, use Asc() function to find out the value/code<br>Windows Data types: Asc(char)<br>ATOM,BOOL,BOOLEAN,BYTE,CHAR,COLORREF,DWORD,DWORDLONG,DWORD_PTR,<br>DWORD32,DWORD64,FLOAT,HACCEL,HALF_PTR,HANDLE,HBITMAP,HBRUSH,HCOLORSPACE,HCONV,HCONVLIST,HCURSOR,HDC,<br>HDDEDATA,HDESK,HDROP,HDWP,HENHMETAFILE,HFILE,HFONT,HGDIOBJ,HGLOBAL,HHOOK,HICON,HINSTANCE,HKEY,HKL,<br>HLOCAL,HMENU,HMETAFILE,HMODULE,HMONITOR,HPALETTE,HPEN,HRESULT,HRGN,HRSRC,HSZ,HWINSTA,HWND,INT,<br>INT_PTR,INT32,INT64,LANGID,LCID,LCTYPE,LGRPID,LONG,LONGLONG,LONG_PTR,LONG32,LONG64,LPARAM,LPBOOL,<br>LPBYTE,LPCOLORREF,LPCSTR,LPCTSTR,LPCVOID,LPCWSTR,LPDWORD,LPHANDLE,LPINT,LPLONG,LPSTR,LPTSTR,LPVOID,<br>LPWORD,LPWSTR,LRESULT,PBOOL,PBOOLEAN,PBYTE,PCHAR,PCSTR,PCTSTR,PCWSTR,PDWORD,PDWORDLONG,PDWORD_PTR,<br>PDWORD32,PDWORD64,PFLOAT,PHALF_PTR,PHANDLE,PHKEY,PINT,PINT_PTR,PINT32,PINT64,PLCID,PLONG,PLONGLONG,<br>PLONG_PTR,PLONG32,PLONG64,POINTER_32,POINTER_64,POINTER_SIGNED,POINTER_UNSIGNED,PSHORT,PSIZE_T,<br>PSSIZE_T,PSTR,PTBYTE,PTCHAR,PTSTR,PUCHAR,PUHALF_PTR,PUINT,PUINT_PTR,PUINT32,PUINT64,PULONG,PULONGLONG,<br>PULONG_PTR,PULONG32,PULONG64,PUSHORT,PVOID,PWCHAR,PWORD,PWSTR,SC_HANDLE,SC_LOCK,SERVICE_STATUS_HANDLE,<br>SHORT,SIZE_T,SSIZE_T,TBYTE,TCHAR,UCHAR,UHALF_PTR,UINT,UINT_PTR,UINT32,UINT64,ULONG,ULONGLONG,<br>ULONG_PTR,ULONG32,ULONG64,USHORT,USN,WCHAR,WORD,WPARAM
; <b>Parameters</b> - <b>Description</b>
; size - The size of structure or data type
; Structure_Definition - C/C++ syntax or usual definition (must not be multiline) e.g. "Int x,Int y", C/C++ definitions must be multiline.
; Return Value:
; sizeof returns size of structures or data types
; Remarks:
; None.
; Related:
; Example:
; file:
sizeof(_TYPE_,parent_offset=0,ByRef _align_total_=0){
;Windows and AHK Data Types, used to find out the corresponding size
static _types__:="
(LTrim Join
,ATOM:2,LANGID:2,WCHAR:2,WORD:2,PTR:" A_PtrSize ",UPTR:" A_PtrSize ",SHORT:2,USHORT:2,INT:4,UINT:4,INT64:8,UINT64:8,DOUBLE:8,FLOAT:4,CHAR:1,UCHAR:1,__int64:8
,TBYTE:" (A_IsUnicode?2:1) ",TCHAR:" (A_IsUnicode?2:1) ",HALF_PTR:" (A_PtrSize=8?4:2) ",UHALF_PTR:" (A_PtrSize=8?4:2) ",INT32:4,LONG:4,LONG32:4,LONGLONG:8
,LONG64:8,USN:8,HFILE:4,HRESULT:4,INT_PTR:" A_PtrSize ",LONG_PTR:" A_PtrSize ",POINTER_64:" A_PtrSize ",POINTER_SIGNED:" A_PtrSize "
,BOOL:4,SSIZE_T:" A_PtrSize ",WPARAM:" A_PtrSize ",BOOLEAN:1,BYTE:1,COLORREF:4,DWORD:4,DWORD32:4,LCID:4,LCTYPE:4,LGRPID:4,LRESULT:4,PBOOL:" A_PtrSize "
,PBOOLEAN:" A_PtrSize ",PBYTE:" A_PtrSize ",PCHAR:" A_PtrSize ",PCSTR:" A_PtrSize ",PCTSTR:" A_PtrSize ",PCWSTR:" A_PtrSize ",PDWORD:" A_PtrSize "
,PDWORDLONG:" A_PtrSize ",PDWORD_PTR:" A_PtrSize ",PDWORD32:" A_PtrSize ",PDWORD64:" A_PtrSize ",PFLOAT:" A_PtrSize ",PHALF_PTR:" A_PtrSize "
,UINT32:4,ULONG:4,ULONG32:4,DWORDLONG:8,DWORD64:8,ULONGLONG:8,ULONG64:8,DWORD_PTR:" A_PtrSize ",HACCEL:" A_PtrSize ",HANDLE:" A_PtrSize "
,HBITMAP:" A_PtrSize ",HBRUSH:" A_PtrSize ",HCOLORSPACE:" A_PtrSize ",HCONV:" A_PtrSize ",HCONVLIST:" A_PtrSize ",HCURSOR:" A_PtrSize ",HDC:" A_PtrSize "
,HDDEDATA:" A_PtrSize ",HDESK:" A_PtrSize ",HDROP:" A_PtrSize ",HDWP:" A_PtrSize ",HENHMETAFILE:" A_PtrSize ",HFONT:" A_PtrSize ",USAGE:" 2 "
)"
static _types_:=_types__ "
(LTrim Join
,HGDIOBJ:" A_PtrSize ",HGLOBAL:" A_PtrSize ",HHOOK:" A_PtrSize ",HICON:" A_PtrSize ",HINSTANCE:" A_PtrSize ",HKEY:" A_PtrSize ",HKL:" A_PtrSize "
,HLOCAL:" A_PtrSize ",HMENU:" A_PtrSize ",HMETAFILE:" A_PtrSize ",HMODULE:" A_PtrSize ",HMONITOR:" A_PtrSize ",HPALETTE:" A_PtrSize ",HPEN:" A_PtrSize "
,HRGN:" A_PtrSize ",HRSRC:" A_PtrSize ",HSZ:" A_PtrSize ",HWINSTA:" A_PtrSize ",HWND:" A_PtrSize ",LPARAM:" A_PtrSize ",LPBOOL:" A_PtrSize ",LPBYTE:" A_PtrSize "
,LPCOLORREF:" A_PtrSize ",LPCSTR:" A_PtrSize ",LPCTSTR:" A_PtrSize ",LPCVOID:" A_PtrSize ",LPCWSTR:" A_PtrSize ",LPDWORD:" A_PtrSize ",LPHANDLE:" A_PtrSize "
,LPINT:" A_PtrSize ",LPLONG:" A_PtrSize ",LPSTR:" A_PtrSize ",LPTSTR:" A_PtrSize ",LPVOID:" A_PtrSize ",LPWORD:" A_PtrSize ",LPWSTR:" A_PtrSize "
,PHANDLE:" A_PtrSize ",PHKEY:" A_PtrSize ",PINT:" A_PtrSize ",PINT_PTR:" A_PtrSize ",PINT32:" A_PtrSize ",PINT64:" A_PtrSize ",PLCID:" A_PtrSize "
,PLONG:" A_PtrSize ",PLONGLONG:" A_PtrSize ",PLONG_PTR:" A_PtrSize ",PLONG32:" A_PtrSize ",PLONG64:" A_PtrSize ",POINTER_32:" A_PtrSize "
,POINTER_UNSIGNED:" A_PtrSize ",PSHORT:" A_PtrSize ",PSIZE_T:" A_PtrSize ",PSSIZE_T:" A_PtrSize ",PSTR:" A_PtrSize ",PTBYTE:" A_PtrSize "
,PTCHAR:" A_PtrSize ",PTSTR:" A_PtrSize ",PUCHAR:" A_PtrSize ",PUHALF_PTR:" A_PtrSize ",PUINT:" A_PtrSize ",PUINT_PTR:" A_PtrSize "
,PUINT32:" A_PtrSize ",PUINT64:" A_PtrSize ",PULONG:" A_PtrSize ",PULONGLONG:" A_PtrSize ",PULONG_PTR:" A_PtrSize ",PULONG32:" A_PtrSize "
,PULONG64:" A_PtrSize ",PUSHORT:" A_PtrSize ",PVOID:" A_PtrSize ",PWCHAR:" A_PtrSize ",PWORD:" A_PtrSize ",PWSTR:" A_PtrSize ",SC_HANDLE:" A_PtrSize "
,SC_LOCK:" A_PtrSize ",SERVICE_STATUS_HANDLE:" A_PtrSize ",SIZE_T:" A_PtrSize ",UINT_PTR:" A_PtrSize ",ULONG_PTR:" A_PtrSize ",VOID:" A_PtrSize "
)"
local _,_ArrName_:="",_ArrType_,_ArrSize_,_defobj_,_idx_,_LF_,_LF_BKP_,_match_,_offset_,_padding_,_struct_
,_total_union_size_,_uix_,_union_,_union_size_,_in_struct_,_mod_,_max_size_,_struct_align_
_offset_:=parent_offset ; Init size/offset to 0 or parent_offset
If IsObject(_TYPE_){ ; If structure object - check for offset in structure and return pointer + last offset + its data size
return _TYPE_["`a`a"]
}
If RegExMatch(_TYPE_,"^[\w\d\._]+$"){ ; structures name was supplied, resolve to global var and run again
If InStr(_types_,"," _TYPE_ ":")
Return SubStr(_types_,InStr(_types_,"," _TYPE_ ":") + 2 + StrLen(_TYPE_),1)
else If InStr(_TYPE_,"."){ ;check for object that holds structure definition
Loop,Parse,_TYPE_,.
If A_Index=1
_defobj_:=%A_LoopField%
else _defobj_:=_defobj_[A_LoopField]
Return sizeof(_defobj_,parent_offset)
} else Return sizeof(%_TYPE_%,parent_offset)
} else _defobj_:=""
If InStr(_TYPE_,"`n") { ; C/C++ style definition, convert
_offset_:="" ; This will hold new structure
,_struct_:=[] ; This will keep track if union is structure
,_union_:=0 ; This will keep track of union depth
Loop,Parse,_TYPE_,`n,`r`t%A_Space%%A_Tab%
{
_LF_:=""
Loop,Parse,A_LoopField,`,`;,`t%A_Space%%A_Tab%
{
If RegExMatch(A_LoopField,"^\s*//") ;break on comments and continue main loop
break
If (A_LoopField){ ; skip empty lines
If (!_LF_ && _ArrType_:=RegExMatch(A_LoopField,"[\w\d_#@]\s+[\w\d_#@]")) ; new line, find out data type and save key in _LF_ Data type will be added later
_LF_:=RegExReplace(A_LoopField,"[\w\d_#@]\K\s+.*$")
If Instr(A_LoopField,"{"){ ; Union, also check if it is a structure
_union_++,_struct_.Insert(_union_,RegExMatch(A_LoopField,"i)^\s*struct\s*\{"))
} else If InStr(A_LoopField,"}") ; end of union/struct
_offset_.="}"
else { ; not starting or ending struct or union so add definitions and apply Data Type.
If _union_ ; add { or struct{
Loop % _union_
_ArrName_.=(_struct_[A_Index]?"struct":"") "{"
_offset_.=(_offset_ ? "," : "") _ArrName_ ((_ArrType_ && A_Index!=1)?(_LF_ " "):"") RegExReplace(A_LoopField,"\s+"," ")
,_ArrName_:="",_union_:=0
}
}
}
}
_TYPE_:=_offset_
,_offset_:=parent_offset ; Init size/offset to 0 or parent_offset
}
; Following keep track of union size/offset
_union_:=[] ; keep track of union level, required to reset offset after union is parsed
,_struct_:=[] ; for each union level keep track if it is a structure (because here offset needs to increase
,_union_size_:=[] ; keep track of highest member within the union or structure, used to calculate new offset after union
,_struct_align_:=[] ; keep track of alignment before structure
,_total_union_size_:=0 ; used in combination with above, each loop the total offset is updated if current data size is higher
;,_align_total_:=0 ; used to calculate alignment for total size of structure
,_in_struct_:=1
; Parse given structure definition and calculate size
; Structures will be resolved by recrusive calls (a structure must be global)
Loop,Parse,_TYPE_,`,`; ;,%A_Space%%A_Tab%`n`r
{
_in_struct_+=StrLen(A_LoopField)+1
If ("" = _LF_ := trim(A_LoopField,A_Space A_Tab "`n`r"))
continue
_LF_BKP_:=_LF_ ;to check for ending brackets = union,struct
; Check for STARTING union and set union helpers
While (_match_:=RegExMatch(_LF_,"i)^(struct|union)?\s*\{\K"))
; correct offset for union/structure, sizeof_maxsize returns max size of union or structure
_max_size_:=sizeof_maxsize(SubStr(_TYPE_,_in_struct_-StrLen(A_LoopField)-1+(StrLen(_LF_BKP_)-StrLen(_LF_))))
,_union_.Insert(_offset_+=(_mod_:=Mod(_offset_,_max_size_))?Mod(_max_size_-_mod_,_max_size_):0)
,_union_size_.Insert(0)
,_struct_align_.Insert(_align_total_>_max_size_?_align_total_:_max_size_)
,_struct_.Insert(RegExMatch(_LF_,"i)^struct\s*\{")?(1,_align_total_:=0):0)
,_LF_:=SubStr(_LF_,_match_)
StringReplace,_LF_,_LF_,},,A
If InStr(_LF_,"*"){ ; It's a pointer, size will be always A_PtrSize
_offset_ += (_mod_:=Mod(_offset_ + A_PtrSize,A_PtrSize)?A_PtrSize-_mod_:0) + A_PtrSize
,_align_total_:=_align_total_<A_PtrSize?A_PtrSize:_align_total_
} else {
; Split array type and optionally the size of array, e.g. "TCHAR chr[5]"
RegExMatch(_LF_,"^(?<ArrType_>[\w\d\._#@]+)?\s*(?<ArrName_>[\w\d\._#@]+)?\s*\[?(?<ArrSize_>\d+)?\]?\s*$",_)
If (!_ArrName_ && !_ArrSize_ && !InStr( _types_ ,"," _ArrType_ ":"))
_ArrName_:=_ArrType_,_ArrType_:="UInt"
If InStr(_ArrType_,"."){ ;check for object that holds structure definition
Loop,Parse,_ArrType_,.
If A_Index=1
_defobj_:=%A_LoopField%
else _defobj_:=_defobj_[A_LoopField]
; _ArrType_:=_defobj_ ; ??????????????????????????????????????
}
If (_idx_:=InStr( _types_ ,"," _ArrType_ ":")) ; AHK or Windows data type
_padding_:=SubStr( _types_ , _idx_+StrLen(_ArrType_)+2 , 1 ),_align_total_:=_align_total_<_padding_?_padding_:_align_total_
else _padding_:= sizeof(_defobj_?_defobj_:%_ArrType_%,0,_align_total_),_max_size_:=sizeof_maxsize(_defobj_?_defobj_:%_ArrType_%)
if (_max_size_){
if (_mod_:=Mod(_offset_,_max_size_))
_offset_ += Mod(_max_size_-_mod_,_max_size_)
} else if _mod_:=Mod(_offset_,_padding_)
_offset_ += Mod(_padding_-_mod_,_padding_)
_offset_ += (_padding_ * (_ArrSize_?_ArrSize_:1))
_max_size_:=0
}
; It's a union or struct, check if new member is higher then previous members
If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ - _union_[_uix_])>_union_size_[_uix_]
_union_size_[_uix_]:=_max_size_
_max_size_:=0
; It's a union and not struct
If (_uix_ && !_struct_[_uix_])
_offset_:=_union_[_uix_]
; Check for ENDING union and reset offset and union helpers
While (SubStr(_LF_BKP_,0)="}"){
If !(_uix_:=_union_.MaxIndex()){
MsgBox,0, Incorrect structure, missing opening braket {`nProgram will exit now `n%_TYPE_%
ExitApp
}
; reset offset and align because we left a union or structure
if (_uix_>1 && _struct_[_uix_-1]){
If (_mod_:=Mod(_offset_,_struct_align_[_uix_]))
_offset_+=Mod(_struct_align_[_uix_]-_mod_,_struct_align_[_uix_])
} else _offset_:=_union_[_uix_]
; a member of union/struct is smaller than previous align, restore
if (_struct_[_uix_] &&_struct_align_[_uix_]>_align_total_)
_align_total_ := _struct_align_[_uix_]
; Increase total size of union/structure if necessary
_total_union_size_ := _union_size_[_uix_]>_total_union_size_?_union_size_[_uix_]:_total_union_size_
,_union_.Remove() ,_struct_.Remove() ,_union_size_.Remove(),_struct_align_.Remove() ; remove latest items
,_LF_BKP_:=SubStr(_LF_BKP_,1,StrLen(_LF_BKP_)-1)
If (_uix_=1){ ; leaving top union, add offset
if (_mod_:=Mod(_total_union_size_,_align_total_))
_total_union_size_ += Mod(_align_total_-_mod_,_align_total_)
_offset_+=_total_union_size_,_total_union_size_:=0
}
}
}
_offset_+= Mod(_align_total_ - Mod(_offset_,_align_total_),_align_total_)
Return _offset_
}
sizeof_maxsize(s){
static _types__:="
(LTrim Join
,ATOM:2,LANGID:2,WCHAR:2,WORD:2,PTR:" A_PtrSize ",UPTR:" A_PtrSize ",SHORT:2,USHORT:2,INT:4,UINT:4,INT64:8,UINT64:8,DOUBLE:8,FLOAT:4,CHAR:1,UCHAR:1,__int64:8
,TBYTE:" (A_IsUnicode?2:1) ",TCHAR:" (A_IsUnicode?2:1) ",HALF_PTR:" (A_PtrSize=8?4:2) ",UHALF_PTR:" (A_PtrSize=8?4:2) ",INT32:4,LONG:4,LONG32:4,LONGLONG:8
,LONG64:8,USN:8,HFILE:4,HRESULT:4,INT_PTR:" A_PtrSize ",LONG_PTR:" A_PtrSize ",POINTER_64:" A_PtrSize ",POINTER_SIGNED:" A_PtrSize "
,BOOL:4,SSIZE_T:" A_PtrSize ",WPARAM:" A_PtrSize ",BOOLEAN:1,BYTE:1,COLORREF:4,DWORD:4,DWORD32:4,LCID:4,LCTYPE:4,LGRPID:4,LRESULT:4,PBOOL:" A_PtrSize "
,PBOOLEAN:" A_PtrSize ",PBYTE:" A_PtrSize ",PCHAR:" A_PtrSize ",PCSTR:" A_PtrSize ",PCTSTR:" A_PtrSize ",PCWSTR:" A_PtrSize ",PDWORD:" A_PtrSize "
,PDWORDLONG:" A_PtrSize ",PDWORD_PTR:" A_PtrSize ",PDWORD32:" A_PtrSize ",PDWORD64:" A_PtrSize ",PFLOAT:" A_PtrSize ",PHALF_PTR:" A_PtrSize "
,UINT32:4,ULONG:4,ULONG32:4,DWORDLONG:8,DWORD64:8,ULONGLONG:8,ULONG64:8,DWORD_PTR:" A_PtrSize ",HACCEL:" A_PtrSize ",HANDLE:" A_PtrSize "
,HBITMAP:" A_PtrSize ",HBRUSH:" A_PtrSize ",HCOLORSPACE:" A_PtrSize ",HCONV:" A_PtrSize ",HCONVLIST:" A_PtrSize ",HCURSOR:" A_PtrSize ",HDC:" A_PtrSize "
,HDDEDATA:" A_PtrSize ",HDESK:" A_PtrSize ",HDROP:" A_PtrSize ",HDWP:" A_PtrSize ",HENHMETAFILE:" A_PtrSize ",HFONT:" A_PtrSize ",USAGE:" 2 "
)"
static _types_:=_types__ "
(LTrim Join
,HGDIOBJ:" A_PtrSize ",HGLOBAL:" A_PtrSize ",HHOOK:" A_PtrSize ",HICON:" A_PtrSize ",HINSTANCE:" A_PtrSize ",HKEY:" A_PtrSize ",HKL:" A_PtrSize "
,HLOCAL:" A_PtrSize ",HMENU:" A_PtrSize ",HMETAFILE:" A_PtrSize ",HMODULE:" A_PtrSize ",HMONITOR:" A_PtrSize ",HPALETTE:" A_PtrSize ",HPEN:" A_PtrSize "
,HRGN:" A_PtrSize ",HRSRC:" A_PtrSize ",HSZ:" A_PtrSize ",HWINSTA:" A_PtrSize ",HWND:" A_PtrSize ",LPARAM:" A_PtrSize ",LPBOOL:" A_PtrSize ",LPBYTE:" A_PtrSize "
,LPCOLORREF:" A_PtrSize ",LPCSTR:" A_PtrSize ",LPCTSTR:" A_PtrSize ",LPCVOID:" A_PtrSize ",LPCWSTR:" A_PtrSize ",LPDWORD:" A_PtrSize ",LPHANDLE:" A_PtrSize "
,LPINT:" A_PtrSize ",LPLONG:" A_PtrSize ",LPSTR:" A_PtrSize ",LPTSTR:" A_PtrSize ",LPVOID:" A_PtrSize ",LPWORD:" A_PtrSize ",LPWSTR:" A_PtrSize "
,PHANDLE:" A_PtrSize ",PHKEY:" A_PtrSize ",PINT:" A_PtrSize ",PINT_PTR:" A_PtrSize ",PINT32:" A_PtrSize ",PINT64:" A_PtrSize ",PLCID:" A_PtrSize "
,PLONG:" A_PtrSize ",PLONGLONG:" A_PtrSize ",PLONG_PTR:" A_PtrSize ",PLONG32:" A_PtrSize ",PLONG64:" A_PtrSize ",POINTER_32:" A_PtrSize "
,POINTER_UNSIGNED:" A_PtrSize ",PSHORT:" A_PtrSize ",PSIZE_T:" A_PtrSize ",PSSIZE_T:" A_PtrSize ",PSTR:" A_PtrSize ",PTBYTE:" A_PtrSize "
,PTCHAR:" A_PtrSize ",PTSTR:" A_PtrSize ",PUCHAR:" A_PtrSize ",PUHALF_PTR:" A_PtrSize ",PUINT:" A_PtrSize ",PUINT_PTR:" A_PtrSize "
,PUINT32:" A_PtrSize ",PUINT64:" A_PtrSize ",PULONG:" A_PtrSize ",PULONGLONG:" A_PtrSize ",PULONG_PTR:" A_PtrSize ",PULONG32:" A_PtrSize "
,PULONG64:" A_PtrSize ",PUSHORT:" A_PtrSize ",PVOID:" A_PtrSize ",PWCHAR:" A_PtrSize ",PWORD:" A_PtrSize ",PWSTR:" A_PtrSize ",SC_HANDLE:" A_PtrSize "
,SC_LOCK:" A_PtrSize ",SERVICE_STATUS_HANDLE:" A_PtrSize ",SIZE_T:" A_PtrSize ",UINT_PTR:" A_PtrSize ",ULONG_PTR:" A_PtrSize ",VOID:" A_PtrSize "
)"
max:=0,i:=0
s:=trim(s,"`n`r`t ")
If InStr(s,"}"){
Loop,Parse,s
if (A_LoopField="{")
i++
else if (A_LoopField="}"){
if --i<1{
end:=A_Index
break
}
}
if end
s:=SubStr(s,1,end)
}
Loop,Parse,s,`n,`r
{
_struct_:=(i:=InStr(A_LoopField," //"))?SubStr(A_LoopField,1,i):A_LoopField
Loop,Parse,_struct_,`;`,{},%A_Space%%A_Tab%
if A_LoopField&&!InStr(".union.struct.","." A_LoopField ".")
if (!InStr(A_LoopField,A_Tab)&&!InStr(A_LoopField," "))
max:=max<4?4:max
else if (sizeof(A_LoopField,0,size:=0) && max<size)
max:=size
}
return max
}
; -- _Struct.ahk --
;: Title: _Struct by HotKeyIt
;
; Function: _Struct
; Description:
; _Struct is based on AHK_L objects and supports both, ANSI and UNICODE version. To use it you will require <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>Lexikos AutoHotkey_L.exe</a> or other versions based on it.<br><br>new _Struct is used to create new structure. A structure must be defined as a global variable or an item of global class (e.g. "MyClass.Struct").<br>_Struct can handle structure in structure as well as Arrays of structures and Vectors.<br>Visit <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>_Struct on AutoHotkey</a> forum, any feedback is welcome.
; Syntax: MyStruct:= new _Struct(Structure_Definition,Address,initialization)
; Parameters:
; General Design - Class _Struct will create Object(s) that will manage fields of structure(s), for example<br>left,top,right,bottom<br>RC := new _Struct("RECT")<br>will create a RECT structure with fields left,top,right,bottom of type UInt. To pass the structure its pointer to a function, DllCall or SendMessage use RC[""].<br><br>To access fields you can use usual Object syntax: RC.left, RC.right ...<br>To set a field of the structure use RC.top := 100.
; Field types - Following AutoHotkey and Windows Data Types are supported:<br><br>AutoHotkey Data Types:<br>Int, Uint, Int64, UInt64, Char, UChar, Short, UShort, Fload and Double.<br><br>Windows Data Types:<br>ATOM,BOOL,BOOLEAN,BYTE,CHAR,COLORREF,DWORD,DWORDLONG,DWORD_PTR,<br>DWORD32,DWORD64,FLOAT,HACCEL,HALF_PTR,HANDLE,HBITMAP,HBRUSH,HCOLORSPACE,HCONV,HCONVLIST,HCURSOR,HDC,<br>HDDEDATA,HDESK,HDROP,HDWP,HENHMETAFILE,HFILE,HFONT,HGDIOBJ,HGLOBAL,HHOOK,HICON,HINSTANCE,HKEY,HKL,<br>HLOCAL,HMENU,HMETAFILE,HMODULE,HMONITOR,HPALETTE,HPEN,HRESULT,HRGN,HRSRC,HSZ,HWINSTA,HWND,INT,<br>INT_PTR,INT32,INT64,LANGID,LCID,LCTYPE,LGRPID,LONG,LONGLONG,LONG_PTR,LONG32,LONG64,LPARAM,LPBOOL,<br>LPBYTE,LPCOLORREF,LPCSTR,LPCTSTR,LPCVOID,LPCWSTR,LPDWORD,LPHANDLE,LPINT,LPLONG,LPSTR,LPTSTR,LPVOID,<br>LPWORD,LPWSTR,LRESULT,PBOOL,PBOOLEAN,PBYTE,PCHAR,PCSTR,PCTSTR,PCWSTR,PDWORD,PDWORDLONG,PDWORD_PTR,<br>PDWORD32,PDWORD64,PFLOAT,PHALF_PTR,PHANDLE,PHKEY,PINT,PINT_PTR,PINT32,PINT64,PLCID,PLONG,PLONGLONG,<br>PLONG_PTR,PLONG32,PLONG64,POINTER_32,POINTER_64,POINTER_SIGNED,POINTER_UNSIGNED,PSHORT,PSIZE_T,<br>PSSIZE_T,PSTR,PTBYTE,PTCHAR,PTSTR,PUCHAR,PUHALF_PTR,PUINT,PUINT_PTR,PUINT32,PUINT64,PULONG,PULONGLONG,<br>PULONG_PTR,PULONG32,PULONG64,PUSHORT,PVOID,PWCHAR,PWORD,PWSTR,SC_HANDLE,SC_LOCK,SERVICE_STATUS_HANDLE,<br>SHORT,SIZE_T,SSIZE_T,TBYTE,TCHAR,UCHAR,UHALF_PTR,UINT,UINT_PTR,UINT32,UINT64,ULONG,ULONGLONG,<br>ULONG_PTR,ULONG32,ULONG64,USHORT,USN,WCHAR,WORD,WPARAM
; <b>Structure Definition</b> - <b>Description</b>
; User defined - To create a user defined structure you will need to pass a string of predefined types and field names.<br>Default type is UInt, so for example for a RECT structure type can be omited: <b>"left,top,right,left"</b>, which is the same as <b>"Uint left,Uint top,Uint right,Uint bottom"</b><br><br>You can also use structures very similar to C#/C++ syntax, see example.
; Global - Global variables can be used to save structures, easily pass name of that variable as first parameter, e.g. new _Struct("MyStruct") where MyStruct must be a global variable with structure definition. Also new _Struct(MyStruct) can be used if variable is accessible.
; Array - To create an array of structures include a digit in the end of your string enclosed in squared brackets.<br>For example "RECT[2]" would create an array of 2 structures.<br>This feature can also be used for user defined arrays, for example "Int age,TCHAR name[10]".
; Union - Using {} you can create union, for example: <br>_AHKVar:="{Int64 ContentsInt64,Double ContentsDouble,object},...
; Struct - Using struct{} you can create structures in union or in structures.
; Pointer - To create a pointer you can use *, for example: CHR:="char *str" will hold a pointer to a character. Same way you can have a structure in structure so you can call it recursive, for example Label.NextLabel.NextLabel.NextLabel.JumpToLine
; <b>Parameters</b> - <b>Description</b>
; MyStruct - This is a variable that will hold the object representing the strucuture which is returned by new _Struct(...).
; Structure_Definition - C/C++ syntax or one-line definition e.g. "Int x,Int y".
; pointer - Pass a pointer as second parameter to occupy existing strucure.
; Initialization - Pass an object to initialize structure, e.g. {left:100,top:20}. If pointer is not used initialization can be specified in second parameter.
; <b>Methods</b> - <b>Description</b>
; Strct.Type(itm) - Returns type of item or structure
; Strct.AhkType(itm) - Returns AHK type of item or structure to be used with NumGet and NumPut as well as DllCall
; Strct.Size() - Returns size of structure, same as sizeof(MyStruct)
; Strct.SizeT(itm) - Returns size of an item
; Strct.Offset(itm) - Returns offset for items
; Strct.Encoding(itm) - Returns encoding for items, to be used with StrGet and StrPut
; Strct.Alloc(itm,size[,ptrsize]) - Allocates memory in bytes, ptrsize is used to create pointers
; Strct.Capacity(itm) - Returns memory capacity for items.
; Strct.IsPointer(itm) - Returns whether the item is a pointer (defined using *).
; Return Value:
; A class object representing your structure
; Remarks:
; <b>NOTE!!! accessing a field that does not exist will cause recrusive calls and will crash your script, these errors are not catched for performance reasons.<br>TCHAR, UCHAR and CHAR return actual character rather than the value, use Asc() function to find out the value/code.
; Related:
; Example:
; file:Struct_Example.ahk
;
Class _Struct {
; Data Sizes
static PTR:=A_PtrSize,UPTR:=A_PtrSize,SHORT:=2,USHORT:=2,INT:=4,UINT:=4,__int64:=8,INT64:=8,UINT64:=8,DOUBLE:=8,FLOAT:=4,CHAR:=1,UCHAR:=1,VOID:=A_PtrSize
,TBYTE:=A_IsUnicode?2:1,TCHAR:=A_IsUnicode?2:1,HALF_PTR:=A_PtrSize=8?4:2,UHALF_PTR:=A_PtrSize=8?4:2,INT32:=4,LONG:=4,LONG32:=4,LONGLONG:=8
,LONG64:=8,USN:=8,HFILE:=4,HRESULT:=4,INT_PTR:=A_PtrSize,LONG_PTR:=A_PtrSize,POINTER_64:=A_PtrSize,POINTER_SIGNED:=A_PtrSize
,BOOL:=4,SSIZE_T:=A_PtrSize,WPARAM:=A_PtrSize,BOOLEAN:=1,BYTE:=1,COLORREF:=4,DWORD:=4,DWORD32:=4,LCID:=4,LCTYPE:=4,LGRPID:=4,LRESULT:=4,PBOOL:=4
,PBOOLEAN:=A_PtrSize,PBYTE:=A_PtrSize,PCHAR:=A_PtrSize,PCSTR:=A_PtrSize,PCTSTR:=A_PtrSize,PCWSTR:=A_PtrSize,PDWORD:=A_PtrSize,PDWORDLONG:=A_PtrSize
,PDWORD_PTR:=A_PtrSize,PDWORD32:=A_PtrSize,PDWORD64:=A_PtrSize,PFLOAT:=A_PtrSize,PHALF_PTR:=A_PtrSize
,UINT32:=4,ULONG:=4,ULONG32:=4,DWORDLONG:=8,DWORD64:=8,ULONGLONG:=8,ULONG64:=8,DWORD_PTR:=A_PtrSize,HACCEL:=A_PtrSize,HANDLE:=A_PtrSize
,HBITMAP:=A_PtrSize,HBRUSH:=A_PtrSize,HCOLORSPACE:=A_PtrSize,HCONV:=A_PtrSize,HCONVLIST:=A_PtrSize,HCURSOR:=A_PtrSize,HDC:=A_PtrSize
,HDDEDATA:=A_PtrSize,HDESK:=A_PtrSize,HDROP:=A_PtrSize,HDWP:=A_PtrSize,HENHMETAFILE:=A_PtrSize,HFONT:=A_PtrSize
static HGDIOBJ:=A_PtrSize,HGLOBAL:=A_PtrSize,HHOOK:=A_PtrSize,HICON:=A_PtrSize,HINSTANCE:=A_PtrSize,HKEY:=A_PtrSize,HKL:=A_PtrSize
,HLOCAL:=A_PtrSize,HMENU:=A_PtrSize,HMETAFILE:=A_PtrSize,HMODULE:=A_PtrSize,HMONITOR:=A_PtrSize,HPALETTE:=A_PtrSize,HPEN:=A_PtrSize
,HRGN:=A_PtrSize,HRSRC:=A_PtrSize,HSZ:=A_PtrSize,HWINSTA:=A_PtrSize,HWND:=A_PtrSize,LPARAM:=A_PtrSize,LPBOOL:=A_PtrSize,LPBYTE:=A_PtrSize
,LPCOLORREF:=A_PtrSize,LPCSTR:=A_PtrSize,LPCTSTR:=A_PtrSize,LPCVOID:=A_PtrSize,LPCWSTR:=A_PtrSize,LPDWORD:=A_PtrSize,LPHANDLE:=A_PtrSize
,LPINT:=A_PtrSize,LPLONG:=A_PtrSize,LPSTR:=A_PtrSize,LPTSTR:=A_PtrSize,LPVOID:=A_PtrSize,LPWORD:=A_PtrSize,LPWSTR:=A_PtrSize,PHANDLE:=A_PtrSize
,PHKEY:=A_PtrSize,PINT:=A_PtrSize,PINT_PTR:=A_PtrSize,PINT32:=A_PtrSize,PINT64:=A_PtrSize,PLCID:=A_PtrSize,PLONG:=A_PtrSize,PLONGLONG:=A_PtrSize
,PLONG_PTR:=A_PtrSize,PLONG32:=A_PtrSize,PLONG64:=A_PtrSize,POINTER_32:=A_PtrSize,POINTER_UNSIGNED:=A_PtrSize,PSHORT:=A_PtrSize,PSIZE_T:=A_PtrSize
,PSSIZE_T:=A_PtrSize,PSTR:=A_PtrSize,PTBYTE:=A_PtrSize,PTCHAR:=A_PtrSize,PTSTR:=A_PtrSize,PUCHAR:=A_PtrSize,PUHALF_PTR:=A_PtrSize,PUINT:=A_PtrSize
,PUINT_PTR:=A_PtrSize,PUINT32:=A_PtrSize,PUINT64:=A_PtrSize,PULONG:=A_PtrSize,PULONGLONG:=A_PtrSize,PULONG_PTR:=A_PtrSize,PULONG32:=A_PtrSize
,PULONG64:=A_PtrSize,PUSHORT:=A_PtrSize,PVOID:=A_PtrSize,PWCHAR:=A_PtrSize,PWORD:=A_PtrSize,PWSTR:=A_PtrSize,SC_HANDLE:=A_PtrSize
,SC_LOCK:=A_PtrSize,SERVICE_STATUS_HANDLE:=A_PtrSize,SIZE_T:=A_PtrSize,UINT_PTR:=A_PtrSize,ULONG_PTR:=A_PtrSize,ATOM:=2,LANGID:=2,WCHAR:=2,WORD:=2,USAGE:=2
; Data Types
static _PTR:="PTR",_UPTR:="UPTR",_SHORT:="Short",_USHORT:="UShort",_INT:="Int",_UINT:="UInt"
,_INT64:="Int64",_UINT64:="UInt64",_DOUBLE:="Double",_FLOAT:="Float",_CHAR:="Char",_UCHAR:="UChar"
,_VOID:="PTR",_TBYTE:=A_IsUnicode?"USHORT":"UCHAR",_TCHAR:=A_IsUnicode?"USHORT":"UCHAR",_HALF_PTR:=A_PtrSize=8?"INT":"SHORT"
,_UHALF_PTR:=A_PtrSize=8?"UINT":"USHORT",_BOOL:="Int",_INT32:="Int",_LONG:="Int",_LONG32:="Int",_LONGLONG:="Int64",_LONG64:="Int64"
,_USN:="Int64",_HFILE:="UInt",_HRESULT:="UInt",_INT_PTR:="PTR",_LONG_PTR:="PTR",_POINTER_64:="PTR",_POINTER_SIGNED:="PTR",_SSIZE_T:="PTR"
,_WPARAM:="PTR",_BOOLEAN:="UCHAR",_BYTE:="UCHAR",_COLORREF:="UInt",_DWORD:="UInt",_DWORD32:="UInt",_LCID:="UInt",_LCTYPE:="UInt"
,_LGRPID:="UInt",_LRESULT:="UInt",_PBOOL:="UPTR",_PBOOLEAN:="UPTR",_PBYTE:="UPTR",_PCHAR:="UPTR",_PCSTR:="UPTR",_PCTSTR:="UPTR"
,_PCWSTR:="UPTR",_PDWORD:="UPTR",_PDWORDLONG:="UPTR",_PDWORD_PTR:="UPTR",_PDWORD32:="UPTR",_PDWORD64:="UPTR",_PFLOAT:="UPTR",___int64:="Int64"
,_PHALF_PTR:="UPTR",_UINT32:="UInt",_ULONG:="UInt",_ULONG32:="UInt",_DWORDLONG:="UInt64",_DWORD64:="UInt64",_ULONGLONG:="UInt64"
,_ULONG64:="UInt64",_DWORD_PTR:="UPTR",_HACCEL:="UPTR",_HANDLE:="UPTR",_HBITMAP:="UPTR",_HBRUSH:="UPTR",_HCOLORSPACE:="UPTR"
,_HCONV:="UPTR",_HCONVLIST:="UPTR",_HCURSOR:="UPTR",_HDC:="UPTR",_HDDEDATA:="UPTR",_HDESK:="UPTR",_HDROP:="UPTR",_HDWP:="UPTR"
static _HENHMETAFILE:="UPTR",_HFONT:="UPTR",_HGDIOBJ:="UPTR",_HGLOBAL:="UPTR",_HHOOK:="UPTR",_HICON:="UPTR",_HINSTANCE:="UPTR",_HKEY:="UPTR"
,_HKL:="UPTR",_HLOCAL:="UPTR",_HMENU:="UPTR",_HMETAFILE:="UPTR",_HMODULE:="UPTR",_HMONITOR:="UPTR",_HPALETTE:="UPTR",_HPEN:="UPTR"
,_HRGN:="UPTR",_HRSRC:="UPTR",_HSZ:="UPTR",_HWINSTA:="UPTR",_HWND:="UPTR",_LPARAM:="UPTR",_LPBOOL:="UPTR",_LPBYTE:="UPTR",_LPCOLORREF:="UPTR"
,_LPCSTR:="UPTR",_LPCTSTR:="UPTR",_LPCVOID:="UPTR",_LPCWSTR:="UPTR",_LPDWORD:="UPTR",_LPHANDLE:="UPTR",_LPINT:="UPTR",_LPLONG:="UPTR"
,_LPSTR:="UPTR",_LPTSTR:="UPTR",_LPVOID:="UPTR",_LPWORD:="UPTR",_LPWSTR:="UPTR",_PHANDLE:="UPTR",_PHKEY:="UPTR",_PINT:="UPTR"
,_PINT_PTR:="UPTR",_PINT32:="UPTR",_PINT64:="UPTR",_PLCID:="UPTR",_PLONG:="UPTR",_PLONGLONG:="UPTR",_PLONG_PTR:="UPTR",_PLONG32:="UPTR"
,_PLONG64:="UPTR",_POINTER_32:="UPTR",_POINTER_UNSIGNED:="UPTR",_PSHORT:="UPTR",_PSIZE_T:="UPTR",_PSSIZE_T:="UPTR",_PSTR:="UPTR"
,_PTBYTE:="UPTR",_PTCHAR:="UPTR",_PTSTR:="UPTR",_PUCHAR:="UPTR",_PUHALF_PTR:="UPTR",_PUINT:="UPTR",_PUINT_PTR:="UPTR",_PUINT32:="UPTR"
,_PUINT64:="UPTR",_PULONG:="UPTR",_PULONGLONG:="UPTR",_PULONG_PTR:="UPTR",_PULONG32:="UPTR",_PULONG64:="UPTR",_PUSHORT:="UPTR"
,_PVOID:="UPTR",_PWCHAR:="UPTR",_PWORD:="UPTR",_PWSTR:="UPTR",_SC_HANDLE:="UPTR",_SC_LOCK:="UPTR",_SERVICE_STATUS_HANDLE:="UPTR"
static _SIZE_T:="UPTR",_UINT_PTR:="UPTR",_ULONG_PTR:="UPTR",_ATOM:="Ushort",_LANGID:="Ushort",_WCHAR:="Ushort",_WORD:="UShort",_USAGE:="UShort"
; Following is used internally only to simplify setting field helpers
; the corresponding key can be set to invalid type (for string integer and vice versa) to set default if necessary, e.g. ___InitField(N,"")
___InitField(_this,N,offset=" ",encoding=0,AHKType=0,isptr=" ",type=0,arrsize=0,memory=0){ ; N = Name of field
static _prefixes_:={offset:"`b",isptr:"`r",AHKType:"`n",type:"`t",encoding:"`f",memory:"`v",arrsize:" "}
,_testtype_:={offset:"integer",isptr:"integer",AHKType:"string",type:"string",encoding:"string",arrsize:"integer"}
,_default_:={offset:0,isptr:0,AHKType:"UInt",type:"UINT",encoding:"CP0",memory:"",arrsize:1}
for _key_,_value_ in _prefixes_
{
_typevalid_:=0
If (_testtype_[_key_]="Integer"){
If %_key_% is integer
useDefault:=1,_typevalid_:=1
else if !_this.HasKey(_value_ N)
useDefault:=1
} else {
If %_key_% is not integer
useDefault:=1,_typevalid_:=1
else if !_this.HasKey(_value_ N)
useDefault:=1
}
If (useDefault) ; item does not exist or user supplied a valid type
If (_key_="encoding")
_this[_value_ N]:=_typevalid_?(InStr(",LPTSTR,LPCTSTR,TCHAR,","," %_key_% ",")?(A_IsUnicode?"UTF-16":"CP0")
:InStr(",LPWSTR,LPCWSTR,WCHAR,","," %_key_% ",")?"UTF-16":"CP0")
:_default_[_key_]
else {
_this[_value_ N]:=_typevalid_?%_key_%:_default_[_key_]
}
}
}
; Struct Contstructor
; Memory, offset and definitions are saved in following character + given key/name
; `a = Allocated Memory
; `b = Byte Offset (related to struct address)
; `f = Format (encoding for string data types)
; `n = New data type (AHK data type)
; `r = Is Pointer (requred for __GET and __SET)
; `t = Type (data type, also when it is name of a Structure it is used to resolve structure pointers dynamically
; `v = Memory used to save string and pointer memory
__NEW(_TYPE_,_pointer_=0,_init_=0){
static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW
,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding
,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj}
local _,_ArrType_,_ArrName_:="",_ArrSize_,_align_total_,_defobj_,_IsPtr_,_key_,_LF_,_LF_BKP_,_match_,_offset_:=""
,_struct_,_StructSize_,_total_union_size_,_union_,_union_size_,_value_,_mod_,_max_size_,_in_struct_,_struct_align_
If (RegExMatch(_TYPE_,"^[\w\d\._]+$") && !_Struct.HasKey(_TYPE_)){ ; structures name was supplied, resolve to global var and run again
If InStr(_TYPE_,"."){ ;check for object that holds structure definition
Loop,Parse,_TYPE_,.
If A_Index=1
_defobj_:=%A_LoopField%
else _defobj_:=_defobj_[A_LoopField]
_TYPE_:=_defobj_
} else _TYPE_:=%_TYPE_%,_defobj_:=""
} else _defobj_:=""
; If a pointer is supplied, save it in key [""] else reserve and zero-fill memory + set pointer in key [""]
If (_pointer_ && !IsObject(_pointer_))
this[""] := _pointer_,this["`a"]:=0,this["`a`a"]:=sizeof(_TYPE_)
else
this._SetCapacity("`a",_StructSize_:=sizeof(_TYPE_)) ; Set Capacity in key ["`a"]
,this[""]:=this._GetAddress("`a") ; Save pointer in key [""]
,DllCall("RtlZeroMemory","UPTR",this[""],"UInt",this["`a`a"]:=_StructSize_) ; zero-fill memory
; C/C++ style structure definition, convert it
If InStr(_TYPE_,"`n") {
_struct_:=[] ; keep track of structures (union is just removed because {} = union, struct{} = struct
_union_:=0 ; init to 0, used to keep track of union depth
Loop,Parse,_TYPE_,`n,`r`t%A_Space%%A_Tab% ; Parse each line
{
_LF_:=""
Loop,Parse,A_LoopField,`,`;,`t%A_Space%%A_Tab% ; Parse each item
{
If RegExMatch(A_LoopField,"^\s*//") ;break on comments and continue main loop
break
If (A_LoopField){ ; skip empty lines
If (!_LF_ && _ArrType_:=RegExMatch(A_LoopField,"[\w\d_#@]\s+[\w\d_#@]")) ; new line, find out data type and save key in _LF_ Data type will be added later
_LF_:=RegExReplace(A_LoopField,"[\w\d_#@]\K\s+.*$")
If Instr(A_LoopField,"{"){ ; Union, also check if it is a structure
_union_++,_struct_.Insert(_union_,RegExMatch(A_LoopField,"i)^\s*struct\s*\{"))
} else If InStr(A_LoopField,"}") ; end of union/struct
_offset_.="}"
else { ; not starting or ending struct or union so add definitions and apply Data Type.
If _union_ ; add { or struct{
Loop % _union_
_ArrName_.=(_struct_[A_Index]?"struct":"") "{"
_offset_.=(_offset_ ? "," : "") _ArrName_ ((_ArrType_ && A_Index!=1)?(_LF_ " "):"") RegExReplace(A_LoopField,"\s+"," ")
,_ArrName_:="",_union_:=0
}
}
}
}
_TYPE_:=_offset_
}
_offset_:=0
,_union_:=[] ; keep track of union level, required to reset offset after union is parsed
,_struct_:=[] ; for each union level keep track if it is a structure (because here offset needs to increase
,_union_size_:=[] ; keep track of highest member within the union or structure, used to calculate new offset after union
,_struct_align_:=[] ; keep track of alignment before structure
,_total_union_size_:=0 ; used in combination with above, each loop the total offset is updated if current data size is higher
,_align_total_:=0 ; used to calculate alignment for total size of structure
,_in_struct_:=1
,this["`t"]:=0,this["`r"]:=0 ; will identify a Structure Pointer without members
; Parse given structure definition and create struct members
; User structures will be resolved by recrusive calls (!!! a structure must be a global variable)
Loop,Parse,_TYPE_,`,`; ;,%A_Space%%A_Tab%`n`r
{
_in_struct_+=StrLen(A_LoopField)+1
If ("" = _LF_ := trim(A_LoopField,A_Space A_Tab "`n`r"))
continue
_LF_BKP_:=_LF_ ;to check for ending brackets = union,struct
_IsPtr_:=0
; Check for STARTING union and set union helpers
While (_match_:=RegExMatch(_LF_,"i)^(struct|union)?\s*\{\K"))
; correct offset for union/structure, sizeof_maxsize returns max size of union or structure
_max_size_:=sizeof_maxsize(SubStr(_TYPE_,_in_struct_-StrLen(A_LoopField)-1+(StrLen(_LF_BKP_)-StrLen(_LF_))))
,_union_.Insert(_offset_+=(_mod_:=Mod(_offset_,_max_size_))?Mod(_max_size_-_mod_,_max_size_):0)
,_union_size_.Insert(0)
,_struct_align_.Insert(_align_total_>_max_size_?_align_total_:_max_size_)
,_struct_.Insert(RegExMatch(_LF_,"i)^struct\s*\{")?(1,_align_total_:=0):0)
,_LF_:=SubStr(_LF_,_match_)
StringReplace,_LF_,_LF_,},,A ;remove all closing brackets (these will be checked later)
; Check if item is a pointer and remove * for further processing, separate key will store that information
While % (InStr(_LF_,"*")){
StringReplace,_LF_,_LF_,*
_IsPtr_:=A_Index
}
; Split off data type, name and size (only data type is mandatory)
RegExMatch(_LF_,"^(?<ArrType_>[\w\d\._]+)?\s*(?<ArrName_>[\w\d_]+)?\s*\[?(?<ArrSize_>\d+)?\]?\s*\}*\s*$",_)
If (!_ArrName_ && !_ArrSize_){
If RegExMatch(_TYPE_,"^\**" _ArrType_ "\**$"){
_Struct.___InitField(this,"",0,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey("_" _ArrType_)?_Struct["_" _ArrType_]:"PTR",_IsPtr_,_ArrType_)
this.base:=_base_
If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20})
for _key_,_value_ in IsObject(_init_)?_init_:_pointer_
{
If !this["`r"]{ ; It is not a pointer, assign value
If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")
this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1))
if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",")
this[_key_]:=_value_
else
this[_key_] := _value_
}else if (_value_<>"") ; It is not empty
If _value_ is integer ; It is a new pointer
this[_key_][""]:=_value_
}
}
Return this ;:= new _Struct(%_ArrType_%,_pointer_) ;only Data type was supplied, object/structure has got no members/keys
} else
_ArrName_:=_ArrType_,_ArrType_:="UInt"
}
If InStr(_ArrType_,"."){ ;check for object that holds structure definition
Loop,Parse,_ArrType_,.
If A_Index=1
_defobj_:=%A_LoopField%
else _defobj_:=_defobj_[A_LoopField]
}
if (!_IsPtr_ && !_Struct.HasKey(_ArrType_)){ ; _ArrType_ not found resolve to global variable (must contain struct definition)
_offset_+=sizeof(_defobj_?_defobj_:%_ArrType_%,_offset_,_align_total_)-_offset_-sizeof(_defobj_?_defobj_:%_ArrType_%)
,_Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,0,0,_ArrType_,_ArrSize_)
; update current union size
If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + sizeof(_defobj_?_defobj_:%_ArrType_%) - _union_[_uix_])>_union_size_[_uix_]
_union_size_[_uix_]:=_max_size_
_max_size:=0
; if not a union or a union + structure then offset must be moved (when structure offset will be reset below
If (!_uix_||_struct_[_struct_.MaxIndex()])
_offset_+=this[" " _ArrName_]*sizeof(_defobj_?_defobj_:%_ArrType_%) ; move offset
;Continue
} else {
If ((_IsPtr_ || _Struct.HasKey(_ArrType_)))
_offset_+=(_mod_:=Mod(_offset_,_max_size_:=_IsPtr_?A_PtrSize:_Struct[_ArrType_]))=0?0:(_IsPtr_?A_PtrSize:_Struct[_ArrType_])-_mod_
,_align_total_:=_max_size_>_align_total_?_max_size_:_align_total_
,_Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey(_ArrType_)?_Struct["_" _ArrType_]:_ArrType_,_IsPtr_,_ArrType_,_ArrSize_)
; update current union size
If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + _Struct[this["`n" _ArrName_]] - _union_[_uix_])>_union_size_[_uix_]
_union_size_[_uix_]:=_max_size_
_max_size_:=0
; if not a union or a union + structure then offset must be moved (when structure offset will be reset below
If (!_uix_||_struct_[_uix_])
_offset_+=_IsPtr_?A_PtrSize:(_Struct.HasKey(_ArrType_)?_Struct[_ArrType_]:%_ArrType_%)*this[" " _ArrName_]
}
; Check for ENDING union and reset offset and union helpers
While (SubStr(_LF_BKP_,0)="}"){
If (!_uix_:=_union_.MaxIndex()){
MsgBox,0, Incorrect structure, missing opening braket {`nProgram will exit now `n%_TYPE_%
ExitApp
} ; Increase total size of union/structure if necessary
; reset offset and align because we left a union or structure
if (_uix_>1 && _struct_[_uix_-1]){
if (_mod_:=Mod(_offset_,_struct_align_[_uix_]))
_offset_+=Mod(_struct_align_[_uix_]-_mod_,_struct_align_[_uix_])
} else _offset_:=_union_[_uix_]
if (_struct_[_uix_]&&_struct_align_[_uix_]>_align_total_)
_align_total_ := _struct_align_[_uix_]
; Increase total size of union/structure if necessary
_total_union_size_ := _union_size_[_uix_]>_total_union_size_?_union_size_[_uix_]:_total_union_size_
,_union_._Remove(),_struct_._Remove(),_union_size_._Remove(),_struct_align_.Remove(),_LF_BKP_:=SubStr(_LF_BKP_,1,StrLen(_LF_BKP_)-1) ; remove latest items
If (_uix_=1){ ; leaving top union, add offset
if (_mod_:=Mod(_total_union_size_,_align_total_))
_total_union_size_ += Mod(_align_total_-_mod_,_align_total_)
_offset_+=_total_union_size_,_total_union_size_:=0
}
}
}
this.base:=_base_ ; apply new base which uses below functions and uses ___GET for __GET and ___SET for __SET
If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20})
for _key_,_value_ in IsObject(_init_)?_init_:_pointer_
{
If !this["`r" _key_]{ ; It is not a pointer, assign value
If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")
this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1))
if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",")
this[_key_]:=_value_
else
this[_key_] := _value_
}else if (_value_<>"") ; It is not empty
if _value_ is integer ; It is a new pointer
this[_key_][""]:=_value_
}
}
Return this
}
ToObj(struct:=""){
obj:=[]
for k,v in struct?struct:struct:=this
if (Asc(k)=10)
If IsObject(_VALUE_:=struct[_TYPE_:=SubStr(k,2)])
obj[_TYPE_]:=this.ToObj(_VALUE_)
else obj[_TYPE_]:=_VALUE_
return obj
}
SizeT(_key_=""){
return sizeof(this["`t" _key_])
}
Size(){
return sizeof(this)
}
IsPointer(_key_=""){
return this["`r" _key_]
}
Type(_key_=""){
return this["`t" _key_]
}
AHKType(_key_=""){
return this["`n" _key_]
}
Offset(_key_=""){
return this["`b" _key_]
}
Encoding(_key_=""){
return this["`b" _key_]
}
Capacity(_key_=""){
return this._GetCapacity("`v" _key_)
}
Alloc(_key_="",size="",ptrsize=0){
If _key_ is integer
ptrsize:=size,size:=_key_,_key_:=""
If size is integer
SizeIsInt:=1
If ptrsize {
If (this._SetCapacity("`v" _key_,!SizeIsInt?A_PtrSize+ptrsize:size + (size//A_PtrSize)*ptrsize)="")
MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!"
else {
DllCall("RtlZeroMemory","UPTR",this._GetAddress("`v" _key_),"UInt",this._GetCapacity("`v" _key_))
If (this[" " _key_]>1){
ptr:=this[""] + this["`b" _key_]
If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ","))
NumPut(ptrs:=this._GetAddress("`v" _key_),ptr+0,"PTR")
else if _key_
this[_key_,""]:=ptrs:=this._GetAddress("`v" _key_)
else this[""]:=ptr:=this._GetAddress("`v" _key_),ptrs:=this._GetAddress("`v" _key_)+(SizeIsInt?size:A_PtrSize)
} else {
If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ","))
NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR")
else this[""]:=ptr:=this._GetAddress("`v" _key_)
ptrs:=ptr+(size?size:A_PtrSize)
}
Loop % SizeIsInt?(size//A_PtrSize):1
NumPut(ptrs+(A_Index-1)*ptrsize,ptr+(A_Index-1)*A_PtrSize,"PTR")
}
} else {
If (this._SetCapacity("`v" _key_,SizeIsInt?size:A_PtrSize)=""){
MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!"
} else
NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR"),DllCall("RtlZeroMemory","UPTR",ptr,"UInt",SizeIsInt?size:A_PtrSize)
}
return ptr
}
___NEW(init*){
this:=this.base
newobj := this.__Clone(1) ;clone structure and keep pointer (1), it will be changed below
If (init.MaxIndex() && !IsObject(init.1))
newobj[""] := init.1
else If (init.MaxIndex()>1 && !IsObject(init.2))
newobj[""] := init.2
else
newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"]
,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""]
,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory
If (IsObject(init.1)||IsObject(init.2))
for _key_,_value_ in IsObject(init.1)?init.1:init.2
newobj[_key_] := _value_
return newobj
}
; Clone structure and move pointer for new structure
___Clone(offset){
static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW
,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding
,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj}
If offset=1
return this
newobj:={} ; new structure object
for _key_,_value_ in this ; copy all values/objects
If (_key_!="`a")
newobj[_key_]:=_value_ ; add key to new object and assign value
newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"]
,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""]
,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory
If this["`r"]{ ; its a pointer so we need too move internal memory
NumPut(NumGet(this[""],"PTR")+A_PtrSize*(offset-1),newobj[""],"Ptr")
newobj.base:=_base_ ;assign base of _Struct
} else ; do not use internal memory, simply assign new pointer to new structure
newobj.base:=_base_,newobj[]:=this[""]+sizeof(this)*(offset-1)
return newobj ; return new object
}
___GET(_key_="",p*){
If (_key_="") ; Key was not given so structure[] has been called, return pointer to structure
Return this[""]
else if !(idx:=p.MaxIndex())
_field_:=_key_,opt:="~"
else {
ObjInsert(p,1,_key_)
opt:=ObjRemove(p),_field_:=_key_:=ObjRemove(p)
for key_,value_ in p
this:=this[value_]
}
If this["`t"] ; structure without keys/members
_key_:="" ; set _key_ empty so items below will resolve to our structure
If (opt!="~"){
If (opt=""){
If _field_ is integer
return (this["`r"]?NumGet(this[""],"PTR"):this[""])+sizeof(this["`t"])*(_field_-1)
else return this["`r" _key_]?NumGet(this[""]+this["`b" _key_],"PTR"):this[""]+this["`b" _key_] ;+sizeof(this["`t" _key_])*(_field_-1)
} else If opt is integer
{ ;offset to a item e.g. struct.a[100] ("Uint a[100]")
; MsgBox % "ja "
If (_Struct.HasKey("_" this["`t" _key_]) && this[" " _key_]>1) {
If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){ ; StrGet 1 character only
Return StrGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),1,this["`f" _key_])
} else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string
Return StrGet(NumGet(this[""]+this["`b" _key_]+(opt-1)*A_PtrSize,"PTR"),this["`f" _key_])
} else {
Return NumGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),this["`n" _key_])
}
} else Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]))
} else
return this[_key_][opt]
} else If _field_ is integer
{ ; array access (must be listed first because otherwise this["`r" _key_] cannot be resolved
If (_key_){ ; Offset for item
return this.__Clone(_field_)
} else if this["`r"] {
Pointer:=""
Loop % (this["`r"]-1) ; dip into one step and return a new structure
pointer.="*"
If pointer
Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+A_PtrSize*(_field_-1))
else Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+sizeof(this["`t"])*(_field_-1)).1
} else if _Struct.HasKey("_" this["`t"]) {
; If this[" "]
; Return new _Struct(this["`t"],this[""])
; else
If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t"] "," )){ ; StrGet 1 character only
Return StrGet(this[""]+sizeof(this["`t"])*(_field_-1),1,this["`f"])
} else if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){ ; StrGet string
Return StrGet(NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"])
} else { ; resolve pointer
Return NumGet(this[""]+sizeof(this["`t"])*(_field_-1),this["`n"])
}
} else {
; return this.__Clone(_field_)
; listVars
; MsgBox % this[""] "+" sizeof(this["`t"])*(_field_-1) "-" this["`t"]
Return new _Struct(this["`t"],this[""]+sizeof(this["`t"])*(_field_-1))
}
} else If this["`r" _key_] { ;pointer
Pointer:=""
Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure
pointer.="*"
If (_key_=""){
return this[1][_field_]
} else {
Return new _Struct(pointer this["`t" _key_],NumGet(this[""]+this["`b" _key_],"PTR"))
}
} else if _Struct.HasKey("_" this["`t" _key_]) { ; default data type, not pointer
If (this[" " _key_]>1)
Return new _Struct(this["`t" _key_],this[""] + this["`b" _key_])
else If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){ ; StrGet 1 character only
Return StrGet(this[""]+this["`b" _key_],1,this["`f" _key_])
} else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string
Return StrGet(NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_])
} else {
Return NumGet(this[""]+this["`b" _key_],this["`n" _key_])
}
} else { ; the field is a non pointer structure
Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_])
}
}
___SET(_key_,p*){ ;="",_value_=-0x8000000000000000 ,opt="~"){
If !(idx:=p.MaxIndex()) ; Set new Pointer, here a value was assigned e.g. struct[]:=&var
return this[""] :=_key_,this._SetCapacity("`a",0) ; free internal memory, it will not be used anymore
else if (idx=1)
_value_:=p.1,opt:="~"
else if (idx>1){
ObjInsert(p,1,_key_)
If (p[idx]="")
opt:=ObjRemove(p),_value_:=ObjRemove(p),_key_:=ObjRemove(p)
else _value_:=ObjRemove(p),_key_:=ObjRemove(p),opt:="~"
for key_,value_ in p
this:=this[value_]
}
If this["`t"] ; structure without members
_field_:=_key_,_key_:="" ; set _key_ empty so it will resolve to our structure
else _field_:=_key_
If this["`r" _key_] { ; Pointer
If opt is integer
return NumPut(opt,this[""] + this["`b" _key_],"PTR")
else if this.HasKey("`t" _key_) {
Pointer:=""
Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure
pointer.="*"
If _key_
Return (new _Struct(pointer this["`t" _key_],NumGet(this[""] + this["`b" _key_],"PTR"))).1:=_value_
else Return (new _Struct(pointer this["`t"],NumGet(this[""],"PTR")))[_field_]:=_value_
} else If _field_ is Integer
if (_key_="") ; replace this for the operation
_this:=this,this:=this.__Clone(_Field_)
If InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," )
StrPut(_value_,NumGet(NumGet(this[""]+this["`b" _key_],"PTR"),"PTR"),this["`f" _key_]) ; StrPut char to addr+A_PtrSize
else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){ ; same as above but for 1 Character only
StrPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut char to addr
} else
NumPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`n" _key_])
If _field_ is integer ; restore this after operation
this:=_this
} else if (RegExMatch(_field_,"^\d+$") && _key_="") {
if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){
StrPut(_value_,NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"]) ; StrPut string to addr
} else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){
StrPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`f"])
} else
NumPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`n"]) ; NumPut new value to key
} else if opt is integer
{
return NumPut(opt,this[""] + this["`b" _key_],"PTR")
} else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){
StrPut(_value_,NumGet(this[""] + this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut string to addr
} else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){
StrPut(_value_,this[""] + this["`b" _key_],this["`f" _key_]) ; StrPut character key
} else
NumPut(_value_,this[""]+this["`b" _key_],this["`n" _key_]) ; NumPut new value to key
Return _value_
}
}
; -- BinRun.ahk --
Class _BinRun {
static IMAGE_DOS_HEADER :="
(
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
)"
,IMAGE_FILE_HEADER :="
(
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
)"
,IMAGE_DATA_DIRECTORY :="
(
DWORD VirtualAddress;
DWORD Size;
)"
,IMAGE_OPTIONAL_HEADER64:="
(
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
_BinRun.IMAGE_DATA_DIRECTORY DataDirectory[16]; // IMAGE_NUMBEROF_DIRECTORY_ENTRIES
)"
,IMAGE_OPTIONAL_HEADER32 :="
(
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
_BinRun.IMAGE_DATA_DIRECTORY DataDirectory[16]; //IMAGE_NUMBEROF_DIRECTORY_ENTRIES
)"
,IMAGE_NT_HEADERS:="
(
DWORD Signature;
_BinRun.IMAGE_FILE_HEADER FileHeader;
_BinRun.IMAGE_OPTIONAL_HEADER" (A_PtrSize=8?64:32) " OptionalHeader;
)"
,IMAGE_NT_HEADERS32:="
(
DWORD Signature;
_BinRun.IMAGE_FILE_HEADER FileHeader;
_BinRun.IMAGE_OPTIONAL_HEADER32 OptionalHeader;
)"
,IMAGE_NT_HEADERS64:="
(
DWORD Signature;
_BinRun.IMAGE_FILE_HEADER FileHeader;
_BinRun.IMAGE_OPTIONAL_HEADER64 OptionalHeader;
)"
,IMAGE_SECTION_HEADER:="
(
BYTE Name[8];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
};
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
)"
,FLOATING_SAVE_AREA :="
(
DWORD ControlWord;
DWORD StatusWord;
DWORD TagWord;
DWORD ErrorOffset;
DWORD ErrorSelector;
DWORD DataOffset;
DWORD DataSelector;
BYTE RegisterArea[80]; //SIZE_OF_80387_REGISTERS
DWORD Cr0NpxState;
)"
,PROCESS_INFORMATION :="
(
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
)"
,STARTUPINFO :="
(
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
)"
,M128A:="ULONGLONG Low;LONGLONG High"
,_XMM_SAVE_AREA32 :="
(
WORD ControlWord;
WORD StatusWord;
BYTE TagWord;
BYTE Reserved1;
WORD ErrorOpcode;
DWORD ErrorOffset;
WORD ErrorSelector;
WORD Reserved2;
DWORD DataOffset;
WORD DataSelector;
WORD Reserved3;
DWORD MxCsr;
DWORD MxCsr_Mask;
_BinRun.M128A FloatRegisters[8];
_BinRun.M128A XmmRegisters[16];
BYTE Reserved4[96];
)"
,CONTEXT64:="
(
DWORD64 P1Home;
DWORD64 P2Home;
DWORD64 P3Home;
DWORD64 P4Home;
DWORD64 P5Home;
DWORD64 P6Home;
DWORD ContextFlags;
DWORD MxCsr;
WORD SegCs;
WORD SegDs;
WORD SegEs;
WORD SegFs;
WORD SegGs;
WORD SegSs;
DWORD EFlags;
DWORD64 Dr0;
DWORD64 Dr1;
DWORD64 Dr2;
DWORD64 Dr3;
DWORD64 Dr6;
DWORD64 Dr7;
DWORD64 Rax;
DWORD64 Rcx;
DWORD64 Rdx;
DWORD64 Rbx;
DWORD64 Rsp;
DWORD64 Rbp;
DWORD64 Rsi;
DWORD64 Rdi;
DWORD64 R8;
DWORD64 R9;
DWORD64 R10;
DWORD64 R11;
DWORD64 R12;
DWORD64 R13;
DWORD64 R14;
DWORD64 R15;
DWORD64 Rip;
union {
_BinRun._XMM_SAVE_AREA32 FltSave;
struct {
_BinRun.M128A Header[2];
_BinRun.M128A Legacy[8];
_BinRun.M128A Xmm0;
_BinRun.M128A Xmm1;
_BinRun.M128A Xmm2;
_BinRun.M128A Xmm3;
_BinRun.M128A Xmm4;
_BinRun.M128A Xmm5;
_BinRun.M128A Xmm6;
_BinRun.M128A Xmm7;
_BinRun.M128A Xmm8;
_BinRun.M128A Xmm9;
_BinRun.M128A Xmm10;
_BinRun.M128A Xmm11;
_BinRun.M128A Xmm12;
_BinRun.M128A Xmm13;
_BinRun.M128A Xmm14;
_BinRun.M128A Xmm15;
};
};
_BinRun.M128A VectorRegister[26];
DWORD64 VectorControl;
DWORD64 DebugControl;
DWORD64 LastBranchToRip;
DWORD64 LastBranchFromRip;
DWORD64 LastExceptionToRip;
DWORD64 LastExceptionFromRip;
)"
,CONTEXT32:="
(
DWORD ContextFlags;
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
_BinRun.FLOATING_SAVE_AREA FloatSave;
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD SegCs; // MUST BE SANITIZED
DWORD EFlags; // MUST BE SANITIZED
DWORD Esp;
DWORD SegSs;
BYTE ExtendedRegisters[512]; // MAXIMUM_SUPPORTED_EXTENSION
)"
__New(pData,cmdLine="",cmdLineScript="",Hide=0,ExeToUse=""){
static IMAGE_NT_SIGNATURE:=17744,IMAGE_DOS_SIGNATURE:=23117,PAGE_EXECUTE_READWRITE:=64,CREATE_SUSPENDED:=4
static MEM_COMMIT:=4096,MEM_RESERVE:=8192,STARTF_USESHOWWINDOW:=1
If pData
If pData is not digit
{
; Try first reading the file from Resource
If res := DllCall("FindResource","PTR",lib:=DllCall("GetModuleHandle","PTR",0,"PTR"),"Str",pData,"PTR",10,"PTR")
VarSetCapacity(data,sz :=DllCall("SizeofResource","PTR",lib,"PTR",res))
,DllCall("RtlMoveMemory","PTR",&data,"PTR",DllCall("LockResource","PTR",hres:=DllCall("LoadResource","PTR",lib,"PTR",res,"PTR"),"PTR"),"PTR",sz)
,DllCall("FreeResource","PTR",hres)
,BinRun_Uncompress(data)
else ; else try reading file from disc etc...
FileRead,Data,*c %pData%
pData:=&Data
}
If InStr(cmdLine,"`n"){ ; a script was given, first line contains the cmdLine
PipeName := "\\.\pipe\AHK" A_TickCount
__PIPE_GA_ := DllCall("CreateNamedPipe","str",PipeName,"UInt",2,"UInt",0,"UInt",255,"UInt",0,"UInt",0,"PTR",0,"PTR",0)
__PIPE_ := DllCall("CreateNamedPipe","str",PipeName,"UInt",2,"UInt",0,"UInt",255,"UInt",0,"UInt",0,"PTR",0,"PTR",0)
if (__PIPE_=-1 or __PIPE_GA_=-1)
Return 0
Script:=(A_IsUnicode ? chr(0xfeff) : (chr(239) . chr(187) . chr(191))) SubStr(cmdLine,InStr(cmdLine,"`n")+1)
cmdLine:=Trim(SubStr(cmdLine,1,InStr(cmdLine,"`n")),"`n`r") A_Space PipeName
}
IDH:=new _Struct(_BinRun.IMAGE_DOS_HEADER,pData)
if (IDH.e_magic != IMAGE_DOS_SIGNATURE){
MsgBox ERROR: e_magic not found
return
}
INH := new _Struct(_BinRun.IMAGE_NT_HEADERS,pData + IDH.e_lfanew)
if (INH.Signature != IMAGE_NT_SIGNATURE){
MsgBox ERROR: Signature not found
return
}
If (A_PtrSize=8&&INH.OptionalHeader.magic=267) ; x86 on x64
pNtHeader:=new _Struct(_BinRun.IMAGE_NT_HEADERS32,pData + IDH.e_lfanew),ctx:=new _Struct(_BinRun.Context32),Force32Bit:=1
,ctx.ContextFlags := (A_PtrSize=8?0x100000:0x10000) | 0x2 ;CONTEXT_INTEGER
,UsedExe:=ExeToUse?ExeToUse:A_WinDir "\Microsoft.NET\Framework\v2.0.50727\vbc.exe"
else if (A_PtrSize=4&&INH.OptionalHeader.magic=523) ; x64 on x86 not possible
Return false
else
pNtHeader:=INH,UsedExe:=ExeToUse?ExeToUse:A_IsCompiled?A_ScriptFullPath:A_AhkPath
,ctx:=new _Struct(A_PtrSize=8?_BinRun.Context64:_BinRun.Context32),ctx.ContextFlags := (A_PtrSize=8?0x100000:0x10000) | 0x2 ;CONTEXT_INTEGER
pi:=new _Struct(_BinRun.PROCESS_INFORMATION)
si:=new _Struct(_BinRun.STARTUPINFO),si.cb:=sizeof(si),si.dwFlags:=HIDE?STARTF_USESHOWWINDOW:0 ;si.wShowWindow already set to 0
if DllCall("CreateProcess","PTR",0,"STR","""" UsedExe """" A_Space cmdLine (cmdLineScript?A_Space cmdLineScript:"")
,"PTR",0,"PTR",0,"int",0,"Int",CREATE_SUSPENDED,"PTR",0,"PTR",0,"PTR",si[],"PTR",pi[]){
if DllCall((Force32Bit?"Wow64":"") "GetThreadContext","PTR",pi.hThread,"PTR", ctx[]){
pPebImageBase:=ctx[A_PtrSize=8&&!Force32Bit?"Rdx":"Ebx"] + (Force32Bit?4:A_PtrSize)*2
if DllCall("ReadProcessMemory","PTR",pi.hProcess, "PTR", pPebImageBase,"PTR*", dwImagebase,"PTR", (Force32Bit?4:A_PtrSize),"Uint*",NumberOfBytes){
DllCall("ntdll\NtUnmapViewOfSection","PTR",pi.hProcess, "PTR",dwImagebase)
pImagebase := DllCall("VirtualAllocEx","PTR",pi.hProcess, "PTR",pNtHeader.OptionalHeader.ImageBase, "PTR",pNtHeader.OptionalHeader.SizeOfImage,"UInt", MEM_COMMIT|MEM_RESERVE,"UInt", PAGE_EXECUTE_READWRITE,"PTR")
if (pImagebase)
{
if DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pImagebase,"PTR",pData,"PTR",pNtHeader.OptionalHeader.SizeOfHeaders,"UInt*",NumberOfBytes){
pSecHeader :=new _Struct(_BinRun.IMAGE_SECTION_HEADER)
pSecHeader[] :=pNtHeader.OptionalHeader[""]+pNtHeader.FileHeader.SizeOfOptionalHeader
counter := 0
while (++counter < pNtHeader.FileHeader.NumberOfSections+1){
DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pImagebase + pSecHeader.VirtualAddress,"PTR",pData + pSecHeader.PointerToRawData,"PTR",pSecHeader.SizeOfRawData,"UInt*", NumberOfBytes)
pSecHeader[]:=pSecHeader[]+sizeof(pSecHeader)
}
if DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pPebImageBase,"PTR",pNtHeader.OptionalHeader.ImageBase[""],"PTR",(Force32Bit?4:A_PtrSize),"UInt*",NumberOfBytes){
ctx[A_PtrSize=8&&!Force32Bit?"Rcx":"Eax"] := pImagebase + pNtHeader.OptionalHeader.AddressOfEntryPoint
if DllCall((Force32Bit?"Wow64":"") "SetThreadContext","PTR",pi.hThread, "PTR",ctx[]){
if DllCall("ResumeThread","PTR",pi.hThread){
if (Script){ ; use pipe to pass script to new executable
DllCall("ConnectNamedPipe","PTR",__PIPE_GA_,"PTR",0)
DllCall("CloseHandle","PTR",__PIPE_GA_)
DllCall("ConnectNamedPipe","PTR",__PIPE_,"PTR",0)
if !DllCall("WriteFile","PTR",__PIPE_,"str",script,"UInt",(StrLen(script)+1)*(A_IsUnicode ? 2 : 1),"UInt*",0,"PTR",0)
Return DllCall("CloseHandle","PTR",__PIPE_),0
DllCall("CloseHandle","PTR",__PIPE_)
}
return pi.dwProcessId
}
}
}
}
}
}
}
DllCall("TerminateProcess","PTR",pi.hProcess,"UInt", 0)
}
return FALSE
}
}
BinRun(pData,cmdLine="",cmdLineScript="",Hide=0,ExeToUse=""){
return new _BinRun(pData,cmdLine,cmdLineScript,Hide,ExeToUse)
}
BinRun_Uncompress( ByRef D ) { ; Shortcode version of VarZ_Decompress() of VarZ 2.0 wrapper
; VarZ 2.0 by SKAN, 27-Sep-2012. http://www.autohotkey.com/community/viewtopic.php?t=45559
IfNotEqual, A_Tab, % ID:=NumGet(D,"UInt"), IfNotEqual, ID, 0x5F5A4C, Return 0, ErrorLevel := -1
savedHash := NumGet(D,4,"UInt"), TZ := NumGet(D,10,"UInt"), DZ := NumGet(D,14,"UInt")
DllCall( "shlwapi\HashData", UInt,&D+8, UInt,DZ+10, UIntP,Hash, UInt,4 )
IfNotEqual, Hash, %savedHash%, Return 0, ErrorLevel := -2
VarSetCapacity( TD,TZ,0 ), NTSTATUS := DllCall( "ntdll\RtlDecompressBuffer", UShort
, NumGet(D,8,"UShort"), PTR, &TD, UInt,TZ, PTR,&D+18, UInt,DZ, UIntP,Final, UInt )
IfNotEqual, NTSTATUS, 0, Return 0, ErrorLevel := NTSTATUS
VarSetCapacity( D,Final,0 ), DllCall( "RtlMoveMemory", PTR,&D, PTR,&TD, PTR,Final )
If NumGet(D,"UInt")=0x315F5A4C && NumPut(0x005F5A4C,D,"UInt")
Return BinRun_Uncompress( D )
Return Final, VarSetCapacity( D,-1 )
}
But i have a new Problem:
1) It's not working if i have special characters in the exe-filename. (not very important)
2) It's not working if i have 2 or more exe included. Only the first one is installed, the second fail. Any ideas? (important)