노현종

ExtractGitCriticalMethodTable 추가

변경된 메서드와 변경된 코드 라인 그리고 각 라인에서 메서드-크리티컬 변수 딕셔너리 맵핑
...@@ -66,6 +66,7 @@ namespace VulnCrawler ...@@ -66,6 +66,7 @@ namespace VulnCrawler
66 } 66 }
67 public static void Run() { 67 public static void Run() {
68 // Repository 폴더들이 있는 주소를 지정하면 하위 폴더 목록을 가져옴(Repository 목록) 68 // Repository 폴더들이 있는 주소를 지정하면 하위 폴더 목록을 가져옴(Repository 목록)
69 +
69 70
70 // var fields = VulnWorker.GetCriticalVariant(@"return _is_safe_url(url, host) and _is_safe_url(url.replace('\\', '/'), host)"); 71 // var fields = VulnWorker.GetCriticalVariant(@"return _is_safe_url(url, host) and _is_safe_url(url.replace('\\', '/'), host)");
71 var c = new VulnC(); 72 var c = new VulnC();
......
...@@ -13,11 +13,10 @@ namespace VulnCrawler ...@@ -13,11 +13,10 @@ namespace VulnCrawler
13 // 추상 클래스 13 // 추상 클래스
14 public abstract class VulnAbstractCrawler 14 public abstract class VulnAbstractCrawler
15 { 15 {
16 - 16 + protected Regex extractMethodLine;
17 protected HashSet<string> ReservedList { get; } 17 protected HashSet<string> ReservedList { get; }
18 protected abstract string ReservedFileName { get; } 18 protected abstract string ReservedFileName { get; }
19 // = { "if", "return", "break", "while", "typedef" }; 19 // = { "if", "return", "break", "while", "typedef" };
20 -
21 /// <summary> 20 /// <summary>
22 /// 생성자 21 /// 생성자
23 /// 경로를 입력받아서(path) 22 /// 경로를 입력받아서(path)
...@@ -25,34 +24,28 @@ namespace VulnCrawler ...@@ -25,34 +24,28 @@ namespace VulnCrawler
25 /// 커밋 목록을 검색함 24 /// 커밋 목록을 검색함
26 /// </summary> 25 /// </summary>
27 /// <param name="path"></param> 26 /// <param name="path"></param>
28 - public VulnAbstractCrawler() { 27 + public VulnAbstractCrawler()
28 + {
29 + extractMethodLine = new Regex(RegexFuncPattern);
29 ReservedList = new HashSet<string>(); 30 ReservedList = new HashSet<string>();
30 LoadReservedList(); 31 LoadReservedList();
31 -
32 } 32 }
33 -
34 -
35 // 소멸자 33 // 소멸자
36 ~VulnAbstractCrawler() { 34 ~VulnAbstractCrawler() {
37 -
38 Repository?.Dispose(); 35 Repository?.Dispose();
39 -
40 } 36 }
41 -
42 private void LoadReservedList() 37 private void LoadReservedList()
43 { 38 {
44 try 39 try
45 { 40 {
46 var lines = File.ReadLines(ReservedFileName, Encoding.Default); 41 var lines = File.ReadLines(ReservedFileName, Encoding.Default);
47 foreach (var item in lines) 42 foreach (var item in lines)
48 - { 43 + {
49 -
50 if (string.IsNullOrWhiteSpace(item)) 44 if (string.IsNullOrWhiteSpace(item))
51 { 45 {
52 continue; 46 continue;
53 } 47 }
54 - ReservedList.Add(item); 48 + ReservedList.Add(item);
55 -
56 } 49 }
57 } 50 }
58 catch(FileNotFoundException) 51 catch(FileNotFoundException)
...@@ -61,7 +54,6 @@ namespace VulnCrawler ...@@ -61,7 +54,6 @@ namespace VulnCrawler
61 } 54 }
62 } 55 }
63 protected virtual Regex MethodExtractor => new Regex(RegexFuncPattern); 56 protected virtual Regex MethodExtractor => new Regex(RegexFuncPattern);
64 -
65 #region 메서드 패턴 정규식 그룹 57 #region 메서드 패턴 정규식 그룹
66 // 정규식 그룹화 58 // 정규식 그룹화
67 // @@ -oldStart,oldLines +newStart,newLines @@ MethodName(): 59 // @@ -oldStart,oldLines +newStart,newLines @@ MethodName():
...@@ -112,9 +104,12 @@ namespace VulnCrawler ...@@ -112,9 +104,12 @@ namespace VulnCrawler
112 /// <param name="oldStream">파일 스트림</param> 104 /// <param name="oldStream">파일 스트림</param>
113 /// <param name="methodName">찾을 메서드 이름</param> 105 /// <param name="methodName">찾을 메서드 이름</param>
114 /// <returns>함수 문자열</returns> 106 /// <returns>함수 문자열</returns>
115 - protected abstract string GetOriginalFunc(Stream oldStream, string methodName); 107 + protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
116 - 108 +
117 - // 테스트용 함수 곧 삭제될 운명 109 + /// <summary>
110 + /// 성능 개선을 위한
111 + /// 코드 라인 위치 기반 취약 원본 함수 추출 테스트용 함수 곧 삭제 예정
112 + /// </summary>
118 public string GetOriginalFuncTest(Stream oldStream, string methodName, int start) 113 public string GetOriginalFuncTest(Stream oldStream, string methodName, int start)
119 { 114 {
120 StringBuilder oldBuilder = new StringBuilder(); 115 StringBuilder oldBuilder = new StringBuilder();
...@@ -227,6 +222,9 @@ namespace VulnCrawler ...@@ -227,6 +222,9 @@ namespace VulnCrawler
227 222
228 return oldBuilder.ToString(); 223 return oldBuilder.ToString();
229 } 224 }
225 +
226 +
227 + public abstract IDictionary<string, IEnumerable<string>> ExtractGitCriticalMethodTable(string srcCode);
230 /// <summary> 228 /// <summary>
231 /// 실제 프로세스 229 /// 실제 프로세스
232 /// </summary> 230 /// </summary>
...@@ -237,9 +235,10 @@ namespace VulnCrawler ...@@ -237,9 +235,10 @@ namespace VulnCrawler
237 // 패치 전 원본 함수 구하고 235 // 패치 전 원본 함수 구하고
238 string func = GetOriginalFunc(oldStream, methodName); 236 string func = GetOriginalFunc(oldStream, methodName);
239 // 주석 제거하고 237 // 주석 제거하고
240 - // func = RemoveComment(func); 238 + //func = RemoveComment(func);
241 // 해쉬하고 239 // 해쉬하고
242 string md5 = MD5HashFunc(func); 240 string md5 = MD5HashFunc(func);
241 + // 튜플로 반환
243 return (func, md5); 242 return (func, md5);
244 } 243 }
245 /// <summary> 244 /// <summary>
...@@ -332,11 +331,11 @@ namespace VulnCrawler ...@@ -332,11 +331,11 @@ namespace VulnCrawler
332 var method = met as Match; 331 var method = met as Match;
333 if (method.Success) 332 if (method.Success)
334 { 333 {
335 - Console.WriteLine(method.Groups[1].Value); 334 + // Console.WriteLine(method.Groups[1].Value);
336 methodSets.Add(method.Groups[1].Value); // aaaa 335 methodSets.Add(method.Groups[1].Value); // aaaa
337 } 336 }
338 } 337 }
339 - Console.WriteLine("----"); 338 + // Console.WriteLine("----");
340 var vars = Regex.Matches(line, fieldPattern) 339 var vars = Regex.Matches(line, fieldPattern)
341 .Cast<Match>() 340 .Cast<Match>()
342 .Where(m => { 341 .Where(m => {
...@@ -359,6 +358,12 @@ namespace VulnCrawler ...@@ -359,6 +358,12 @@ namespace VulnCrawler
359 { 358 {
360 return false; 359 return false;
361 } 360 }
361 +
362 + /* 알파벳이 하나도 없으면 넘어감 */
363 + if(!m.Value.Any(c => char.IsLetter(c)))
364 + {
365 + return false;
366 + }
362 return true; 367 return true;
363 }) 368 })
364 .Distinct(new MatchComparer()); 369 .Distinct(new MatchComparer());
......
...@@ -10,7 +10,8 @@ namespace VulnCrawler ...@@ -10,7 +10,8 @@ namespace VulnCrawler
10 { 10 {
11 public class VulnC : VulnAbstractCrawler 11 public class VulnC : VulnAbstractCrawler
12 { 12 {
13 - protected override string RegexFuncPattern => $@"@@ \-(?<{OldStart}>\d+),(?<{OldLines}>\d+) \+(?<{NewStart}>\d+),(?<{NewLines}>\d+) @@ (?<{MethodName}>(static)?( const )? [\w]+ [\w]+\([\w \*\,\t\n]*[\)\,])"; 13 +// protected override string RegexFuncPattern => $@"@@ \-(?<{OldStart}>\d+),(?<{OldLines}>\d+) \+(?<{NewStart}>\d+),(?<{NewLines}>\d+) @@ (?<{MethodName}>(static)?( const )? [\w]+ [\w]+\([\w \*\,\t\n]*[\)\,])";
14 + protected override string RegexFuncPattern => $@"(?<{MethodName}>(unsigned|static)?( const )? [\w]+ [\w]+\(([\w \*\,\t\n])*[\)\,])";
14 protected override string Extension => ".c"; 15 protected override string Extension => ".c";
15 protected override string ReservedFileName => "CReserved.txt"; 16 protected override string ReservedFileName => "CReserved.txt";
16 public override MatchCollection GetMatches(string patchCode) { 17 public override MatchCollection GetMatches(string patchCode) {
...@@ -31,13 +32,79 @@ namespace VulnCrawler ...@@ -31,13 +32,79 @@ namespace VulnCrawler
31 return replace; 32 return replace;
32 } 33 }
33 34
35 + public override IDictionary<string, IEnumerable<string>> ExtractGitCriticalMethodTable(string srcCode)
36 + {
37 + var table = new Dictionary<string, IEnumerable<string>>();
38 + string prevMethodName = string.Empty;
39 + StringBuilder builder = new StringBuilder();
40 + // 라인으로 나누고 @@가 시작하는 곳까지 생략
41 + var split = Regex.Split(srcCode, "\n").SkipWhile(s => !s.StartsWith("@@")).ToArray();
42 + for(int i = 0; i < split.Length; i++)
43 + {
44 + string line = split[i].Trim();
45 + // 문자열 제거
46 + line = Regex.Replace(line, @""".+""", "");
47 +
48 + var methodMatch = extractMethodLine.Match(line);
49 + string methodName = methodMatch.Groups[MethodName].Value.Trim();
50 + // 추가된, 제거된 라인인지 확인
51 + if (Regex.IsMatch(line, @"^[+-]\s"))
52 + {
53 + // 주석문인지 확인
54 + if (Regex.IsMatch(line, @"^[+-]\s*(\*|\/\*|\*\/)"))
55 + {
56 + continue;
57 + }
58 + Console.WriteLine(line);
59 + builder.AppendLine(line);
60 + continue;
61 + }
62 + // 메서드 매칭이 성공했거나 마지막 문단일 경우
63 + if (methodMatch.Success || i == split.Length - 1)
64 + {
65 + if (string.IsNullOrWhiteSpace(prevMethodName))
66 + {
67 + builder.Clear();
68 + prevMethodName = methodName;
69 + continue;
70 + }
71 + if (methodName.Contains("return"))
72 + {
73 + continue;
74 + }
75 + if (methodName.Contains("="))
76 + {
77 + continue;
78 + }
79 + if (!table.ContainsKey(prevMethodName))
80 + {
81 + table[prevMethodName] = new HashSet<string>();
82 + }
83 + var list = table[prevMethodName] as HashSet<string>;
84 + foreach (var b in Regex.Split(builder.ToString(), "\n"))
85 + {
86 + // 각 수집된 라인 별로 크리티컬 변수 선정
87 + foreach (var var in ExtractCriticalVariant(b))
88 + {
89 + if (string.IsNullOrWhiteSpace(var))
90 + {
91 + continue;
92 + }
93 + list.Add(var);
94 + }
95 + }
96 + prevMethodName = methodName;
97 + builder.Clear();
98 + }
99 + }
100 + return table;
101 + }
102 +
34 protected override string GetOriginalFunc(Stream oldStream, string methodName) { 103 protected override string GetOriginalFunc(Stream oldStream, string methodName) {
35 StringBuilder oldBuilder = new StringBuilder(); 104 StringBuilder oldBuilder = new StringBuilder();
36 - methodName = Regex.Escape(methodName);
37 - using (var reader = new StreamReader(oldStream)) {
38 - Console.WriteLine(methodName);
39 -
40 105
106 + string method = Regex.Escape(methodName);
107 + using (var reader = new StreamReader(oldStream)) {
41 bool found = false; 108 bool found = false;
42 bool found2 = false; 109 bool found2 = false;
43 bool commentLine = false; 110 bool commentLine = false;
...@@ -131,7 +198,7 @@ namespace VulnCrawler ...@@ -131,7 +198,7 @@ namespace VulnCrawler
131 else 198 else
132 { 199 {
133 // 메서드 찾았는지 확인 200 // 메서드 찾았는지 확인
134 - if (Regex.Match(line, $"{methodName}").Success) 201 + if (Regex.Match(line, $"{method}").Success)
135 { 202 {
136 string trim = line.Trim(); 203 string trim = line.Trim();
137 // 주석으로 시작했다면 넘어감 204 // 주석으로 시작했다면 넘어감
...@@ -146,13 +213,13 @@ namespace VulnCrawler ...@@ -146,13 +213,13 @@ namespace VulnCrawler
146 } 213 }
147 214
148 // 혹시 메서드가 문자열 사이에 있다면 넘어감.. 215 // 혹시 메서드가 문자열 사이에 있다면 넘어감..
149 - if (Regex.Match(trim, $@"""[.]*({methodName})").Success) 216 + if (Regex.Match(trim, $@"""[.]*({method})").Success)
150 { 217 {
151 continue; 218 continue;
152 } 219 }
153 220
154 // 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우 221 // 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우
155 - if (Regex.Match(trim, $@"{methodName}\s*" + @"\{").Success) 222 + if (Regex.Match(trim, $@"{method}\s*" + @"\{").Success)
156 { 223 {
157 // 동시에 } 닫히기까지 한 경우 드물겠지만.. 224 // 동시에 } 닫히기까지 한 경우 드물겠지만..
158 if (trim.EndsWith("}")) 225 if (trim.EndsWith("}"))
...@@ -170,8 +237,8 @@ namespace VulnCrawler ...@@ -170,8 +237,8 @@ namespace VulnCrawler
170 } 237 }
171 238
172 } 239 }
173 - Console.WriteLine(oldBuilder.ToString()); 240 + //Console.WriteLine(oldBuilder.ToString());
174 - Console.ReadLine(); 241 + //Console.ReadLine();
175 242
176 return oldBuilder.ToString(); 243 return oldBuilder.ToString();
177 } 244 }
......
...@@ -65,5 +65,10 @@ namespace VulnCrawler ...@@ -65,5 +65,10 @@ namespace VulnCrawler
65 } 65 }
66 return replace; 66 return replace;
67 } 67 }
68 +
69 + public override IDictionary<string, IEnumerable<string>> ExtractGitCriticalMethodTable(string srcCode)
70 + {
71 + throw new NotImplementedException();
72 + }
68 } 73 }
69 } 74 }
......
...@@ -84,17 +84,24 @@ namespace VulnCrawler ...@@ -84,17 +84,24 @@ namespace VulnCrawler
84 Console.ForegroundColor = ConsoleColor.Yellow; 84 Console.ForegroundColor = ConsoleColor.Yellow;
85 Console.WriteLine($"Commit Message: {commitMsg}"); 85 Console.WriteLine($"Commit Message: {commitMsg}");
86 Console.ResetColor(); 86 Console.ResetColor();
87 -
88 -
89 -
90 Console.BackgroundColor = ConsoleColor.DarkRed; 87 Console.BackgroundColor = ConsoleColor.DarkRed;
91 Console.WriteLine($"Patched: \n{entry.Patch}"); 88 Console.WriteLine($"Patched: \n{entry.Patch}");
92 -
93 Console.ResetColor(); 89 Console.ResetColor();
94 - // Console.WriteLine("-----------");
95 -
96 -
97 90
91 + var table = self.ExtractGitCriticalMethodTable(entry.Patch);
92 + foreach (var item in table)
93 + {
94 + Console.WriteLine($"Method : {item.Key}");
95 + foreach (var b in item.Value)
96 + {
97 + Console.WriteLine($"--{b}");
98 + }
99 + }
100 + Console.ReadLine();
101 + }
102 + else
103 + {
104 + continue;
98 } 105 }
99 106
100 107
...@@ -106,10 +113,11 @@ namespace VulnCrawler ...@@ -106,10 +113,11 @@ namespace VulnCrawler
106 113
107 foreach (var reg in regs) 114 foreach (var reg in regs)
108 { 115 {
116 +
109 var match = reg as Match; 117 var match = reg as Match;
110 string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim(); 118 string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
111 - int start = int.Parse(match.Groups[VulnAbstractCrawler.OldStart].Value); 119 + int start = 0; //int.Parse(match.Groups[VulnAbstractCrawler.OldStart].Value);
112 - Console.WriteLine("methodName = " + methodName); 120 + // Console.WriteLine("methodName = " + methodName);
113 string originalFunc, md5; 121 string originalFunc, md5;
114 (originalFunc, md5) = self.Process(oldBlob.GetContentStream(), 122 (originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
115 methodName, start); 123 methodName, start);
...@@ -127,14 +135,17 @@ namespace VulnCrawler ...@@ -127,14 +135,17 @@ namespace VulnCrawler
127 //Console.WriteLine($"Patched: \n{entry.Patch}"); 135 //Console.WriteLine($"Patched: \n{entry.Patch}");
128 136
129 Console.ResetColor(); 137 Console.ResetColor();
138 + Console.ForegroundColor = ConsoleColor.Red;
130 Console.WriteLine("=============================="); 139 Console.WriteLine("==============================");
131 - 140 + Console.ResetColor();
132 #endregion 141 #endregion
133 142
134 } 143 }
144 + Console.ReadLine();
135 } 145 }
136 catch (Exception e) 146 catch (Exception e)
137 { 147 {
148 + Console.WriteLine(entry.Patch);
138 Console.WriteLine(e.ToString()); 149 Console.WriteLine(e.ToString());
139 Console.ReadLine(); 150 Console.ReadLine();
140 continue; 151 continue;
......