Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Assembly Language Programming (ALP) Forum (http://www.go4expert.com/forums/assembly-language-programming-forum/)
-   -   [HELP] Problems with URLDownloadToFileA (http://www.go4expert.com/forums/help-urldownloadtofilea-t18627/)

lShadowl 20Jul2009 09:27

[HELP] Problems with URLDownloadToFileA
 
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 ?

-------------------------------------------------------------------------

xpi0t0s 20Jul2009 12:14

Re: [HELP] Problems with URLDownloadToFileA
 
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.

lShadowl 20Jul2009 12:33

Re: [HELP] Problems with URLDownloadToFileA
 
Well, thanks for the reply.

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

Quote:

_b1 db 'LINK',0
_b2 db 'FILE',0
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.

xpi0t0s 20Jul2009 14:31

Re: [HELP] Problems with URLDownloadToFileA
 
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.

xpi0t0s 20Jul2009 14:34

Re: [HELP] Problems with URLDownloadToFileA
 
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?


All times are GMT +5.5. The time now is 06:00.