소스 코드

C | 쉘코드 로더

쉘코드 로더 쉘코드를 테스트하는 간단한 명령줄 도구입니다.
C로 작성되었으며 오픈 소스를 제공합니다.
WinXP에서 Win10까지 모든 Windows에서 작동합니다.

쉘코드 로더

자세한 정보 및 해당 페이지에서 다운로드

C++ 및 Delphi | CryptoGear 암호화 알고리즘

BreakingSecurity에서 개발한 대칭 키 블록 암호화 암호.

여기에서 C++ 구현을 찾을 수 있습니다..
당신은 그것을 찾을 수 있습니다 Delphi 여기에 구현.

C++ | RC4 클래스

기본 RC4 암호화 알고리즘.
간단하고 빠르며 많은 응용 프로그램에서 사용되는 유명한 알고리즘입니다.

cRC4.h :

/***********************************************************
* Standard RC4 Encryption
* C++ Class
* Coded by Viotto © BreakingSecurity.net
***********************************************************/
#include <string>
using namespace std;
class CRC4
{
public:
	CRC4(unsigned char* pKey, unsigned int lenKey);
	CRC4();
	void RC4(unsigned char pData[], unsigned long lenData);
	string RC4Str(unsigned char* pInputData, unsigned long InputSize);
	void Initialize(unsigned char* pKey, unsigned int lenKey);
private:
	int m_sBox[256]; //substitution-box
	int a, b;	
	unsigned char swap;
};

 

cRC4.cpp:

/***********************************************************
* Standard RC4 Encryption
* C++ Class
* Coded by Viotto © BreakingSecurity.net
***********************************************************/

#include "cRC4.h"
// Constructor. It will generate s-box based on the provided key.
// This way future encryption/decryptions routines will not have to recreate s-box each time.
CRC4::CRC4(unsigned char* pKey, unsigned int lenKey)
{
	Initialize(pKey, lenKey);
}
/* Overloaded costructor with no arguments.
   Must initialize s-box manually.           */
CRC4::CRC4()
{}

void CRC4::Initialize(unsigned char* pKey, unsigned int lenKey)
{
	// Initialize substitution box, based on the provided key.
	b = 0;
	for (a = 0; a < 256; a++)
	{
		m_sBox[a] = a;
	}
	for (a = 0; a < 256; a++)
	{
		b = (b + m_sBox[a] + pKey[a % lenKey]) % 256;
		swap = m_sBox[a];
		m_sBox[a] = m_sBox[b];
		m_sBox[b] = swap;
	}
}

void CRC4::RC4(unsigned char pData[], unsigned long lenData)
{
	int sBox[256];
	int i = 0, j = 0;
	long Offset;
	// Create a local copy of the s-box. Better than recreating each time before encrypting/decrypting.
	memcpy(sBox, m_sBox, 256 * sizeof(int));
	//Encrypt the data
	for (Offset = 0; Offset < lenData; Offset++)
	{
		i = (i + 1) % 256;
		j = (j + sBox[i]) % 256;
		swap = sBox[i];
		sBox[i] = sBox[j];
		sBox[j] = swap;
		pData[Offset] ^= sBox[(sBox[i] + sBox[j]) % 256];
	}
}

// This function does not overwrite input with output, but saves it on a separate string.
string CRC4::RC4Str(unsigned char* pInputData, unsigned long InputSize)
{
	string sInputOutputData((char*)pInputData, InputSize);
	RC4((unsigned char*)sInputOutputData.c_str(), InputSize);
	return sInputOutputData;
}
C | 커널 수준에서 PID에서 프로세스 경로 가져오기

사용자 수준에서는 GetModuleFileNameEx()와 같은 API를 사용하여 이러한 간단한 작업을 간단하게 수행할 수 있습니다.

