[HELP] Problems with URLDownloadToFileA

Discussion in 'Assembly Language Programming (ALP) Forum' started by lShadowl, Jul 20, 2009.

  1. lShadowl

    lShadowl New Member

    Joined:
    Jul 20, 2009
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    I am guessing why this code are not working

    --------------------------------------code.asm--------------
    Code:
    format PE GUI 4.0
    entry start
    
    include 'win32a.inc'
    include 'cmd.inc'
    
      start:
        invoke    GetProcessHeap
        mov    [_hheap],eax
        invoke    HeapAlloc,[_hheap],HEAP_ZERO_MEMORY,1000h
        mov    [_b1],eax
        mov    [_b2],eax
    
        call    GetMainArgs
        mov    esi,[_argv]
        mov    ebx,[_argc]
        add    esi,4
        cinvoke wsprintf,[_b1],_fmt,[esi]
        add    esi,4
        cinvoke wsprintf,[_b2],_fmt,[esi]
        invoke URLDownloadToFileA,0,[_b1],[_b2],0,0
        invoke Sleep,7000
    
        invoke    HeapFree,[_hheap],0,[_argv]
        invoke    HeapFree,[_hheap],0,[_b1]
        invoke    HeapFree,[_hheap],0,[_b2]
        invoke    ExitProcess,0
    
    _fmt     db '"%s"',0
    _hheap     dd ?
    _b1     dd ?
    _b2     dd ?
    
    data import
     library kernel,'KERNEL32.DLL',\
         urlmon,'urlmon.dll',\
         user,'USER32.DLL'
    
     import kernel,\
         GetCommandLine,'GetCommandLineA',\
         GetProcessHeap,'GetProcessHeap',\
         HeapAlloc,'HeapAlloc',\
         HeapFree,'HeapFree',\
         Sleep, 'Sleep',\
         ExitProcess,'ExitProcess'
    
     import user,\
        wsprintf,'wsprintfA'
    
     import urlmon,\
         URLDownloadToFileA,'URLDownloadToFileA'
    end data
    ----------------------------------------------------------------------



    Ok, the problem is in this line:

    invoke URLDownloadToFileA,0,[_b1],[_b2],0,0

    when i invoke the function defining _b1 and _b2 like:

    _b1 db 'LINK',0
    _b2 db 'FILE',0

    and invoking like:

    invoke URLDownloadToFileA,0,_b1,_b2,0,0

    it works pretty good, but if i try to do it with the given cmd parameters it just doesnt work.

    How can i get it work using the given parameters?

    Thanks for the help!


    -----------------------------------------cmd.inc--------------------
    Code:
    ; GetMainArgs v1.01
    ; Copyright © 2003 Theodor-Iulian Ciobanu
    
    ; uses heap instead of local
    
      GetMainArgs:
            pusha
            invoke  GetCommandLine  ;_argc - number of args, _argv - ptr to arg table
            mov     [_argc],0
            xor     ebx,ebx
            cmp     byte [eax],22h  ;quotation mark
            jz      .startquote
            mov     [_argc],1
            push    eax
    
        .count:
            cmp     byte [eax],0
            jz      .endcount
            cmp     byte [eax],22h  ;quotation mark
            jz      .solvequote
            cmp     ebx,1           ;is in quote
            jz      .isinquote
            cmp     byte [eax],20h  ;space
            jz      .pusharg
            cmp     byte [eax],09h  ;tab
            jz      .pusharg
          .isinquote:
            inc     eax
            jmp     .count
    
        .pusharg:
            mov     byte [eax],0
            inc     eax
          .remspaces:
            cmp     byte [eax],0
            jz      .endcount
            cmp     byte [eax],22h  ;quotation mark
            jz      .startquote
            cmp     byte [eax],20h  ;space
            jz      .isspace
            cmp     byte [eax],09h  ;tab
            jnz     .endremspaces
          .isspace:
            inc     eax
            jmp     .remspaces
          .endremspaces:
            inc     [_argc]
            push    eax
            jmp     .count
    
        .solvequote:
            cmp     ebx,1
            jz      .endquote
          .startquote:
            mov     ebx,1
            inc     eax
            jmp     .endremspaces
          .endquote:
            mov     ebx,0
            jmp     .pusharg
    
        .endcount:
            mov     eax,[_argc]
            mov     ecx,4
            mul     ecx
            push    eax
            invoke  HeapAlloc,[_hheap],HEAP_ZERO_MEMORY,eax
            mov     [_argv],eax
            pop     eax
            sub     eax,4
            mov     esi,[_argv]
            add     esi,eax
    
        .saveargs:
            cmp     esi,[_argv]
            jb      .endsaveargs
            pop     eax
            mov     [esi],eax
            sub     esi,4
            jmp     .saveargs
    
        .endsaveargs:
            popa
            ret
    
    _argc    dd ?
    _argv    dd ?
    -------------------------------------------------------------------------
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    What's the difference between [_b1] and _b1?
    If it works with _b1, why do you want to use [_b1] instead of _b1, especially knowing that [_b1] doesn't work?
    How exactly doesn't it work - do you get an error, a warning, a crash, ...what?
    If you're only guessing how the whole code doesn't work, how did you decide it was the URLDownloadToFileA line that was broken?

    The first question has two aims: (1) to get you to think about the difference because that might show why it doesn't work, and (2) because I don't know. At a guess the square brackets transform the value in the register in some way, but I'm not clear what; thought perhaps it dereferenced the pointer but if that's the case then "mov [_argc],0" doesn't make sense. The prototype at
    http://msdn.microsoft.com/en-us/library/ms836120.aspx
    shows the two parameters in question are defined as LPCTSTR so maybe that has something to do with it.
     
  3. lShadowl

    lShadowl New Member

    Joined:
    Jul 20, 2009
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Well, thanks for the reply.

    1)about [_b1] and _b1, remember that it works if i define b1

    but i dont want to define those variables, i want to give the parameters to the variables so i can call the program like:

    >program LINK FILE

    the code put "LINK" in b1 and "FILE" in b2 then invoke URLDownloadToFileA with those parameters.

    2) The program doesn't crash, it compiles without any error or warning, but when i execute it, it just doesn't do what is supposed to do (download a file). But, as i said, if i define the variables and giving no parameters when i execute it, it work (it download the file).

    3) The difference about [_b1] and _b1 is that _b1 is a pointer and [_b1] is the value contained in this address.
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    OK, so [] does dereference the pointer as I guessed. Dereferencing isn't going to solve the problem. _b1 is defined as "_b1 db 'LINK',0", i.e. _b1 is the address of the L which is the first character of a null-terminated string. If you invoke the program as you want, i.e. "program LINK FILE" then LINK will be in argv[1] and FILE in argv[2] (*), so just set _b1 and _b2 equal to argv[1] and argv[2] (which also contain the address of the first character of a null-terminated string).
    Code:
    mov _b1, (whatever is equivalent to argv[1])
    mov _b2, (whatever is equivalent to argv[2])
    invoke URLDownloadToFileA,0,_b1,_b2,0,0
    
    (*) Assuming that, say, program "C:\a b c\link" "C:\d e f\file" results in argv containing two items and not 6 (which would be "C:\a, b, c\link", "C:\d, e, f\file" (comma separated)) (yeah I know the first is a URL but this is illustrative only). If you get 6 items then obviously you're going to have to do some string manipulation before you can assign _b1 and _b2.
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Ref. "mov [_argc],0" In C argc is provided to the program as int, not pointer-to-int, so the equivalent of this, i.e. "*argc=0;" would crash the program. Make sure _argc is a pointer-to-int and not just an int. However why would you want to set argc zero anyway?
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice