Pages

Tuesday, October 4, 2016

[DELPHI/NATIVE] inaccessible folder

program main32;

uses Windows, SysUtils; // Old Delphi like delphi 7.
//uses Winapi.Windows, System.SysUtils; // Modern Delphi like XE8.

type
  PLARGE_INTEGER = ^LARGE_INTEGER;
  PVOID = pointer;
  HANDLE = THANDLE;
  NTSTATUS = LongInt;

  TUnicodeString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
  end;
  UNICODE_STRING = TUnicodeString;
  PUNICODE_STRING = ^TUnicodeString;

  TObjectAttributes = packed record
    Length: ULONG;
    RootDirectory: THandle;
    ObjectName: PUNICODE_STRING;
    Attributes: ULONG;
    SecurityDescriptor: Pointer;
    SecurityQualityOfService: Pointer;
  end;
  OBJECT_ATTRIBUTES = TObjectAttributes;
  POBJECT_ATTRIBUTES = ^TObjectAttributes;

  TIoStatusBlock = packed record
    Status: NTSTATUS;
    Information: ULONG;
  end;
  IO_STATUS_BLOCK = TIoStatusBlock;
  PIO_STATUS_BLOCK = ^TIoStatusBlock;

const
  STATUS_SUCCESS = NTSTATUS(0);
  OBJ_CASE_INSENSITIVE = $00000040;
  FILE_ATTRIBUTE_HIDDEN = $00000002;
  FILE_DIRECTORY_FILE = $00000001;
  FILE_CREATE = $00000002;
  FILE_READ_DATA = $0001;
  FILE_WRITE_DATA = $0002;

function NtCreateFile(FileHandle: PHANDLE;
  DesiredAccess: ACCESS_MASK;
  ObjectAttributes: POBJECT_ATTRIBUTES;
  IoStatusBlock: PIO_STATUS_BLOCK;
  AllocationSize: PLARGE_INTEGER;
  FileAttributes: ULONG;
  ShareAccess: ULONG;
  CreateDisposition: ULONG;
  CreateOptions: ULONG;
  EaBuffer: PVOID;
  EaLength: ULONG): NTSTATUS; stdcall;
  external 'ntdll.dll' name 'NtCreateFile';