그러나 커널 수준에서 이를 수행하는 문서화된 방법은 없습니다.
많은 사람들이 요청하는 것을 찾았지만 명확하게 작동하는 스니펫을 찾지 못했기 때문에 내 것을 공유하는 것이 유용할 수 있다고 생각했습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
BOOLEAN KrnGetProcessPath(HANDLE hProcessId)
// ProcessID handle can be get using PsGetCurrentProcessId(),
// or by using process callback routines such as PsSetCreateProcessNotifyRoutine()
{
	HANDLE hProcess = NULL;
	OBJECT_ATTRIBUTES obj_attr;
	CLIENT_ID cid;
	cid.UniqueProcess = hProcessId; 
	cid.UniqueThread = NULL;
	InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL);
	ZwOpenProcess(&hProcess, GENERIC_READ, &obj_attr, &cid);
	// When the ProcessInformationClass parameter is ProcessImageFileName, 
	//	the buffer pointed to by the ProcessInformation parameter should be large enough to hold a UNICODE_STRING structure, 
	//	as well as the string itself.
	WCHAR ustrBuffer[(sizeof(UNICODE_STRING) / sizeof(WCHAR)) + 260];
	UNICODE_STRING ustrPath;
	// Initialize UNICODE_STRING
	ustrPath.Buffer = ustrBuffer;
	ustrPath.Length = 0x0;
	ustrPath.MaximumLength = sizeof(ustrBuffer);
	// Process path will be saved inside the unicode string.
	NTSTATUS ret = ZwQueryInformationProcess(hProcess, ProcessImageFileName, &ustrPath, sizeof(ustrBuffer), NULL);
	if (NT_SUCCESS(ret))
	{
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[DEBUG] process path: %wZ\n", ustrPath);
		return TRUE;
	}
	else
	{
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[ERROR] error getting process path: %x\n", ret);
		return FALSE;
	}
}
씨 | LoadDll: LoadLibrary 대안

다음 코드는 주소 공간에서 DLL을 로드하는 대체 방법인 Windows LoadLibrary() 함수를 대체합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <Windows.h>
// UNICODE_STRING structure
typedef struct _UNICODE_STRING 
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
//LdrLoadDll function prototype 
typedef NTSTATUS (WINAPI *fLdrLoadDll) 
(
	IN PWCHAR PathToFile OPTIONAL,
	IN ULONG Flags OPTIONAL, 
	IN PUNICODE_STRING ModuleFileName, 
	OUT PHANDLE ModuleHandle 
); 
//RtlInitUnicodeString function prototype
typedef VOID (WINAPI *fRtlInitUnicodeString) 
(
	PUNICODE_STRING DestinationString,
	PCWSTR SourceString
);
HMODULE hNtDll;
fLdrLoadDll _LdrLoadDll;
fRtlInitUnicodeString _RtlInitUnicodeString;
//_____________________________________________
//
// LoadDll: LoadLibrary replacement
// 
// This function loads the specified DLL into our process.
// This function is a replacement for the Windows LoadLibrary() function. 
//
// PARAMETERS:
// szFileName: path of the DLL to load.
//
// RETURN VALUE:
// HMODULE DllHandle: An handle to the DLL module in memory.
//_____________________________________________
//
HMODULE LoadDll( LPCSTR szFileName) 
{  
   // Load required functions dinamically
   hNtDll = GetModuleHandleA("ntdll.dll");
   _LdrLoadDll = (fLdrLoadDll) GetProcAddress( hNtDll, "LdrLoadDll");
   _RtlInitUnicodeString = (fRtlInitUnicodeString) GetProcAddress( hNtDll, "RtlInitUnicodeString");
   int StrLen = lstrlenA(szFileName);
   BSTR WideStr = SysAllocStringLen(NULL, StrLen);
   MultiByteToWideChar(CP_ACP, 0, szFileName, StrLen, WideStr, StrLen);
   UNICODE_STRING usDllName;
   _RtlInitUnicodeString(&usDllName, WideStr);
   SysFreeString(WideStr);
   HANDLE DllHandle; 
   _LdrLoadDll(0, 0, &usDllName, &DllHandle);
   return (HMODULE)DllHandle;
}
int main() //Usage example
{
   HMODULE hmodule = LoadDll("Kernel32.dll");
   return (int)hmodule;
}

