The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ragdog on February 04, 2008, 07:54:01 PM

Title: c++ translate
Post by: ragdog on February 04, 2008, 07:54:01 PM
hi

can your help me with translate a small algo from c++ to masm32 please?
   
I convert a c + + source to masm32
And here I come not Continue


void DoMeta(const char *meta)
{
char *p;
if (meta && (p=strstr(meta,"StreamTitle='"))) {
p=strdup(p+13);
strchr(p,';')[-1]=0;
MESS(30,WM_SETTEXT,0,p);
free(p);
}
}




thanks in forward

ragdog

Title: Re: c++ translate
Post by: ToutEnMasm on February 04, 2008, 09:43:24 PM
Hello,
With c++ the better way is to use the option  /FAs  that disassemble the source.

Title: Re: c++ translate
Post by: ragdog on February 04, 2008, 09:54:03 PM
thanks

Which I had already done, I found the apis not!

here is the dissambled code


sub_4014EC      proc near             
                                         
var_18          = dword ptr -18h
arg_0           = dword ptr  8

                 push    ebp
                 mov     ebp, esp
                 sub     esp, 14h
                 push    ebx
                 mov     eax, [ebp+arg_0]
                 test    eax, eax
                 jz      short loc_40154C
                 add     esp, 0FFFFFFF8h
              ;   push    offset aStreamtitle ; "StreamTitle='"
                ; push    eax             ; char *
                ; call    strstr       
             invoke StrStr,eax, offset aStreamtitle ; "StreamTitle='"
                 mov     ebx, eax
                 add     esp, 10h
                 test    ebx, ebx
                 jz      short loc_40154C
                 add     esp, 0FFFFFFF4h
                 lea     eax, [ebx+0Dh]
                 push    eax             ; char *
                 call    _strdup    ;  <-----------------------------------------------------------
                 mov     ebx, eax
                 add     esp, 0FFFFFFF8h
                 push    3Bh             ; int
                 push    ebx             ; char *
                 call    strchr    ;  <-----------------------------------------------------------
                 mov     byte ptr [eax-1], 0
                 add     esp, 20h
                 add     esp, 0FFFFFFF4h
                 push    ebx             ; lParam
                 push    0               ; wParam
                 push    0Ch             ; Msg
                 push    1Eh             ; nIDDlgItem
                 push    hWnd            ; hDlg
                 call    SendDlgItemMessageA
                 push    ebx             ; void *
                 call    free    ;  <-----------------------------------------------------------

loc_40154C:                             ; CODE XREF: sub_4014EC+Cj
                                         ; sub_4014EC+23j
                 mov     ebx, [ebp+var_18]
                 leave
                 retn
sub_4014EC      endp

here ist the format

StreamTitle='xxx-songxxx)';StreamUrl='http://www.xxx.com';




best regards
ragdog
Title: Re: c++ translate
Post by: ragdog on February 04, 2008, 10:20:50 PM
i have the StrStr algo found in the shlwapi.inc

   
Where can I find these strdup and strchr

can i use the free algo from the m32lib?

i have solved a little

my problem is

push  ebx   ; void *
call    Free 

i use this from m32lib and by this crash ma program
Title: Re: c++ translate
Post by: ragdog on February 04, 2008, 11:13:58 PM
here is my solution


ReadTitel     proc lpMetaData :DWORD     
                                         
                 push    ebx
                 mov     eax, lpMetaData
                 test    eax, eax
                 jz      @F
                 
              invoke     StrStr,eax,offset aStreamtitle ; "StreamTitle='"
                 mov     ebx, eax
                 test    ebx, ebx
                 jz      @F

                 lea     eax, [ebx+0Dh]
               invoke    StrDup,eax
                 mov     ebx, eax

               invoke    StrChr ,eax,3Bh
                 mov     byte ptr [eax-1], 0
              invoke     SendDlgItemMessage,hMain,1001,WM_SETTEXT,0,ebx
                ; push    ebx             ; void *
               ;  call    Free    ;  <-----------------------------------------------------------
