
Generatore di origine per aggiungere metodi D/Invoke e syscall indirette a un progetto C#.
Source generator to add D/Invoke and indirect syscall methods to a C# project.
Aggiungi il pacchetto NuGet più recente al tuo progetto e abilita il codice unsafe.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net481</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
</PropertyGroup>
<!-- CsWhispers package -->
<ItemGroup>
<PackageReference Include="CsWhispers" Version="0.0.3" />
</ItemGroup>
<!-- Allow unsafe code -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
Crea un file nel tuo progetto chiamato CsWhispers.txt e imposta le sue proprietà di azione di compilazione su AdditionalFiles.
<ItemGroup>
<None Remove="CsWhispers.txt" />
<AdditionalFiles Include="CsWhispers.txt" />
</ItemGroup>
Aggiungi ogni API NT e le eventuali struct/enum di supporto che vuoi includere nel tuo progetto. Ciascuna deve essere sulla propria riga, ad esempio:
NtOpenProcess
HANDLE
NTSTATUS
CLIENT_ID
UNICODE_STRING
OBJECT_ATTRIBUTES
PWSTR
PCWSTR
Consulta la Wiki del progetto per un elenco completo delle API supportate.
Gli spazi dei nomi globali vengono aggiunti automaticamente per consentire un codice pulito.
public static unsafe void Main()
{
// use self as example
using var self = Process.GetCurrentProcess();
HANDLE hProcess;
OBJECT_ATTRIBUTES oa;
CLIENT_ID cid = new()
{
UniqueProcess = new HANDLE((IntPtr)self.Id)
};
var status = NtOpenProcess(
&hProcess,
PROCESS_ALL_ACCESS,
&oa,
&cid);
Console.WriteLine("Status: {0}", status.SeverityCode);
Console.WriteLine("HANDLE: 0x{0:X}", hProcess.Value.ToInt64());
}
CsWhispers include una versione minimizzata di D/Invoke, quindi puoi anche chiamare Generic.GetLibraryAddress, Generic.DynamicFunctionInvoke, ecc.
Tutto il codice generato finisce in una classe parziale CsWhispers.Syscalls, che puoi estendere per aggiungere le tue API. Ad esempio, crea MyAPIs.cs e aggiungi:
namespace CsWhispers;
public static partial class Syscalls
{
public static NTSTATUS NtCreateThreadEx()
{
// whatever
return new NTSTATUS(0);
}
}
Questo può quindi essere chiamato nel tuo codice principale senza dover aggiungere ulteriori istruzioni using.
namespace ConsoleApp1;
internal static class Program
{
public static void Main()
{
var status = NtCreateThreadEx();
}
}
CsWhispers.txt.Questo progetto è stato ispirato dalle versioni precedenti di SysWhispers e SharpWhispers in particolare. Quindi tanto di cappello a @Jackson_T, @KlezVirus, @d_glenx, e a tutti gli altri che hanno contribuito con codice e/o idee.