노현종

GetCriticalBlocks 크리티컬 블록 선정

90% 완성
크리티컬 변수가 참조된 블록 선정은 잘 되지만

블록 중에 코드 라인이 누락되는 경우 발생
......@@ -104,8 +104,9 @@ namespace VulnCrawler
/// <param name="oldStream">파일 스트림</param>
/// <param name="methodName">찾을 메서드 이름</param>
/// <returns>함수 문자열</returns>
protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
protected abstract IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList);
/// <summary>
/// 성능 개선을 위한
/// 코드 라인 위치 기반 취약 원본 함수 추출 테스트용 함수 곧 삭제 예정
......@@ -231,15 +232,33 @@ namespace VulnCrawler
/// <param name="oldStream"></param>
/// <param name="methodName"></param>
/// <returns></returns>
public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName, int start) {
// 패치 전 원본 함수 구하고
string func = GetOriginalFunc(oldStream, methodName);
// 주석 제거하고
//func = RemoveComment(func);
// 해쉬하고
string md5 = MD5HashFunc(func);
// 튜플로 반환
return (func, md5);
public virtual IEnumerable<(string originalFunc, string hash)> Process(Blob oldBlob, IDictionary<string, IEnumerable<string>> table) {
foreach (var item in table)
{
string methodName = item.Key;
// 패치 전 원본 파일 스트림
Stream oldStream = oldBlob.GetContentStream();
// 패치 전 원본 함수 구하고
string func = GetOriginalFunc(oldStream, methodName);
Console.WriteLine(func);
string bs = string.Empty;
string md5 = string.Empty;
int blockNum = 1;
if (item.Value.Count() != 0)
{
var blocks = GetCriticalBlocks(func, item.Value);
StringBuilder builder = new StringBuilder();
foreach (var block in blocks)
{
Console.WriteLine($"=====block({blockNum})");
Console.WriteLine(block);
builder.AppendLine(block);
}
bs = builder.ToString();
md5 = MD5HashFunc(bs);
}
yield return (bs, md5);
}
}
/// <summary>
/// 주석 제거 함수
......
......@@ -99,10 +99,8 @@ namespace VulnCrawler
}
return table;
}
protected override string GetOriginalFunc(Stream oldStream, string methodName) {
StringBuilder oldBuilder = new StringBuilder();
string method = Regex.Escape(methodName);
using (var reader = new StreamReader(oldStream)) {
bool found = false;
......@@ -115,12 +113,10 @@ namespace VulnCrawler
string commentPattern3 = @"\*\/";
while (!reader.EndOfStream) {
string line = reader.ReadLine();
// 메서드를 찾은 경우
if (found)
{
string trim = line.Trim();
// 범위 주석 진행되고 있으면 넘어감
if (commentLine)
{
......@@ -135,10 +131,8 @@ namespace VulnCrawler
continue;
}
}
// "" 문자열 제거
string removeString = Regex.Replace(trim, stringPattern, "");
// /* ~ 패턴
if (Regex.IsMatch(trim, commentPattern2))
{
......@@ -156,7 +150,6 @@ namespace VulnCrawler
{
continue;
}
int openBracketCount = removeString.Count(c => c == '{');
int closeBracketCount = removeString.Count(c => c == '}');
int subtract = openBracketCount - closeBracketCount;
......@@ -170,7 +163,6 @@ namespace VulnCrawler
{
break;
}
}
else // 메서드는 찾았으나 아직 시작 괄호를 못찾은 경우
{
......@@ -189,10 +181,7 @@ namespace VulnCrawler
continue;
}
}
}
}
// 아직 메서드를 못찾은 경우
else
......@@ -217,7 +206,6 @@ namespace VulnCrawler
{
continue;
}
// 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우
if (Regex.Match(trim, $@"{method}\s*" + @"\{").Success)
{
......@@ -235,15 +223,88 @@ namespace VulnCrawler
}
}
}
}
//Console.WriteLine(oldBuilder.ToString());
//Console.ReadLine();
return oldBuilder.ToString();
}
protected override IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList)
{
var split = srcCode.Split('\n');
int bracketCount = 0;
var blockList = new List<string>();
StringBuilder builder = new StringBuilder();
var crList = criticalList as HashSet<string>;
if (crList == null)
{
return null;
}
bool mainLine = true; /* 현재 라인이 메인 코드 라인인지 */
foreach (var line in split)
{
string trim = line.Trim();
/* 중괄호 수 세기 */
int openBracketCount = trim.Count(c => c == '{');
int closeBracketCount = trim.Count(c => c == '}');
int subtract = openBracketCount - closeBracketCount;
bracketCount += subtract;
/* 중괄호 연산 결과 1이라는 것은 메인 라인 */
if (bracketCount == 1)
{
/*
* 깊이가 1인데 mainLine이
* false 이면 넘어왔다는 것이니 현재까지 코드
* blockList에 추가
*/
if (!mainLine)
{
string s = builder.ToString();
if (!string.IsNullOrWhiteSpace(s))
{
blockList.Add(s);
builder.Clear();
}
}
mainLine = true;
}
/* 2 이상이라는 건 메인 라인 X */
else if(bracketCount >= 2)
{
/*
* 깊이가 2 이상인데 mainLine이
* true면 넘어왔다는 것이니 현재까지 코드
* blockList에 추가
*/
if (mainLine)
{
string s = builder.ToString();
if (!string.IsNullOrWhiteSpace(s))
{
blockList.Add(s);
builder.Clear();
}
}
mainLine = false;
}
/* 이도 저도 아니면 그냥 넘어감 */
else
{
continue;
}
/* 현재 코드 라인에서 변수 추출시켜서 크리티컬 리스트와 대조 */
foreach (var var in ExtractCriticalVariant(line))
{
/* 크리티컬 리스트에 추출한 변수가 들어있다면 추가 */
if (criticalList.Contains(var))
{
builder.AppendLine(line);
break;
}
}
}
return blockList;
}
}
}
......
......@@ -70,5 +70,10 @@ namespace VulnCrawler
{
throw new NotImplementedException();
}
protected override IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList)
{
throw new NotImplementedException();
}
}
}
......
......@@ -89,14 +89,28 @@ namespace VulnCrawler
Console.ResetColor();
var table = self.ExtractGitCriticalMethodTable(entry.Patch);
foreach (var item in table)
string originalFunc = string.Empty, md5 = string.Empty;
foreach (var tuple in self.Process(oldBlob, table))
{
Console.WriteLine($"Method : {item.Key}");
foreach (var b in item.Value)
{
Console.WriteLine($"--{b}");
}
Console.WriteLine("===z");
(originalFunc, md5) = tuple;
// 패치 전 원본 함수
Console.WriteLine($"Original Func: {originalFunc}");
// 해쉬 후
Console.WriteLine($"Original Func MD5: {md5}");
}
//foreach (var item in table)
//{
// Console.WriteLine($"Method : {item.Key}");
// //foreach (var b in item.Value)
// //{
// // Console.WriteLine($"--{b}");
// //}
//}
Console.ReadLine();
}
else
......@@ -111,37 +125,35 @@ namespace VulnCrawler
//
#endregion
foreach (var reg in regs)
{
//foreach (var reg in regs)
//{
var match = reg as Match;
string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
int start = 0; //int.Parse(match.Groups[VulnAbstractCrawler.OldStart].Value);
// Console.WriteLine("methodName = " + methodName);
string originalFunc, md5;
(originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
methodName, start);
// var match = reg as Match;
// string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
// string originalFunc, md5;
// (originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
// methodName);
#region 현재 패치 엔트리 정보 출력(추가된 , 삭제된 , 패치 이전 경로, 패치 경로)
// #region 현재 패치 엔트리 정보 출력(추가된 줄 수, 삭제된 줄 수, 패치 이전 경로, 패치 후 경로)
// 패치 전 원본 함수
Console.WriteLine($"Original Func: {originalFunc}");
// 해쉬 후
Console.WriteLine($"Original Func MD5: {md5}");
//Console.BackgroundColor = ConsoleColor.DarkRed;
//Console.WriteLine($"Patched: \n{entry.Patch}");
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("==============================");
Console.ResetColor();
#endregion
}
Console.ReadLine();
// // 패치 전 원본 함수
// Console.WriteLine($"Original Func: {originalFunc}");
// // 해쉬 후
// Console.WriteLine($"Original Func MD5: {md5}");
// //Console.BackgroundColor = ConsoleColor.DarkRed;
// //Console.WriteLine($"Patched: \n{entry.Patch}");
// Console.ResetColor();
// Console.ForegroundColor = ConsoleColor.Red;
// Console.WriteLine("==============================");
// Console.ResetColor();
// #endregion
//}
//Console.ReadLine();
}
catch (Exception e)
{
......