Example #1
0
        public dynamic[] WalkProcList(DetectedProc dp)
        {
            bool GotData = false;
            // TODO: Build out symbol system / auto registration into DLR for DIA2
            // expected kernel hardcoded


            var pdbFile = (from kern in dp.Sections
                           where kern.DebugDetails != null &&
                           !string.IsNullOrWhiteSpace(kern.DebugDetails.PDBFullPath) && 
                           kern.DebugDetails.PDBFullPath.ToLower().Contains("ntkrnlmp")
                           select kern.DebugDetails.PDBFullPath).FirstOrDefault();

            if (string.IsNullOrWhiteSpace(pdbFile))
                return null;

            // this is for DIA API SDK... 
            // TODO: Perf analysis of switching over to xStruct... however it's expando objects
            // are a lot slower than using the dictionary
            SymForKernel = Sym.Initalize(pdbFile);
            long[] memRead = null;

            var PsHeadAddr = GetSymValueLong(dp, "PsActiveProcessHead");


            // TODO: update this to be used instead of legacy .Dictionary kludge ;)
            //var rv = SymForKernel.xStructInfo(pdbFile, "_EPROCESS");
            // figure out OFFSET_OF the process LIST_ENTRY
            // MemberInfo returned is Byte Position, Length
            var aplinks = SymForKernel.StructMemberInfo(pdbFile, "_EPROCESS", "ActiveProcessLinks.Flink");
            var offset_of = aplinks.Item1;
            var sym_dtb = SymForKernel.StructMemberInfo(pdbFile, "_EPROCESS", "Pcb.DirectoryTableBase");
            var sym_ImagePathPtr = SymForKernel.StructMemberInfo(pdbFile, "_EPROCESS", "SeAuditProcessCreationInfo.ImageFileName");
            var sym_procID = SymForKernel.StructMemberInfo(pdbFile, "_EPROCESS", "UniqueProcessId");
            var sym_vadRoot = SymForKernel.StructMemberInfo(pdbFile, "_EPROCESS", "VadRoot");

            // adjust the first link through 
            //var flink = dp.GetLongValue(PsHeadAddr);

            var typeDefs = from typeDef in SymForKernel.StructInfo
                            where typeDef.Key.StartsWith("_EPROCESS")
                            select typeDef;

            var flink = PsHeadAddr;
            do 
            {
                // walk the offset back to the head of the _EPROCESS
                // this needs to adjsut since we get the entire block here based to the page not offset 
                memRead = dp.GetVirtualLong((flink - offset_of), ref GotData);
                if (!GotData)
                    break;

                // memRead is a long array so we have to divide the length by 8
                var EprocCR3 = memRead[sym_dtb.Item1 / 8];
                var ProcessID = memRead[sym_procID.Item1 / 8];
                var VadRootPtr = memRead[sym_vadRoot.Item1 / 8];

                // ImagePath here is a pointer to a struct, get ptr
                // +0x10 in this unicode string object
                var ImagePathPtr = memRead[sym_ImagePathPtr.Item1 / 8];
                var ImagePathArr = dp.GetVirtualByte(ImagePathPtr+0x10);
                var ImagePath = Encoding.Unicode.GetString(ImagePathArr);
                var pathTrim = ImagePath.Split('\x0');
                ImagePath = pathTrim[0];

                dynamic lproc = new ExpandoObject();
                var dproc = (IDictionary<string, object>)lproc;

                var staticDict = new Dictionary<string, object>();
                lproc.Dictionary = staticDict;

                foreach (var def in typeDefs)
                {
                    // custom types are not fitted this way
                    // we just recuse into basic types
                    if (def.Value.Item2 > 8)
                        continue;

                    // TODO: expand on this dynamic object stuff
                    var defName = def.Key.Substring("_EPROCESS".Length + 1); //.Replace('.', '_');

                    switch (def.Value.Item2)
                    {
                        case 4:
                            var ival = (int)(memRead[def.Value.Item1 / 8] & 0xffffffffff);
                            dproc.Add(defName, ival);
                            staticDict.Add(defName, ival);
                            break;
                        case 2:
                            var sval = (short)(memRead[def.Value.Item1 / 8] & 0xffffff);
                            dproc.Add(defName, sval);
                            staticDict.Add(defName, sval);
                            break;
                        case 1:
                            var bval = (byte)(memRead[def.Value.Item1 / 8] & 0xff);
                            dproc.Add(defName, bval);
                            staticDict.Add(defName, bval);
                            break;
                        default:
                            var lval = memRead[def.Value.Item1 / 8];
                            dproc.Add(defName, lval);
                            staticDict.Add(defName, lval);
                            break;
                    }
                } 

                lproc.ImagePath = ImagePath;

                dp.LogicalProcessList.Add(lproc);

                // move flink to next list entry
                flink = memRead[offset_of / 8];

            } while (PsHeadAddr != flink);
            return dp.LogicalProcessList.ToArray();
        }