@@:                           
                pop ebx         
                ret
ReadTitel      endp
Title: Re: c++ translate
Post by: MichaelW on February 04, 2008, 11:43:55 PM
The CRT  _strdup (http://msdn2.microsoft.com/en-us/library/y471khhc(VS.71).aspx) function calls the CRT malloc function to allocate the buffer, so to free the buffer you need to call the CRT free function, passing it the pointer returned by _strdup.
Title: Re: c++ translate
Post by: ragdog on February 05, 2008, 05:43:01 AM
hi

If I use (invoke free,ebx) works that not?!

greets
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 05, 2008, 09:08:00 AM
Hello,
Found !
The StrDup function use the  LocalAlloc  function to duplicate the string.
You must free the string with LocalFree


Quote
ReadTitel proc uses ebx lpMetaData :DWORD

.if lpMetaData != 0
   invoke StrStr,lpMetaData,addr aStreamtitle ; "StreamTitle="
   mov ebx, eax
   .if ebx != 0
      lea eax, [ebx+0Dh]
      invoke StrDup,eax         ;duplicate
      mov ebx, eax

      invoke StrChr ,ebx,";"
                                .If eax != 0
             mov byte ptr [eax-1], 0
                                .endif
      ;invoke SendDlgItemMessage,hMain,1001,WM_SETTEXT,0,ebx
      invoke LocalFree,ebx
   .endif   
.endif   
ret
ReadTitel endp
Title: Re: c++ translate
Post by: ragdog on February 05, 2008, 03:35:22 PM
thanks you ToutEnMasm for this source  :U

thanks you michaelW for your help

best regards
ragdog
Title: Re: c++ translate
Post by: ragdog on February 06, 2008, 06:02:07 PM
hi

   
I have a problem with new convert problem a callback proc!

What does this callback function in masm32

c++

void CALLBACK TestProc(
    HSYNC handle,
    DWORD channel,
    DWORD data,
    void *user
);


Is that correct so in masm32?



TestProc     proc handle:DWORD,channel:DWORD,data:DWORD,user:DWORD
                ret
TestProc     endp


disassembler code


TestProc     proc near               ; DATA XREF: DialogFunc+1FEo
                push    ebp
                 mov     ebp, esp
                 sub     esp, 8
                 call    sub_4014EC
                leave
               retn    10h
TestProc      endp




thanks in forward
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 06, 2008, 07:01:54 PM
Hello,
:U
Title: Re: c++ translate
Post by: ragdog on February 06, 2008, 08:07:11 PM
thanks :U
Title: Re: c++ translate
Post by: ragdog on February 07, 2008, 06:06:01 AM
good morning :bg

How can I call this function??

TestProg       PROTO :DWORD,:DWORD,:QWORD,:DWORD,:DWORD

this crash my program

invoke TestProg ,handle,Met,0,offset TestCallback,0

greets
ragdog
Title: Re: c++ translate
Post by: jj2007 on February 07, 2008, 07:55:50 AM
One usual syntax for subclassing callbacks is

       invoke SetWindowLong, hControl, GWL_WNDPROC, NameOfCallbackProc

So I wonder if removing the "offset" would help you, or if you should switch to the syntax above, i.e. use SetWindowLong.
Title: Re: c++ translate
Post by: ToutEnMasm on February 07, 2008, 08:51:45 AM
Hello,
Post the full source if you want help.
Title: Re: c++ translate
Post by: xmetal on February 07, 2008, 01:07:20 PM
Quote from: ragdog on February 07, 2008, 06:06:01 AM
How can I call this function??

TestProg       PROTO :DWORD,:DWORD,:QWORD,:DWORD,:DWORD

this crash my program

invoke TestProg ,handle,Met,0,offset TestCallback,0

I cannot even get something like that to assemble. MASM complains with an argument type mismatch error for the qword argument.

Try creating a qword variable, initializing it with the value you want to (in this case 0), and then passing it on.
Title: Re: c++ translate
Post by: ToutEnMasm on February 07, 2008, 01:38:47 PM
Hello,
Just replace the 0 of the QWORD by a QWORD in data and all is good.
Seems that 0 or NULL can be only a dword.
Quote
.data
DOUBLEQ QWORD 0
.code
invoke TestProg ,handle,Met,DOUBLEQ,offset TestCallback,0


Title: Re: c++ translate
Post by: ragdog on February 07, 2008, 04:03:08 PM
this works :U

invoke TestProgc,handle,Met,eax::edx,offset TestCallback,0

what is eax::edx??

greets
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 07, 2008, 04:27:53 PM

to make tests use a listing (ML /Fl or something like that) ,use .LISTALL and .NOLIST for a short listing.

Quote
         invoke Essai,NULL,NULL,DOUBLEQ,NULL,NULL   
0000003B  6A 00      *       push   +000000000h
0000003D  6A 00      *       push   +000000000h
0000003F  FF 35 00000004 R *       push   dword  ptr DOUBLEQ+000000004h
00000045  FF 35 00000000 R *       push   dword  ptr DOUBLEQ
0000004B  6A 00      *       push   +000000000h
0000004D  6A 00      *       push   +000000000h
0000004F  E8 00000959      *       call   Essai

Quote
   invoke Essai,NULL,NULL,eax::edx,NULL,NULL
0000003B  6A 00      *       push   +000000000h
0000003D  6A 00      *       push   +000000000h
0000003F  50         *       push   eax
00000040  52         *       push   edx
00000041  6A 00      *       push   +000000000h
00000043  6A 00      *       push   +000000000h
00000045  E8 00000959      *       call   Essai

Title: Re: c++ translate
Post by: ragdog on February 07, 2008, 04:38:09 PM
thanks for your help and examples :P

I have found a macro  that works well  :U


qinvoke MACRO function:REQ,p1,p2,p3,p4,p5,p6,p7,p8
                               
   push 0
    FOR arg,<p8,p7,p6,p5,p4,p3,p2,p1>
      IFNB <arg>         ; if not blank
         push arg     ; push parameter
      ENDIF
    ENDM
       call function       
ENDM


i use this

.data
DOUBLEQ QWORD 0
.code
invoke TestProg ,handle,Met,DOUBLEQ,offset TestCallback,0

greets
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 07, 2008, 05:14:23 PM

Be carefull with the various macro that can be found.You must understand well  what they do before use them.

Invoke is an integrate MASM macro.He grant you a correct result and is able to made some verifies.
The number of arguments is verify.
The size of each argument is verify.
He can solve for you arguments passed by value.

Title: Re: c++ translate
Post by: ragdog on February 07, 2008, 05:17:22 PM
ok thanks i use your DOUBLEQ function
Title: Re: c++ translate
Post by: MichaelW on February 07, 2008, 05:21:36 PM
Quote from: ragdog on February 07, 2008, 04:03:08 PM
what is eax::edx??

The description that I have seen in the MASM Programmer's Guide is:
Quote
You can pass a FAR pointer in a segment::offset pair, as shown in the following. Note the use of double colons to separate the register pair. The registers could be any other register pair, including a pair that an MS-DOS call uses to return values.

For the edx:eax register pair, used for example by the CRT to return a 64-bit integer, edx contains the most significant dword, so the pair would normally be specified as edx::eax. This would cause invoke to push edx first, placing it at the higher address and eax at the lower address, which is the normal order for values stored in memory.


Title: Re: c++ translate
Post by: ragdog on February 07, 2008, 06:11:45 PM
thank you MichaelW

which I would make without the forum?! certainly mikado playing  :bg :bdg

best regards
ragdog
Title: Re: c++ translate
Post by: ragdog on February 12, 2008, 04:45:06 PM
hi

i have a next problem with convert a c to masm32


URLDownloadToBuffer(szURL, &lpBuffer, &dwSize


BOOL URLDownloadToBuffer(LPCSTR lpszURL, LPBYTE *lpBuffer, DWORD *lpdwSize)
{
BOOL bResult = FALSE;
IStream *lpStream;
if(lpszURL && SUCCEEDED(URLOpenBlockingStream(NULL, lpszURL, &lpStream, 0, NULL))){
STATSTG statStream;
if(SUCCEEDED(lpStream->Stat(&statStream, STATFLAG_NONAME))){
DWORD dwSize = ++statStream.cbSize.LowPart;
*lpBuffer = (LPBYTE)malloc(dwSize);
if(*lpBuffer){
LARGE_INTEGER liPos;
ZeroMemory(&liPos, sizeof(liPos));
ZeroMemory(*lpBuffer, dwSize);
*lpdwSize = --dwSize;
lpStream->Seek(liPos, STREAM_SEEK_SET, NULL);
lpStream->Read(*lpBuffer, *lpdwSize, NULL);
bResult = TRUE;
}
}
lpStream->Release();
}
return bResult;
}



this works not correct with disassembled


sub_401260 proc near ; CODE XREF: _main+6Ep

var_50 = byte ptr -50h
Size = dword ptr -48h
Dst = dword ptr -8
var_4 = dword ptr -4
arg_0 = dword ptr  8
arg_4 = dword ptr  0Ch
arg_8 = dword ptr  10h

push ebp
mov ebp, esp
sub esp, 50h
push ebx
xor ebx, ebx
cmp [ebp+arg_0], ebx
jz loc_4012FC
push ebx ; LPBINDSTATUSCALLBACK
lea eax, [ebp+arg_0]
push ebx ; DWORD
push eax ; LPSTREAM *
push [ebp+arg_0] ; LPCSTR
push ebx ; LPUNKNOWN
call URLOpenBlockingStreamA
test eax, eax
jl short loc_4012FC
mov eax, [ebp+arg_0]
push esi
push edi
lea edx, [ebp+var_50]
mov ecx, [eax]
push 1
push edx
push eax
call dword ptr [ecx+30h]
test eax, eax
jl short loc_4012F1
inc [ebp+Size]
mov edi, [ebp+Size]
push edi ; Size
call malloc
mov esi, [ebp+arg_4]
cmp eax, ebx
pop ecx
mov [esi], eax
jz short loc_4012F1
push 8 ; Size
lea eax, [ebp+Dst]
push ebx ; Val
push eax ; Dst
call memset
push edi ; Size
push ebx ; Val
push dword ptr [esi] ; Dst
call memset
add esp, 18h
lea eax, [edi-1]
mov edi, [ebp+arg_8]
push ebx
push ebx
push [ebp+var_4]
mov [edi], eax
mov eax, [ebp+arg_0]
push [ebp+Dst]
mov ecx, [eax]
push eax
call dword ptr [ecx+14h]
mov eax, [ebp+arg_0]
push ebx
push dword ptr [edi]
mov ecx, [eax]
push dword ptr [esi]
push eax
call dword ptr [ecx+0Ch]
inc ebx

loc_4012F1: ; CODE XREF: sub_401260+38j
; sub_401260+4Fj
mov eax, [ebp+arg_0]
push eax
mov ecx, [eax]
call dword ptr [ecx+8]
pop edi
pop esi

loc_4012FC: ; CODE XREF: sub_401260+Cj
; sub_401260+23j
mov eax, ebx
pop ebx
leave
retn
sub_401260 endp



can you help me please?

greets
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 12, 2008, 05:20:28 PM
Hello,
This one use the IStream interface.You can't translate it without a translate of Objidl.h (objidl.sdk).You can download it in the masm32->windows.inc project.
You can use it in addition to your declaration or used the windows.sdk.
The Istream interface use the LARGE_INTEGER  and ULARGE_INTEGER structure passed by value.
ULARGE_INTEGER is defined in winnt.sdk.
using the trnslated interface:

Quote
using them
If you want to use NameInterface,all you have to do is:
1) create a data named ppvNameInterface,to put in the pointer on the interface.
2) Call the API that give you the pointer on it.
3) Use the macro NameInterface instead of invoke
   and use the functions of the interface as they were API
   sample:
   ISecurityInformation Release

