News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Treeview and 64 bit program with LARGEADDRESSAWARE switch set

Started by FlySky, April 16, 2016, 08:14:19 PM

Previous topic - Next topic

FlySky

I am having problems porting x86 code x64.
I am having a Treeview on a dialogbox which I want to fill with all running processes.

Having the LARGEADDRESSAWARE switch NOT set the Treeview works but the information is not set inside the Treeview.
My guess it has to do with structure definitions but can't seem to figure it out.
Using the LARGEADDRESSAWARE switch the Treeview will crash.

here's my code:

Info_DialogProc Frame hWin, uMsg, wParam, lParam

      cmp D[uMsg], WM_INITDIALOG
      jne >> .WM_CLOSE_MESSAGE
      
      //set icon
      invoke LoadIcon, [hInstance], 90   
      invoke SendMessage, [hWin], WM_SETICON, ICON_SMALL, rax               //set icon
      
      //retrieve handle from treeview control
      invoke GetDlgItem, [hWin], ID_DIALOG_INFO_TREEVIEW
      mov [TreeViewHandle], rax
      
      //fill our treeview with all processes running
      invoke Retrieve_ProcessList, [TreeViewHandle]
      
.WM_CLOSE_MESSAGE:
   
      cmp D[uMsg], WM_CLOSE
      jne > .WM_COMMAND_MESSAGE
         invoke EndDialog, [hWin], NULL

.WM_COMMAND_MESSAGE:

      cmp D[uMsg], WM_COMMAND
      jne >

      :
.end:
      xor rax, rax
      ret
EndF

Retrieve_ProcessList Frame TreeViewHandle
   
   //this functions shows all running processes
   Local tvinsert      :TV_INSERTSTRUCT
   Local pe32         :PROCESSENTRY32
   Local hProcessSnap   :Q
   Local Wow64Bool   :Q
   Local phandle      :Q

   invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
   mov [hProcessSnap], rax

   mov D[pe32.dwSize], SIZEOF PROCESSENTRY32
   invoke Process32First, [hProcessSnap], offset pe32
   cmp rax, 0
   jnz > .store_running_process_string
   
.get_next_running_process
   invoke Process32Next, [hProcessSnap], offset pe32
   cmp rax, 0
   jz >> .get_running_process_exit

.store_running_process_string
   invoke OpenProcess, PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION| PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_TERMINATE, NULL,[pe32.th32ProcessID]
   mov [phandle], rax
   invoke IsWow64Process, rax, offset Wow64Bool
   cmp B[Wow64Bool], 1
   je >>
   //retrieve process id and .exe name string
   invoke wsprintf, offset wsprintfbuffer, '%.8d %s', [pe32.th32ProcessID], offset pe32.szExeFile
   mov Q[tvinsert.hParent], NULL
       mov Q[tvinsert.hInsertAfter], TVI_ROOT
       mov D[tvinsert.item.mask], TVIF_TEXT
       mov Q[tvinsert.item.pszText], offset wsprintfbuffer
     mov D[tvinsert.item.iImage], NULL
       mov D[tvinsert.item.iSelectedImage], 1
       invoke SendMessage, [TreeViewHandle], TVM_INSERTITEM, 0, offset tvinsert
        
     //invoke GetProcessImageFileName, eax, offset ImageFileName, sizeof ImageFileName   //returns full device name
     //invoke GetModuleFileNameEx, eax, NULL, offset ImageFileName, sizeof ImageFileName
     invoke GetModuleFileNameEx, [phandle], NULL, offset FilePathBuffer, sizeof FilePathBuffer    
     mov Q[tvinsert.hInsertAfter], TVI_LAST
     //mov Q[tvinsert.item.pszText], offset ImageFileName
     mov Q[tvinsert.item.pszText], offset FilePathBuffer
     invoke SendMessage, [TreeViewHandle], TVM_INSERTITEM, 0, offset tvinsert
   :
   jmp < .get_next_running_process

.get_running_process_exit
   xor rax, rax
   ret
Endf

And here are the structure definitions in Commctrl.h

#define TV_INSERTSTRUCTA TVINSERTSTRUCTA
#define TV_INSERTSTRUCTA TVINSERTSTRUCTW

TVINSERTSTRUCTA STRUCT
   hParent HANDLE
   hInsertAfter HANDLE
   UNION
      itemex TVITEMEXA
      item TVITEMA
   ENDUNION
ENDS

TVITEMEXA STRUCT
   mask DD
   hItem HANDLE
   state DD
   stateMask DD
   pszText PTR
   cchTextMax DD
   iImage DD
   iSelectedImage DD
   cChildren DD
   lParam LPARAM
   iIntegral DD
   uStateEx DD
#IF WINVER >= NTDDI_VISTA
   hwnd HANDLE
   iExpandedImage DD
#ENDIF
#IF WINVER >= NTDDI_WIN7
   iReserved DD
#ENDIF
ENDS

TVITEMA STRUCT
   mask DD
   hItem HANDLE
   state DD
   stateMask DD
   pszText PTR
   cchTextMax DD
   iImage DD
   iSelectedImage DD
   cChildren DD
   lParam LPARAM
