コード例 #1
0
        public ILTryInfo GetTryInfo(int addr, out TryCodeType type)
        {
            type = TryCodeType.None;
            ILTryInfo last  = null;
            int       begin = -1;
            int       end   = -1;

            foreach (var info in tryInfos)
            {
                //check try first
                if (info.addr_Try_Begin <= addr && addr < info.addr_Try_End)
                {
                    if (last == null)
                    {
                        type  = TryCodeType.Try;
                        last  = info;
                        begin = info.addr_Try_Begin;
                        end   = last.addr_Try_End;
                    }
                    else if (begin <= info.addr_Try_Begin && last.addr_Try_End < end)
                    {
                        type  = TryCodeType.Try;
                        last  = info;
                        begin = info.addr_Try_Begin;
                        end   = last.addr_Try_End;
                    }
                }

                //then code in final but not in try
                if (info.addr_Try_Begin <= addr && addr < info.addr_Try_End_F)
                {
                    if (last == null)
                    {
                        type  = TryCodeType.Try_Final;
                        last  = info;
                        begin = info.addr_Try_Begin;
                        end   = last.addr_Try_End_F;
                    }
                    else if (begin <= info.addr_Try_Begin && last.addr_Try_End_F < end)
                    {
                        type  = TryCodeType.Try_Final;
                        last  = info;
                        begin = info.addr_Try_Begin;
                        end   = last.addr_Try_End_F;
                    }
                }

                //find match finally
                if (info.addr_Finally_Begin <= addr && addr < info.addr_Finally_End)
                {
                    if (last == null)
                    {
                        type  = TryCodeType.Final;
                        last  = info;
                        begin = info.addr_Finally_Begin;
                        end   = last.addr_Finally_End;
                    }
                    else if (begin <= info.addr_Finally_Begin && last.addr_Finally_End < end)
                    {
                        type  = TryCodeType.Final;
                        last  = info;
                        begin = info.addr_Finally_Begin;
                        end   = last.addr_Finally_End;
                    }
                }
                //find match catch
                foreach (var c in info.catch_Infos)
                {
                    if (c.Value.addrBegin <= addr && addr < c.Value.addrEnd)
                    {
                        if (last == null)
                        {
                            type  = TryCodeType.Catch;
                            last  = info;
                            begin = c.Value.addrBegin;
                            end   = c.Value.addrEnd;
                        }
                        else if (begin <= c.Value.addrBegin && c.Value.addrBegin < end)
                        {
                            type  = TryCodeType.Catch;
                            last  = info;
                            begin = c.Value.addrBegin;
                            end   = c.Value.addrEnd;
                        }
                    }
                }
            }
            return(last);
        }
コード例 #2
0
        public ILMethod(ILType type, Mono.Cecil.MethodDefinition method, ILogger logger = null)
        {
            this.type   = type;
            this.method = method;

            if (method != null)
            {
                returntype = method.ReturnType.FullName;
                if (method.HasParameters)
                {
                    hasParam = true;
                    foreach (var p in method.Parameters)
                    {
                        string paramtype = p.ParameterType.FullName;
                        try
                        {
                            var _type = p.ParameterType.Resolve();
                            foreach (var i in _type.Interfaces)
                            {
                                if (i.InterfaceType.Name == "IApiInterface")
                                {
                                    paramtype = "IInteropInterface";
                                }
                            }
                        }
                        catch
                        {
                        }
                        this.paramtypes.Add(new NeoParam(p.Name, paramtype));
                    }
                }
                if (method.HasBody)
                {
                    var bodyNative = method.Body;
                    if (bodyNative.HasVariables)
                    {
                        foreach (var v in bodyNative.Variables)
                        {
                            var indexname = v.VariableType.Name + ":" + v.Index;
                            this.body_Variables.Add(new NeoParam(indexname, v.VariableType.FullName));
                        }
                    }
                    for (int i = 0; i < bodyNative.Instructions.Count; i++)
                    {
                        var    code = bodyNative.Instructions[i];
                        OpCode c    = new OpCode
                        {
                            code = (CodeEx)(int)code.OpCode.Code,
                            addr = code.Offset
                        };

                        var sp = method.DebugInformation.GetSequencePoint(code);
                        if (sp != null)
                        {
                            c.debugcode = sp.Document.Url;
                            c.debugline = sp.StartLine;
                        }
                        c.InitToken(code.Operand);
                        this.body_Codes.Add(c.addr, c);
                    }
                    if (method.Body.HasExceptionHandlers)
                    {
                        var mapTryInfos = new Dictionary <string, ILTryInfo>();
                        foreach (var e in method.Body.ExceptionHandlers)
                        {
                            if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch)
                            {
                                var key = e.TryStart.Offset + "_" + e.TryEnd.Offset;
                                if (mapTryInfos.ContainsKey(key) == false)
                                {
                                    mapTryInfos[key] = new ILTryInfo();
                                }

                                var tryinfo = mapTryInfos[key];
                                tryinfo.addr_Try_Begin = e.TryStart.Offset;
                                tryinfo.addr_Try_End   = e.TryEnd.Offset;

                                var catchtypestr = e.CatchType.FullName;

                                tryinfo.catch_Infos[catchtypestr] = new ILCatchInfo()
                                {
                                    addrBegin = e.HandlerStart.Offset,
                                    addrEnd   = e.HandlerEnd.Offset,
                                    catchType = catchtypestr
                                };
                            }
                            else if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Finally)
                            {
                                int start = e.TryStart.Offset;
                                int end   = e.TryEnd.Offset;
                                Mono.Cecil.Cil.ExceptionHandler handler = null;
                                foreach (var tryinfocatch in method.Body.ExceptionHandlers)
                                {
                                    if (tryinfocatch.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch && tryinfocatch.TryStart.Offset == e.TryStart.Offset && tryinfocatch.TryEnd.Offset <= e.TryEnd.Offset)
                                    {//find include catch element.
                                        if (handler == null)
                                        {
                                            handler = tryinfocatch;
                                        }
                                        else if (handler.TryEnd.Offset < tryinfocatch.TryEnd.Offset)
                                        {
                                            handler = tryinfocatch;
                                        }
                                    }
                                }
                                if (handler != null)
                                {
                                    start = handler.TryStart.Offset;
                                    end   = handler.TryEnd.Offset;
                                }

                                var key = start + "_" + end;

                                if (mapTryInfos.ContainsKey(key) == false)
                                {
                                    mapTryInfos[key] = new ILTryInfo();
                                }

                                var tryinfo = mapTryInfos[key];
                                tryinfo.addr_Try_Begin = start;
                                tryinfo.addr_Try_End   = end;
                                tryinfo.addr_Try_End_F = e.TryEnd.Offset;

                                tryinfo.addr_Finally_Begin = e.HandlerStart.Offset;
                                tryinfo.addr_Finally_End   = e.HandlerEnd.Offset;
                            }
                            else
                            {
                                throw new Exception("not support yet." + e.HandlerType);
                            }
                        }
                        this.tryInfos = new List <ILTryInfo>(mapTryInfos.Values);
                        foreach (var info in this.tryInfos)
                        {
                            if (this.tryPositions.Contains(info.addr_Try_Begin) == false)
                            {
                                this.tryPositions.Add(info.addr_Try_Begin);
                            }
                        }
                    }
                }
            }
        }