Wednesday, October 22, 2014

Windows System Programming: File Handling


Creating File

#include <windows.h>
int main()
{
    HANDLE fH = NULL;
    LPCTSTR fileName = "testfile.txt";
    char buff_in[512] = "Creating test file using windows API's";
    int bytes_written = 0;
    int status;
 
    /* http://bit.ly/ISRjD6 */
    fH = CreateFile(fileName, /*lpFileName*/
             GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
             FILE_SHARE_WRITE, /* dwShareMode */
             NULL, /* lpSecurityAttributes */
             CREATE_NEW, /* dwCreationDisposition, Creates a 
                         new file, only if it does not already exist.*/
             SECURITY_SQOS_PRESENT|FILE_ATTRIBUTE_HIDDEN, 
                         /* dwFlagsAndAttributes, we can also pass 
FILE_FLAG_DELETE_ON_CLOSE to close file once  we are done handling it */              NULL        /* hTemplateFile */                       );     if (fH == INVALID_HANDLE_VALUE) {                printf("Invalid file handle");     }         status = WriteFile(fH, /* hFile */               buff_in, /* lpBuffer */               512, /* nNumberOfBytesToWrite */               &bytes_written, /* lpNumberOfBytesWritten */               NULL /* lpOverlapped */               );     if (status != 0) {         printf("Successfully wrote to file %s", fileName);     }     return 0; }


Snap shot shows execution, file created with text inside and properties set.

#include <windows.h>
int main()
{
    HANDLE fH, hFind;
    WIN32_FIND_DATA fileData;
    LPCTSTR fileName = "testfile.txt";
    char buff_in[512] = "Creating test file using windows API's";
    int bytes_written = 0;
    int status, ftype, fsize, fsh, binary_type;
    char dir_path[80]="C:\\Documents and Settings\\praveen \
                       \\My Documents\\mal_files\\";
    char file_ext[8] = "*.exe";
    char filepath[128];
   
    strcpy(filepath, dir_path);
    strcat(filepath, file_ext);   
    /* relative path did not work*/
    hFind = FindFirstFile(filepath, /* lpFileName, */
                       &fileData /* lpFindFileData */ );
    while (hFind != INVALID_HANDLE_VALUE) {
        printf("fileName=%s(%d)\n", fileData.cFileName, GetLastError());
        strcpy(filepath, dir_path);
        strcat(filepath, fileData.cFileName);
        fH = CreateFile(filepath, /*lpFileName*/
                        GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
                        FILE_SHARE_WRITE, /* dwShareMode */
                        NULL, /* lpSecurityAttributes */
                        OPEN_EXISTING, /* dwCreationDisposition, Creates a
                         new file, only if it does not already exist.*/
                         SECURITY_SQOS_PRESENT|FILE_ATTRIBUTE_HIDDEN,
                         /* dwFlagsAndAttributes */
                         NULL        /* hTemplateFile */);
        if (fH == INVALID_HANDLE_VALUE) {
            if (ERROR_FILE_EXISTS == GetLastError())
                printf("file exists(%d)\n", GetLastError());
            else
                printf("Invalid file handle (%d)\n", GetLastError());
            return -1;   
        }
        printf("Stats of file=\"%s\"\n", filepath);
        ftype = GetFileType(fH);
        fsize = GetFileSize(fH, &fsh);
        GetBinaryType(filepath, &binary_type);
        printf("file type =%d(1=Disk File)\n", ftype);
        printf("file size=%d(%d) bytes\n", fsize, fsh);
        printf("binary_type=%d, error=%d\n", binary_type, GetLastError());
        printf("We can print file attributes from fileData\n");
        printf("*****************************************\n");  
       
        if(!FindNextFile(hFind, &fileData)) {
            FindClose(hFind);
            hFind = INVALID_HANDLE_VALUE;
        }
    }
    return 0;
}
Somehow binary_type value is not getting printed properly. By using fileData,  we can also print access times, modified time etc.

Sunday, October 5, 2014

Windows System Programming: Registry Handling


Malware (malicious software) uses different techniques to maintain persistence i.e. execute itself after reboot, one of the persistence mechanisms is using Windows Registry modification.

Following are few important registry hives used by Malware
Autostart Directory
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
Run/RunOnce/RunService
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
Explorer
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
Browser Helper Objects (BHO)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects 

Other registries include Autoruns, Terminal Server Autoruns, Registry Shell Spawning, Explorer (say, plugins, addons, toolbars) etc.

Following are different API's for registry manipulation
RegCreateKeyEx
RegDeleteKeyEx
RegQueryValueA
RegQueryValueExA
RegCloseKeyA
RegOpenKeyEx


