Skip to content

Commit

Permalink
added binary cmdlet - DllExportNS
Browse files Browse the repository at this point in the history
+ should be fixed bug #6
  • Loading branch information
3F committed Aug 28, 2016
1 parent 3c18d8a commit c45523b
Show file tree
Hide file tree
Showing 11 changed files with 680 additions and 5 deletions.
8 changes: 6 additions & 2 deletions .vssbe
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,13 @@
"Mode": {
"$type": "net.r_eg.vsSBE.Events.ModeScript, vsSolutionBuildEvent",
"Type": "Script",
"Command": "#[$(dbin = \"bin/$(Configuration)/\")]\n\n$(pDllExport = \"RGiesecke.DllExport\")\n$(pMeta = \"Metadata\")\n$(pMSBuild = \"RGiesecke.DllExport.MSBuild\")\n$(odir = \"$(dbin)raw/\")\n\n#[IO delete.directory(\"$(dbin)\", true)]\n#[IO copy.directory(\"\", \"$(dbin)\", true)]",
"Command": "#[$(dbin = \"bin/$(Configuration)/\")]\n\n$(pDllExport = \"RGiesecke.DllExport\")\n$(pMeta = \"Metadata\")\n$(pNSBin = \"NSBin\")\n$(pMSBuild = \"RGiesecke.DllExport.MSBuild\")\n$(odir = \"$(dbin)raw/\")\n\n#[IO delete.directory(\"$(dbin)\", true)]\n#[IO copy.directory(\"\", \"$(dbin)\", true)]",
"Command__": [
"#[$(dbin = \"bin/$(Configuration)/\")]",
"",
"$(pDllExport = \"RGiesecke.DllExport\")",
"$(pMeta = \"Metadata\")",
"$(pNSBin = \"NSBin\")",
"$(pMSBuild = \"RGiesecke.DllExport.MSBuild\")",
"$(odir = \"$(dbin)raw/\")",
"",
Expand Down Expand Up @@ -158,7 +159,7 @@
"Mode": {
"$type": "net.r_eg.vsSBE.Events.ModeScript, vsSolutionBuildEvent",
"Type": "Script",
"Command": "#[IO copy.file(\n \"$(SolutionDir)tools/*.*\", \n \"$(odir)/tools/\", \n true, \n {\"*.nuspec\"})]\n\n#[IO copy.file(\"tools/DllExport.nuspec\", \"$(odir)/DllExport.nuspec\", true)]\n\n#[IO copy.file(\"$(pDllExport)/$(OutDir:$(pDllExport))/*.dll\", \n \"$(odir)/tools/\", true)]\n\n#[IO copy.file(\"$(pMSBuild)/$(OutDir:$(pMSBuild))/*.dll\", \n \"$(odir)/tools/\", true)]\n \n#[IO copy.file(\"$(pMeta)/$(OutDir:$(pMeta))/*.dll\", \n \"$(odir)/lib/net20/\", true)]\n\n#[IO copy.file(\"LICENSE\", \"$(odir)/\", true)]\n#[IO copy.file(\"Readme.md\", \"$(odir)/\", true)]",
"Command": "#[IO copy.file(\n \"$(SolutionDir)tools/*.*\", \n \"$(odir)/tools/\", \n true, \n {\"*.nuspec\"})]\n\n#[IO copy.file(\"tools/DllExport.nuspec\", \"$(odir)/DllExport.nuspec\", true)]\n\n#[IO copy.file(\"$(pDllExport)/$(OutDir:$(pDllExport))/*.dll\", \n \"$(odir)/tools/\", true)]\n\n#[IO copy.file(\"$(pMSBuild)/$(OutDir:$(pMSBuild))/*.dll\", \n \"$(odir)/tools/\", true)]\n \n#[IO copy.file(\"$(pMeta)/$(OutDir:$(pMeta))/*.dll\", \n \"$(odir)/lib/net20/\", true)]\n \n#[IO copy.file(\"$(pNSBin)/$(OutDir:$(pNSBin))/$(AssemblyName:$(pNSBin)).dll\", \n \"$(odir)/tools/\", true)]\n\n#[IO copy.file(\"LICENSE\", \"$(odir)/\", true)]\n#[IO copy.file(\"Readme.md\", \"$(odir)/\", true)]",
"Command__": [
"#[IO copy.file(",
" \"$(SolutionDir)tools/*.*\", ",
Expand All @@ -177,6 +178,9 @@
"#[IO copy.file(\"$(pMeta)/$(OutDir:$(pMeta))/*.dll\", ",
" \"$(odir)/lib/net20/\", true)]",
"",
"#[IO copy.file(\"$(pNSBin)/$(OutDir:$(pNSBin))/$(AssemblyName:$(pNSBin)).dll\", ",
" \"$(odir)/tools/\", true)]",
"",
"#[IO copy.file(\"LICENSE\", \"$(odir)/\", true)]",
"#[IO copy.file(\"Readme.md\", \"$(odir)/\", true)]"
]
Expand Down
6 changes: 6 additions & 0 deletions DllExport.sln
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{55898433
packages.config = packages.config
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSBin", "NSBin\NSBin.csproj", "{311706A5-5ED2-4006-B794-055009D8A256}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -55,6 +57,10 @@ Global
{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}.Release|Any CPU.Build.0 = Release|Any CPU
{311706A5-5ED2-4006-B794-055009D8A256}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{311706A5-5ED2-4006-B794-055009D8A256}.Debug|Any CPU.Build.0 = Debug|Any CPU
{311706A5-5ED2-4006-B794-055009D8A256}.Release|Any CPU.ActiveCfg = Release|Any CPU
{311706A5-5ED2-4006-B794-055009D8A256}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
173 changes: 173 additions & 0 deletions NSBin/DefNs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Modification of binary assemblies. Format and specification:
//
// https://github.com/3F/DllExport/issues/2#issuecomment-231593744
//
// Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
//
// 000005B0 00 C4 7B 01 00 00 00 2F 00 12 05 .Д{..../...
// 000005C0 00 00 02 00 00 00 00 00 00 00 00 00 00 00 26 00 ..............&.
// 000005D0 20 02 00 00 00 00 00 00 00 44 33 46 30 30 46 46 ........D3F00FF <<<<
// 000005E0 31 37 37 30 44 45 44 39 37 38 45 43 37 37 34 42 1770DED978EC774B <<<<...
//
// - - - -
// byte-seq via chars:
// + Identifier = [32]bytes
// + size of buffer = [ 4]bytes (range: 0000 - FFF9; reserved: FFFA - FFFF)
// + buffer of n size
// - - - -
// v1.2: 01F4 - allocated buffer size
//

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using net.r_eg.Conari.Log;

namespace NSBin
{
public class DefNs
{
public const string IDNS = "D3F00FF1770DED978EC774BA389F2DC9";
public const string DEFAULT_NS = "System.Runtime.InteropServices";

public Encoding encoding = Encoding.UTF8;
protected string dll;

public ISender Log
{
get { return LSender._; }
}

public void setNamespace(string name)
{
Log.send(this, $"set new namespace: ({name}) - ({dll})");

if(String.IsNullOrWhiteSpace(dll) || !File.Exists(dll)) {
throw new FileNotFoundException("The DllExport assembly for modifications was not found.");
}

if(String.IsNullOrWhiteSpace(name)) {
//name = DEFAULT_NS;
throw new ArgumentException("The namespace cannot be null or empty.");
}

defNS(name);
}

/// <param name="dll">The DllExport assembly for modifications.</param>
public DefNs(string dll)
{
this.dll = dll;
}

protected void defNS(string ns)
{
string origin = _postfixToOrigin(dll);

if(!File.Exists(origin)) {
File.Copy(dll, origin);
}
else {
File.Copy(origin, dll, true);
}

var ident = encoding.GetBytes(IDNS);

byte[] data = File.ReadAllBytes(dll);
if(data.Length < ident.Length) {
throw new FileNotFoundException("Incorrect size of library.");
}

int lpos = -1;
for(int i = 0; i < data.Length; ++i)
{
lpos = i;
for(int j = 0; j < ident.Length; ++j) {
if(data[i + j] != ident[j]) {
lpos = -1;
break;
}
}
if(lpos != -1) {
break;
}
}

if(lpos == -1) {
throw new FileNotFoundException("Incorrect library.");
}

// ~
binmod(lpos, ident.Length, nsrule(ns));
}

protected void binmod(int lpos, int ident, string ns)
{
using(FileStream stream = new FileStream(dll, FileMode.Open, FileAccess.ReadWrite))
{
stream.Seek(lpos + ident, SeekOrigin.Begin);

byte[] bsize = new byte[4];
stream.Read(bsize, 0, 4);

var buffer = sysrange(
Convert.ToUInt16(encoding.GetString(bsize), 16)
);

byte[] nsBytes = encoding.GetBytes(ns);
int fullseq = ident + bsize.Length + buffer;

// beginning of miracles

var nsb = new List<byte>();
nsb.AddRange(nsBytes);
nsb.AddRange(Enumerable.Repeat((byte)0x00, fullseq - nsBytes.Length));

stream.Seek(lpos, SeekOrigin.Begin);
stream.Write(nsb.ToArray(), 0, nsb.Count);

using(var fs = File.Create(_postfixToUpdated(dll))) {
fs.Write(nsBytes, 0, nsBytes.Length);
}

Log.send(this, "The DllExport Library has been modified !");
Log.send(this, $"namespace: {ns}");
Log.send(this, "Details here: https://github.com/3F/DllExport/issues/2");
}
}

protected virtual UInt16 sysrange(UInt16 val)
{
/* reserved: FFFA - FFFF */

if(val < 0xFFFA) {
return val;
}

var reserved = 0xFFFF - val;
//switch(reserved) {
// // ...
//}

throw new NotImplementedException("The reserved combination is not yet implemented or not supported: " + reserved);
}

protected virtual string nsrule(string name)
{
return Regex.Replace(name, @"[\.\s]{1,}", ".").Trim(new char[] { '.', ' ' });
}

private string _postfixToUpdated(string dll)
{
return $"{dll}.updated";
}

private string _postfixToOrigin(string dll)
{
return $"{dll}.origin";
}
}
}
83 changes: 83 additions & 0 deletions NSBin/Log/ISender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Denis Kuzmin <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System;

namespace net.r_eg.Conari.Log
{
public interface ISender
{
/// <summary>
/// When message has been received.
/// </summary>
event EventHandler<Message> Received;

/// <summary>
/// To send new message.
/// </summary>
/// <param name="sender"></param>
/// <param name="msg"></param>
void send(object sender, Message msg);

/// <summary>
/// To send new message.
/// </summary>
/// <param name="sender"></param>
/// <param name="msg"></param>
void send(object sender, string msg);

/// <summary>
/// To send new message.
/// </summary>
/// <param name="sender"></param>
/// <param name="msg"></param>
/// <param name="type"></param>
void send(object sender, string msg, Message.Level type);

/// <summary>
/// To send new message with default sender as typeof(T).
/// It useful for static methods etc.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="msg"></param>
void send<T>(Message msg) where T: class;

/// <summary>
/// To send new message with default sender as typeof(T).
/// It useful for static methods etc.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="msg"></param>
void send<T>(string msg) where T : class;

/// <summary>
/// To send new message with default sender as typeof(T).
/// It useful for static methods etc.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="msg"></param>
/// <param name="type"></param>
void send<T>(string msg, Message.Level type) where T : class;
}
}
Loading

0 comments on commit c45523b

Please sign in to comment.