C++ | 파일검색

파일 이름 또는 그 일부를 검색하는 데 사용할 수 있는 간단하고 빠른 재귀 함수,
지정된 폴더와 모든 하위 디렉토리 안에 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <windows.h>
#include <algorithm>
#include <string>
using namespace std;
//_____________________________________________
//
// FileSearch Function
// 
// This function will search for a filename or part of it,
// inside the specified directory and in all of the subdirectories.
// © BreakingSecurity.net
//
// PARAMETERS:
// sSearch: String which specifies a filename, or a part of filename to be searched for.
// sDir: Path to search in (ex: "C:\\Windows")
//_____________________________________________
//
bool FileSearch(string sSearch, string sDir)
{
	// Convert all characters to lowercase
	std::transform(sSearch.begin(), sSearch.end(), sSearch.begin(), ::tolower);
	
	// Check for final slash in path and append it if missing
	if (sDir[sDir.length() -1] != '\\')
	{
		sDir += "\\";
	}
	
	WIN32_FIND_DATA FileInfo;
	HANDLE hFind = FindFirstFileA(string(sDir + "*").c_str(), &FileInfo);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		FindClose(hFind);
		return false;
	}
	string sFileInfo;
	while (FindNextFile(hFind, &FileInfo) != 0)
	{
		if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
			&& strcmp(FileInfo.cFileName, ".") != 0
			&& strcmp(FileInfo.cFileName, "..") != 0)
		{
			// Recursive seach inside subdirectory
			string sRecursiveDir = sDir + string(FileInfo.cFileName);
			FileSearch(sSearch, sRecursiveDir);
		}
		
		string sFileName(FileInfo.cFileName);
		
		// Convert all characters to lowercase
		std::transform(sFileName.begin(), sFileName.end(), sFileName.begin(), ::tolower);
		
		// Check if filename contains search string
		if (sFileName.find(sSearch) != string::npos)
		{
			//Search string has been found inside file name
			printf(string(sDir + FileInfo.cFileName + "\n").c_str());
		}
	}
	FindClose(hFind);
	return true;
}
// Usage example:
// FileSearch.exe "Notepad" "C:Windows"
void main(int argc, char* argv[])
{
	if (argc == 3)
	{
		FileSearch(argv[1], argv[2]);
		printf("Search finished!\n");
	}
	else printf("Wrong number of parameters\n");
	system("pause");
}

C++ | Viotto .OCX 등록자

Viotto OCX Registrator는 설치, 등록 및 등록 취소를 위한 간단한 도구입니다. OCX 파일.
무료 및 오픈 소스로 출시됩니다.
Embarcadero C++로 코딩되어 있습니다.
너는 그것을 발견 할 수있다. 여기.

Delphi | Windows 명명된 파이프를 사용한 프로세스 간 통신

이 샘플은 서로 다른 프로세스가 서로 통신하고 데이터를 교환하도록 하는 방법을 보여주기 위한 것입니다.
좋은 글을 쓴 Peter Bloomfield에게 감사합니다. C++의 Windows 파이프에 대한 자습서.
program PipeServer;
// Server application which creates an inbound pipe and waits for data from client processes.
{$APPTYPE CONSOLE}
uses
  SysUtils,
  Windows;
procedure ReceivePipeData();
var
  pipe: Cardinal;
  RecBuffer: Array[0..999] of Byte;
  numBytesRead: DWORD;
  result: LongBool;
  sReadData: AnsiString;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