Headers and Libraries
Winreg.h (include Windows.h)
Advapi32.dll


Predefined Keys
    HKEY_CLASSES_ROOT
    HKEY_CURRENT_CONFIG
    HKEY_CURRENT_USER
    HKEY_LOCAL_MACHINE
    HKEY_USERS 


Following hives point to files on disk
HKEY_LOCAL_MACHINE\HARDWARE    created when a new hardware is added/available
HKEY_LOCAL_MACHINE\SAM              %SystemRoot%\System32\config\SAM
HKEY_LOCAL_MACHINE\SECURITY      %SystemRoot%\System32\config\SECURITY
HKEY_LOCAL_MACHINE\SOFTWARE     %SystemRoot%\System32\config\SOFTWARE
HKEY_LOCAL_MACHINE\SYSTEM         %SystemRoot%\System32\config\SYSTEM
HKEY_USERS\.DEFAULT                    %SystemRoot%\System32\config\DEFAULT

Print suspicious Registries
We are printing suspicious registries, in the example below I had hard coded the values.

#include <windows.h>
int main()
{
    HKEY hKey;
    DWORD status;
    DWORD type = REG_SZ;
    char sKey[255]="Software\\Microsoft\\Windows\\CurrentVersion\\Run";
    PPERF_DATA_BLOCK data = (PPERF_DATA_BLOCK) malloc(1024);
    DWORD dsize = 1024;
  
    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, /**/
                          sKey, 0, /* lpSubKey, ulOptions */
                          KEY_READ, &hKey /* samDesired, phkResult */
                          );
    if (status != ERROR_SUCCESS) {
               printf("Error RegOpenKeyEx\n");
               return 0;
    } 
    status = RegQueryValueEx(hKey, "VBoxTray", /* hKey, lpValueName */
                             NULL, &type, /* lpReserved, lpType */
                             (LPBYTE)data, &dsize /* lpData, lpcbData*/
                             );    
    if (status != ERROR_SUCCESS) {
       MessageBox(0, "Error querying Registry", "Error", 0);  
       return 0;         
    }
    /* Using RegEnumKeyEx, RegEnumValue we can enumerate through 
     * subkeys and value names*/
    printf("\nQuerying Registry HKEY_LOCAL_MACHINE\\%s\n", sKey);
    printf("VBoxTray executes from %s\n", data);
    
    return 0;   
}
Add new Registry
RegCreateKeyEx function is used to create new registry key or open already existing keys. A registry tree can be 512 levels deep. We can create up to 32 levels at a time through a single registry API call.
#include<windows.h>
#include<string.h>
#define MAX_KEY_NAME 255
#define MAX_STR 32
int main()
{
    HKEY hKey_ptr = NULL;
    DWORD status;
    char data[MAX_STR-1] = "Praveen Darshanam";
    char sKey[MAX_KEY_NAME] = "disects\\Tutorial";
    DWORD createdornot;
       
    printf("\nAdding new Registry Information\n");
    /*
     * http://msdn.microsoft.com/en-us/library/windows/
     * desktop/ms724844%28v=vs.85%29.aspx
     */
    status = RegCreateKeyEx(HKEY_CURRENT_USER, /* hKey */
                          sKey, /* lpSubKey */
                          0, NULL, /* Reserved, lpClass */
                          REG_OPTION_NON_VOLATILE, /* dwOptions */
                          KEY_ALL_ACCESS, /* samDesired */
                          NULL, /* lpSecurityAttributes */
                          &hKey_ptr, /* phkResult */
                          &createdornot /* lpdwDisposition */
                          );
    if (status != ERROR_SUCCESS) {
               printf("Error RegCreateKeyEx(%d), lpdwDisposition=%u\n",
                      status, createdornot);
               return 0;
    }

    status = RegSetValueEx(hKey_ptr, "Name", /* hKey, lpValueName*/
                           0, REG_SZ, /* Reserved, dwType */
                           data,  strlen(data)/* *lpData, cbData */
                           );    
    if (status != ERROR_SUCCESS) {  
       printf("Error RegSetValueEx(%d)\n", status);
       return 0;         
    }
    printf("Value of createdornot(lpdwDisposition)=%u\n", createdornot);
    printf("Successfully created registry HKEY_CURRENT_USER\\%s\n", sKey);
    
    return 0;   
}


Modify/Delete Registry
RegDeleteKeyEx function can be used to remove any registry.
In the above program call RegDeleteKeyEx function before final return.
RegDeleteKeyEx(hKey_ptr, sKey, KEY_WOW64_32KEY, 0);
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724836%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724880%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724875%28v=vs.85%29.aspx
http://gladiator-antivirus.com/forum/index.php?showtopic=24610