C | Shellcode 加载器

Shellcode 加载器 是一个简单的命令行工具来测试shellcode。
它是用 C 语言编写并提供开源的。
适用于从 WinXP 到 Win10 的任何 Windows。

Shellcode 加载器

更多信息并在其页面上下载

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 替代方案

以下代码替代了 Windows LoadLibrary() 函数,这是在我们的地址空间中加载 DLL 的另一种方法。

 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/表单/组件!

使用这个简单的类,您可以创建一个不需要任何表单的 FileDialog,也无需在表单上使用 comdlg32.OCX 及其可视的 CommonDialog 组件。

与使用 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