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
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
;--------------------------
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
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