Pages

Monday, May 18, 2015

[C/C++] Lite OllyDbg 2 plugin Template.

Code snippet:   

#include <windows.h>
#include "plugin.h"

#define PLUGINNAME     L"Lite OD2 plugin Template"
#define PLUGINVERSION        L"0.00.01"

HINSTANCE pluginHandle;

int __cdecl AboutProc(t_table *pt, wchar_t *name, ulong index,int mode);
int __cdecl AllInOneFunction(t_table *pt, wchar_t *name, ulong index, int mode);

t_menu SubMenuOptions[] = {
    {L"Do Something2...", NULL,  K_NONE, AllInOneFunction, NULL, 1},
    {L"Something to do....", NULL, K_NONE, AllInOneFunction, NULL, 2},
    { NULL, NULL, K_NONE, NULL, NULL, 0}
};

t_menu MainMenu[] = {
    {L"Hide Debugger", NULL,  K_NONE, AllInOneFunction, NULL, 20},
    {L"Do Something...", NULL, K_NONE, AllInOneFunction, NULL, 21},
    {L"|Options", NULL, K_NONE, NULL, SubMenuOptions, 0},
    {L"|About", NULL, K_NONE, AboutProc, NULL, 22},
    { NULL, NULL, K_NONE, NULL, NULL, 0}
};

int __cdecl AllInOneFunction(t_table *pt, wchar_t *name, ulong index, int mode) {

    LPWSTR mainMsg = L"error!";
    if (mode == MENU_VERIFY)
        return MENU_NORMAL;
    else if (mode == MENU_EXECUTE) {

        switch (index) {
        case 1: {
            mainMsg = SubMenuOptions[0].name;
            break;
        }

        case 2: {
            mainMsg = SubMenuOptions[1].name;
            break;
        }

        case 20: {
            mainMsg = MainMenu[0].name;
            break;
        }

        case 21: {
            mainMsg = MainMenu[1].name;
            break;
        }

        }

        MessageBoxW(hwollymain, mainMsg, L"INFORMATION", MB_ICONINFORMATION);

        return MENU_NOREDRAW;
    }
    return MENU_ABSENT;
}


int AboutProc(t_table *pt, wchar_t *name, ulong index, int mode) {
    if (mode == MENU_VERIFY)
        return MENU_NORMAL;
    else if (mode == MENU_EXECUTE) {
        MessageBoxW(
            hwollymain,
            L"Lite OllyDbg 2 plugin Template v0.00.01\nRelease date 12/2013\n\n"
            "[by stigma from I3CT]\nInsid3Code Team",
            L"About",
            MB_ICONINFORMATION);

        return MENU_NOREDRAW;
    }
    return MENU_ABSENT;
}

extc t_menu * __cdecl ODBG2_Pluginmenu(PWCHAR type) {

    if (wcscmp(type, PWM_MAIN) == 0)
        return MainMenu;
    return NULL;
}

extc int __cdecl ODBG2_Pluginquery(int ollyDbgVersion, PULONG features, 
wchar_t pluginName[SHORTNAME], wchar_t pluginVersion[SHORTNAME]) {
    if (ollyDbgVersion < 201)
        return 0;

    wcscpy(pluginName, PLUGINNAME);
    wcscpy(pluginVersion, PLUGINVERSION);
    return PLUGIN_VERSION;
}

extc int __cdecl ODBG2_Plugininit(void) {

    return 0;
}

BOOLEAN __cdecl iWinMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved) {
    if (reason == DLL_PROCESS_ATTACH)
        pluginHandle = hInstance;
    return true;
}

Source:
http://www.mediafire.com/download/dz4oq6m5mvmvw6i/LiteOD2Plugin.rar

[C/C++] From kernel32!GetCurrentDirectoryW to ntdll!RtlGetCurrentDirectory_U

Code snippet:  
#include <windows.h>

#define NATIVE

extern "C" {
    NTSTATUS
    WINAPI
    RtlGetCurrentDirectory_U(ULONG,  LPWSTR);
}

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    WCHAR lpCurrentDirectory[MAX_PATH] = {0};

#ifdef NATIVE
    RtlGetCurrentDirectory_U(MAX_PATH, lpCurrentDirectory);
#else
    GetCurrentDirectoryW(MAX_PATH, lpCurrentDirectory);
#endif
    MessageBoxW(
        NULL,
        lpCurrentDirectory,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}

Source:
http://www.mediafire.com/download/ilrbigpei02w71t/CurrentDirectory.rar

[C/C++] Protect handle from close.

Code snippet:  
#include <windows.h>
#include <stdio.h>
#include <ntdll.h>

int iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif
    WCHAR mainMsg[MAX_PATH] = {0};
    HANDLE FileHandle = NULL;
    UNICODE_STRING ObjectName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_HANDLE_ATTRIBUTE_INFORMATION ObjectHandleAttributeInformation;

    RtlInitUnicodeString(&ObjectName, L"\\REGISTRY\\USER\\.DEFAULT");
    InitializeObjectAttributes(&ObjectAttributes, &ObjectName, OBJ_CASE_INSENSITIVE, NULL, NULL);

    LPWSTR finishedMsg = L"Failed!";

    if (NtOpenKey(
                &FileHandle,
                KEY_READ,
                &ObjectAttributes) == STATUS_SUCCESS) {

        ObjectHandleAttributeInformation.ProtectFromClose = TRUE;

        if (NtSetInformationObject(
                    FileHandle,
                    ObjectHandleInformation,
                    &ObjectHandleAttributeInformation,
                    sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) == STATUS_SUCCESS) {
//
// MessageId: STATUS_HANDLE_NOT_CLOSABLE 0xC0000235L
// MessageText: NtClose was called on a handle that was protected from close via NtSetInformationObject.
//
            LONG_PTR  ntCloseStatus = NtClose(FileHandle);
            _snwprintf(
                mainMsg,
                MAX_PATH * 2,
                L"Job done!\n\nProtected Handle: 0x%p\n"
                L"TargetName: \"%ws\"\nNtClose Status: 0x%p\n\n"
    "Try to close the protected Handle!\n\n[by stigma from I3CT]\nInsid3Code Team",
                FileHandle,
                ObjectName.Buffer,
                ntCloseStatus);

            MessageBoxW(NULL, mainMsg, captionMsg, MB_ICONINFORMATION);
            finishedMsg = L"Finished!";
        }
    }
    MessageBoxW(NULL, finishedMsg, captionMsg, MB_ICONINFORMATION);
    return 0;
}
Source:
http://www.mediafire.com/download/jiontnu194y16zq/ProtectHandleFromClose.rar

[C/C++] From GetModuleHandleW to LdrGetDllHandle