function NtDeleteFile(ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; stdcall;
  external 'ntdll.dll' name 'NtDeleteFile';

procedure RtlInitUnicodeString(DestinationString: PUNICODE_STRING; SourceString: PWideChar); stdcall;
  external 'ntdll.dll' name 'RtlInitUnicodeString';

function NtClose(Handle: THANDLE): NTSTATUS; stdcall;
  external 'ntdll.dll' name 'NtClose';

procedure InitializeObjectAttributes(p: POBJECT_ATTRIBUTES; n: PUNICODE_STRING; a: ULONG; r: HANDLE; s: PSECURITY_DESCRIPTOR);
begin
  p.Length := sizeof(OBJECT_ATTRIBUTES);
  p.RootDirectory := r;
  p.Attributes := a;
  p.ObjectName := n;
  p.SecurityDescriptor := s;
  p.SecurityQualityOfService := nil;
end;

procedure Report(NtStatus: NTSTATUS; msg: PAnsiChar; path: PWideChar);
var
  buffer: WideString;
  statusMsg: string;

begin
  statusMsg := 'FAILED!';
  if NtStatus = 0 then
    statusMsg := 'SUCCESS';

  buffer := format('Task: %s' + #13 + 'Path: %S' + #13 + 'Status: 0x%X (%s)',
    [msg, path, NtStatus, statusMsg]);

  if NtStatus = 0 then
    MessageBoxW(GetDesktopWindow(),
      PWideChar(buffer),
      'Report',
      MB_ICONINFORMATION)
  else
    MessageBoxW(GetDesktopWindow(),
      PWideChar(buffer),
      'Report',
      MB_ICONERROR);

end;

var
  ObjectAttributes: OBJECT_ATTRIBUTES;
  IoStatusBlock: IO_STATUS_BLOCK;
  hTarget: THandle;
  Status: NTSTATUS;
  FolderName: UNICODE_STRING;

  folders: array[0..2] of PWideChar = (
    '\??\C:\Winmend~Folder~Hidden',
    '\??\C:\Winmend~Folder~Hidden\...',
    '\??\C:\Winmend~Folder~Hidden\...\cn');

  x, z: byte;
begin

  for x := 0 to 2 do
  begin
    RtlInitUnicodeString(@FolderName, folders[x]);
    InitializeObjectAttributes(@ObjectAttributes, @FolderName, OBJ_CASE_INSENSITIVE, 0, nil);

    Status := NtCreateFile(@hTarget,
      FILE_READ_DATA + FILE_WRITE_DATA,
      @ObjectAttributes,
      @IoStatusBlock,
      nil,
      FILE_ATTRIBUTE_HIDDEN,
      FILE_SHARE_READ + FILE_SHARE_WRITE,
      FILE_CREATE,
      FILE_DIRECTORY_FILE,
      nil,
      0);

    Report(Status, 'Creating folder...', folders[x]);
    NtClose(hTarget);
  end;

  for z := 2 downto 0 do
  begin
    RtlInitUnicodeString(@FolderName, folders[z]);
    InitializeObjectAttributes(@ObjectAttributes, @FolderName, OBJ_CASE_INSENSITIVE, 0, nil);

    Status := NtDeleteFile(@ObjectAttributes);
    Report(Status, 'Deleting folder...', folders[z]);
  end;
end.
Link: http://www.mediafire.com/file/c87ck5a8htrbc87/inaccessible_folder_delphi.rar

Friday, September 30, 2016

[C++/NATIVE] inaccessible folder

Inaccessible folder inspired from "WinMend Folder Hidden" work.


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

#ifdef _WIN64
char *captionMsg = "64-bit Application";
#else
char *captionMsg = "32-bit Application";
#endif

char *statusMsg = "FAILED!";

#define MAIN_FOLDER L"\\??\\C:\\Winmend~Folder~Hidden"

wchar_t *folders[] = {
    MAIN_FOLDER,
    MAIN_FOLDER L"\\..." ,
    MAIN_FOLDER L"\\...\\cn"
};

void Report(NTSTATUS NtStatus, char *msg, wchar_t *path) {
    char buffer[256] = {0};

    if (NtStatus == 0)
        statusMsg = "SUCCESS";

    sprintf(buffer,
            "Task:\t%s\nPath:\t%S\nStatus:\t0x%X (%s)",
            msg,
            path,
            NtStatus,
            statusMsg);

    if (NtStatus == 0)
        MessageBoxA(NULL,
                    buffer,
                    captionMsg,
                    MB_ICONINFORMATION);
    else
        MessageBoxA(NULL,
                    buffer,
                    captionMsg,
                    MB_ICONERROR);
}

int main() {

    NTSTATUS NtStatus;
    HANDLE hTarget;
    UNICODE_STRING ObjectName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;

    for (int x = 0; x < 3; x++) {
        RtlInitUnicodeString(&ObjectName, folders[x]);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &ObjectName,
                                   OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);

        NtStatus = NtCreateFile(&hTarget,
                                FILE_READ_DATA | FILE_WRITE_DATA,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                NULL,
                                FILE_ATTRIBUTE_HIDDEN,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                FILE_CREATE,
                                FILE_DIRECTORY_FILE,
                                NULL,
                                0);

        Report(NtStatus, "Creating folder...", folders[x]);
        NtClose(hTarget);
    }

    for (int x = 2; x >= 0; x--) {
        RtlInitUnicodeString(&ObjectName, folders[x]);

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

        NtStatus = NtDeleteFile(&ObjectAttributes);
        Report(NtStatus, "Deleting folder...", folders[x]);
    }

    return 0;
}

Link: http://www.mediafire.com/file/9wwiembfz3vbacn/inaccessible_folder.rar

Tuesday, October 20, 2015

Memory patcher to deal with (ASLR) 02 Updated

Code snippet updated to support Wow64 for 64bit patcher to patch 32bit target...

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

#ifdef _WIN64
#define CAPTION "atomos - memory patcher for chimera #01 (64-bit)"
#define EXENAME "target64.exe" // change it to target "target32.exe" for Wow64 test.
#else
#define CAPTION "atomos - memory patcher for chimera #01 (32-bit)"
#define EXENAME "target32.exe"
#endif

