Pelles C forum

C language => Tips & tricks => Topic started by: TimoVJL on August 08, 2010, 02:56:12 PM

Title: URLDownloadToFile example
Post by: TimoVJL on August 08, 2010, 02:56:12 PM
here is simple URLDownloadToFile example.

Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <urlmon.h>

#pragma lib "urlmon.lib"

/*
HRESULT URLDownloadToFile(LPUNKNOWN pCaller,LPCTSTR szURL,
LPCTSTR szFileName,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB);
*/

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HRESULT hRC;
int nIdx, nLen, nPos;
char szIni[260], szURL[260], szURLFile[260], szFile[260], szTmp[100];
char szDir[260];

//SearchPath(NULL, TEXT("."), NULL, sizeof(szIni)/sizeof(TCHAR), szIni, NULL);
SearchPath(NULL, ".", NULL, sizeof(szIni), szIni, NULL);
lstrcat(szIni, "\\Files.ini");
if (!GetPrivateProfileString("Server", "URL", "", szURL, sizeof(szURL), szIni)) {
MessageBox(0, "Missing URL", "URLDownload", MB_OK);
return 1;
}

nIdx = 1;
while (1) {
wsprintf(szTmp, TEXT("File_%i"), nIdx);
if (!GetPrivateProfileString("Files", szTmp, "", szFile, sizeof(szFile), szIni))
break;
nLen = lstrlen(szFile); // name length
for (nPos = 0; nPos<nLen; nPos++) {
szDir[nPos] = szFile[nPos];
if (szDir[nPos] == '\\' || szDir[nPos] == '/') { // directory
//szDir[nPos] = '\\'; // works without this in WinXP
//szFile[nPos] = '/'; //
szDir[nPos+1] = 0;
if (GetFileAttributes(szDir) == -1)
CreateDirectory(szDir, NULL);
}
}
wsprintf(szURLFile, "%s%s", szURL, szFile);
hRC = URLDownloadToFile(NULL, szURLFile, szFile, BINDF_GETNEWESTVERSION, NULL);
nIdx++;
}
return 0;
}
Code: [Select]
;Files.ini
[Server]
URL=http://owbuilder.malakovi.cz/snapshot/

[Files]
;File_1=binnt\cl.exe
File_1=binnt\wasm.exe
Title: Re: URLDownloadToFile example
Post by: Vortex on November 07, 2017, 06:55:26 PM
Hi Timo,

I am trying to get to work the API function URLDownloadToFile.

According to the function declaration :

Code: [Select]
HRESULT URLDownloadToFile(LPUNKNOWN pCaller,LPCTSTR szURL,
LPCTSTR szFileName,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB);

The 4th parameter should be reserved but in your code it's BINDF_GETNEWESTVERSION.
Title: Re: URLDownloadToFile example
Post by: jj2007 on November 08, 2017, 09:43:01 AM
I have a shorter, more basic version:
Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
  Init
  FileWrite "PellesC.htm", FileRead$("https://forum.pellesc.de/index.php?topic=3253.0")
  ShEx "PellesC.htm" ; show it in your browser
EndOfCode

Jokes apart, there used to be URLDownloadToFile under the hood of FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075), but it's one of the favourite functions of the AV brigade. Try submitting your exe to Jotti - here are results for a small exe, with manifest, that uses the function (https://virusscan.jotti.org/en-US/filescanjob/b371lifjg8): 3/18 scanners reported malware (I am actually surprised that only three complain...)

