383 lines
15 KiB
C#
383 lines
15 KiB
C#
|
using Microsoft.AspNetCore.Mvc;
|
||
|
using SharpPdb.Native;
|
||
|
|
||
|
using System.Net;
|
||
|
using System.Net.Http.Headers;
|
||
|
using System.Text;
|
||
|
using System.IO;
|
||
|
using Microsoft.AspNetCore.StaticFiles;
|
||
|
using System.Runtime.InteropServices;
|
||
|
|
||
|
using Zodiacon.DebugHelp;
|
||
|
|
||
|
using Microsoft.PdbDownloader.Logic.Pdb;
|
||
|
using Microsoft.PdbDownloader.Logic.Pe;
|
||
|
|
||
|
namespace PdbServer.Controllers
|
||
|
{
|
||
|
[ApiController]
|
||
|
[Route("[controller]")]
|
||
|
public class Symbols : ControllerBase
|
||
|
{
|
||
|
[DllImport("Symbol Parser.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
|
||
|
public static extern int EnumFunction(IntPtr pdbpath,IntPtr fname);
|
||
|
|
||
|
//const string pdburl = "http://msdl.microsoft.com/download/";
|
||
|
const string pdburl = "http://msdl.blackint3.com:88/download/";
|
||
|
const string selfdocpath = "D:\\Web\\Symbols";
|
||
|
private readonly ILogger<Symbols> _logger;
|
||
|
public Symbols(ILogger<Symbols> logger)
|
||
|
{
|
||
|
_logger = logger;
|
||
|
}
|
||
|
|
||
|
[HttpGet]
|
||
|
[Route("QueryAllModuleSymbol")]
|
||
|
public string QueryAllModuleSymbol(string ModuleName, string Guid, string Agent)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
using var reader = new PdbFileReader(filename);
|
||
|
|
||
|
foreach (var v in reader.Functions)
|
||
|
{
|
||
|
sb.Append(v.Offset);
|
||
|
sb.Append('#');
|
||
|
sb.Append(v.Name);
|
||
|
sb.Append('|');
|
||
|
}
|
||
|
}
|
||
|
if (sb.Length > 0) sb.Length -= 1;
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
[HttpGet]
|
||
|
[Route("SymbolCheck")]
|
||
|
public int SymbolCheck(string ModuleName, string Guid, string Agent)
|
||
|
{
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if(System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes($"{selfdocpath}\\{Guid}_{Agent}.no", new byte[0]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
public static byte[] Compress(byte[] rawData)
|
||
|
{
|
||
|
System.IO.MemoryStream ms = new System.IO.MemoryStream();
|
||
|
System.IO.Compression.GZipStream compressedzipStream = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress, true);
|
||
|
compressedzipStream.Write(rawData, 0, rawData.Length);
|
||
|
compressedzipStream.Close();
|
||
|
return ms.ToArray();
|
||
|
}
|
||
|
[HttpGet]
|
||
|
[Route("SymbolDownLoad")]
|
||
|
public string SymbolDownLoad(string ModuleName, string Guid, string Agent)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return "";
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
byte[] filebuffer = System.IO.File.ReadAllBytes(filename);
|
||
|
var bytes= Compress(filebuffer);
|
||
|
for(int i=0;i<bytes.Length; i++)
|
||
|
{
|
||
|
sb.Append(bytes[i].ToString("X2"));
|
||
|
}
|
||
|
}
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
|
||
|
[HttpGet]
|
||
|
[Route("QueryModuleSymbol")]//https://localhost:7001/Symbols/QueryModuleSymbol?ModuleName=dwmcore.pdb&Guid=47E4AD6A46A936FC873379E0D86E94FC&Agent=1&QueryName=CLegacySwapChain::Present
|
||
|
public Int64 QueryModuleSymbol(string ModuleName, string Guid, string Agent, string QueryName)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
var offst = EnumFunction(Marshal.StringToHGlobalAnsi(filename), Marshal.StringToHGlobalAnsi(QueryName));
|
||
|
return offst;
|
||
|
//SymbolHandler handler = SymbolHandler.Create();
|
||
|
//ulong ptr = 0;
|
||
|
//ptr = handler.TryLoadSymbolsForModuleAsync(filename, 0x1000000UL).Result;
|
||
|
//foreach (var v in handler.EnumSymbols(ptr))
|
||
|
//{
|
||
|
// if (v.Name.Trim().ToLower() == QueryName.ToLower())
|
||
|
// {
|
||
|
// handler.Dispose();
|
||
|
// return (Int64)(v.Address - 0x1000000UL);
|
||
|
// }
|
||
|
//}
|
||
|
//handler.Dispose();
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
[HttpGet]
|
||
|
[Route("QueryModuleSymbolEX00A")]//https://localhost:7001/Symbols/QueryModuleSymbol?ModuleName=dwmcore.pdb&Guid=47E4AD6A46A936FC873379E0D86E94FC&Agent=1&QueryName=CLegacySwapChain::Present
|
||
|
public Int64 QueryModuleSymbolEX00A(string ModuleName, string Guid, string Agent, string QueryName)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return -1;
|
||
|
}Marshal.StringToHGlobalAnsi(filename);
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
var offst = EnumFunction(Marshal.StringToHGlobalAnsi(filename), Marshal.StringToHGlobalAnsi(QueryName));
|
||
|
return offst;
|
||
|
//SymbolHandler handler = SymbolHandler.Create();
|
||
|
//ulong ptr = 0;
|
||
|
//ptr = handler.TryLoadSymbolsForModuleAsync(filename, 0x1000000UL).Result;
|
||
|
//foreach (var v in handler.EnumSymbols(ptr))
|
||
|
//{
|
||
|
// if (v.Name.Trim().ToLower() == QueryName.ToLower())
|
||
|
// {
|
||
|
// handler.Dispose();
|
||
|
// return (Int64)(v.Address - 0x1000000UL);
|
||
|
// }
|
||
|
//}
|
||
|
//handler.Dispose();
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
//https://localhost:7001/Symbols/QueryModuleStruct?ModuleName=ntkrnlmp.pdb&Guid=F55005B80C686C739E763E6CF2559D9F&Agent=1&StructName=_EPROCESS&FildName=ActiveProcessLinks
|
||
|
[HttpGet]
|
||
|
[Route("QueryModuleStructFildOffset")]
|
||
|
public Int64 QueryModuleStructFildOffset(string ModuleName, string Guid, string Agent, string StructName, string FildName)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
using var reader = new PdbFileReader(filename);
|
||
|
foreach (var v in reader.UserDefinedTypes)
|
||
|
{
|
||
|
if (v is SharpPdb.Native.Types.PdbClassType _struct)
|
||
|
{
|
||
|
if (_struct.Name == StructName)
|
||
|
{
|
||
|
foreach (var fild in _struct.Fields)
|
||
|
{
|
||
|
if (fild.Name == FildName)
|
||
|
{
|
||
|
return (Int64)fild.Offset;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbUnionType _struct1)
|
||
|
{
|
||
|
if (_struct1.Name == StructName)
|
||
|
{
|
||
|
foreach (var fild in _struct1.Fields)
|
||
|
{
|
||
|
if (fild.Name == FildName)
|
||
|
{
|
||
|
return (Int64)fild.Offset;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbEnumType _enum)
|
||
|
{
|
||
|
if (_enum.Name == StructName)
|
||
|
{
|
||
|
foreach (var val in _enum.Values)
|
||
|
{
|
||
|
if (val.Name == FildName)
|
||
|
{
|
||
|
return (Int64)val.Value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
[HttpGet]
|
||
|
[Route("QueryModuleStructFilds")]
|
||
|
public string QueryModuleStructFilds(string ModuleName, string Guid, string Agent, string StructName)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
using var reader = new PdbFileReader(filename);
|
||
|
foreach (var v in reader.UserDefinedTypes)
|
||
|
{
|
||
|
if (v is SharpPdb.Native.Types.PdbClassType _struct)
|
||
|
{
|
||
|
if (_struct.Name == StructName)
|
||
|
{
|
||
|
foreach (var fild in _struct.Fields)
|
||
|
{
|
||
|
sb.Append($"{fild.Name},{(Int64)fild.Offset};");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbUnionType _struct1)
|
||
|
{
|
||
|
if (_struct1.Name == StructName)
|
||
|
{
|
||
|
foreach (var fild in _struct1.Fields)
|
||
|
{
|
||
|
sb.Append($"{fild.Name},{(Int64)fild.Offset};");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbEnumType _enum)
|
||
|
{
|
||
|
if (_enum.Name == StructName)
|
||
|
{
|
||
|
foreach (var val in _enum.Values)
|
||
|
{
|
||
|
sb.Append($"{val.Name},{val.Value};");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
//http://www.sym101.com/Symbols/QueryModuleStruct?ModuleName=ntkrnlmp.pdb&Guid=F55005B80C686C739E763E6CF2559D9F&Agent=1
|
||
|
[HttpGet]
|
||
|
[Route("QueryModuleStruct")]
|
||
|
public string QueryModuleStruct(string ModuleName, string Guid, string Agent)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
string filename = $"{selfdocpath}\\{ModuleName}_{Guid}_{Agent}.pdb";
|
||
|
if (!System.IO.File.Exists(filename))
|
||
|
{
|
||
|
if (System.IO.File.Exists($"{selfdocpath}\\{Guid}_{Agent}.no"))
|
||
|
{
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
byte[] data = Helpers.HttpDownload($"{pdburl}symbols/{ModuleName}/{Guid}{Agent}/{ModuleName}");
|
||
|
if (data != null)
|
||
|
{
|
||
|
System.IO.File.WriteAllBytes(filename, data);
|
||
|
}
|
||
|
}
|
||
|
if (System.IO.File.Exists(filename))
|
||
|
{
|
||
|
using var reader = new PdbFileReader(filename);
|
||
|
foreach (var v in reader.UserDefinedTypes)
|
||
|
{
|
||
|
if (v is SharpPdb.Native.Types.PdbClassType _struct)
|
||
|
{
|
||
|
sb.Append($"{v.Name}@");
|
||
|
foreach (var fild in _struct.Fields)
|
||
|
{
|
||
|
sb.Append($"{fild.Name},{(Int64)fild.Offset};");
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbUnionType _struct1)
|
||
|
{
|
||
|
sb.Append($"{v.Name}@");
|
||
|
foreach (var fild in _struct1.Fields)
|
||
|
{
|
||
|
sb.Append($"{fild.Name},{(Int64)fild.Offset};");
|
||
|
}
|
||
|
}
|
||
|
else if (v is SharpPdb.Native.Types.PdbEnumType _enum)
|
||
|
{
|
||
|
sb.Append($"{v.Name}@");
|
||
|
foreach (var val in _enum.Values)
|
||
|
{
|
||
|
sb.Append($"{val.Name},{val.Value};");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|