A (weird) way to download a file in C
#1
A (weird) C Downloader with WinAPI and soon-to-be-deprecated-binaries (LOLBin-esque)
Using the Installer Engine which seems to stem from Internet Explorer, which you may know is being fully replaced with Edge (Chromium) later in the next year.

Yeah, you won't be used to this sample, probably.

So, we start off by our usual file headers and dynamically linking, like done in my last snippet:

For the lazy who don't want to deal with poor formatting here...

Code:
#include <stdio.h>
#include <Windows.h>

typedef INT64 (__cdecl* fnde)(LPCSTR url, LPCSTR path, int noExec);

int main(int argc, char** argv) {
    //Load relevant library
    HINSTANCE LibInseng = LoadLibrary(L"C:\\WINDOWS\\system32\\inseng.dll");
    //DEBUG
    //printf("%p", LibInseng);

    //Declare our function
    LPVOID fn = (LPVOID)GetProcAddress(LibInseng, "DownloadFile");
    const char* url = "https://www.google.com";
    const char* path = "robots.txt_downloaded.txt";
    INT64 result = 0;


    //And we store the ESP value for future reference. No RSP beause inseng.dll is 32bit anyway. Just keep it optimized.
    int espValue;
    __asm mov espValue, esp;
    printf("ESP: 0x%x\n", espValue);

    //Some inline ASM...
    __asm {
        push esp;
        push 1;
        push path;
        push url;
        call fn;
        push 0;
    }

    //And the new (old) ESP value to make sure function executed successfully...
    __asm mov espValue, esp;
    printf("ESP: 0x%x\n", espValue);
    system("PAUSE");
       
    return 0;

}


So, a brief explanation.
inseng.dll is one of those pretty poorly documented files available in the WinAPI.
Luckily, using a tool called DLL Export Viewer from Nirsoft, you can get some pretty good info on any .dll file:

[Image: 4zgrrEt.png]

Pretty cool, huh. Shows the actual exports plus their offsets in memory AND their offsets from each other. So you could load one function then make your function pointer offset by a bit and cast it to a different type instead of loading two function pointers.

Now. In VisualStudio 2019, I have it set to the following settings:
-->x86 Arch
-->Release

Once built and debugged, you should just see two numbers. They should be the same if it worked.
Go to your project folder, find the binary, and click it agian.
After a second, you'll see a new file, robots.txt_downloaded.txt

So you've figured out what it does. It downloads a file.
But in C. Somehow. without a million networking imports, just some obscure .dll.

So, pop it into the debugger:

[Image: jvEwCHB.png]

And you'll see even the actual compiled code segment is really small.
Using inline ASM is nice because it allows you to use C variables in ASM code without forcing you to .bss or .data sections.



the line at 0x56108A:
CALL DWORD PTR SS:[EBP-10]

Is the call to our loaded DownloadFile function. It takes goes straight to the DownloadFile() function in inseng.dll
It does its magic based on arguments taken from stack, and not registers like a lot of the libgc standard library (or linux syscalls) that use xmm registers to store data needed. Hence we need to actually use the inline ASM to make sure the data gets into the stack in the right order before DownloadFile() can actually get called.

Sure, we can just use the same function call convention that I used previously, but where's the fun in that.

Not to mention, I said this is a 'weird' way to download a file. Maybe you can come up with something to do with this obscure method...?
Reply
#2
This is pretty neat, since it's an obscure DLL i doubt it will be blacklisted as potentially dangerous either making it an effective dropper.
Reply