The malloc function isn't accessible by masm ( perhaps someone as made it).You can used The Imalloc interface instead.



Title: Re: c++ translate
Post by: ragdog on February 12, 2008, 06:25:39 PM
thanks for your repply

mean you this?

IStream STRUCT
    Read          dd   ?
    Write          dd   ?
    Seek          dd   ?
    SetSize          dd   ?
    CopyTo          dd   ?
    Commit          dd   ?
    Revert          dd   ?
    LockRegion          dd   ?
    UnlockRegion       dd   ?
    Stat          dd   ?
    Clone          dd   ?
IStream ENDS
Title: Re: c++ translate
Post by: ToutEnMasm on February 12, 2008, 06:54:28 PM

You haven't donwloaded this:
http://pagesperso-orange.fr/luce.yves/translator.zip

A declaration of a com interface is in this form.It's a memory location with pointers to functions.

Quote
IStream_Seek TYPEDEF  PROTO :DWORD ,:LARGE_INTEGER ,:DWORD ,:DWORD
FIStream_Seek TYPEDEF PTR  IStream_Seek

IStream_SetSize TYPEDEF  PROTO :DWORD ,:ULARGE_INTEGER
FIStream_SetSize TYPEDEF PTR  IStream_SetSize

IStream_CopyTo TYPEDEF  PROTO :DWORD ,:DWORD ,:ULARGE_INTEGER ,:DWORD ,:DWORD
FIStream_CopyTo TYPEDEF PTR  IStream_CopyTo

