노현종

VulnUserCodeAnalyzer 수정

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flicker
{
public class Start
{
}
}
using System;
namespace Flicker
{
public abstract class Element : IRenderable
{
public readonly int Height;
public readonly int Width;
public readonly int X;
public readonly int Y;
protected Element(int x, int y, int width, int height)
{
X = x;
Y = y;
Width = width;
Height = height;
}
protected Element(float x, float y, float width, float height)
{
x = x.Clamp(0, .99f);
y = y.Clamp(0, .99f);
width = width.Clamp(0, .99f);
height = height.Clamp(0, .99f);
X = (int)(Console.BufferWidth * x);
Y = (int)(Console.BufferHeight * y);
Width = (int)(Console.BufferWidth * width);
Height = (int)(Console.BufferHeight * height);
}
public bool Visible { get; set; } = true;
public char Border { get; set; } = ' ';
public int Padding { get; set; } = 1; // Must be at least 1 (to make room for header), TODO enforce this
public ConsoleColor Foreground { get; set; } = ConsoleColor.White;
public ConsoleColor Background { get; set; } = ConsoleColor.Black;
public Renderer AssociatedRenderer { get; set; }
public virtual void HandleKey(ConsoleKeyInfo key) { }
/// <summary>
/// Draw this element
/// </summary>
void IRenderable.Render(bool selected)
{
if (!Visible) return;
Console.ForegroundColor = Foreground;
Console.BackgroundColor = Background;
Console.CursorLeft = X;
Console.CursorTop = Y;
Tools.Console.Fill(
X,
Y,
Width,
Height,
' '
);
if (Border != ' ')
{
// Top and bottom borders
Console.CursorLeft = X;
Console.CursorTop = Y;
Console.Write(new string(Border, Width));
Console.CursorLeft = X;
Console.CursorTop = Y + Height - 1;
Console.Write(new string(Border, Width));
// Left and right borders
for (var y = Y; y < Y + Height - 1; ++y)
{
Tools.Console.WriteAt(X, y, Border.ToString());
Tools.Console.WriteAt(X + Width - 1, y, Border.ToString());
}
}
if (selected)
Tools.Console.WriteAt(
X, Y,
new string('\u2580', Width),
ConsoleColor.Red
);
Console.CursorLeft = X + Padding * 2;
Console.CursorTop = Y + Padding;
CustomRender();
Console.ResetColor();
}
public void Select() => AssociatedRenderer.Select(this);
public void Destroy() => AssociatedRenderer.Destroy(this);
protected virtual void CustomRender() { }
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Flicker
{
internal static class Extensions
{
internal static IEnumerable<string> Chunks(this string str, int size)
{
return Regex.Matches(str, "(.{1," + size + "})").Cast<Match>().Select(m => m.Value);
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DB1A8C9F-3FA2-4D8C-BBBA-F88F245E13B4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Flicker</RootNamespace>
<AssemblyName>Flicker</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Element.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="IRenderable.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderer.cs" />
<Compile Include="MenuElement.cs" />
<Compile Include="InputElement.cs" />
<Compile Include="TextElement.cs" />
<Compile Include="Tools.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
using System;
namespace Flicker
{
public interface IRenderable
{
Renderer AssociatedRenderer { get; set; }
void Render(bool selected);
void HandleKey(ConsoleKeyInfo key);
void Select();
void Destroy();
}
}
\ No newline at end of file
using System;
namespace Flicker
{
public class InputElement : Element
{
public InputElement(out string result, string label)
: base(0, 0, 0, 0)
{
Visible = false;
Console.Clear();
Tools.Console.Fill(0, 1, Console.BufferWidth, Console.BufferHeight - 2, '\u2588');
Tools.Console.WriteAt(0, 0, label);
result = Console.ReadLine();
}
}
public class InputElement<T> : Element
{
public InputElement(out T result, string label)
: base(0, 0, 0, 0)
{
Visible = false;
Console.Clear();
Tools.Console.Fill(0, 1, Console.BufferWidth, Console.BufferHeight - 2, '\u2588');
Tools.Console.WriteAt(0, 0, label);
var input = Console.ReadLine();
try
{
result = (T)Convert.ChangeType(input, typeof(T));
}
catch
{
// Fail silently
result = default(T);
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
namespace Flicker
{
public class MenuElement : Element
{
public MenuElement(int x, int y, int width, int height)
: base(x, y, width, height) { }
public MenuElement(float x, float y, float width, float height)
: base(x, y, width, height) { }
public List<MenuItem> Items { get; set; } = new List<MenuItem>();
private int SelectedIndex { get; set; }
public override void HandleKey(ConsoleKeyInfo key)
{
switch (key.Key)
{
case ConsoleKey.UpArrow:
SelectedIndex = (--SelectedIndex).Wrap(0, Items.Count - 1);
break;
case ConsoleKey.DownArrow:
SelectedIndex = (++SelectedIndex).Wrap(0, Items.Count - 1);
break;
case ConsoleKey.Enter:
Items[SelectedIndex].Method();
break;
}
}
protected override void CustomRender()
{
for (var i = 0; i < Items.Count; ++i)
{
Console.BackgroundColor = Background;
Console.ForegroundColor = Foreground;
if (i == SelectedIndex)
{
Console.BackgroundColor = ConsoleColor.DarkGray;
Console.ForegroundColor = ConsoleColor.White;
}
Console.Write(Items[i].Label);
++Console.CursorTop;
Console.CursorLeft = X + Padding * 2;
}
}
}
public class MenuItem
{
public Action Method { get; set; }
public string Label { get; set; }
}
}
\ No newline at end of file
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Flicker")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Flicker")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("db1a8c9f-3fa2-4d8c-bbba-f88f245e13b4")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
using System;
using System.Collections.Generic;
namespace Flicker
{
public class Renderer
{
public Renderer()
{
// Make buffer the size of the window
Console.BufferWidth = Console.WindowWidth;
Console.BufferHeight = Console.WindowHeight;
Console.CursorVisible = false;
}
private List<IRenderable> RenderItems { get; } = new List<IRenderable>();
private int SelectedIndex { get; set; }
public void Render()
{
while (true)
{
Console.ResetColor();
Console.Clear();
try
{
foreach (var el in RenderItems)
el.Render(RenderItems[SelectedIndex] == el);
}
catch
{
// Nom
}
Poll();
}
}
private void Poll()
{
var key = Console.ReadKey(false);
if ((key.Modifiers & ConsoleModifiers.Control) != 0)
{
switch (key.Key)
{
case ConsoleKey.RightArrow:
SelectedIndex = (++SelectedIndex).Wrap(0, RenderItems.Count - 1);
break;
case ConsoleKey.LeftArrow:
SelectedIndex = (--SelectedIndex).Wrap(0, RenderItems.Count - 1);
break;
}
return;
}
RenderItems[SelectedIndex].HandleKey(key);
}
public bool Register(IRenderable element)
{
element.AssociatedRenderer = this;
RenderItems.Add(element);
return true;
}
public void Select(IRenderable element)
{
SelectedIndex = RenderItems.IndexOf(element);
}
public void Destroy(IRenderable element)
{
RenderItems.Remove(element);
}
}
}
\ No newline at end of file
using System;
namespace Flicker
{
public class TextElement : Element
{
public TextElement(int x, int y, int width, int height)
: base(x, y, width, height) { }
public TextElement(float x, float y, float width, float height)
: base(x, y, width, height) { }
public string Text { get; set; } = "";
public bool Wrap { get; set; } = true;
protected override void CustomRender()
{
if (!Wrap)
{
Console.Write(Text);
return;
}
foreach (var line in Text.Chunks(Width - Padding * 4))
{
Console.Write(line.Trim());
++Console.CursorTop;
Console.CursorLeft = X + Padding * 2;
}
}
}
}
\ No newline at end of file
using System;
namespace Flicker
{
internal static class Tools
{
public static T Clamp<T>(this T val, T min)
where T : IComparable<T> =>
val.CompareTo(min) < 0
? min
: val;
public static T Clamp<T>(this T val, T min, T max)
where T : IComparable<T> =>
val.CompareTo(min) < 0
? min
: val.CompareTo(max) > 0
? max
: val;
public static T Wrap<T>(this T val, T min, T max)
where T : IComparable<T> =>
val.CompareTo(min) < 0
? max
: val.CompareTo(max) > 0
? min
: val;
public static class Console
{
public static void WriteAt(int x, int y, string str)
{
System.Console.CursorLeft = x;
System.Console.CursorTop = y;
System.Console.Write(str);
}
public static void WriteAt(int x, int y, string str, ConsoleColor colour)
{
var old = System.Console.ForegroundColor;
System.Console.ForegroundColor = colour;
WriteAt(x, y, str);
System.Console.ForegroundColor = old;
}
public static void Fill(int x, int y, int width, int height, char c)
{
for (var i = x; i < x + width; ++i)
for (var j = y; j < y + height; ++j)
WriteAt(i, j, c.ToString());
}
public static void Fill(int x, int y, int width, int height, char c, ConsoleColor colour)
{
var old = System.Console.ForegroundColor;
System.Console.ForegroundColor = colour;
Fill(x, y, width, height, c);
System.Console.ForegroundColor = old;
}
}
}
}
\ No newline at end of file
......@@ -24,6 +24,28 @@ namespace VulnCrawler
public IEnumerable<string> CriticalList { get; set; }
}
public class UserBlock
{
public int Len { get; set; }
public string FuncName { get; set; }
public string Hash { get; set; }
public string Path { get; set; }
public override bool Equals(object obj)
{
var block = obj as UserBlock;
return block != null &&
Hash == block.Hash;
}
public override int GetHashCode()
{
var hashCode = -481433985;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Hash);
return hashCode;
}
}
protected Regex extractMethodLine;
protected HashSet<string> ReservedList { get; }
protected abstract string ReservedFileName { get; }
......@@ -121,7 +143,7 @@ namespace VulnCrawler
/// <returns>함수 문자열</returns>
protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
public abstract IDictionary<int, List<string>> CrawlUserCode(StreamReader reader);
public abstract IDictionary<int, IEnumerable<UserBlock>> CrawlUserCode(StreamReader reader);
protected abstract IList<Block> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList);
/// <summary>
......
......@@ -533,7 +533,7 @@ namespace VulnCrawler
var removes = Regex.Split(blockCode, Environment.NewLine, RegexOptions.Multiline);
StringBuilder builder = new StringBuilder();
Console.ForegroundColor = ConsoleColor.DarkYellow;
// Console.ForegroundColor = ConsoleColor.DarkYellow;
foreach (var item in removes)
{
if (string.IsNullOrWhiteSpace(item))
......@@ -543,8 +543,8 @@ namespace VulnCrawler
string rm = regex1.Replace(item, "");
builder.Append(rm);
}
Console.WriteLine(builder.ToString());
Console.ResetColor();
// Console.WriteLine(builder.ToString());
// Console.ResetColor();
string line = builder.ToString();
var varList = ExtractMethodVariantList(line, skipDefine: false);
......@@ -642,9 +642,11 @@ namespace VulnCrawler
return temp;
}
public override IDictionary<int, List<string>> CrawlUserCode(StreamReader reader)
public override IDictionary<int, IEnumerable<UserBlock>> CrawlUserCode(StreamReader reader)
{
var dict = new Dictionary<int, List<string>>();
var dict = new Dictionary<int, IEnumerable<UserBlock>>();
StringBuilder oldBuilder = new StringBuilder();
bool found = false;
......@@ -662,33 +664,74 @@ namespace VulnCrawler
bool found3 = false;
bool com = false;
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Console.WriteLine(line);
string trim = line.Trim();
if (commentLine)
{
// 혹시 범위 주석이 끝났는지 체크
if (regex1.IsMatch(trim))
{
commentLine = false;
trim = regex1.Split(trim)[1];
}
else
{
continue;
}
}
// /* ~ 패턴
if (regex3.IsMatch(trim))
{
// /* ~ */ 패턴이 아닌 경우
if (!regex4.IsMatch(trim))
{
commentLine = true;
}
trim = Regex.Split(trim, "/*")[0];
}
if (com)
{
if (trim.StartsWith("*"))
{
continue;
}
else
{
com = false;
}
}
// 메서드를 찾은 경우
if (found3)
{
string obStr = oldBuilder.ToString();
obStr = Abstract(obStr, new Dictionary<string, string>(), new Dictionary<string, string>());
if (!dict.ContainsKey(obStr.Length))
{
dict[obStr.Length] = new List<string>();
dict[obStr.Length] = new HashSet<UserBlock>();
}
dict[obStr.Length].Add(MD5HashFunc(obStr));
string funcName = new string(oldBuilder.ToString().TakeWhile(c => c != '{').ToArray());
(dict[obStr.Length] as HashSet<UserBlock>).Add(new UserBlock
{
Hash = MD5HashFunc(obStr),
Len = obStr.Length,
FuncName = funcName,
});
oldBuilder.Clear();
found = false;
found2 = false;
found3 = false;
bracketCount = -1;
commentLine = false;
}
if (found)
{
string trim = line.Trim();
// 범위 주석 진행되고 있으면 넘어감
if (trim.StartsWith("#"))
{
......@@ -718,7 +761,6 @@ namespace VulnCrawler
commentLine = true;
}
trim = Regex.Split(trim, "/*")[0];
}
// 비어있는 경우 넘어감
if (string.IsNullOrWhiteSpace(trim))
......@@ -732,15 +774,10 @@ namespace VulnCrawler
// 메서드 시작 괄호 찾은 경우
if (found2)
{
oldBuilder.AppendLine(line);
// 괄호가 모두 닫혔으니 종료
if (bracketCount < 0)
{
if (reader.EndOfStream)
{
Console.WriteLine("파일끝");
}
found3 = true;
continue;
}
......@@ -758,9 +795,6 @@ namespace VulnCrawler
//아직 { 괄호를 못찾았는데 );를 만났다면 메서드 선언 부분이니 넘어감
if (trim.EndsWith(");"))
{
Console.WriteLine("-------");
Console.WriteLine(trim);
Console.WriteLine("-----");
found = false;
oldBuilder.Clear();
continue;
......@@ -782,7 +816,7 @@ namespace VulnCrawler
// 메서드 찾았는지 확인
if (Regex.IsMatch(line, RegexFuncPattern))
{
string trim = line.Trim();
// 주석으로 시작했다면 넘어감
if (trim.StartsWith("//"))
{
......@@ -791,6 +825,7 @@ namespace VulnCrawler
if (trim.StartsWith("/*"))
{
com = true;
continue;
}
......@@ -821,9 +856,19 @@ namespace VulnCrawler
if (!dict.ContainsKey(obStr.Length))
{
dict[obStr.Length] = new List<string>();
dict[obStr.Length] = new HashSet<UserBlock>();
}
dict[obStr.Length].Add(MD5HashFunc(obStr));
string funcName = new string(oldBuilder.ToString().TakeWhile(c => c != '{').ToArray());
(dict[obStr.Length] as HashSet<UserBlock>).Add(new UserBlock
{
Hash = MD5HashFunc(obStr),
Len = obStr.Length,
FuncName = funcName,
});
oldBuilder.Clear();
found = false;
found2 = false;
......@@ -831,6 +876,7 @@ namespace VulnCrawler
bracketCount = -1;
commentLine = false;
}
......
......@@ -81,7 +81,7 @@ namespace VulnCrawler
throw new NotImplementedException();
}
public override IDictionary<int, List<string>> CrawlUserCode(StreamReader reader)
public override IDictionary<int, IEnumerable<UserBlock>> CrawlUserCode(StreamReader reader)
{
throw new NotImplementedException();
}
......
using System;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
......@@ -13,10 +14,13 @@ namespace VulnUserCodeAnalyzer
{
static void Main(string[] args)
{
var hashDict = new Dictionary<int, HashSet<VulnAbstractCrawler.UserBlock>>();
DirectoryInfo dirInfo = new DirectoryInfo(@"c:\code");
var codeFiles = dirInfo.EnumerateFiles("*.c", SearchOption.AllDirectories);
int totalFileCount = codeFiles.Count();
var crawler = new VulnC();
int count = 0;
foreach (var codeFile in codeFiles)
{
Console.WriteLine(codeFile.FullName);
......@@ -27,16 +31,44 @@ namespace VulnUserCodeAnalyzer
foreach (var item in dict)
{
Console.WriteLine($"----{item.Key}->");
if (!hashDict.ContainsKey(item.Key))
{
hashDict[item.Key] = new HashSet<VulnAbstractCrawler.UserBlock>();
}
foreach (var hash in item.Value)
{
Console.WriteLine(hash);
hash.Path = codeFile.FullName;
hashDict[item.Key].Add(hash);
}
}
count++;
double per = ((double)count / (double)totalFileCount) * 100;
Console.Clear();
Console.WriteLine($"{count} / {totalFileCount} :: {per.ToString("#0.0")}%, 개체 수 : {hashDict.Count}");
//if (count > 20)
//{
// break;
//}
}
}
foreach (var set in hashDict)
{
Console.WriteLine($"-----key:{set.Key}");
foreach (var hash in set.Value)
{
Console.WriteLine($"{hash.FuncName}, {hash.Hash}, {hash.Len}, {hash.Path}");
}
}
}
}
}
......