int iWinMain() {
    PROCESS_INFORMATION lpProcessInfo = {0};
    STARTUPINFO lpStartupInfo = {0};

    printf("%s\nFilename: %s\n\n", CAPTION, EXENAME);

    if(CreateProcessA(EXENAME,
                      NULL,
                      NULL,
                      NULL,
                      0,
                      CREATE_SUSPENDED,
                      NULL,
                      NULL,
                      &lpStartupInfo,
                      &lpProcessInfo))    {

#ifdef _WIN64  // 64bit Application
        DWORD64* peb64bit;
        DWORD32* wowPeb;

        CONTEXT lpContext64bit = {0};
        WOW64_CONTEXT lpWoWContext = {0};

        DWORD64 uTargetAddress64bit;
        char newByte64bit;

        DWORD64 uTargetAddressWow64;
        char newByteWow64;

        BOOL  Wow64Process = FALSE;

        IsWow64Process(lpProcessInfo.hProcess, &Wow64Process);

        if (Wow64Process) { // Wow64 Process
            lpWoWContext.ContextFlags = CONTEXT_FULL;
            Wow64GetThreadContext(lpProcessInfo.hThread, &lpWoWContext);
            wowPeb = (DWORD32*)lpWoWContext.Ebx;

            DWORD32 ImageBaseAddress = NULL;
            ReadProcessMemory(lpProcessInfo.hProcess,
                              &wowPeb[2],
                              (LPVOID)&ImageBaseAddress,
                              sizeof(DWORD32),
                              NULL);

            printf("[-] Wow64 ImageBase Address     = 0x%08X\n", ImageBaseAddress);
            printf("[-] Wow64 EntryPoint Address    = 0x%08X\n", lpWoWContext.Eax);
            printf("[-] Wow64 Process (PEB Address) = 0x%08X\n", lpWoWContext.Ebx);

            uTargetAddressWow64 = lpWoWContext.Eax + 0x64;
            newByteWow64 = 0x74;

            WriteProcessMemory(lpProcessInfo.hProcess,
                               (LPVOID)uTargetAddressWow64,
                               &newByteWow64,
                               1,
                               NULL);
        } else { // 64bit Process

            lpContext64bit.ContextFlags = CONTEXT_FULL;
            GetThreadContext(lpProcessInfo.hThread, &lpContext64bit);
            peb64bit = (DWORD64*)lpContext64bit.Rdx;

            DWORD64 ImageBaseAddress = NULL;
            ReadProcessMemory(lpProcessInfo.hProcess,
                              &peb64bit[2],
                              (LPVOID)&ImageBaseAddress,
                              sizeof(DWORD64),
                              NULL);

            printf("[-] 64bit ImageBase Address     = 0x%p\n", ImageBaseAddress);
            printf("[-] 64bit EntryPoint Address    = 0x%p\n", lpContext64bit.Rcx);
            printf("[-] 64bit Process (PEB Address) = 0x%p\n", lpContext64bit.Rdx);

            uTargetAddress64bit = lpContext64bit.Rcx + 0x7E;
            newByte64bit = 0x75;

            WriteProcessMemory(lpProcessInfo.hProcess,
                               (LPVOID)uTargetAddress64bit,
                               &newByte64bit,
                               1,
                               NULL);

        }

        ResumeThread(lpProcessInfo.hThread);
        WaitForSingleObject(lpProcessInfo.hThread, INFINITE);

#else // 32bit Application
        DWORD32* peb32bit;
        CONTEXT lpContext32bit = {0};

        DWORD32 uTargetAddress32bit;
        char newByte32bit;

        lpContext32bit.ContextFlags = CONTEXT_FULL;
        GetThreadContext(lpProcessInfo.hThread, &lpContext32bit);
        peb32bit = (DWORD32*)lpContext32bit.Ebx;

        DWORD32 ImageBaseAddress = NULL;
        ReadProcessMemory(lpProcessInfo.hProcess,
                          &peb32bit[2],
                          (LPVOID)&ImageBaseAddress,
                          sizeof(DWORD32),
                          NULL);

        printf("[-] 32bit ImageBase Address     = 0x%08X\n", ImageBaseAddress);
        printf("[-] 32bit EntryPoint Address    = 0x%08X\n", lpContext32bit.Eax);
        printf("[-] 32bit Process (PEB Address) = 0x%08X\n", lpContext32bit.Ebx);

        uTargetAddress32bit = lpContext32bit.Eax + 0x64;
        newByte32bit = 0x74;

        WriteProcessMemory(lpProcessInfo.hProcess,
                           (LPVOID)uTargetAddress32bit,
                           &newByte32bit,
                           1,
                           NULL);

        ResumeThread(lpProcessInfo.hThread);
        WaitForSingleObject(lpProcessInfo.hThread, INFINITE);
#endif

    }

    return 0;
}

Attached file contains (source and binary (32bit/64bit and Wow64) for testing purposes):
Link: http://www.mediafire.com/download/l81e74mr9nc09he/loader02.rar

Monday, September 7, 2015

Memory patcher to deal with (ASLR)

Memory patcher to deal with Address Space Layout Randomization (ASLR)


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