IStream_LockRegion TYPEDEF  PROTO :DWORD ,:ULARGE_INTEGER ,:ULARGE_INTEGER ,:DWORD
FIStream_LockRegion TYPEDEF PTR  IStream_LockRegion

IStream_UnlockRegion TYPEDEF  PROTO :DWORD ,:ULARGE_INTEGER ,:ULARGE_INTEGER ,:DWORD
FIStream_UnlockRegion TYPEDEF PTR  IStream_UnlockRegion

   STIStream   STRUCT
      QueryInterface                  comethod3 ?
      AddRef                          comethod1 ?
      Release                         comethod1 ?
      Read                            comethod4 ?
      Write                           comethod4 ?
      Seek      FIStream_Seek  ?
      SetSize      FIStream_SetSize  ?
      CopyTo      FIStream_CopyTo  ?
      Commit                          comethod2 ?
      Revert                          comethod1 ?
      LockRegion      FIStream_LockRegion  ?
      UnlockRegion      FIStream_UnlockRegion  ?
      Stat                            comethod3 ?
      Clone                           comethod2 ?
   STIStream   ENDS

IStream MACRO  Function:REQ, args:VARARG
   ; definition de la macro locale InvokeInterface
    LOCAL InvokeInterface, arg
    FOR arg, <args>     ;verifier que edx n'est pas dans la liste d'arguments args
        IFIDNI <&arg>, <edx>   ;
            .ERR <edx is not allowed as a coinvoke parameter>
        ENDIF
    ENDM
    IFIDNI <&pInterface>, <edx>
        .ERR <edx is not allowed as a coinvoke parameter>
    ENDIF
   ;InvokeInterface = concatene ...CATSTR(concatene) MACRO instruction MASM32   
   ;---------- on doit mettre ppv en premier argument -----------------------------------
    InvokeInterface CATSTR <invoke (STIStream PTR[edx]).>,<&Function,ppvIStream>
    IFNB <args>     ; add the list of parameter arguments if any
        InvokeInterface CATSTR InvokeInterface, <, >, <&args>
    ENDIF
   ;   forme les lignes de codes
    mov edx, ppvIStream
    mov edx, [edx]
    InvokeInterface
