hammackj

Extracting binary resources in win32

Here is a useful snippet for extracting a binary resource from a compiled resource in a exe or dll. I haven't really seen any thing demonstrates how to do this exactly. So hopefully this helps someone. Maybe next time I will post the code to extract into memory and execute a PE file.

/**
 * Extracts a binary resource and write it to the specified output file.
 *
 * @param output_filename filename of the output file
 * @param resource_id resource id of object to extract from the resource file
 *
 * @author Jacob Hammack
 *
 */
void extract_resource(TCHAR *output_filename, int resource_id)
{
    HGLOBAL resource_handle = NULL;
    HANDLE file_handle;
    HRSRC resource;
    TCHAR *resource_data;
    DWORD resource_size;
    DWORD bytes_written = 0;

    if(!(resource = FindResource(0, MAKEINTRESOURCE(resource_id), RT_RCDATA))
    {
        return;
    }

    if(!(res_handle = LoadResource(NULL, resource)))
    {
        return;
    }

    resource_data = (TCHAR*) LockResource(resource_handle);
    resource_size = SizeofResource(NULL, resource);

    file_handle = CreateFile(output_filename,
            GENERIC_WRITE,
            FILE_SHARE_WRITE,
            0,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    if(file_handle == INVALID_HANDLE_VALUE)
    {
        _tprintf(TEXT("[!] Unable to create file handle for writing temp data to disk.\n"));

        return;
    }

    while(bytes_written < resource_size)
    {
        if(FALSE == WriteFile(file_handle,
            resource_data + bytes_written,
            resource_size - bytes_written,
            &bytes_written,
            NULL))
        {
            CloseHandle(file_handle);

            return;
        }
    }

    CloseHandle(file_handle);
}
hammackj on win32csnippetresources

List Windows File System Recursively

In a few of the tools that I have written, I have needed to list the windows file system recursively. While .Net makes this much easier, all of the tools I write are in win32 C. Hopefully this will help someone else, as when I looked for information on this I did not find very much.

static void RecurseFileSystem(TCHAR *StartingPath)
{
    HANDLE CurrentFileHandle;
    WIN32_FIND_DATA FileInformation;
    TCHAR CurrentFileName[MAX_PATH];
    TCHAR m_szFolderInitialPath[MAX_PATH];
    TCHAR wildCard[MAX_PATH] = TEXT("\\*.*");

    _tcscpy_s(CurrentFileName, MAX_PATH, StartingPath);
    _tcscpy_s(m_szFolderInitialPath, MAX_PATH, StartingPath);
    _tcsncat_s(m_szFolderInitialPath, MAX_PATH, wildCard, MAX_PATH);

    CurrentFileHandle = FindFirstFile(m_szFolderInitialPath, &FileInformation);

    if(CurrentFileHandle != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(
                (_tcscmp(FileInformation.cFileName, TEXT(".") ) != 0)
                &&
                (_tcscmp(FileInformation.cFileName, TEXT("..")) != 0))
            {
                _tcscpy_s(CurrentFileName, MAX_PATH, StartingPath);
                _tcsncat_s(CurrentFileName, MAX_PATH, TEXT("\\/**/"), MAX_PATH);
                _tcsncat_s(CurrentFileName, MAX_PATH, FileInformation.cFileName, MAX_PATH);

                if(FileInformation.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
                {
                    RecurseFileSystem(CurrentFileName);
                }
                else
                {
                    /* Do action on file here! */
                }
            }
        }
        while(FindNextFile(CurrentFileHandle, &FileInformation) == TRUE);

        FindClose(CurrentFileHandle);
    }
}
hammackj on win32csnippet

Simple Win32 Window

I seem to always need this skeleton code to build a window but I can never seem to memorize the whole thing. I figured I would post it here to make it easier for me to find. The #programa comments are not cross platform and only work on Microsoft based compilers, so watch out.

/**
 * SimpleWindow v1.0
 * @file
 *
 * 09-24-2008: JPH - Created.
 *
 * @author Jacob Hammack
 */

#include <windows.h>

/**
 * Forces the compiler to link these libraries
 *
 */
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "kernel32.lib")

/**
 * WindowsMessageLoop processes
 *
 * @author Jacob Hammack
 */
LRESULT CALLBACK WindowsMessageLoop(HWND WindowHandle, UINT Message, WPARAM WindowParameters, LPARAM MoreWindowsParameters)
{
    switch(Message)
    {
        case WM_CREATE:
            return 0;

        case WM_PAINT:
            return 0;

        case WM_SIZE:
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    return DefWindowProc(WindowHandle, Message, WindowParameters, MoreWindowsParameters);
}

/**
 * WinMain is the main() equivilent for a windows program, execution starts here.
 *
 * @author Jacob Hammack
 */
int WINAPI WinMain (HINSTANCE CurrentInstance, HINSTANCE PreviousInstance,  PSTR CommandLine, int CommandShow)
{
    static TCHAR ApplicationName[] = TEXT("SimpleWindow");
    HWND WindowHandle;
    MSG Message;
    WNDCLASS WindowsClass;

    WindowsClass.style = CS_HREDRAW | CS_VREDRAW;
    WindowsClass.lpfnWndProc = WindowsMessageLoop;
    WindowsClass.cbClsExtra = 0;
    WindowsClass.cbWndExtra = 0;
    WindowsClass.hInstance = CurrentInstance;
    WindowsClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WindowsClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowsClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    WindowsClass.lpszMenuName = NULL;
    WindowsClass.lpszClassName = ApplicationName;

    if(!RegisterClass(&WindowsClass))
    {
        MessageBox(NULL, TEXT("Unable to create a window."), ApplicationName, MB_ICONERROR);

        return 0;
    }

    WindowHandle = CreateWindow(ApplicationName,        /* Window Class Name*/
                                TEXT("Simple Window"),  /* Window Caption */
                                WS_OVERLAPPEDWINDOW,    /* Window Style*/
                                CW_USEDEFAULT,          /* Initial X position*/
                                CW_USEDEFAULT,          /* Initial Y position */
                                300,                    /* Initial Width of the window*/
                                100,                    /* Initial Height of the window */
                                NULL,                   /* Parent Window Handle */
                                NULL,                   /* Window Menu Handle */
                                CurrentInstance,        /* Instance of the Program Handle*/
                                NULL);                  /* Window Creation Parameters */

    ShowWindow(WindowHandle, CommandShow);
    UpdateWindow(WindowHandle);

    while(GetMessage(&Message, NULL, 0, 0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }

    return Message.wParam;
}
CC=cl
CFLAGS= /nologo /MT /O2 /TC
LINKS=/link /OUT:simplewindow.exe /SUBSYSTEM:WINDOWS

all: simplewindow

simplewindow: simplewindow.c
    $(CC) $(CFLAGS) simplewindow.c $(LINKS)

clean:
    del *.exe; del *.obj

Simple Window

hammackj on toolcwin32snippet

Tool: drivelist

This is a tool I wrote for windows, that will list all of the drives currently mounted. I didn't know of a better way to show this information from the command line. This is using the windows api and is very straight forward, it should work on every version of windows.

/**
 * Drivelist v1.0.1
 * @file
 *
 * 05-25-2008: JPH - Created.
 * 08-22-2008: JPH - Added case 0, 1 and 6 to the switch of types.
 *
 * @author Jacob Hammack
 */

#include <windows.h>
#include <stdio.h>

/**
 * List's and prints all mounted drives and their drive type.
 *
 * @author Jacob Hammack
 */
void ListMountedDrives(void)
{
    char Buffer[MAX_PATH];
    char *DriveLetter;
    int DriveType;
    GetLogicalDriveStrings(MAX_PATH, Buffer);
    DriveLetter = Buffer;

    while (*DriveLetter)
    {
        if(*DriveLetter == 0)
        {
            break;
        }

        DriveType = GetDriveType(DriveLetter);

        switch(DriveType)
        {
            case 0:
                printf("%s\tUnknown Type\n", DriveLetter);
            break;

            case 1:
                printf("%s\tInvalid Root Path\n", DriveLetter);
            break;

            case 2:
                printf("%s\tRemoveable Drive\n", DriveLetter);
            break;

            case 3:
                printf("%s\tFixed Drive\n", DriveLetter);
            break;

            case 4:
                printf("%s\tNetwork Drive\n", DriveLetter);
            break;

            case 5:
                printf("%s\tCD-ROM Drive\n", DriveLetter);
            break;

            case 6:
                printf("%s\tRam Drive\n", DriveLetter);
            break;
        }

        DriveLetter = &DriveLetter[strlen(DriveLetter) + 1];
    }
}

/**
 * Main entry point for the DriveList Application.
 *
 * @author Jacob Hammack
 */
int main(int argc, char *argv[])
{
    printf("Drivelist v1.0.1\nJacob Hammack\nhttp://www.hammackj.com\n\n");

    ListMountedDrives();

    return 0;
}
CC=cl
CFLAGS= /nologo /MT /O2 /TC
LINKS=/link kernel32.lib /OUT:dl.exe /SUBSYSTEM:CONSOLE

all: drivelist

drivelist: drivelist.c
$(CC) $(CFLAGS) drivelist.c $(LINKS)

clean:
del *.exe; del *.obj
C:\drivelist>dl.exe
Drivelist v1.0.1
Jacob Hammack
http://www.hammackj.com

A:\     Removeable Drive
C:\     Fixed Drive
D:\     Fixed Drive
E:\     CD-ROM Drive
Z:\     Network Drive

C:\drivelist>
hammackj on toolcwin32