Example #2
0
 public AModInfo()
 {
     LoadedMods = new List <string>();
     SymCtx     = Sym.Initalize();
     uniqD      = new Dictionary <ulong, AStepEvent>();
 }
Example #3
0
        /// <summary>
        /// We use sympath environment variable
        /// </summary>
        /// <param name="cv_data"></param>
        /// <param name="BaseVA"></param>
        /// <param name="SymPath"></param>
        /// <returns></returns>
        public static bool TryLoadSymbols(long Handle, CODEVIEW_HEADER cv_data, ulong BaseVA, bool Verbose = false)
        {
#if NETSTANDARD2_0
            cv_data.PDBFullPath = $"NET_BINDING-{cv_data}";
            return(true);
#else
            var symStatus = false;
            if (string.IsNullOrWhiteSpace(cv_data.PdbName))
            {
                return(symStatus);
            }

            var sym = Sym.Initalize(Handle, null, DebugHelp.SymOptions.SYMOPT_UNDNAME);

            if (!sym && Verbose)
            {
                Sym.Errors.Enqueue($"Can not initialize symbols for ${Handle}, error:  {new Win32Exception(Marshal.GetLastWin32Error()).Message }");
            }


            StringBuilder sbx    = new StringBuilder(1024);
            StringBuilder sbName = new StringBuilder(cv_data.PdbName.Substring(0, cv_data.PdbName.IndexOf(".pdb") + 4));

            uint three = 0;
            var  flags = DebugHelp.SSRVOPT_GUIDPTR;
            symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, ref cv_data.aGuid, cv_data.Age, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
            //// try twice, just in case
            if (!symStatus)
            {
                symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, ref cv_data.aGuid, cv_data.Age, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
            }

            if (!symStatus)
            {
                if (Verbose)
                {
                    Sym.Errors.Enqueue($" Symbol locate returned {symStatus}: {new Win32Exception(Marshal.GetLastWin32Error()).Message }, attempting less precise request.");
                }

                flags = DebugHelp.SSRVOPT_DWORDPTR;
                var      refBytes    = BitConverter.GetBytes(cv_data.TimeDateStamp);
                GCHandle pinnedArray = GCHandle.Alloc(refBytes, GCHandleType.Pinned);
                IntPtr   pointer     = pinnedArray.AddrOfPinnedObject();

                symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, pointer, cv_data.VSize, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
                pinnedArray.Free();
                if (!symStatus && Verbose)
                {
                    Sym.Errors.Enqueue($" Find Symbols returned value: {symStatus}:[{sbx.ToString()}]");
                }
            }
            if (symStatus)
            {
                var symLoaded = DebugHelp.SymLoadModuleEx(Handle, IntPtr.Zero, sbx.ToString(), null, BaseVA, cv_data.VSize, IntPtr.Zero, 0);
                if (symLoaded == 0 && Verbose)
                {
                    Sym.Errors.Enqueue($"Symbols file located @ {sbx.ToString()} yet load Failed: [{new Win32Exception(Marshal.GetLastWin32Error()).Message }]");
                }

                cv_data.PDBFullPath = sbx.ToString();
            }

            return(symStatus);
#endif
        }