ENDM      

Title: Re: c++ translate
Post by: ToutEnMasm on February 12, 2008, 07:27:32 PM

I have said one error, the malloc function is usable with the windows.sdk,just include the malloc.sdk and give to your masm source code a c entry code with WinMain and the libcmt.lib
Title: Re: c++ translate
Post by: ragdog on February 12, 2008, 08:51:48 PM
thanks for the good information :U

i convert the OnProgressProc callback

my question is this correct?


;sub_401468   proc near      ; DATA XREF: .data:00401230o
;
;var_18      = qword   ptr -18h    ; lpThis
;var_10      = qword   ptr -10h    ';ulProgress
;var_8      = qword   ptr -8        ;ulProgressMax
;arg_4      = dword   ptr  0Ch    ;,ulStatusCode
;arg_8      = dword   ptr  10h   ;szStatusText


masm32
OnProgressProc      PROC lpThis:DWORD, ulProgress:DWORD,ulProgressMax:DWORD,ulStatusCode:DWORD,szStatusText:DWORD

in c++

printf("%.2fMb of %.2fMb\r", ((float)ulProgress / (1024*1024)), ((float)ulProgressMax / (1024*1024)));


here is the disassembled code



.data
a_2fmbOf_2fmb db "%.2fMb of %.2fMb",0