begin
  // Must grant access rights in case User Account Control is on, on WinVista and above,
  // and communicating processes are under a different user (which can be also SYSTEM).
  // Otherwise, the other side of the pipe will receive ERROR_ACCESS_DENIED upon CreateFile().
  // If UAC is on and we are trying to use pipe between a userlevel and a system process,
  // even if we are inside the same user account, pipe communication will fail.
  // In order to avoid this, we must initialize a security descriptor for the pipe.
  InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
  // There is an important difference between an empty and a nonexistent DACL.
  // When a DACL is empty, it contains no access control entries (ACEs); therefore, no access 
     rights are explicitly granted.
  // As a result, access to the object is implicitly denied.
  // When an object has no DACL (when the pDacl parameter is NULL),
  // no protection is assigned to the object, and all access requests are granted.
  SetSecurityDescriptorDacl(@sd, True, nil, False);
  sa.bInheritHandle := false;
  sa.lpSecurityDescriptor := @sd;
  sa.nLength := sizeof(sa);
  while true do begin
    repeat
      // Create a new pipe to receive data
      pipe := CreateNamedPipe(
         '\.pipeSamplePipe', // Our pipe name
         PIPE_ACCESS_INBOUND, // Read-only pipe
         PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE, //Using Message mode
         PIPE_UNLIMITED_INSTANCES ,
         0,  // No outbound buffer
         0,  // No inbound buffer
         0,  // Use default wait time
         @sa // Set security attributes to grant access rights
      );
      if (pipe = INVALID_HANDLE_VALUE) then begin
        Write('[ERROR] Failed to create pipe. Error code ' + IntToStr(GetLastError()) + #13#10 + 
              'Press Enter to retry');
        Readln;
      end;
    until pipe <> INVALID_HANDLE_VALUE;
    WriteLn('[INFO] Inbound pipe created! Waiting for a client process to connect...');
    // This call blocks until a client process connects to the pipe
    result := ConnectNamedPipe(pipe, nil);
    if (result = false) then begin
      Writeln('[ERROR] Failed to connect to pipe. Error code ' + IntToStr(GetLastError()));
    end
    else begin
      Writeln('[INFO] Client connected! Waiting for data...');
      numBytesRead := 0;
      // The read operation will block until there is data to read
      result := ReadFile(
          pipe,
          RecBuffer[0], // The data from the pipe will be put here
          sizeof(RecBuffer), // Number of bytes allocated
          numBytesRead, // This will store number of bytes actually read
          nil // Not using overlapped IO
      );
      if (result = false) then begin
          Writeln('[ERROR] Failed to read pipe data! Error code ' + IntToStr(GetLastError()));
      end else begin
          SetString(sReadData,PAnsiChar(@recBuffer[0]), numBytesRead); //Copy byte array to string
          Writeln('[SUCCESS] Data received: ' + sReadData);
      end;
    end;
    //Close our pipe handle
    CloseHandle(pipe);
  end;
