Example #1
0
        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);
        }
Example #2
0
        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();
        }
Example #3
0
 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);
        }
Example #5
0
        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));
        }
Example #6
0
        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
        }
Example #8
0
        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;
        }
Example #9
0
        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());
        }
Example #11
0
        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)
 {
 }
Example #13
0
        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));
        }
Example #14
0
 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;
 }
Example #16
0
 public virtual void VisitPInvokeInfo(PInvokeInfo pinvk)
 {
 }
Example #17
0
        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;
        }