.data?
   flt_401244 dd 9.5367432e-7

.code
;sub_401468 proc near ; DATA XREF: .data:00401230o
;
;var_18 = qword ptr -18h
;var_10 = qword ptr -10h
;var_8 = qword ptr -8
;arg_4 = dword ptr  0Ch
;arg_8 = dword ptr  10h
;
; push ebp
; mov ebp, esp
; push ecx
; push ecx
; mov eax, [ebp+arg_8]
; and dword ptr [ebp+var_8+4], 0
; mov dword ptr [ebp+var_8], eax
; mov eax, [ebp+arg_4]
; fild [ebp+var_8]
; and dword ptr [ebp+var_8+4], 0
; sub esp, 10h
; mov dword ptr [ebp+var_8], eax
; fmul flt_401244
; fstp [esp+18h+var_10]
; fild [ebp+var_8]
; fmul flt_401244
; fstp [esp+18h+var_18]
; push offset a_2fmbOf_2fmb ; "%.2fMb of %.2fMb\r"
; call printf
; add esp, 14h
; xor eax, eax
; leave
; retn 14h
;sub_401468 endp



thanks in forward
and best regards
Title: Re: c++ translate
Post by: ragdog on February 13, 2008, 06:14:46 AM
hi

can your help PLEASE :'(

   
The download status calculated in kp> mb> gb

I understand fpu not so good


OnProgressProc proc PROC lpThis:DWORD, ulProgress:DWORD,ulProgressMax:DWORD,ulStatusCode:DWORD,szStatusText:DWORD
LOCAL lpAvailableBytes :DWORD
LOCAL lpTotalBytes:DWORD

.data
OneK REAL10 1024.0

.code
;; kb
      finit
  fld OneK
  fild ulProgress    
  fdiv ST(0),ST(1)
  fistp lpAvailableBytes
  fild ulProgressMax
  fdiv ST(0),ST(1)
  fistp  lpTotalBytes
;; mb

;; gb
invoke wsprintf, addr szStringBuff, chr$("%lu of %lu"),lpAvailableBytes, lpTotalBytes
invoke SendMessage, hTitle, WM_SETTEXT, 0, offset szStringBuff
ret
OnProgressProc endp


greets
ragdog
Title: Re: c++ translate
Post by: ToutEnMasm on February 13, 2008, 08:30:20 AM
Problem with the translation of c++ code fpu is that c++ optimize the  calcul in ways not very clear.
You can follow these steps to reach the goal.
- Understand well what the fpu calculate (make an algebric formula).
-Don't follow the disassembled code,rewrite it.
- Take care with the size of each operand and his type (instructions are not the same)
- Use a trick: Create a QWORD and use the fst instruction to store (without poping the stack) the content  of st(n).Debug it and have a look on this QWORD.
At each step of the calcul,verify that you have what you want,surprises are granted.
-Leave the FPU with nothing in the stack
Title: Re: c++ translate
Post by: ragdog on February 13, 2008, 04:24:04 PM
thanks ToutEnMasm :U

for the good information and help!!!!

my problem is solved my algo convert fom (byte>kb>mb>gb>tb) in fpu

best regards
ragdog