コンパイラについて少し勉強しようとしています。私はNASMを使用して私のオブジェクトファイルをコンパイルし、dllに変換するためにalinkを使用しています。依存関係ウォーカーを使用して、私のdllの内容を確認しています。これまでのところ、コードで私のdllをコンパイルするのが得意で、GetProcAddressでそれを取得できます。しかし、私はそれを起動しようとすると、私は次のエラーを取得する:私はエラーを取得する理由C#で基本的なコンパイラを作成しようとしましたが、アクセス違反エラーが発生しました
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
私はすべてがそうではない1〜100%eaxに設定されています。私はどのメモリが壊れているかわからない、私はこのDLLを適切に呼び出すために何ができるかについての援助は非常に高く評価されるだろう。
編集:Windows x64上で32ビットアセンブリを使用していますが、動作するかどうかを確認するためにx64アセンブリ/アセンブラを試している可能性があります。
動的に生成されたアセンブリファイル
global DllMain
export DllMain
global testfunc
export testfunc
section .code use32
DllMain: ; This code is required in .dll files
mov eax,1
ret 12
testfunc:
mov eax, 1
ret
C#コード
namespace KCompiler
{
public static class NativeMethods
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int TestFuncDelegate();
static int Main(string[] args)
{
/*
AntlrFileStream stream = new AntlrFileStream("../../example.k");
CLexer lexer = new CLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CParser parser = new CParser(tokens);
ParseTreeWalker tree = new ParseTreeWalker();
CListener listener = new CListener();
tree.Walk(listener, parser.file());
*/
KAssembler assembler = new KAssembler();
//assembler.PushR("ebp");
//assembler.Mov32RR("ebp", "esp");
assembler.Mov32RI("eax", 1);
//assembler.PopR("ebp");
assembler.Return();
string RelativeDirectory = @"..\..";
string fullAssembly = File.ReadAllText(Path.Combine(RelativeDirectory,"k_template.asm")).Replace("{ASSEMBLY}", assembler.ToString());
Console.WriteLine(fullAssembly);
File.WriteAllText(Path.Combine(RelativeDirectory,"k.asm"), fullAssembly);
ProcessStartInfo nasmInfo = new ProcessStartInfo()
{
UseShellExecute = false,
FileName = Path.Combine(RelativeDirectory,"nasm.exe"),
RedirectStandardOutput = true,
Arguments = @"-fobj ..\..\k.asm",
};
using (Process nasm = Process.Start(nasmInfo))
{
nasm.WaitForExit();
Console.WriteLine($"NASM exited with code: {nasm.ExitCode}");
if (nasm.ExitCode != 0) return nasm.ExitCode;
}
ProcessStartInfo alinkInfo = new ProcessStartInfo()
{
UseShellExecute = false,
FileName = Path.Combine(RelativeDirectory,"alink.exe"),
RedirectStandardOutput = true,
Arguments = Path.Combine(RelativeDirectory,"k.obj") + " -oPE -dll",
};
using (Process alink = Process.Start(alinkInfo))
{
alink.WaitForExit();
Console.WriteLine($"alink exited with code: {alink.ExitCode}");
if (alink.ExitCode != 0) return alink.ExitCode;
}
IntPtr dll = new IntPtr(0);
try
{
dll = NativeMethods.LoadLibrary(Path.Combine(RelativeDirectory, "k.dll"));
Console.WriteLine(dll.ToInt32() == 0 ? "Unable to Load k.dll" : "Loaded k.dll");
if (dll.ToInt32() == 0) return 1;
IntPtr TestFunctionPtr = NativeMethods.GetProcAddress(dll, "testfunc");
Console.WriteLine(TestFunctionPtr.ToInt32() == 0 ? "Unable to Load 'testfunc'" : "Loaded 'testfunc'");
if (TestFunctionPtr.ToInt32() == 0) return 1;
TestFuncDelegate Test = Marshal.GetDelegateForFunctionPointer<TestFuncDelegate>(TestFunctionPtr);
int result = Test(); //Error right here
Console.WriteLine($"Test Function Returned: {result}");
}
finally
{
if(dll.ToInt32() != 0)
NativeMethods.FreeLibrary(dll);
}
return 0;
}
}
}
私が直接あなたを助けることはできませんが、あなたの場所で私が最初に 'Cに7'返すのと同等の代わりに、DLLのいくつかの基本的なexeファイルを、作成します、これが動作すれば、私はCまたはC++プログラムでこのDLLを読み込もうとします。あなたは何が間違っているかを見つけるためにステップバイステップで知っています。 – greenoldman
私はyaを持っていました、私は約45分を過ぎてから仕事に行く前にそれを昨晩デバッグしました。私は何かを働かせたら、私が終わったらここにそれを掲示するでしょう。これは良いアイデアです、そして、x64アセンブリを試してみることは、私が今夜試してみるものになるでしょう。 – user2927848