News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

struct memory in new thread problem

Started by ecube, September 12, 2007, 04:39:30 AM

Previous topic - Next topic

ecube

the code below is simple yet the results are confusing to me, first if I try and copy a string to a buffer within a struct and messagebox it, it shows the string but also a bunch of garbage...i'm guessing this is from the stack, and I fix this using rtlzeromemory ahead of time. The real problem is the string isn't showing correctly in a messagebox in the new thread and I have no idea why, any help would be much appreciated.


.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\advapi32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib

ThreadMaker proto
NewDataTest proto :DWORD
CopyMem proto :dword, :dword, :dword

     CTEXT MACRO text:VARARG
            local TxtName
              .data
               TxtName BYTE text,0
              .code
            EXITM <ADDR TxtName>
     ENDM

.data?
mytest struct
  dwone             dword ?
  dwtwo             byte ?
  szbuff            byte 64 dup (?)
mytest ends

.code
start:
invoke ThreadMaker
invoke Sleep,10000
invoke ExitProcess,0

ThreadMaker proc
local testit:mytest
  invoke RtlZeroMemory,addr testit,sizeof testit
  mov testit.dwone, 3
  mov testit.dwtwo, 0
  invoke CopyMem, addr testit.szbuff,CTEXT("abc"),3
  invoke Sleep,10
  invoke MessageBox,0,CTEXT("startin new thread"),addr testit.szbuff,MB_OK
  invoke CreateThread, 0, 0, addr NewDataTest, addr testit, 0, 0
  invoke CloseHandle,eax
  ret
ThreadMaker endp

NewDataTest proc lpParam:dword
local testit:mytest
invoke RtlZeroMemory,addr testit,sizeof testit
invoke CopyMem, addr testit, lpParam, sizeof testit
invoke MessageBox,0,addr testit.szbuff,CTEXT("the string"),MB_OK
invoke ExitProcess,0
ret
NewDataTest endp


CopyMem proc public uses esi edi dwDestination:dword, dwSource:dword, dwLen: dword
    cld
    mov esi, [dwSource]
    mov edi, [dwDestination]
    mov ecx, [dwLen]

    shr ecx, 2
    rep movsd

    mov ecx, [dwLen]
    and ecx, 3
    rep movsb   
    ret
CopyMem endp
end start

six_L

Hello,E^cube
lpParam(Local) is an address, but the datas is in another proc.
.data?
   ...
   aBuf   db 69 dup(?) (Global)
.code

;--------------------------
   invoke MessageBox,0,CTEXT("start in new thread"),addr testit.szbuff,MB_OK
   invoke CopyMem, addr aBuf,addr testit, sizeof testit
   invoke CreateThread, 0, 0, addr NewDataTest, addr aBuf, 0, 0
;--------------------------

regards

ecube

thanks six but I figured it out it the new thread time to copy the data over, heres the fixed code


.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\advapi32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
ThreadMaker proto
NewDataTest proto :DWORD
CopyMem proto :dword, :dword, :dword
     CTEXT MACRO text:VARARG
            local TxtName
              .data
               TxtName BYTE text,0
              .code
            EXITM <ADDR TxtName>
     ENDM

.data?
mytest struct
  dwone             dword ?
  dwtwo             byte ?
  szbuff            byte 64 dup (?)
mytest ends

.code
start:
invoke ThreadMaker
invoke Sleep,10000
invoke ExitProcess,0

ThreadMaker proc
local testit:mytest
  invoke RtlZeroMemory,addr testit,sizeof testit
  mov testit.dwone, 3
  mov testit.dwtwo, 0
  invoke CopyMem, addr testit.szbuff,CTEXT("abc"),3
  invoke Sleep,10
  invoke MessageBox,0,CTEXT("startin new thread"),addr testit.szbuff,MB_OK
  invoke CreateThread, 0, 0, addr NewDataTest, addr testit, 0, 0
  .while testit.dwtwo != 1
    invoke Sleep, 10
  .endw
  invoke CloseHandle,eax
  ret
ThreadMaker endp

NewDataTest proc lpParam:dword
local testit:mytest
invoke RtlZeroMemory,addr testit,sizeof testit
invoke CopyMem, addr testit, lpParam, sizeof testit
mov eax, lpParam
assume eax:ptr mytest
mov [eax].dwtwo, 1
assume eax:nothing
invoke MessageBox,0,addr testit.szbuff,CTEXT("the string"),MB_OK
invoke ExitProcess,0
ret
NewDataTest endp


CopyMem proc public uses esi edi dwDestination:dword, dwSource:dword, dwLen: dword
    cld
    mov esi, [dwSource]
    mov edi, [dwDestination]
    mov ecx, [dwLen]

    shr ecx, 2
    rep movsd

    mov ecx, [dwLen]
    and ecx, 3
    rep movsb   
    ret
CopyMem endp
end start

zooba

The garbage is caused because (by convention) strings require a null-terminator, ie. there must be one character after the last one with a value of zero.

CopyMem copies exactly 3 bytes, which won't include the null-terminator added by CTEXT(). You can copy 4 bytes and it will work. Zeroing the entire structure also works because there is now a null-terminator.

There's also no need to copy the structure in the new thread, you can simply access it. Threads within a single process share the same address space, so addresses are valid across threads. To share something across processes you need to use a file map (see CreateFileMapping, and notice that you don't actually need to use a file to create a file map).

Cheers,

Zooba :U