ENDS


sinsi

Structure elements in x64 need to be aligned to their natural size.

TVITEMA STRUCT
   mask DD
   hItem HANDLE
...
ENDS

hItem is 8 bytes but here is aligned to 4, so everything after it is misaligned.
MASM syntax would be

TVITEMA STRUCT 8
   mask DD
   hItem HANDLE
...
ENDS
;or
TVITEMA STRUCT
   mask DD
   align1  DD
   hItem HANDLE
...
ENDS


TWell

typedef struct tagTVITEMEX {
  UINT      mask;
  HTREEITEM hItem;
  UINT      state;
  UINT      stateMask;
  LPTSTR    pszText;
  int       cchTextMax;
  int       iImage;
  int       iSelectedImage;
  int       cChildren;
  LPARAM    lParam;
  int       iIntegral;
#if (_WIN32_IE >= 0x0600)
  UINT      uStateEx;
  HWND      hwnd;
  int       iExpandedImage;
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
  int       iReserved;
#endif
} TVITEMEX, *LPTVITEMEX;
So in x64 int and pointers are QWORD / DQ?
Your structs are for 32-bit?

habran

Hi TWell,
If you want to keep LARGEADDRESSAWARE you can not use :
   jmp somelabel[rax*8]
  or
   jmp [somelabel+rax*8] 
you have to dothis:
  lea rcx,somelabel
  jmp QWORD PTR[rcx+rax*8]
Cod-Father

FlySky

Thanks for the answers guys,

I've found on google that the TVITEMEX structure on x86 = 60 bytes and on x64 = 80 bytes

I am trying to determine the right function defintions, here are my results so far.

Freaking code still crashes though so at the moment it's trial and error to determine the right structures.

TV_INSERTSTRUCT64 STRUCT
   hParent DQ
   hInsertAfter DQ
   UNION
      itemex TV_ITEMEX64
      item TV_ITEM64
   ENDUNION
ENDS

TV_ITEMEX64 STRUCT      //Total size on x86 = 60 bytes on x64 = 80 bytes
   mask DD             // 0                    - size 4
    hItem DD            // 4                    - size 8
   state DD            // 8                    - size 12
    stateMask DD        // 12                   - size 16
    padding2 DD         //                      - size 20
    pszText DQ          // 16 --> 20 after padding (a pointer)  - size 28
   cchTextMax DD       // 28                   - size 32
    iImage DD           // 32                   - size 36
    iSelectedImage DD   // 36                   - size 40
    cChildren DD        // 40                   - size 44
    padding3 DD         //                      - size 48                           
    lParam DQ           // 44 --> 48 after padding (a pointer)  - size 56
   iIntegral DD        // 56                   - size 60
#IF WINVER >= NTDDI_VISTA
    uStateEx DD         // 60                   - size 64
    hwnd DD             // 64                   - size 68
   iExpandedImage DD   // 68                   - size 72
#ENDIF
#IF WINVER >= NTDDI_WIN7
    iReserved DD        // 72                   - size 76
    padding4 DD         // 76 --> Total lenght before padding is 76 which is not dividable by 8 - size 80
#ENDIF
ENDS

TV_ITEM64 STRUCT        //Total size 56 bytes
mask DD             // 0                    - size 4
hItem DD            // 4                    - size 8
state DD            // 8                    - size 12
stateMask DD        // 12                   - size 16
padding2 DD         //                      - size 20
pszText DQ          // 16 --> 20 after padding (a pointer)  - size 28
cchTextMax DD       // 28                   - size 32
iImage DD           // 32                   - size 36
iSelectedImage DD   // 36                   - size 40
cChildren DD        // 40                   - size 44
padding3 DD         //                      - size 48
lParam DQ           // 44 --> 48 after padding (a pointer) - Total lenght is 56 which is dividable by 8 - size 56 bytes
ENDS

Although I think hItem should be a QWORD aswell following the rules that handles are 64 bit on 64 bit Windows.

TouEnMasm

Quote
I've found on google that the TVITEMEX structure on x86 = 60 bytes and on x64 = 80 bytes
Must be a world of despair,you have include who give you the correct size of the structure here:
http://masm32.com/board/index.php?topic=563.msg4563#msg4563
in commctrl.sdk DEFALIGNMASM get a defaut value,8=QWORD
Quote
TVITEMEXA   STRUCT DEFALIGNMASM
   imask DWORD ?
   hItem XMASM ?
   state DWORD ?
   stateMask DWORD ?
   pszText XMASM ?
   cchTextMax DWORD ?
   iImage DWORD ?
   iSelectedImage DWORD ?
   cChildren DWORD ?
   lParam LPARAM ?
   iIntegral DWORD ?
IF ( _WIN32_IE GE 00600h)
   uStateEx DWORD ?
   hwnd HWND ?
   iExpandedImage DWORD ?
ENDIF
IF ( NTDDI_VERSION GE  NTDDI_WIN7)
   iReserved DWORD ?
ENDIF
TVITEMEXA      ENDS

Fa is a musical note to play with CL