Code snippet:

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

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    HMODULE moduleHandle;
    WCHAR mainMsg[MAX_PATH] = {0};

    moduleHandle = GetModuleHandleW(L"kernel32.dll");

    _snwprintf(
        mainMsg,
        MAX_PATH,
        L"kernel32.dll ImageBaseAddress: 0x%p",
        moduleHandle);

    MessageBoxW(
        NULL,
        mainMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Inside the Debugger:
Push     ebp
Mov      ebp, esp
sub      esp, 208h
xor      eax, eax
push     206h            ; Size
push     eax             ; Val
mov      [ebp+Text], ax
lea      eax, [ebp+Dst]
push     eax             ; Dst
call     memset
add      esp, 0Ch
push     0               ; lpModuleName
call     GetModuleHandleW
push     eax
push     offset Format   ; "kernel32.dll"...
lea      eax, [ebp+Text]
push     104h            ; Count
push     eax             ; Dest
call     _snwprintf
add      esp, 10h
push     40h             ; uType
push     offset Caption  ; "32-bit Application"
lea      eax, [ebp+Text]
push     eax             ; lpText
push     0               ; hWnd
call     MessageBoxW
xor      eax, eax
leave
retn
Case when GetModuleHandleW handle NULL parameter: I observed than if we pass "NULL" as parameter the function doesn't call any other function and retrieve the ImageBaseAddress directly from the information stored in the current PEB (Process Environment Block)
GetModuleHandleW(NULL);
mov      edi, edi
push     ebp
mov      ebp, esp
cmp      dword ptr [ebp+8], 0
jz       loc_75668DD6
Check the parameter and redirection to the PEB if the parameter is equal to NULL.
75668DD6 moveax, large fs:18h
75668DDC moveax, [eax+30h]
75668DDF moveax, [eax+8] ImageBaseAddress

typedefstruct _PEB
{
 /* 0x0000 */ BOOLEAN InheritedAddressSpace;
 /* 0x0001 */ BOOLEAN ReadImageFileExecOptions;
 /* 0x0002 */ BOOLEAN BeingDebugged;
 /* 0x0003 */ BOOLEAN Spare;
 /* 0x0004 */ HANDLE Mutant;
 /* 0x0008 */ PVOID ImageBaseAddress;
 /* 0x000C */ PPEB_LDR_DATA LoaderData;
......
......
Case when GetModuleHandleW handle a valid parameter:
GetModuleHandleW(L"kernel32.dll");
Calling native function
ntdll!LdrGetDllHandle
Rewriting the Code snippet:
#include <windows.h>
#include <stdio.h>

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

extern "C" {
    VOID
    WINAPI
    RtlInitUnicodeString (
        PUNICODE_STRING DestinationString,
        PCWSTR SourceString);

    NTSTATUS
    WINAPI
    LdrGetDllHandle(
        ULONG,
        ULONG,
        const UNICODE_STRING*,
        HMODULE*);
}

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    HMODULE moduleHandle;
    WCHAR mainMsg[MAX_PATH] = {0};

    UNICODE_STRING moduleName;
    RtlInitUnicodeString(&moduleName, L"kernel32.dll");
    LdrGetDllHandle(NULL, NULL, &moduleName, &moduleHandle);

    _snwprintf(
        mainMsg,
        MAX_PATH,
        L"kernel32.dll ImageBaseAddress: 0x%p",
        moduleHandle);

    MessageBoxW(
        NULL,
        mainMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
The final Code snippet:
#include <windows.h>
#include <stdio.h>

#define NATIVE

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

extern "C" {
    VOID
    WINAPI
    RtlInitUnicodeString (
        PUNICODE_STRING DestinationString,
        PCWSTR SourceString);

    NTSTATUS
    WINAPI
    LdrGetDllHandle(
        ULONG,
        ULONG,
        const UNICODE_STRING*,
        HMODULE*);
}

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    HMODULE moduleHandle;
    WCHAR mainMsg[MAX_PATH] = {0};

#ifdef NATIVE
    UNICODE_STRING moduleName;
    RtlInitUnicodeString(&moduleName, L"kernel32.dll");
    LdrGetDllHandle(NULL, NULL, &moduleName, &moduleHandle);
#else
    moduleHandle = GetModuleHandleW(L"kernel32.dll");
#endif
    _snwprintf(
        mainMsg,
        MAX_PATH,
        L"kernel32.dll ImageBaseAddress: 0x%p",
        moduleHandle);

    MessageBoxW(
        NULL,
        mainMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
 
Source:
http://www.mediafire.com/download/uj0wprstq9q9jpu/ImageBaseAddress.rar

[C/C++] From kernel32!GetLastError to pTEB->LastErrorValue

Code snippet: 
#include <windows.h>
#include <stdio.h>
#include <ntdll.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    PTEB_7 pTEB = (PTEB_7)__readgsqword(0x30);
    LPWSTR captionMsg = L"64-bit Application";
#else
    PTEB_7 pTEB = (PTEB_7)__readfsdword(0x18);
    LPWSTR captionMsg = L"32-bit Application";
#endif

    ULONG_PTR lastError;
    WCHAR mainMsg[MAX_PATH] = {0};

    LoadLibraryW(L"target.dll");

    lastError = GetLastError();

    _snwprintf(
        mainMsg,
        MAX_PATH,
        L"LastError: 0x%p",
        lastError);

    MessageBoxW(
        NULL,
        mainMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Inside debugger:
........
........
004010A5 PUSH main.00401068                            ; UNICODE "target.dll"
004010AA CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryW>]  ; kernel32.LoadLibraryW
004010B0 CALL DWORD PTR DS:[<&KERNEL32.GetLastError>]  ; kernel32.GetLastError
........
........
GetLastError  MOV EAX,DWORD PTR FS:[18]
751F680C      MOV EAX,DWORD PTR DS:[EAX+34]
751F680F      RET
........
........
Retrieve the LastErrorValue directly from the information stored in the current TEB (Thread Environment Block)
typedef struct _TEB_7
{
 NT_TIB     NtTib;
 PVOID                   EnvironmentPointer;
 CLIENT_ID               Cid;
 PVOID                   ActiveRpcInfo;
 PVOID                   ThreadLocalStoragePointer;
 PPEB_VISTA_7            Peb;
 ULONG                   LastErrorValue;

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

#define GET_LAST_ERROR_FROM_TEB

int WINAPI iWinMain() {
#ifdef _WIN64
    PTEB_7 pTEB = (PTEB_7)__readgsqword(0x30);
    LPWSTR captionMsg = L"64-bit Application";
#else
    PTEB_7 pTEB = (PTEB_7)__readfsdword(0x18);
    LPWSTR captionMsg = L"32-bit Application";
#endif

    ULONG_PTR lastError;
    WCHAR mainMsg[MAX_PATH] = {0};

    LoadLibraryW(L"target.dll");

#ifdef GET_LAST_ERROR_FROM_TEB
    lastError = pTEB->LastErrorValue;
#else
    lastError = GetLastError();
#endif

    _snwprintf(
        mainMsg,
        MAX_PATH,
        L"LastError: 0x%p",
        lastError);

    MessageBoxW(
        NULL,
        mainMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}

Source:
http://www.mediafire.com/download/dobcx2s4v0tm5zv/GetLastError.rar

[C/C++] RtlSetProcessIsCritical

Set current process Critical with RtlSetProcessIsCritical. 

Code snippet:  
#include <windows.h>
#include <ntdll.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif
    BOOLEAN oldValue;
    LPWSTR finishedMsg = L"Failed!";

    if (RtlAdjustPrivilege(
                SE_DEBUG_PRIVILEGE,
                TRUE,
                FALSE,
                &oldValue) == STATUS_SUCCESS) {
        if (RtlSetProcessIsCritical(
                    TRUE,
                    NULL,
                    FALSE) == STATUS_SUCCESS) {
            MessageBoxW(
                NULL,
                L"I'm critical process don't kill me!",
                captionMsg,
                MB_ICONINFORMATION);
            if (RtlSetProcessIsCritical(
                        FALSE,
                        NULL,
                        FALSE) == STATUS_SUCCESS) {
                MessageBoxW(
                    NULL,
                    L"Now, I'm normal process!",
                    captionMsg,
                    MB_ICONINFORMATION);
                finishedMsg = L"Finished!";
            }
        }
    }
    MessageBoxW(
        NULL,
        finishedMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}

Source:
http://www.mediafire.com/download/0k5ti3rnppcd8db/RtlSetProcessIsCritical.rar

[C/C++] Protected Reg Key (Embedded null characters)

Inspired from Mark Russinovich's work - Sysinternals.
Create a registry key that contain embedded-null characters.
The created registry key become in-accessible using standard registry editing tools.



Code snippet:  
#include <windows.h>
#include <ntdll.h>

int WINAPI iWinMain() {

#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif
    LPWSTR finishedMsg = L"Failed!\nRun me with Admin privileges.";

#define HIDE_IT

    WCHAR HiddenKeyNameBuffer[] = L"Try2OpenOrRenameOrDeleteMe!\0";
    WCHAR valueBuffer[]= L"Value";
    WCHAR dataBuffer[]= L"Data";

    UNICODE_STRING ObjectName;
    HANDLE ObjectNameHandle, HiddenKeyHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG Disposition;

    RtlInitUnicodeString(
        &ObjectName,
        L"\\REGISTRY\\USER\\.DEFAULT\\Targeted Key");

    InitializeObjectAttributes(
        &ObjectAttributes,
        &ObjectName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    if (NtCreateKey(
                &ObjectNameHandle,
                KEY_ALL_ACCESS,
                &ObjectAttributes,
                0,
                NULL,
                REG_OPTION_NON_VOLATILE,
                &Disposition) == STATUS_SUCCESS) {

        ObjectName.Buffer = HiddenKeyNameBuffer;

#ifdef HIDE_IT
        ObjectName.Length = wcslen(HiddenKeyNameBuffer) * sizeof(WCHAR) + sizeof(WCHAR);
#else
        ObjectName.Length = wcslen(HiddenKeyNameBuffer) * sizeof(WCHAR);
#endif

        InitializeObjectAttributes(
            &ObjectAttributes,
            &ObjectName,
            OBJ_CASE_INSENSITIVE,
            ObjectNameHandle,
            NULL);

        if (NtCreateKey(&HiddenKeyHandle,
                        KEY_ALL_ACCESS,
                        &ObjectAttributes,
                        0,
                        NULL,
                        REG_OPTION_NON_VOLATILE,
                        &Disposition ) == STATUS_SUCCESS) {

            ObjectName.Buffer = valueBuffer;
            ObjectName.Length = wcslen(valueBuffer) * sizeof(WCHAR);

            if (NtSetValueKey(
                        HiddenKeyHandle,
                        &ObjectName,
                        0,
                        REG_SZ,
                        dataBuffer,
                        wcslen(dataBuffer)  * sizeof(WCHAR)) == STATUS_SUCCESS) {

                MessageBoxW(
                    NULL,
                    L"Done...\nTry this key: [HKEY_USERS\\.DEFAULT\\Targeted Key]",
                    captionMsg,
                    MB_ICONINFORMATION);
                finishedMsg = L"Finished!";
            }
        }
    }
    NtDeleteKey(HiddenKeyHandle);
    NtDeleteKey(ObjectNameHandle);

    MessageBoxW(
        NULL,
        finishedMsg,
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}

Source:
http://www.mediafire.com/download/lfmr79316lbvdg2/ProtectedRegKey.rar

[C/C++] From kernel32!Sleep to ntdll!NtDelayExecution

Code snippet:

#include <windows.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    MessageBoxW(
        NULL,
        L"Close me to start delay!",
        captionMsg,
        MB_ICONINFORMATION);

    Sleep(2000);

    MessageBoxW(
        NULL,
        L"Finished!",
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Inside Debugger:
........
........
PUSH  0
CALL  ESI
PUSH  7D0
CALL  DWORD PTR DS:[<&KERNEL32.Sleep>] ; kernel32.Sleep
PUSH  40
PUSH  EDI
........
........
PUSH  ESI
PUSH  DWORD PTR SS:[EBP+C]
CALL  DWORD PTR DS:[<&ntdll.NtDelayExecution>] ; ntdll.ZwDelayExecution
MOV   DWORD PTR SS:[EBP-1C],EAX
CMP   DWORD PTR SS:[EBP+C],EDI
........
........
Final code snippet:
#include <windows.h>
#include <ntdll.h>

#define NATIVE

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    LARGE_INTEGER Interval;

    MessageBoxW(
        NULL,
        L"Close me to start delay!",
        captionMsg,
        MB_ICONINFORMATION);

#ifdef NATIVE
    Interval.QuadPart = -20000000; // delay 2 seconds
    NtDelayExecution(FALSE, &Interval);
#else
    Sleep(2000);
#endif

    MessageBoxW(
        NULL,
        L"Finished!",
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Source:
http://www.mediafire.com/download/afrw4e8lx8zrud4/Sleep.rar

[C/C++] FILE_DELETE_ON_CLOSE flag

Using FILE_DELETE_ON_CLOSE flag as parameter with NtOpenFile to delete file. 

#include <windows.h>
#include <ntdll.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif
    LPWSTR finishedMsg = L"Failed!";
    NTSTATUS ntStatus;

    HANDLE    FileHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING      ObjectName;
    IO_STATUS_BLOCK     IoStatusBlock;

    RtlInitUnicodeString(&ObjectName, L"\\??\\c:\\test.txt");
    InitializeObjectAttributes(
        &ObjectAttributes,
        &ObjectName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    if (NtOpenFile(
                &FileHandle,
                DELETE,
                &ObjectAttributes,
                &IoStatusBlock,
                0,
                FILE_DELETE_ON_CLOSE) == STATUS_SUCCESS) {
        if (NtClose(FileHandle) == STATUS_SUCCESS) {
            MessageBoxW(
                NULL,
                L"Done...\nFile:\"C:\\test.txt\" deleted.",
                captionMsg,
                MB_ICONINFORMATION);
            finishedMsg = L"Finished!";
        }
    }

    MessageBoxW(
        NULL,
        finishedMsg,
        captionMsg,
        MB_ICONINFORMATION);
    return 0;
}
 
Source:
http://www.mediafire.com/download/eqe09020m829lmv/FileDeleteOnClose.rar

[C/C++] FILE_DISPOSITION_INFORMATION structure.

Using FILE_DISPOSITION_INFORMATION structure to delete file. 
 
#include <windows.h>
#include <ntdll.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif
    LPWSTR finishedMsg = L"Failed!";

    FILE_DISPOSITION_INFORMATION dispositionInfo;

    HANDLE    FileHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING      ObjectName;
    IO_STATUS_BLOCK     IoStatusBlock;

    RtlInitUnicodeString(&ObjectName, L"\\??\\c:\\test.txt");
    InitializeObjectAttributes(
        &ObjectAttributes,
        &ObjectName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    if (NtOpenFile(
                &FileHandle,
                GENERIC_ALL,
                &ObjectAttributes,
                &IoStatusBlock,
                FILE_SHARE_DELETE,
                0) == STATUS_SUCCESS) {

        dispositionInfo.DeleteFile = TRUE;

        if (NtSetInformationFile(
                    FileHandle,
                    &IoStatusBlock,
                    &dispositionInfo,
                    sizeof(FILE_DISPOSITION_INFORMATION),
                    FileDispositionInformation) == STATUS_SUCCESS) {

            if (NtClose(FileHandle) == STATUS_SUCCESS) {
                MessageBoxW(
                    NULL,
                    L"Done...\nFile:\"C:\\test.txt\" deleted.",
                    captionMsg,
                    MB_ICONINFORMATION);
                finishedMsg = L"Finished!";
            }
        }
    }

    MessageBoxW(
        NULL,
        finishedMsg,
        captionMsg,
        MB_ICONINFORMATION);
    return 0;
}

Source:
http://www.mediafire.com/download/31cbw6onfxzr7am/FileDispositionInformation.rar