노현종

패치 전 취약한 함수 코드 추출 완성

......@@ -114,14 +114,126 @@ namespace VulnCrawler
/// <returns>함수 문자열</returns>
protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
// 테스트용 함수 곧 삭제될 운명
public string GetOriginalFuncTest(Stream oldStream, string methodName, int start)
{
StringBuilder oldBuilder = new StringBuilder();
using (var reader = new StreamReader(oldStream))
{
bool found = false;
bool found2 = false;
bool commentLine = false;
int bracketCount = -1;
string stringPattern = @"[""].*[""]";
string commentPattern = @"\/\*.+\*\/";
string commentPattern2 = @"\/\*";
string commentPattern3 = @"\*\/";
int readCount = 0;
Queue<string> tempQ = new Queue<string>();
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (readCount++ < start)
{
tempQ.Enqueue(line);
continue;
}
Stack<string> tempStack = new Stack<string>();
while (tempQ.Count > 0)
{
string s = tempQ.Dequeue();
tempStack.Push(s);
string method = Regex.Escape(methodName);
if (Regex.Match(s, $"{method}").Success)
{
break;
}
}
while (tempStack.Count > 0)
{
string s = tempStack.Pop();
string trim = s.Trim();
if (commentLine)
{
if (Regex.IsMatch(trim, commentPattern3))
{
commentLine = false;
trim = Regex.Split(trim, commentPattern3)[1];
}
continue;
}
string removeString = Regex.Replace(trim, stringPattern, "");
// /* ~ 패턴
if (Regex.IsMatch(trim, commentPattern2))
{
// /* ~ */ 패턴이 아닌 경우
if (!Regex.IsMatch(trim, commentPattern))
{
commentLine = true;
}
trim = Regex.Split(trim, "/*")[0];
}
if (string.IsNullOrWhiteSpace(trim))
{
continue;
}
int openBracketCount = removeString.Count(c => c == '{');
int closeBracketCount = removeString.Count(c => c == '}');
int subtract = openBracketCount - closeBracketCount;
bracketCount += subtract;
// 메서드 시작 괄호 찾은 경우
if (found2)
{
// 괄호가 모두 닫혔으니 종료
if (bracketCount < 0)
{
Console.WriteLine("괄호끝");
break;
}
// oldBuilder.AppendLine(line);
}
else
{
if (openBracketCount > 0)
{
found2 = true;
}
}
oldBuilder.AppendLine(s);
}
}
}
Console.WriteLine("찾음");
Console.WriteLine(oldBuilder.ToString());
Console.ReadLine();
return oldBuilder.ToString();
}
/// <summary>
/// 실제 프로세스
/// </summary>
/// <param name="oldStream"></param>
/// <param name="methodName"></param>
/// <returns></returns>
public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName) {
public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName, int start) {
// 패치 전 원본 함수 구하고
string func = GetOriginalFunc(oldStream, methodName);
// 주석 제거하고
......
......@@ -52,34 +52,44 @@ namespace VulnCrawler
// 메서드를 찾은 경우
if (found)
{
Console.WriteLine("찾았었음");
string trim = line.Trim();
// 범위 주석 진행되고 있으면 넘어감
if (commentLine)
{
// 혹시 범위 주석이 끝났는지 체크
if (Regex.IsMatch(trim, commentPattern3))
{
commentLine = false;
trim = Regex.Split(trim, commentPattern3)[1];
}
}
if (string.IsNullOrWhiteSpace(trim))
else
{
continue;
}
}
// "" 문자열 제거
string removeString = Regex.Replace(trim, stringPattern, "");
// /* ~ 패턴
if (Regex.IsMatch(trim, commentPattern2))
{
trim = Regex.Split(trim, "/*")[0];
// /* ~ */ 패턴이 아닌 경우
if (!Regex.IsMatch(trim, commentPattern))
{
commentLine = true;
}
trim = Regex.Split(trim, "/*")[0];
}
// 비어있는 경우 넘어감
if (string.IsNullOrWhiteSpace(trim))
{
continue;
}
int openBracketCount = removeString.Count(c => c == '{');
int closeBracketCount = removeString.Count(c => c == '}');
int subtract = openBracketCount - closeBracketCount;
......@@ -87,31 +97,44 @@ namespace VulnCrawler
// 메서드 시작 괄호 찾은 경우
if (found2)
{
oldBuilder.AppendLine(line);
// 괄호가 모두 닫혔으니 종료
if (bracketCount < 0)
{
Console.WriteLine("괄호끝");
break;
}
oldBuilder.AppendLine(line);
}
else
else // 메서드는 찾았으나 아직 시작 괄호를 못찾은 경우
{
oldBuilder.AppendLine(line);
if (openBracketCount > 0)
{
found2 = true;
}
else
{
//아직 { 괄호를 못찾았는데 );를 만났다면 메서드 선언 부분이니 넘어감
if (trim.EndsWith(");"))
{
found = false;
oldBuilder.Clear();
continue;
}
}
}
}
// 아직 메서드를 못찾은 경우
else
{
// 메서드 찾았는지 확인
if (Regex.Match(line, $"{methodName}").Success)
{
string trim = line.Trim();
// 주석으로 시작했다면 넘어감
if (trim.StartsWith("//"))
{
continue;
......@@ -122,15 +145,19 @@ namespace VulnCrawler
continue;
}
if (Regex.Match(trim, $@"""[\s]*({methodName})").Success)
// 혹시 메서드가 문자열 사이에 있다면 넘어감..
if (Regex.Match(trim, $@"""[.]*({methodName})").Success)
{
continue;
}
// 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우
if (Regex.Match(trim, $@"{methodName}\s*" + @"\{").Success)
{
// 동시에 } 닫히기까지 한 경우 드물겠지만..
if (trim.EndsWith("}"))
{
oldBuilder.AppendLine(line);
break;
}
found2 = true;
......@@ -143,11 +170,13 @@ namespace VulnCrawler
}
}
Console.WriteLine("찾음");
Console.WriteLine(oldBuilder.ToString());
Console.ReadLine();
return oldBuilder.ToString();
}
}
}
......
......@@ -108,10 +108,13 @@ namespace VulnCrawler
{
var match = reg as Match;
string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
int start = int.Parse(match.Groups[VulnAbstractCrawler.OldStart].Value);
Console.WriteLine("methodName = " + methodName);
string originalFunc, md5;
(originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
methodName);
methodName, start);
#region 현재 패치 엔트리 정보 출력(추가된 , 삭제된 , 패치 이전 경로, 패치 경로)
......