Re BINDF_GETNEWESTVERSION: you MUST use UrlDownloadToCacheFile because the flags DO NOT WORK with UrlDownloadToFile (https://www.experts-exchange.com/questions/21920359/URLDownlloadToFile-How-to-clear-Cache-First.html)

P.S.: Just found this thread again googling for BINDF_GETNEWESTVERSION - #5 in the list! I didn't realise it was 7 years old :)
Title: Re: URLDownloadToFile example
Post by: TimoVJL on November 08, 2017, 06:54:49 PM
@jj2007: This isn't shorter, but more a C version and smaller ;)
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <urlmon.h>
#include <shellapi.h>

#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "shell32.lib")

void __cdecl WinMainCRTStartup(void)
{
if (!URLDownloadToFile(NULL, "https://forum.pellesc.de/index.php?topic=3253.0", "PellesC.htm", BINDF_GETNEWESTVERSION, NULL))
ShellExecute(0, "open", "PellesC.htm", NULL, NULL, SW_SHOWDEFAULT);
ExitProcess(0);
}
And in jotti (https://virusscan.jotti.org/en-US/filescanjob/h9g1g5zp5h), virus scanners loves it, except Avast. ::)
Title: Re: URLDownloadToFile example
Post by: Vortex on November 08, 2017, 07:09:08 PM
Hi Jochen,

Thanks for the info. The problem is that Ollydbg does not like the URLDownloadToFile and stops debugging with an exception. x32dbg displays an exception message but does not stop the session. My Jotti score is 2 \ 18 :

https://virusscan.jotti.org/en-US/filescanjob/209i5kb1fq

The Poasm code below displays your WAN IP address :

Code: [Select]
include     WanIP.inc

SIZE_OF_BUFFER = 280

.data

szURL       db 'http://icanhazip.com',0
FileName    db 'wanip.txt',0

.data?

buffer      db SIZE_OF_BUFFER dup(?)
BytesRead   dd ?
hMem        dd ?

.code

start:

    invoke  GetTempPath,280,ADDR buffer
    invoke  lstrcat,ADDR buffer,ADDR FileName

    xor     eax,eax
    invoke  URLDownloadToFile,eax,ADDR szURL,\
            ADDR buffer,eax,eax
   
    invoke  ReadFileToMem,ADDR buffer,\
            ADDR hMem,ADDR BytesRead
           
    mov     eax,hMem
    add     eax,BytesRead
    mov     BYTE PTR [eax],0
   
    invoke  Sleep,1000
    invoke  StdOut,hMem
    invoke  VirtualFree,hMem,0,MEM_RELEASE

    invoke  ExitProcess,0

END start
Title: Re: URLDownloadToFile example
Post by: Vortex on November 08, 2017, 07:14:33 PM
Hi Timo,

Thanks for the code but it does not work on my XP 64-bit system.
Title: Re: URLDownloadToFile example
Post by: Jokaste on November 09, 2017, 12:42:15 PM
Did you try InternetReadFile (https://msdn.microsoft.com/en-us/library/windows/desktop/aa385103(v=vs.85).aspx)
Title: Re: URLDownloadToFile example
Post by: Vortex on November 09, 2017, 06:28:54 PM
Hi Jokaste,

Thanks, InternetReadFile is already in my mind. I think those internet access functions are more reliable. By the way, Timo's example is working on Windows 7 64-bit.
Title: Re: URLDownloadToFile example
Post by: jj2007 on November 09, 2017, 09:19:39 PM
The problem is that Ollydbg does not like the URLDownloadToFile and stops debugging with an exception.

Where, in which code?

InternetReadFile is already in my mind.

Not only in your mind. It's also under the hood of FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075) ;)
Title: Re: URLDownloadToFile example
Post by: Vortex on November 10, 2017, 06:43:48 PM
Hi Jochen,

Sorry for the trouble. It was again a trick of XP 64-bit causing the exception. It's the code retrieving the WAN IP address.
Title: Re: URLDownloadToFile example
Post by: Jokaste on November 10, 2017, 09:08:56 PM

Quote
Not only in your mind. It's also under the hood of [size=0px]FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075)[/size][/color]


Like I did in this CatchImages (https://forum.pellesc.de/index.php?topic=7225.0)
:P
Title: Re: URLDownloadToFile example
Post by: bitcoin on July 12, 2019, 07:31:17 PM
Thanks for the code but it does not work on my XP 64-bit system.
In my test win2003 x64 it works.. But I dload file from localhost.

May be problem with SSL? XP don't recognize new HTTPS certificates.

Don't use olly, use x64dbg ;) It's more better.
Title: Re: URLDownloadToFile example
Post by: Vortex on July 21, 2019, 10:32:15 AM
Hi bitcoin,

Thanks for your message. The problem is not the SSL handling of XP. This Poasm code to retrieve the WAN IP works on XP. It uses the API function URLDownloadToFile :

Code: [Select]
include     WanIP.inc

SIZE_OF_BUFFER = 280

.data

szURL       db 'http://icanhazip.com',0
FileName    db 'wanip.txt',0

.data?

buffer      db SIZE_OF_BUFFER dup(?)
BytesRead   dd ?
hMem        dd ?

.code

start:

    invoke  GetTempPath,280,ADDR buffer
    invoke  lstrcat,ADDR buffer,ADDR FileName

    xor     eax,eax
    invoke  URLDownloadToFile,eax,ADDR szURL,\
            ADDR buffer,eax,eax
   
    invoke  ReadFileToMem,ADDR buffer,\
            ADDR hMem,ADDR BytesRead
           
    mov     eax,hMem
    add     eax,BytesRead
    mov     BYTE PTR [eax],0
   
    invoke  Sleep,1000
    invoke  StdOut,hMem
    invoke  VirtualFree,hMem,0,MEM_RELEASE

    invoke  ExitProcess,0

END start