2025-06-05 10:51:52 +08:00

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();
}
}
}