#ifdef _WIN64
#define CAPTION "atomos - memory patcher for chimera #01 (64-bit)"
#define EXENAME "target64.exe"
#else
#define CAPTION "atomos - memory patcher for chimera #01 (32-bit)"
#define EXENAME "target32.exe"
#endif

int iWinMain() {
    PROCESS_INFORMATION lpProcessInfo = {0};
    CONTEXT lpContext = {0};
    STARTUPINFO lpStartupInfo = {0};

    printf("%s\nFilename: %s\n\n", CAPTION, EXENAME);

    if(CreateProcessA(EXENAME,
                      NULL,
                      NULL,
                      NULL,
                      0,
                      CREATE_SUSPENDED,
                      NULL,
                      NULL,
                      &lpStartupInfo,
                      &lpProcessInfo)) {

        lpContext.ContextFlags = CONTEXT_FULL;
        GetThreadContext(lpProcessInfo.hThread, &lpContext);

#ifdef _WIN64
        ULONG_PTR* peb = (ULONG_PTR*)lpContext.Rdx;
#else
        ULONG_PTR* peb = (ULONG_PTR*)lpContext.Ebx;
#endif
        ULONG_PTR ImageBaseAddress = NULL;

        ReadProcessMemory(lpProcessInfo.hProcess,
                          &peb[2],
                          (LPVOID)&ImageBaseAddress,
                          sizeof(ULONG_PTR),
                          NULL);
      
        printf("[-] ImageBase Address     = 0x%p\n", ImageBaseAddress);

#ifdef _WIN64
        printf("[-] EntryPoint Address    = 0x%p\n", lpContext.Rcx);
        printf("[-] Process (PEB Address) = 0x%p\n", lpContext.Rdx);

#else
        printf("[-] EntryPoint Address    = 0x%p\n", lpContext.Eax);
        printf("[-] Process (PEB Address) = 0x%p\n", lpContext.Ebx);
#endif



#ifdef _WIN64
        ULONG_PTR uTargetAddress = lpContext.Rcx + 0x7E;
        const char newByte = 0x75;
#else
        ULONG_PTR uTargetAddress = lpContext.Eax + 0x64;
        const char newByte = 0x74;
#endif
        WriteProcessMemory(lpProcessInfo.hProcess,
                           (LPVOID)uTargetAddress,
                           &newByte,
                           1,
                           NULL);

        ResumeThread(lpProcessInfo.hThread);
        WaitForSingleObject(lpProcessInfo.hThread, INFINITE);
    }

    return 0;
}


Source: http://www.mediafire.com/download/dobdsqd6dsplwsq/loader.rar

Friday, May 22, 2015

[C/C++] Using RtlAdjustPrivilege to detect debugger.

A basic way using RtlAdjustPrivilege to detect the debugger (OllyDbg and IDA demo 6.6)
As usually but not (enabled by default) for all debugger, the Debugger must acquiring debug privilege
to work with its complete capacity.
The snippet is simple and probably already used but I write it as simple as possible to get a clear ASM code
inside the debugger.

RtlAdjustPrivilege: Enables or disables a privilege from the calling thread or process.

NTSTATUS RtlAdjustPrivilege
 (
  ULONG    Privilege,     //[In]    Privilege index to change.
  BOOLEAN  Enable,        //[In]    If TRUE, then enable the privilege otherwise disable.
  BOOLEAN  CurrentThread, //[In]    If TRUE, then enable in calling thread, otherwise process.
  PBOOLEAN Enabled        //[Out]   Whether privilege was previously enabled or disabled.
 
)


RtlAdjustPrivilege store the previous status into boolean variable
Our work is to read the contents of this variable after calling RtlAdjustPrivilege with SE_DEBUG_PRIVILEGE as parameter,
and of course if a status is already enabled then we have a likely debugging situation.


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

#ifdef _WIN64
#define captionMsg L"Application 64-bit"
#else
#define captionMsg L"Application 32-bit"
#endif

int WINAPI iWinMain() {
    //Boolean to check after calling RtlAdjustPrivilege.
    BOOLEAN bPreviousPrivilegeStatus; 

    RtlAdjustPrivilege(
        SE_DEBUG_PRIVILEGE,
        FALSE, // avoid to adjust privilege (DISABLE IT).
        FALSE,
        &bPreviousPrivilegeStatus);

// check if SE_DEBUG_PRIVILEGE was already acquired then voluntary crash the application,
// by calling memset with invalid pointer as parameter.        
    if (bPreviousPrivilegeStatus) 
        memset(NULL, 0, 1); //<-- BOOM! PADA BOOM!!!

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

    return 0;
}

