노현종

ExtractGitCriticalMethodTable 추가

변경된 메서드와 변경된 코드 라인 그리고 각 라인에서 메서드-크리티컬 변수 딕셔너리 맵핑
...@@ -67,6 +67,7 @@ namespace VulnCrawler ...@@ -67,6 +67,7 @@ namespace VulnCrawler
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();
72 var fields = c.ExtractCriticalVariant(@"if (s->session->peer != s->session->sess_cert->peer_key->x509)"); 73 var fields = c.ExtractCriticalVariant(@"if (s->session->peer != s->session->sess_cert->peer_key->x509)");
......
...@@ -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,20 +24,16 @@ namespace VulnCrawler ...@@ -25,20 +24,16 @@ 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
...@@ -46,13 +41,11 @@ namespace VulnCrawler ...@@ -46,13 +41,11 @@ namespace VulnCrawler
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():
...@@ -114,7 +106,10 @@ namespace VulnCrawler ...@@ -114,7 +106,10 @@ namespace VulnCrawler
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,78 @@ namespace VulnCrawler ...@@ -31,13 +32,78 @@ 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 + var split = Regex.Split(srcCode, "\n").SkipWhile(s => !s.StartsWith("@@")).ToArray();
41 + for(int i = 0; i < split.Length; i++)
42 + {
43 + string line = split[i].Trim();
44 +
45 + line = Regex.Replace(line, @""".+""", "");
46 +
47 + var methodMatch = extractMethodLine.Match(line);
48 + string methodName = methodMatch.Groups[MethodName].Value.Trim();
49 + // 추가된, 제거된 라인인지 확인
50 + if (Regex.IsMatch(line, @"^[+-]\s"))
51 + {
52 + // 주석문인지 확인
53 + if (Regex.IsMatch(line, @"^[+-]\s*(\*|\/\*|\*\/)"))
54 + {
55 + continue;
56 + }
57 + Console.WriteLine(line);
58 + builder.AppendLine(line);
59 + continue;
60 + }
61 + // 메서드 매칭이 성공했거나 마지막 문단일 경우
62 + if (methodMatch.Success || i == split.Length - 1)
63 + {
64 + if (string.IsNullOrWhiteSpace(prevMethodName))
65 + {
66 + builder.Clear();
67 + prevMethodName = methodName;
68 + continue;
69 + }
70 + if (methodName.Contains("return"))
71 + {
72 + continue;
73 + }
74 + if (methodName.Contains("="))
75 + {
76 + continue;
77 + }
78 + if (!table.ContainsKey(prevMethodName))
79 + {
80 + table[prevMethodName] = new HashSet<string>();
81 + }
82 + var list = table[prevMethodName] as HashSet<string>;
83 + foreach (var b in Regex.Split(builder.ToString(), "\n"))
84 + {
85 + // 각 수집된 라인 별로 크리티컬 변수 선정
86 + foreach (var var in ExtractCriticalVariant(b))
87 + {
88 + if (string.IsNullOrWhiteSpace(var))
89 + {
90 + continue;
91 + }
92 + list.Add(var);
93 + }
94 + }
95 + prevMethodName = methodName;
96 + builder.Clear();
97 + }
98 + }
99 + return table;
100 + }
101 +
34 protected override string GetOriginalFunc(Stream oldStream, string methodName) { 102 protected override string GetOriginalFunc(Stream oldStream, string methodName) {
35 StringBuilder oldBuilder = new StringBuilder(); 103 StringBuilder oldBuilder = new StringBuilder();
36 - methodName = Regex.Escape(methodName);
37 - using (var reader = new StreamReader(oldStream)) {
38 - Console.WriteLine(methodName);
39 -
40 104
105 + string method = Regex.Escape(methodName);
106 + using (var reader = new StreamReader(oldStream)) {
41 bool found = false; 107 bool found = false;
42 bool found2 = false; 108 bool found2 = false;
43 bool commentLine = false; 109 bool commentLine = false;
...@@ -131,7 +197,7 @@ namespace VulnCrawler ...@@ -131,7 +197,7 @@ namespace VulnCrawler
131 else 197 else
132 { 198 {
133 // 메서드 찾았는지 확인 199 // 메서드 찾았는지 확인
134 - if (Regex.Match(line, $"{methodName}").Success) 200 + if (Regex.Match(line, $"{method}").Success)
135 { 201 {
136 string trim = line.Trim(); 202 string trim = line.Trim();
137 // 주석으로 시작했다면 넘어감 203 // 주석으로 시작했다면 넘어감
...@@ -146,13 +212,13 @@ namespace VulnCrawler ...@@ -146,13 +212,13 @@ namespace VulnCrawler
146 } 212 }
147 213
148 // 혹시 메서드가 문자열 사이에 있다면 넘어감.. 214 // 혹시 메서드가 문자열 사이에 있다면 넘어감..
149 - if (Regex.Match(trim, $@"""[.]*({methodName})").Success) 215 + if (Regex.Match(trim, $@"""[.]*({method})").Success)
150 { 216 {
151 continue; 217 continue;
152 } 218 }
153 219
154 // 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우 220 // 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우
155 - if (Regex.Match(trim, $@"{methodName}\s*" + @"\{").Success) 221 + if (Regex.Match(trim, $@"{method}\s*" + @"\{").Success)
156 { 222 {
157 // 동시에 } 닫히기까지 한 경우 드물겠지만.. 223 // 동시에 } 닫히기까지 한 경우 드물겠지만..
158 if (trim.EndsWith("}")) 224 if (trim.EndsWith("}"))
...@@ -170,8 +236,8 @@ namespace VulnCrawler ...@@ -170,8 +236,8 @@ namespace VulnCrawler
170 } 236 }
171 237
172 } 238 }
173 - Console.WriteLine(oldBuilder.ToString()); 239 + //Console.WriteLine(oldBuilder.ToString());
174 - Console.ReadLine(); 240 + //Console.ReadLine();
175 241
176 return oldBuilder.ToString(); 242 return oldBuilder.ToString();
177 } 243 }
......
...@@ -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;
......