end;
//Program start procedure
begin
  Writeln('*** Pipe Server Application ***' + #13#10);
  Write('[INFO] Press Enter to create pipe server and start listening for incoming data');
  ReadLn;
  ReceivePipeData();
end.
program PipeClient;
// Client application which sends data to pipe server.
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
Classes;
// Data to send via pipe is read from a file.
function GetDataFromFile(sFileName: AnsiString): AnsiString;
var
DataFile: TFileStream;
ReadBuffer: array of Byte;
sDataToSend: AnsiString;
begin
  try
    DataFile := TFileStream.Create( sFileName , fmOpenRead);
    SetLength(ReadBuffer, DataFile.Size);
    DataFile.Read(ReadBuffer[0], Length(ReadBuffer));
    SetString(sDataToSend,PAnsiChar(@ReadBuffer[0]), DataFile.Size); //Copy byte array to string
    DataFile.Free;
    Result := sDataToSend;
  except
    Result := '';
  end;
end;
procedure SendPipeData();
var
pipe: Cardinal;
numBytesWritten: DWORD;
result: LongBool;
sDataToSend: AnsiString;
begin
  repeat
    // Open the named pipe, previusly created by server application
    pipe := CreateFile(
    '\.pipeSamplePipe', // Our pipe name
    GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE,
    nil,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0
    );
    if (pipe = INVALID_HANDLE_VALUE) then begin
      Write('[ERROR] Failed to open pipe (server must be running first).' + #13#10 + 'Press Enter to 
      retry');
      Readln;
    end;
  until pipe <> INVALID_HANDLE_VALUE;
  repeat
    //Get data to send from file
    sDataToSend := GetDataFromFile(ExtractFilePath(ParamStr(0)) + 'DataToSend.txt');
    if sDataToSend = '' then begin
      Write('[ERROR] Unable to read data from file (may be unexistent or empty).' + #13#10 + 'Press
      Enter to retry');
      Readln;
    end;
  until sDataToSend <> '';
  numBytesWritten := 0;
  result := WriteFile(
  pipe, // Handle to our outbound pipe
  sDataToSend[1], // Pointer to data to send
  Length(sDataToSend), // Length of data to send (bytes)
  numBytesWritten, // Will store actual amount of data sent
  nil // Not using overlapped IO
  );
  if (result = false) then
    Writeln('[ERROR] Failed to send pipe data. Error code ' + IntToStr(GetLastError()))
  else Writeln('[SUCCESS] Pipe data sent: ' + sDataToSend);
  // Close the pipe handle
  CloseHandle(pipe);
end;
//Program start procedure
begin
  Writeln('*** Pipe Client Application ***' + #13#10);
  while true do begin
    Write('[INFO] Press Enter to send pipe data to server');
    Readln;
    SendPipeData();
  end;
end.

VB6 | Viotto Binder

당신은 찾을 수 Viotto Binder 자체 페이지의 소스 여기.

VB6 | 양식 없는 파일 대화 상자: OCX/양식/구성 요소가 필요하지 않습니다!

이 간단한 클래스를 사용하면 양식에서 comdlg32.OCX 및 시각적 CommonDialog 구성 요소를 사용할 필요 없이 양식 없이도 FileDialog를 만들 수 있습니다.

또한 OCX 구성 요소를 사용할 때보다 성능이 더 좋습니다.
오른쪽 스크린샷은 FileDialog를 열 때의 성능 차이를 보여줍니다. 왼쪽은 전통적인 OCX CommonDialog 컨트롤을 사용하고 오른쪽은 이 코드를 사용하여 DLL을 직접 호출합니다.

' cFileDialog.cls
' by Viotto - www.BreakingSecurity.net
'
' Provides CommonDialog functionality,
' without the need of ocx file and graphical component.
'
' ComDlg32.OCX provides an easy-to-use interface, but if you use the OCX control,
' you have to load the module into memory and also distribute a 90K OCX file to users of your software.
' To improve performance, and eliminate the need of additional dependencies,
' you should minimize the use of controls in your applications.
' Instead, you can use the Win32 API calls directly.
'
' More info from Microsoft: https://support.micr...en-us/kb/161286
 
 
Option Explicit
 
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _
  "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
  
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias _
  "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long
  
Private Declare Sub CopyMemory Lib "kernel32" Alias _
  "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
 
Private Type OPENFILENAME
  lStructSize As Long
  hwndOwner As Long
  hInstance As Long
  lpstrFilter As String
  lpstrCustomFilter As String
  nMaxCustFilter As Long
  nFilterIndex As Long
  lpstrFile As String
  nMaxFile As Long
  lpstrFileTitle As String
  nMaxFileTitle As Long
  lpstrInitialDir As String
  lpstrTitle As String
  flags As Long
  nFileOffset As Integer
  nFileExtension As Integer
  lpstrDefExt As String
  lCustData As Long
  lpfnHook As Long
  lpTemplateName As String
End Type
 
Private Dlg As OPENFILENAME
Private bDialogExecuted As Boolean ' will be true if user pressed OK, false if dialog was canceled
 
' This can be used to set an initial filename before displaying the dialog
Public Property Let strFile(value As String)
  CopyMemory ByVal Dlg.lpstrFile, ByVal value, Len(value)
End Property
 
' This can be used to retrieve full path of the selected file, after dialog display.
Public Property Get strFile() As String
  strFile = Dlg.lpstrFile
End Property
 
' This can be used to get the filename (without path) of the selected file, after dialog display.
Public Property Get FileName() As String
  FileName = Dlg.lpstrFileTitle
End Property
 
Public Property Get Executed() As Boolean
  Executed = bDialogExecuted
End Property
 
' Set dialog title
Public Property Let Title(value As String)
  Dlg.lpstrTitle = value
End Property
 
' Set default file extension
Public Property Let DefaultExt(value As String)
  Dlg.lpstrDefExt = value
End Property
 
Public Property Let Filter(value As String)
  Dlg.lpstrFilter = value
End Property
 
Public Property Let Owner(value As Long)
  Dlg.hwndOwner = value
End Property
 
 
Public Sub Initialize()
  Dlg.lStructSize = Len(Dlg)
  Dlg.hInstance = App.hInstance
  Dlg.nFilterIndex = 1
  Dlg.lpstrFile = String(257, 0)
  Dlg.nMaxFile = Len(Dlg.lpstrFile) - 1
  Dlg.lpstrFileTitle = Dlg.lpstrFile
  Dlg.nMaxFileTitle = Dlg.nMaxFile
  Dlg.lpstrInitialDir = vbNullString
  Dlg.flags = 0
End Sub
 
Public Sub ShowOpenDialog()
  bDialogExecuted = GetOpenFileName(Dlg)
End Sub
 
Public Sub ShowSaveDialog()
  bDialogExecuted = GetSaveFileName(Dlg)
End Sub

VB6 | ROT-N 암호화

VB6의 Rot-N 암호화 암호.
매우 기본적인 암호화이며 안전한 보호를 위해 신뢰할 수 없습니다.

'********************************************************************************
'* Title:       ROT-N encryption module                                         *
'* Author:      Viotto                                                          *
'* Website:     www.viotto-security.net                                         *
'* Description: simple substitution cipher for bytes: each input                *
'*              byte value will be rotated by the specified number of bytes.    *
'* Purpose:     simple encryption for text and files.                           *
'* Usage:       Encryption key should be a number between 1 and 255; higher     *
'*              numbers will work but they cause redundant rotations.           *
'* Notes:       with key value 128 (ROT-128), you can use same function to      *
'*              encrypt and decrypt data. Otherwise you can use ROTN_Forward    *
'*              to encrypt and ROTN_Backward to decrypt.                        *
'*                                                                              *
'********************************************************************************

Public Function ROTN_Forward(ByVal InputData As String, ByVal NumKey As Integer) As String
Dim i As Long, OutChar As String
For i = 1 To Len(InputData)
OutChar = Asc(Mid(InputData, i, 1)) + NumKey
While OutChar > 255
OutChar = OutChar - 256
Wend
ROTN_Forward = ROTN_Forward + Chr(OutChar)
Next
End Function

Public Function ROTN_Backward(ByVal InputData As String, ByVal NumKey As Integer) As String
Dim i As Long, OutChar As String
For i = 1 To Len(InputData)
OutChar = Asc(Mid(InputData, i, 1)) - NumKey
While OutChar < 0
OutChar = OutChar + 256
Wend
ROTN_Backward = ROTN_Backward + Chr(OutChar)
Next
End Function

VB6 | 기본 브라우저 경로 가져오기

몇 줄의 코드와 Windows API가 없습니다.

Function DefaultBrowser() As String
  Dim regshell As Object
  Set regshell = CreateObject("Wscript.Shell")
  ' Reads the registry value where is stored the default application to use with HTTP
  DefaultBrowser = regshell.regread("HKEY_CLASSES_ROOT\HTTP\shell\open\command\")
  ' Removes shell parameters after the actual path, preserving only path included in double             ' quotes
  DefaultBrowser = Left(DefaultBrowser, InStr(1, DefaultBrowser, ".exe", vbTextCompare) + 4)
  ' Removes double quotes (")
  DefaultBrowser = Replace(DefaultBrowser, Chr(34), vbNullString)
End Function
메뉴