Source:
http://www.mediafire.com/download/z3udrn29pd93wvl/RtlAdjustPrivilege.rar

[C/C++] Using "csrss.exe" ProcessId to detect debugger.

Code Snippet:

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

#ifdef _WIN64
#define captionMsg L"64-bit Application"
#else
#define captionMsg L"32-bit Application"
#endif

int WINAPI iWinMain() {

    HANDLE ProcessHandle = NULL;
    OBJECT_ATTRIBUTES ObjectAttributes;
    CLIENT_ID ClientId;

    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
    ObjectAttributes.RootDirectory = 0;
    ObjectAttributes.ObjectName = NULL;
    ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
    ObjectAttributes.SecurityDescriptor = NULL;
    ObjectAttributes.SecurityQualityOfService = NULL;

    ClientId.UniqueProcess = CsrGetProcessId(); // getting "csrss.exe" ProcessId.
    ClientId.UniqueThread = 0;

    NtOpenProcess(
        &ProcessHandle,
        PROCESS_ALL_ACCESS, // This parameter need SeDebugPrivilege.
        &ObjectAttributes,
        &ClientId);

    if (ProcessHandle != NULL)
        memset(NULL, 0, 1); //<-- BOOM! PADA BOOM!!!

    MessageBoxW(
        NULL,
        L"Nothing!",
        captionMsg,
        MB_ICONINFORMATION);
    return 0;
}

Source:
http://www.mediafire.com/download/uqm9shm64trv2q6/csrssDBG.rar

Monday, May 18, 2015

DSEFix (kernelmode.info)

Windows x64 Driver Signature Enforcement Overrider from kernelmode.info.

For more info see Defeating x64 Driver Signature Enforcement.
http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3322

Source:
https://github.com/hfiref0x/DSEFix

UACMe (kernelmode.info)

Defeating Windows User Account Control by abusing built-in Windows AutoElevate backdoor.
More info http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3643


Source:
https://github.com/hfiref0x/UACME 

WinObjEx64 (kernelmode.info)

Windows Object Explorer 64-bit (WinObjEx64) from kernelmode.info.
http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3751

Quote(kernelmode.info):
WinObjEx64 is an advanced utility that lets you explore the Windows Object Manager namespace.
For certain object types, you can double-click on it or use the "Properties..."
toolbar button to get more information, such as description, attributes, resource usage etc.
WinObjEx64 let you view and edit object-related security information if you have required access rights.

System Requirements:
WinObjEx64 does not require administrative privileges. However administrative privilege is required
to view much of the namespace and to edit object-related security information.
WinObjEx64 works only on the following x64 Windows:
Windows 7, Windows 8, Windows 8.1 and Windows 10, including Server variants.
WinObjEx64 does not work on Windows XP, Windows Vista is partially supported.
We have no plans of their full support.
In order to use all program features Windows must be booted in the DEBUG mode.

Build:
WinObjEx64 comes with full source code.
In order to build from source you need Microsoft Visual Studio 2013 U4 and later versions.

Authors:
(c) 2015 WinObjEx64 Project
Original WinObjEx (c) 2003 - 2005 Four-F

Acknowledgements:
We would like to thanks the following people for their contributions (in the alphabetical order):

Andrew Ivlev aka Four-F - author of the original x86-32 WinObjEx
Giuseppe Bonfa aka Evilcry - KDSubmarine author
Mark Russinovich - author of the original proof-of-concept tool WinObj
Microsoft WinDBG developers team

Source and compiled binary here:
https://github.com/hfiref0x/WinObjEx64

Project files SHA1 https://github.com/hfiref0x/WinObjEx64/ ... /SHA1.hash

Copyrights:
WinObjEx64 developed by WinObjEx64 Project group, in the alphabetical order:

EP_X0FF
MP_ART

This program uses Windows Debugger Local Kernel Debugging Driver © Microsoft Corporation.
Please use this thread for bugreports. Also take a note that Windows 10 is supported *AS IS*
since it wasn't released yet, official support will be added after official release.

VirtualBox Hardened Loader x64 (kernelmode.info)

VirtualBox Hardened VM detection mitigation loader x64 from kernelmode.info.

Step by step guide for VirtualBox Hardened (4.3.14+) VM detection mitigation configuring.
http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3478

Quote(kernelmode.info):
Project comes with full source code. In order to build from source you need: Microsoft Visual Studio 2013 U4 and later versions for loader build. Windows Driver Kit 8.1 U1 and later versions for driver build.

https://github.com/hfiref0x/VBoxHardenedLoader

[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