mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-30 22:19:17 +02:00
Beginning of work on the building blocks for PSH->Meterp bindings
This commit is contained in:
parent
6e5afca1b3
commit
ee807408ec
c/meterpreter
source
common
extensions/powershell
workspace/ext_server_powershell
powershell/MSF.Powershell
@ -6,7 +6,7 @@
|
|||||||
#define _METERPRETER_SOURCE_COMMON_COMMON_H
|
#define _METERPRETER_SOURCE_COMMON_COMMON_H
|
||||||
|
|
||||||
/*! @brief Set to 0 for "normal", and 1 to "verbose", comment out to disable completely. */
|
/*! @brief Set to 0 for "normal", and 1 to "verbose", comment out to disable completely. */
|
||||||
//#define DEBUGTRACE 0
|
#define DEBUGTRACE 0
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||||
|
|
||||||
#include "powershell_bridge.h"
|
#include "powershell_bridge.h"
|
||||||
|
#include "powershell_bindings.h"
|
||||||
|
|
||||||
// this sets the delay load hook function, see DelayLoadMetSrv.h
|
// this sets the delay load hook function, see DelayLoadMetSrv.h
|
||||||
EnableDelayLoadMetSrv();
|
EnableDelayLoadMetSrv();
|
||||||
@ -34,6 +35,7 @@ Command customCommands[] =
|
|||||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||||
{
|
{
|
||||||
hMetSrv = remote->met_srv;
|
hMetSrv = remote->met_srv;
|
||||||
|
gRemote = remote;
|
||||||
|
|
||||||
DWORD result = initialize_dotnet_host();
|
DWORD result = initialize_dotnet_host();
|
||||||
|
|
||||||
|
47
c/meterpreter/source/extensions/powershell/powershell_bindings.cpp
Executable file
47
c/meterpreter/source/extensions/powershell/powershell_bindings.cpp
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
/*!
|
||||||
|
* @file powershell_bindings.cpp
|
||||||
|
* @brief Wrapper functions for bridging native meterp calls to powershell
|
||||||
|
*/
|
||||||
|
extern "C" {
|
||||||
|
#include "../../common/common.h"
|
||||||
|
#include "powershell_bindings.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
Remote* gRemote = NULL;
|
||||||
|
|
||||||
|
VOID MeterpreterInvoke(unsigned int isLocal, unsigned char* input, unsigned int inputLength, unsigned char** output, unsigned int* outputLength)
|
||||||
|
{
|
||||||
|
dprintf("[PSH BINDING] Input %p of %d bytes received", input, inputLength);
|
||||||
|
/*
|
||||||
|
dprintf("[PYTHON] a function was invoked on: %s", self->ob_type->tp_name);
|
||||||
|
const char* packetBytes = NULL;
|
||||||
|
BOOL isLocal = FALSE;
|
||||||
|
Py_ssize_t packetLength = 0;
|
||||||
|
|
||||||
|
PyArg_ParseTuple(args, "is#", &isLocal, &packetBytes, &packetLength);
|
||||||
|
dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local");
|
||||||
|
|
||||||
|
Packet packet = { 0 };
|
||||||
|
packet.header = *(PacketHeader*)packetBytes;
|
||||||
|
packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader));
|
||||||
|
packet.payloadLength = (ULONG)packetLength - sizeof(TlvHeader);
|
||||||
|
|
||||||
|
// If the functionality doesn't require interaction with MSF, then
|
||||||
|
// make the packet as local so that the packet receives the request
|
||||||
|
// and so that the packet doesn't get sent to Meterpreter
|
||||||
|
packet.local = isLocal;
|
||||||
|
|
||||||
|
command_handle(gRemote, &packet);
|
||||||
|
|
||||||
|
// really not sure how to deal with the non-local responses at this point.
|
||||||
|
if (packet.partner == NULL)
|
||||||
|
{
|
||||||
|
// "None"
|
||||||
|
return Py_BuildValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength);
|
||||||
|
packet_destroy(packet.partner);
|
||||||
|
return result;
|
||||||
|
*/
|
||||||
|
}
|
13
c/meterpreter/source/extensions/powershell/powershell_bindings.h
Executable file
13
c/meterpreter/source/extensions/powershell/powershell_bindings.h
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
/*!
|
||||||
|
* @file powershell_bindings.h
|
||||||
|
* @brief Declarations for bindings to meterpreter functions that can be called from Powershell.
|
||||||
|
*/
|
||||||
|
#ifndef _METERPRETER_SOURCE_EXTENSION_POWERSHELL_BINDINGS_H
|
||||||
|
#define _METERPRETER_SOURCE_EXTENSION_POWERSHELL_BINDINGS_H
|
||||||
|
|
||||||
|
extern Remote* gRemote;
|
||||||
|
|
||||||
|
VOID MeterpreterInvoke(unsigned char* input, unsigned int inputLength, unsigned char** output, unsigned int* outputLength);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* @file powershell_bridge.c
|
* @file powershell_bridge.cpp
|
||||||
* @brief Wrapper functions for bridging native meterp calls to powershell
|
* @brief Wrapper functions for bridging native meterp calls to powershell
|
||||||
*/
|
*/
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -273,11 +273,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\source\extensions\powershell\powershell.c" />
|
<ClCompile Include="..\..\source\extensions\powershell\powershell.c" />
|
||||||
|
<ClCompile Include="..\..\source\extensions\powershell\powershell_bindings.cpp" />
|
||||||
<ClCompile Include="..\..\source\extensions\powershell\powershell_bridge.cpp" />
|
<ClCompile Include="..\..\source\extensions\powershell\powershell_bridge.cpp" />
|
||||||
<ClCompile Include="..\..\source\extensions\powershell\powershell_runner.cpp" />
|
<ClCompile Include="..\..\source\extensions\powershell\powershell_runner.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\source\extensions\powershell\powershell.h" />
|
<ClInclude Include="..\..\source\extensions\powershell\powershell.h" />
|
||||||
|
<ClInclude Include="..\..\source\extensions\powershell\powershell_bindings.h" />
|
||||||
<ClInclude Include="..\..\source\extensions\powershell\powershell_bridge.h" />
|
<ClInclude Include="..\..\source\extensions\powershell\powershell_bridge.h" />
|
||||||
<ClInclude Include="..\..\source\extensions\powershell\powershell_runner.h" />
|
<ClInclude Include="..\..\source\extensions\powershell\powershell_runner.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
148
powershell/MSF.Powershell/Enumerations.cs
Executable file
148
powershell/MSF.Powershell/Enumerations.cs
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MSF.Powershell
|
||||||
|
{
|
||||||
|
public enum PacketType
|
||||||
|
{
|
||||||
|
Request = 0,
|
||||||
|
Response = 1,
|
||||||
|
PlainRequest = 10,
|
||||||
|
PlainResponse = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum MetaType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
String = 1 << 16,
|
||||||
|
Uint = 1 << 17,
|
||||||
|
Raw = 1 << 18,
|
||||||
|
Bool = 1 << 19,
|
||||||
|
Qword = 1 << 20,
|
||||||
|
Compressed = 1 << 21,
|
||||||
|
|
||||||
|
Group = 1 << 30,
|
||||||
|
Complex = 1 << 31
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum ExtensionBase
|
||||||
|
{
|
||||||
|
Stdapi = 0,
|
||||||
|
Incognito = 20000,
|
||||||
|
Priv = 20000,
|
||||||
|
Kiwi = 20000
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum TlvType
|
||||||
|
{
|
||||||
|
// Actual types
|
||||||
|
Any = MetaType.None,
|
||||||
|
Method = MetaType.String | 1,
|
||||||
|
RequestId = MetaType.String | 2,
|
||||||
|
Exception = MetaType.Group | 3,
|
||||||
|
Result = MetaType.Uint | 4,
|
||||||
|
|
||||||
|
String = MetaType.String | 10,
|
||||||
|
Uint = MetaType.Uint | 11,
|
||||||
|
Bool = MetaType.Bool | 12,
|
||||||
|
|
||||||
|
Length = MetaType.Uint | 25,
|
||||||
|
Data = MetaType.Raw | 26,
|
||||||
|
Flags = MetaType.Uint | 27,
|
||||||
|
|
||||||
|
ChannelId = MetaType.Uint | 50,
|
||||||
|
ChannelType = MetaType.String | 51,
|
||||||
|
ChannelData = MetaType.Raw | 52,
|
||||||
|
ChannelDataGroup = MetaType.Group | 53,
|
||||||
|
ChannelClass = MetaType.Uint | 54,
|
||||||
|
ChannelParentId = MetaType.Uint | 55,
|
||||||
|
|
||||||
|
SeekWhence = MetaType.Uint | 70,
|
||||||
|
SeekOffset = MetaType.Uint | 71,
|
||||||
|
SeekPos = MetaType.Uint | 72,
|
||||||
|
|
||||||
|
ExceptionCode = MetaType.Uint | 300,
|
||||||
|
ExceptionString = MetaType.String | 301,
|
||||||
|
|
||||||
|
LibraryPath = MetaType.String | 400,
|
||||||
|
TargetPath = MetaType.String | 401,
|
||||||
|
MigratePid = MetaType.Uint | 402,
|
||||||
|
MigrateLen = MetaType.Uint | 403,
|
||||||
|
|
||||||
|
TransType = MetaType.Uint | 430,
|
||||||
|
TransUrl = MetaType.String | 431,
|
||||||
|
TransUa = MetaType.String | 432,
|
||||||
|
TransCommTimeout = MetaType.Uint | 433,
|
||||||
|
TransSessExp = MetaType.Uint | 434,
|
||||||
|
TransCertHash = MetaType.Raw | 435,
|
||||||
|
TransProxyHost = MetaType.String | 436,
|
||||||
|
TransProxyUser = MetaType.String | 437,
|
||||||
|
TransProxyPass = MetaType.String | 438,
|
||||||
|
TransRetryTotal = MetaType.Uint | 439,
|
||||||
|
TransRetryWait = MetaType.Uint | 440,
|
||||||
|
TransGroup = MetaType.Group | 441,
|
||||||
|
|
||||||
|
MachineId = MetaType.String | 460,
|
||||||
|
Uuid = MetaType.Raw | 461,
|
||||||
|
|
||||||
|
CipherName = MetaType.String | 500,
|
||||||
|
CipherParameters = MetaType.Group | 501,
|
||||||
|
|
||||||
|
PeerHost = MetaType.String | 1500,
|
||||||
|
PeerPort = MetaType.Uint | 1501,
|
||||||
|
LocalHost = MetaType.String | 1502,
|
||||||
|
LocalPort = MetaType.Uint | 1503,
|
||||||
|
|
||||||
|
// STDAPI stuff
|
||||||
|
ComputerName = MetaType.String | (ExtensionBase.Stdapi + 1040),
|
||||||
|
OsName = MetaType.String | (ExtensionBase.Stdapi + 1041),
|
||||||
|
UserName = MetaType.String | (ExtensionBase.Stdapi + 1042),
|
||||||
|
Architecture = MetaType.String | (ExtensionBase.Stdapi + 1043),
|
||||||
|
LangSystem = MetaType.String | (ExtensionBase.Stdapi + 1044),
|
||||||
|
Sid = MetaType.String | (ExtensionBase.Stdapi + 1045),
|
||||||
|
Domain = MetaType.String | (ExtensionBase.Stdapi + 1046),
|
||||||
|
LoggedOnUserCount = MetaType.Uint | (ExtensionBase.Stdapi + 1047),
|
||||||
|
|
||||||
|
Mount = MetaType.Group | (ExtensionBase.Stdapi + 1207),
|
||||||
|
MountName = MetaType.String | (ExtensionBase.Stdapi + 1208),
|
||||||
|
MountType = MetaType.Uint | (ExtensionBase.Stdapi + 1209),
|
||||||
|
MountSpaceUser = MetaType.Qword | (ExtensionBase.Stdapi + 1210),
|
||||||
|
MountSpaceTotal = MetaType.Qword | (ExtensionBase.Stdapi + 1211),
|
||||||
|
MountSpaceFree = MetaType.Qword | (ExtensionBase.Stdapi + 1212),
|
||||||
|
MountUncPath = MetaType.String | (ExtensionBase.Stdapi + 1213),
|
||||||
|
|
||||||
|
Pid = MetaType.Uint | (ExtensionBase.Stdapi + 2300),
|
||||||
|
ProcessName = MetaType.String | (ExtensionBase.Stdapi + 2301),
|
||||||
|
ProcessPath = MetaType.String | (ExtensionBase.Stdapi + 2302),
|
||||||
|
ProcessGroup = MetaType.Group | (ExtensionBase.Stdapi + 2303),
|
||||||
|
ProcessArch = MetaType.Uint | (ExtensionBase.Stdapi + 2306),
|
||||||
|
ParentPid = MetaType.Uint | (ExtensionBase.Stdapi + 2307),
|
||||||
|
ProcessSession = MetaType.Uint | (ExtensionBase.Stdapi + 2308),
|
||||||
|
|
||||||
|
// PRIV stuff
|
||||||
|
ElevateTechnique = MetaType.Uint | (ExtensionBase.Priv + 200),
|
||||||
|
ElevateServiceName = MetaType.String | (ExtensionBase.Priv + 201),
|
||||||
|
|
||||||
|
// KIWI stuff
|
||||||
|
KiwiPwdId = MetaType.Uint | (ExtensionBase.Kiwi + 1),
|
||||||
|
KiwiPwdResult = MetaType.Group | (ExtensionBase.Kiwi + 2),
|
||||||
|
KiwiPwdUserName = MetaType.String | (ExtensionBase.Kiwi + 3),
|
||||||
|
KiwiPwdDomain = MetaType.String | (ExtensionBase.Kiwi + 4),
|
||||||
|
KiwiPwdPassword = MetaType.String | (ExtensionBase.Kiwi + 5),
|
||||||
|
KiwiPwdAuthHi = MetaType.Uint | (ExtensionBase.Kiwi + 6),
|
||||||
|
KiwiPwdAuthLo = MetaType.Uint | (ExtensionBase.Kiwi + 7),
|
||||||
|
KiwiPwdLmHash = MetaType.String | (ExtensionBase.Kiwi + 8),
|
||||||
|
KiwiPwdNtlmHash = MetaType.String | (ExtensionBase.Kiwi + 9),
|
||||||
|
|
||||||
|
// INCOGNITO stuff
|
||||||
|
IncognitoListTokensDelegation = MetaType.String | (ExtensionBase.Incognito + 2),
|
||||||
|
IncognitoListTokensImpersonation = MetaType.String | (ExtensionBase.Incognito + 3),
|
||||||
|
IncognitoListTokensTokenOrder = MetaType.Uint | (ExtensionBase.Incognito + 4),
|
||||||
|
IncognitoImpersonateToken = MetaType.String | (ExtensionBase.Incognito + 5),
|
||||||
|
IncognitoGenericResponse = MetaType.String | (ExtensionBase.Incognito + 6),
|
||||||
|
IncognitoUserName = MetaType.String | (ExtensionBase.Incognito + 7),
|
||||||
|
IncognitoPassword = MetaType.String | (ExtensionBase.Incognito + 8),
|
||||||
|
IncognitoServerName = MetaType.String | (ExtensionBase.Incognito + 9),
|
||||||
|
IncognitoGroupName = MetaType.String | (ExtensionBase.Incognito + 10)
|
||||||
|
};
|
||||||
|
}
|
@ -38,8 +38,11 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Enumerations.cs" />
|
||||||
|
<Compile Include="Meterpreter.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Runner.cs" />
|
<Compile Include="Runner.cs" />
|
||||||
|
<Compile Include="Tlv.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using MSF.Powershell;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -8,10 +9,17 @@ namespace MSF.PowershellTester
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var x = MSF.Powershell.Runner.Get("Default");
|
//var x = MSF.Powershell.Runner.Get("Default");
|
||||||
System.Console.Write(x.Execute("$x = $(whoami)"));
|
//System.Console.Write(x.Execute("$x = $(whoami)"));
|
||||||
System.Console.Write(x.Execute("$x"));
|
//System.Console.Write(x.Execute("$x"));
|
||||||
MSF.Powershell.Runner.Remove("Default");
|
//MSF.Powershell.Runner.Remove("Default");
|
||||||
|
|
||||||
|
Tlv t = new Tlv();
|
||||||
|
t.Pack(TlvType.ElevateTechnique, 1);
|
||||||
|
t.Pack(TlvType.ElevateServiceName, "abcd1234");
|
||||||
|
|
||||||
|
var x = t.Bytes;
|
||||||
|
var y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
powershell/MSF.Powershell/Meterpreter.cs
Executable file
59
powershell/MSF.Powershell/Meterpreter.cs
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MSF.Powershell
|
||||||
|
{
|
||||||
|
public static class Meterpreter
|
||||||
|
{
|
||||||
|
private delegate void MeterpreterInvoke(uint isLocal, byte[] input, uint inputSize, ref IntPtr output, ref uint outputSize);
|
||||||
|
|
||||||
|
private static MeterpreterInvoke _callback = null;
|
||||||
|
|
||||||
|
public static void SetInvocationPointer(Int64 callbackPointer)
|
||||||
|
{
|
||||||
|
_callback = (MeterpreterInvoke)Marshal.GetDelegateForFunctionPointer(new IntPtr(callbackPointer), typeof(MeterpreterInvoke));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RandomString(int length)
|
||||||
|
{
|
||||||
|
var r = new Random();
|
||||||
|
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
var bytes = new byte[length];
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
bytes[i] = (byte)chars[r.Next(chars.Length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Encoding.ASCII.GetString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] InvokeMeterpreterBinding(bool isLocal, byte[] input)
|
||||||
|
{
|
||||||
|
if (_callback != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
IntPtr output = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint outputLength = 0;
|
||||||
|
_callback(isLocal ? 1U : 0U, input, (uint)input.Length, ref output, ref outputLength);
|
||||||
|
|
||||||
|
var result = new byte[outputLength];
|
||||||
|
Marshal.Copy(output, result, 0, result.Length);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (output != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeCoTaskMem(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
powershell/MSF.Powershell/Tlv.cs
Executable file
108
powershell/MSF.Powershell/Tlv.cs
Executable file
@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MSF.Powershell
|
||||||
|
{
|
||||||
|
public class Tlv
|
||||||
|
{
|
||||||
|
private MemoryStream _stream = null;
|
||||||
|
|
||||||
|
public byte[] Bytes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_stream != null)
|
||||||
|
{
|
||||||
|
return _stream.ToArray();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tlv()
|
||||||
|
{
|
||||||
|
_stream = new MemoryStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, bool b)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Bool, t);
|
||||||
|
Append(t, b ? new byte[] { 1 } : new byte[] { 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, uint i)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Uint, t);
|
||||||
|
Append(t, ToBytes(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, int i)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Uint, t);
|
||||||
|
Append(t, ToBytes(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, Int64 i)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Qword, t);
|
||||||
|
Append(t, ToBytes(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, string s)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.String, t);
|
||||||
|
var value = Encoding.UTF8.GetBytes(s + "\x00");
|
||||||
|
Append(t, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, Tlv tlv)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Group, t);
|
||||||
|
var tlvBytes = tlv.Bytes;
|
||||||
|
if (tlvBytes != null)
|
||||||
|
{
|
||||||
|
Append(t, tlv.Bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pack(TlvType t, byte[] value)
|
||||||
|
{
|
||||||
|
ValidateMetaType(MetaType.Raw, t);
|
||||||
|
Append(t, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Append(TlvType t, byte[] value)
|
||||||
|
{
|
||||||
|
var type = ToBytes((int)t);
|
||||||
|
var length = ToBytes(value.Length);
|
||||||
|
_stream.Write(length, 0, length.Length);
|
||||||
|
_stream.Write(type, 0, type.Length);
|
||||||
|
_stream.Write(value, 0, value.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateMetaType(MetaType expected, TlvType actual)
|
||||||
|
{
|
||||||
|
if ((MetaType)((TlvType)expected & actual) != expected)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid Meta type given");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] ToBytes(Int64 i)
|
||||||
|
{
|
||||||
|
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] ToBytes(int i)
|
||||||
|
{
|
||||||
|
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] ToBytes(uint i)
|
||||||
|
{
|
||||||
|
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user