public RuleResult CheckMethod(MethodDefinition method) { // rule does not apply to non-pinvoke methods if (!method.IsPInvokeImpl) { return(RuleResult.DoesNotApply); } PInvokeInfo info = method.PInvokeInfo; if (info == null) { return(RuleResult.DoesNotApply); } if (!info.IsCharSetNotSpec || !method.HasParameters) { return(RuleResult.Success); } foreach (ParameterDefinition parameter in method.Parameters) { if (IsStringOrSBuilder(parameter.ParameterType) && (parameter.MarshalInfo == null)) { string text = String.Format(CultureInfo.InvariantCulture, "Parameter '{0}', of type '{1}', does not have [MarshalAs] attribute, yet no [DllImport CharSet=] is set for the method '{2}'.", parameter.Name, parameter.ParameterType.Name, method.Name); Runner.Report(parameter, Severity.High, Confidence.Total, text); } } return(Runner.CurrentRuleResult); }
private static void InternalConvertFromPInvokeFunction( CodeTextWriter tw, IMethodInformation method, PInvokeInfo pinvokeInfo) { tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// [6] P/Invoke: {0}", method.FriendlyName); tw.SplitLine(); tw.WriteLine(method.CLanguageFunctionPrototype); tw.WriteLine("{"); using (var _ = tw.Shift()) { var arguments = string.Join( ", ", method.Parameters. Select(parameter => parameter.GetMarshaledInExpression())); if (method.ReturnType.IsVoidType) { tw.WriteLine("{0}({1});", pinvokeInfo.EntryPoint, arguments); } else { tw.WriteLine("return {0}({1});", pinvokeInfo.EntryPoint, arguments); } } tw.WriteLine("}"); tw.SplitLine(); }
public FunctionSignature(Type returnType, Type[] parameterTypes, MethodCallingConvention callingConvention, PInvokeInfo pinvoke) { ReturnType = returnType; ParameterTypes = parameterTypes; CallingConvention = callingConvention; PInvokeInfo = pinvoke; }
protected override MethodDefinition MarkMethod(MethodReference reference) { var method = base.MarkMethod(reference); if ((method != null) && !method.HasBody && method.IsPInvokeImpl) { // for some C++ stuff HasPInvokeInfo can be true without giving back any info PInvokeInfo info = method.PInvokeInfo; if (info != null) { var m = info.Module; Annotations.Mark(m); string name = m.Name; if (PInvokeModules != null && !String.IsNullOrEmpty(name)) { List <MethodDefinition> methods; if (!PInvokeModules.TryGetValue(name, out methods)) { PInvokeModules.Add(name, methods = new List <MethodDefinition> ()); } methods.Add(method); } } } return(method); }
private static PreparedFunction PreparePInvokeMethod( IPrepareContext prepareContext, string methodName, string rawMethodName, TypeReference returnType, Parameter[] parameters, PInvokeInfo pinvokeInfo) { // TODO: Switch DllImport.Value include direction to library direction. if (string.IsNullOrWhiteSpace(pinvokeInfo.Module.Name)) { throw new InvalidProgramSequenceException( "Not given DllImport attribute argument. Name={0}", methodName); } prepareContext.RegisterPrivateIncludeFile(pinvokeInfo.Module.Name); return(new PreparedFunction( methodName, rawMethodName, returnType, parameters, false, null)); }
private static void Retarget(TypeDefinition type, DllImportMap map, DllImports imports) { foreach (var nested in type.NestedTypes) { Retarget(nested, map, imports); } foreach (MethodDefinition md in type.Methods) { if (!md.HasBody) { continue; } for (int i = 0; i < md.Body.Instructions.Count; i++) { Instruction ins = md.Body.Instructions[i]; if (ins.OpCode == OpCodes.Call) { MethodDefinition method_operand = ins.Operand as MethodDefinition; if (method_operand == null) { continue; } PInvokeInfo pinfo = method_operand.PInvokeInfo; if (pinfo == null) { continue; } ImportKey key = new ImportKey(pinfo.Module.Name, pinfo.EntryPoint); if (imports.ContainsKey(key)) { //Console.WriteLine ("{0} is a pinvoke, {1}/{2}", method_operand, pinfo.EntryPoint, pinfo.Module.Name); if (map.ContainsKey(key)) { Console.WriteLine("retargeting reference to method method {0}/{1}", key.module_name, key.entry_point); var il = md.Body.GetILProcessor(); MethodDefinition mapped_method = map[key]; MethodReference mapped_ref; mapped_ref = type.Module.Import(mapped_method); Instruction callMethod = il.Create(OpCodes.Call, mapped_ref); il.Replace(ins, callMethod); } else { Console.WriteLine("WARNING: no map entry for method {0}/{1}", key.module_name, key.entry_point); } } } } } }
private static void HookDllFun(TypeDefinition profilerType, Dictionary <string, InjectMethodAction> hookExternfunDict, AssemblyDefinition assembly) { #if XLUA || TOLUA || SLUA var methods = new List <MethodDefinition>(profilerType.Methods); foreach (var m in methods) { InjectMethodAction action; if (hookExternfunDict.TryGetValue(m.Name, out action)) { if (!m.IsPInvokeImpl) { continue; } MethodAttributes attr = MethodAttributes.Public; PInvokeInfo pInfo = null; attr = m.Attributes; pInfo = m.PInvokeInfo; m.ImplAttributes = MethodImplAttributes.IL; m.Attributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig; var method = new MethodDefinition(m.Name + "_profiler", attr, m.ReturnType); method.ImplAttributes = MethodImplAttributes.PreserveSig; method.PInvokeInfo = pInfo; if (m.Body.Variables != null) { foreach (var item in m.Body.Variables) { method.Body.Variables.Add(item); } } method.Parameters.Clear(); foreach (var item in m.Parameters) { method.Parameters.Add(item); } profilerType.Methods.Add(method); if (action != null) { action(m, assembly.MainModule, method); } } //else if (m.Name == LUA_TOSTRING) //{ // var method = new MethodDefinition(m.Name + "_profiler", m.Attributes, m.ReturnType); // profilerType.Methods.Add(method); // CopyMethod(m, method); // ModifyTostring(m, assembly.MainModule, method); //} } #endif }
public FunctionSignature(IABI abi, Type returnType, Type[] parameterTypes, MethodCallingConvention callingConvention, PInvokeInfo pinvoke) { ReturnType = new FunctionParameterType(abi, returnType); ParameterTypes = new FunctionParameterType[parameterTypes.Length]; for (int index = 0; index < parameterTypes.Length; index++) { ParameterTypes[index] = new FunctionParameterType(abi, parameterTypes[index]); } CallingConvention = callingConvention; PInvokeInfo = pinvoke; }
private static DllImports CollectDllImports(AssemblyDefinition assembly) { DllImports imports = new DllImports(); foreach (TypeDefinition t in assembly.MainModule.GetAllTypes()) { if (t.Name == "<Module>") { continue; } if (t.IsSpecialName || t.IsRuntimeSpecialName) { continue; } foreach (MethodDefinition md in t.Methods) { if (md.IsSpecialName) { continue; } if (IsFinalizer(md)) { continue; } PInvokeInfo pinfo = md.PInvokeInfo; if (pinfo == null) { continue; } // Console.WriteLine ("{0} is a pinvoke, hashcode = {1}", md, md.GetHashCode()); ImportKey key = new ImportKey(pinfo.Module.Name, pinfo.EntryPoint); if (imports.ContainsKey(key)) { Console.WriteLine("WARNING: pinvoke {0}/{1} shows up more than once in input assembly", key.module_name, key.entry_point); } else { imports.Add(key, md); } } } return(imports); }
public static void GetTextualRepresentation(this PInvokeInfo invokeInfo, Action <string> appendAction, TextualRepresentationOptions options) { if (invokeInfo == null) { return; } appendAction(invokeInfo.IsBestFitDisabled.ToString()); appendAction(invokeInfo.IsBestFitEnabled.ToString()); appendAction(invokeInfo.IsCallConvCdecl.ToString()); appendAction(invokeInfo.IsCallConvFastcall.ToString()); appendAction(invokeInfo.IsCallConvStdCall.ToString()); appendAction(invokeInfo.IsCallConvThiscall.ToString()); appendAction(invokeInfo.IsCallConvWinapi.ToString()); appendAction(invokeInfo.IsCharSetAnsi.ToString()); appendAction(invokeInfo.IsCharSetAuto.ToString()); appendAction(invokeInfo.IsCharSetNotSpec.ToString()); appendAction(invokeInfo.IsCharSetUnicode.ToString()); appendAction(invokeInfo.IsNoMangle.ToString()); appendAction(invokeInfo.IsThrowOnUnmappableCharDisabled.ToString()); appendAction(invokeInfo.IsThrowOnUnmappableCharEnabled.ToString()); }
private static void InternalConvertFromPInvokeFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, PInvokeInfo pinvokeInfo, string indent) { var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// P/Invoke: {0}", preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); var arguments = string.Join( ", ", preparedFunction.Parameters .Select(parameter => parameter.GetMarshaledInExpression())); if (preparedFunction.ReturnType.IsVoidType()) { tw.WriteLine("{0}{1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } else { tw.WriteLine("{0}return {1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } tw.WriteLine("}"); }
public void VisitPInvokeInfo(PInvokeInfo pinvk) { }
void DisassembleMethodInternal(MethodDefinition method) { // .method public hidebysig specialname // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed // //emit flags WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility); WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags); if (method.IsCompilerControlled) { output.Write("privatescope "); } if ((method.Attributes & MethodAttributes.PInvokeImpl) == MethodAttributes.PInvokeImpl) { output.Write("pinvokeimpl"); if (method.HasPInvokeInfo && method.PInvokeInfo != null) { PInvokeInfo info = method.PInvokeInfo; output.Write("(\"" + CSharp.OutputVisitor.ConvertString(info.Module.Name) + "\""); if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) { output.Write(" as \"" + CSharp.OutputVisitor.ConvertString(info.EntryPoint) + "\""); } if (info.IsNoMangle) { output.Write(" nomangle"); } if (info.IsCharSetAnsi) { output.Write(" ansi"); } else if (info.IsCharSetAuto) { output.Write(" autochar"); } else if (info.IsCharSetUnicode) { output.Write(" unicode"); } if (info.SupportsLastError) { output.Write(" lasterr"); } if (info.IsCallConvCdecl) { output.Write(" cdecl"); } else if (info.IsCallConvFastcall) { output.Write(" fastcall"); } else if (info.IsCallConvStdCall) { output.Write(" stdcall"); } else if (info.IsCallConvThiscall) { output.Write(" thiscall"); } else if (info.IsCallConvWinapi) { output.Write(" winapi"); } output.Write(')'); } output.Write(' '); } output.WriteLine(); output.Indent(); if (method.ExplicitThis) { output.Write("instance explicit "); } else if (method.HasThis) { output.Write("instance "); } //call convention WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention); //return type method.ReturnType.WriteTo(output); output.Write(' '); if (method.MethodReturnType.HasMarshalInfo) { WriteMarshalInfo(method.MethodReturnType.MarshalInfo); } if (method.IsCompilerControlled) { output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8"))); } else { output.Write(DisassemblerHelpers.Escape(method.Name)); } WriteTypeParameters(output, method); //( params ) output.Write(" ("); if (method.HasParameters) { output.WriteLine(); output.Indent(); WriteParameters(method.Parameters); output.Unindent(); } output.Write(") "); //cil managed WriteEnum(method.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType); if ((method.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed) { output.Write("managed "); } else { output.Write("unmanaged "); } WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl); output.Unindent(); OpenBlock(defaultCollapsed: isInType); WriteAttributes(method.CustomAttributes); if (method.HasOverrides) { foreach (var methodOverride in method.Overrides) { output.Write(".override method "); methodOverride.WriteTo(output); output.WriteLine(); } } foreach (var p in method.Parameters) { WriteParameterAttributes(p); } WriteSecurityDeclarations(method); if (method.HasBody) { // create IL code mappings - used in debugger CreateCodeMappings(method.MetadataToken.ToInt32(), currentMember); MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings[method.MetadataToken.ToInt32()], currentMember); methodBodyDisassembler.Disassemble(method.Body, methodMapping); } CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); }
public static CharSet?ToCharset(this PInvokeInfo pinv) => pinv.IsCharSetAnsi ? CharSet.Ansi : pinv.IsCharSetAuto ? CharSet.Auto : pinv.IsCharSetUnicode ? CharSet.Unicode : default(CharSet?);
public PInvokeMethodBodyWriter(MethodReference interopMethod) : base(interopMethod, interopMethod, MarshalType.PInvoke, MarshalingUtils.UseUnicodeAsDefaultMarshalingForStringParameters(interopMethod)) { this._methodDefinition = interopMethod.Resolve(); this._pinvokeInfo = this._methodDefinition.PInvokeInfo; }
public virtual void VisitPInvokeInfo(PInvokeInfo pinvk) { }
private void MapPInvokeInfo(MethodBase method, MethodDefinition method_definition) { var attributes = method.GetCustomAttributes(typeof(DllImportAttribute), inherit: false); if (attributes.Length == 0) { return; } var import = (DllImportAttribute)attributes[0]; var info = new PInvokeInfo(0, import.EntryPoint, ModuleReferenceFor(import.Value)) { IsBestFitEnabled = import.BestFitMapping, IsThrowOnUnmappableCharEnabled = import.ThrowOnUnmappableChar, SupportsLastError = import.SetLastError, IsNoMangle = import.ExactSpelling, }; switch (import.CallingConvention) { case CallingConvention.Cdecl: info.IsCallConvCdecl = true; break; case CallingConvention.FastCall: info.IsCallConvFastcall = true; break; case CallingConvention.StdCall: info.IsCallConvStdCall = true; break; case CallingConvention.ThisCall: info.IsCallConvThiscall = true; break; case CallingConvention.Winapi: info.IsCallConvWinapi = true; break; } switch (import.CharSet) { case CharSet.Ansi: info.IsCharSetAnsi = true; break; case CharSet.Auto: info.IsCharSetAuto = true; break; case CharSet.None: info.IsCharSetNotSpec = true; break; case CharSet.Unicode: info.IsCharSetUnicode = true; break; } method_definition.PInvokeInfo = info; }