Skip to content

Commit

Permalink
+ArchitectureMismatchException + more info for PE images:
Browse files Browse the repository at this point in the history
ArchitectureMismatchException will help clarify the #4

Changed IPE interface

\+ Characteristics
\+ Magic
\+ Machine
\+ Export reference to (addresses + names + ordinals)
\! ExportedProcNamesArray marked as Obsolete

Added tests
  • Loading branch information
3F committed Apr 18, 2021
1 parent d0ee501 commit 8ec6eed
Show file tree
Hide file tree
Showing 19 changed files with 896 additions and 148 deletions.
2 changes: 1 addition & 1 deletion Conari/Core/ExVar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public override IEnumerable<string> GetDynamicMemberNames()
// TODO: the exported variables are free from decorations but '@' still may be used if it's not a C linkage
// For example: LIBAPI_CPP const char* eVariableTest
// -> ?eVariableTest@API@UnLib@Conari@r_eg@net@@3PBDB
return ((ILoader)provider).PE.ExportedProcNames/*.Where(p => p.IndexOfAny(new[] { '@' }) == -1)*/;
return ((ILoader)provider).PE.Export.Names/*.Where(p => p.IndexOfAny(new[] { '@' }) == -1)*/;
}

public ExVar(IProvider p)
Expand Down
14 changes: 9 additions & 5 deletions Conari/Core/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using net.r_eg.Conari.Extension;
using net.r_eg.Conari.Log;
using net.r_eg.Conari.PE;
using net.r_eg.Conari.PE.WinNT;
using net.r_eg.Conari.Resources;
using net.r_eg.Conari.WinAPI;

Expand Down Expand Up @@ -70,6 +71,8 @@ public abstract class Loader: ILoader, IDisposable
/// </summary>
public IPE PE { get; protected set; }

internal static string TempDstPath => Path.Combine(Path.GetTempPath(), CLLI);

internal bool Disposed => disposed;

public static explicit operator IntPtr(Loader l) => l.Library.handle;
Expand All @@ -96,13 +99,14 @@ protected bool load(string lib)
return false;
}

if(Library.handle == IntPtr.Zero) {
// TODO: clarify specific error
PE = new PEFile(Library.module);

if(Library.handle == IntPtr.Zero)
{
if(PE.Magic != PE.Current) throw new ArchitectureMismatchException(PE);
throw new LoadLibException($"Failed loading '{Library}'. Possible incorrect architecture or missing file or its dependencies. https://github.com/3F/Conari/issues/4", true);
}

PE = new PEFile(Library.module);

AfterLoad(this, new DataArgs<Link>(Library));
return true;
}
Expand Down Expand Up @@ -192,7 +196,7 @@ protected bool tryIsolateModule(Link l, out string module)
module = l.module;
}

var dstDir = Path.Combine(Path.GetTempPath(), CLLI, Guid.NewGuid().ToString());
var dstDir = Path.Combine(TempDstPath, Guid.NewGuid().ToString());
Directory.CreateDirectory(dstDir);

var dst = Path.Combine(dstDir, Path.GetFileName(module));
Expand Down
2 changes: 1 addition & 1 deletion Conari/Core/Provider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ protected IntPtr getProcAddress(IntPtr hModule, string lpProcName, bool mangling

LSender.Send(this, $"{msgerr} Trying to decorate with C rules.", Message.Level.Warn);

var func = CMangling.Decorate(lpProcName, ((ILoader)this).PE.ExportedProcNames.ToArray());
var func = CMangling.Decorate(lpProcName, ((ILoader)this).PE.Export.Names.ToArray());
if(func == null) {
throw new EntryPointNotFoundException(
$"{msgerr} The `Mangling.C` does not help. Check a correct name manually. Related issue: https://github.com/3F/Conari/issues/3"
Expand Down
60 changes: 60 additions & 0 deletions Conari/Exceptions/ArchitectureMismatchException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2021 Denis Kuzmin <x-3F@outlook.com> github/3F
* Copyright (c) Conari contributors https://github.com/3F/Conari/graphs/contributors
*
* 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;
using System.Text;
using net.r_eg.Conari.PE;
using net.r_eg.Conari.PE.WinNT;

namespace net.r_eg.Conari.Exceptions
{
[Serializable]
public class ArchitectureMismatchException: LoadLibException
{
public ArchitectureMismatchException(IPE pe, bool getError = true)
: base(format(pe), getError)
{

}

private static string format(IPE pe)
{
StringBuilder sb = new();
sb.Append($"Target architecture of the image is {pe.Machine} (");

if(pe.Characteristics.HasFlag(Characteristics.IMAGE_FILE_LARGE_ADDRESS_AWARE)) {
sb.Append($"can ");
}
else {
sb.Append($"cannot ");
}

sb.Append($"handle > 2-GB addresses): `{pe.CurrentImageName}`({pe.Current}) cannot process `{pe.FileName}`({pe.Magic}). ");

sb.Append($"Possible solution https://github.com/3F/Conari/issues/4");
return sb.ToString();
}
}
}
2 changes: 1 addition & 1 deletion Conari/Exceptions/WinFuncFailException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public WinFuncFailException()

protected static string detail(string message)
{
return $"{message}[Error: {Marshal.GetLastWin32Error()}]";
return $"{message} [Error: {Marshal.GetLastWin32Error()}]";
}
}
}
71 changes: 71 additions & 0 deletions Conari/PE/Export.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2021 Denis Kuzmin <x-3F@outlook.com> github/3F
* Copyright (c) Conari contributors https://github.com/3F/Conari/graphs/contributors
*
* 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;
using System.Collections.Generic;
using System.Linq;
using net.r_eg.Conari.PE.Hole;

namespace net.r_eg.Conari.PE
{
using DWORD = System.UInt32;
using WORD = System.UInt16;

public sealed class Export
{
private readonly DWORD[] addresses;
private readonly string[] names;
private readonly WORD[] ordinals;

public IEnumerable<DWORD> Addresses => addresses;

public IEnumerable<string> Names => names;

public IEnumerable<WORD> NameOrdinals => ordinals;

public DWORD getAddressOf(string name)
{
for(DWORD i = 0; i < names.Length; ++i)
{
if(name == names[i]) return addresses[ordinals[i]];
}
return 0;
}

public IntPtr getAddressOf(string name, IntPtr loaded)
{
return IntPtr.Add(loaded, Convert.ToInt32(getAddressOf(name)));
}

internal Export(ExportDirectory exdir)
{
if(exdir == null) throw new ArgumentNullException(nameof(exdir));

names = exdir.Names.ToArray();
ordinals = exdir.Ordinals.ToArray();
addresses = exdir.AddressesOfProc.ToArray();
}
}
}
Loading

0 comments on commit 8ec6eed

Please sign in to comment.