노현종

C언어 GetCriticalBlocks 크리티컬 블록 완성

코드 block별로 크리티컬과 넌크리티컬 완벽히 나눠짐
...@@ -10,9 +10,18 @@ using System.Threading.Tasks; ...@@ -10,9 +10,18 @@ using System.Threading.Tasks;
10 10
11 namespace VulnCrawler 11 namespace VulnCrawler
12 { 12 {
13 +
13 // 추상 클래스 14 // 추상 클래스
14 public abstract class VulnAbstractCrawler 15 public abstract class VulnAbstractCrawler
15 { 16 {
17 + public class Block
18 + {
19 + public int Num { get; set; }
20 + public bool HasCritical { get; set; }
21 + public string Code { get; set; }
22 + public string Hash { get; set; }
23 +
24 + }
16 protected Regex extractMethodLine; 25 protected Regex extractMethodLine;
17 protected HashSet<string> ReservedList { get; } 26 protected HashSet<string> ReservedList { get; }
18 protected abstract string ReservedFileName { get; } 27 protected abstract string ReservedFileName { get; }
...@@ -106,7 +115,7 @@ namespace VulnCrawler ...@@ -106,7 +115,7 @@ namespace VulnCrawler
106 /// <returns>함수 문자열</returns> 115 /// <returns>함수 문자열</returns>
107 protected abstract string GetOriginalFunc(Stream oldStream, string methodName); 116 protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
108 117
109 - protected abstract IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList); 118 + protected abstract IList<Block> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList);
110 /// <summary> 119 /// <summary>
111 /// 성능 개선을 위한 120 /// 성능 개선을 위한
112 /// 코드 라인 위치 기반 취약 원본 함수 추출 테스트용 함수 곧 삭제 예정 121 /// 코드 라인 위치 기반 취약 원본 함수 추출 테스트용 함수 곧 삭제 예정
...@@ -226,13 +235,14 @@ namespace VulnCrawler ...@@ -226,13 +235,14 @@ namespace VulnCrawler
226 235
227 236
228 public abstract IDictionary<string, IEnumerable<string>> ExtractGitCriticalMethodTable(string srcCode); 237 public abstract IDictionary<string, IEnumerable<string>> ExtractGitCriticalMethodTable(string srcCode);
238 +
229 /// <summary> 239 /// <summary>
230 - /// 실제 프로세스 240 + /// 패치 전 코드 파일과 크리티컬 메서드 테이블로 부터 크리티컬 블록 추출
231 /// </summary> 241 /// </summary>
232 - /// <param name="oldStream"></param> 242 + /// <param name="oldBlob">패치 전 파일 Blob</param>
233 - /// <param name="methodName"></param> 243 + /// <param name="table">크리티컬 메서드 테이블(Key: 메서드 이름, Value: 변수 리스트)</param>
234 /// <returns></returns> 244 /// <returns></returns>
235 - public virtual IEnumerable<(string originalFunc, string hash)> Process(Blob oldBlob, IDictionary<string, IEnumerable<string>> table) { 245 + public virtual IEnumerable<(string methodName, IList<Block> blocks)> Process(Blob oldBlob, IDictionary<string, IEnumerable<string>> table) {
236 foreach (var item in table) 246 foreach (var item in table)
237 { 247 {
238 string methodName = item.Key; 248 string methodName = item.Key;
...@@ -243,21 +253,23 @@ namespace VulnCrawler ...@@ -243,21 +253,23 @@ namespace VulnCrawler
243 Console.WriteLine(func); 253 Console.WriteLine(func);
244 string bs = string.Empty; 254 string bs = string.Empty;
245 string md5 = string.Empty; 255 string md5 = string.Empty;
246 - int blockNum = 1;
247 if (item.Value.Count() != 0) 256 if (item.Value.Count() != 0)
248 { 257 {
249 - var blocks = GetCriticalBlocks(func, item.Value); 258 + // 크리티컬 블록 추출
250 - StringBuilder builder = new StringBuilder(); 259 + var blocks = GetCriticalBlocks(func, item.Value).ToList();
260 + if (blocks == null)
261 + {
262 + continue;
263 + }
264 +
251 foreach (var block in blocks) 265 foreach (var block in blocks)
252 { 266 {
253 - Console.WriteLine($"=====block({blockNum})"); 267 + block.Hash = MD5HashFunc(block.Code);
254 - Console.WriteLine(block);
255 - builder.AppendLine(block);
256 } 268 }
257 - bs = builder.ToString(); 269 +
258 - md5 = MD5HashFunc(bs); 270 + yield return (methodName, blocks);
259 } 271 }
260 - yield return (bs, md5); 272 +
261 } 273 }
262 } 274 }
263 /// <summary> 275 /// <summary>
...@@ -274,7 +286,6 @@ namespace VulnCrawler ...@@ -274,7 +286,6 @@ namespace VulnCrawler
274 /// <returns>커밋 목록</returns> 286 /// <returns>커밋 목록</returns>
275 public virtual IEnumerable<Commit> SearchCommits() { 287 public virtual IEnumerable<Commit> SearchCommits() {
276 // where => 조건에 맞는 것을 찾음(CVE-20\d\d-\d{4}로 시작하는 커밋만 골라냄) 288 // where => 조건에 맞는 것을 찾음(CVE-20\d\d-\d{4}로 시작하는 커밋만 골라냄)
277 - Console.WriteLine("출력중");
278 Console.WriteLine(Repository.Commits.Count()); 289 Console.WriteLine(Repository.Commits.Count());
279 var commits = Repository.Commits 290 var commits = Repository.Commits
280 .Where(c => Regex.Match(c.Message, SearchCommitPattern, RegexOptions.IgnoreCase).Success) 291 .Where(c => Regex.Match(c.Message, SearchCommitPattern, RegexOptions.IgnoreCase).Success)
......
...@@ -227,11 +227,11 @@ namespace VulnCrawler ...@@ -227,11 +227,11 @@ namespace VulnCrawler
227 return oldBuilder.ToString(); 227 return oldBuilder.ToString();
228 } 228 }
229 229
230 - protected override IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList) 230 + protected override IList<Block> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList)
231 { 231 {
232 var split = srcCode.Split('\n'); 232 var split = srcCode.Split('\n');
233 int bracketCount = 0; 233 int bracketCount = 0;
234 - var blockList = new List<string>(); 234 + var blockList = new List<Block>();
235 StringBuilder builder = new StringBuilder(); 235 StringBuilder builder = new StringBuilder();
236 var crList = criticalList as HashSet<string>; 236 var crList = criticalList as HashSet<string>;
237 if (crList == null) 237 if (crList == null)
...@@ -239,6 +239,8 @@ namespace VulnCrawler ...@@ -239,6 +239,8 @@ namespace VulnCrawler
239 return null; 239 return null;
240 } 240 }
241 bool mainLine = true; /* 현재 라인이 메인 코드 라인인지 */ 241 bool mainLine = true; /* 현재 라인이 메인 코드 라인인지 */
242 + bool criticalBlock = false; /* 현재 라인이 메인 코드 라인인지 */
243 + int blockNum = 1; /* 현재 라인이 메인 코드 라인인지 */
242 foreach (var line in split) 244 foreach (var line in split)
243 { 245 {
244 string trim = line.Trim(); 246 string trim = line.Trim();
...@@ -248,6 +250,11 @@ namespace VulnCrawler ...@@ -248,6 +250,11 @@ namespace VulnCrawler
248 int subtract = openBracketCount - closeBracketCount; 250 int subtract = openBracketCount - closeBracketCount;
249 bracketCount += subtract; 251 bracketCount += subtract;
250 252
253 + if (trim.Equals("}"))
254 + {
255 + builder.AppendLine(line);
256 + continue;
257 + }
251 /* 중괄호 연산 결과 1이라는 것은 메인 라인 */ 258 /* 중괄호 연산 결과 1이라는 것은 메인 라인 */
252 if (bracketCount == 1) 259 if (bracketCount == 1)
253 { 260 {
...@@ -261,7 +268,9 @@ namespace VulnCrawler ...@@ -261,7 +268,9 @@ namespace VulnCrawler
261 string s = builder.ToString(); 268 string s = builder.ToString();
262 if (!string.IsNullOrWhiteSpace(s)) 269 if (!string.IsNullOrWhiteSpace(s))
263 { 270 {
264 - blockList.Add(s); 271 + blockList.Add(new Block() { HasCritical = criticalBlock, Code = s, Num = blockNum });
272 + blockNum++;
273 + criticalBlock = false;
265 builder.Clear(); 274 builder.Clear();
266 } 275 }
267 } 276 }
...@@ -280,7 +289,9 @@ namespace VulnCrawler ...@@ -280,7 +289,9 @@ namespace VulnCrawler
280 string s = builder.ToString(); 289 string s = builder.ToString();
281 if (!string.IsNullOrWhiteSpace(s)) 290 if (!string.IsNullOrWhiteSpace(s))
282 { 291 {
283 - blockList.Add(s); 292 + blockList.Add(new Block() { HasCritical = criticalBlock, Code = s, Num = blockNum });
293 + blockNum++;
294 + criticalBlock = false;
284 builder.Clear(); 295 builder.Clear();
285 } 296 }
286 } 297 }
...@@ -291,19 +302,31 @@ namespace VulnCrawler ...@@ -291,19 +302,31 @@ namespace VulnCrawler
291 { 302 {
292 continue; 303 continue;
293 } 304 }
294 -
295 /* 현재 코드 라인에서 변수 추출시켜서 크리티컬 리스트와 대조 */ 305 /* 현재 코드 라인에서 변수 추출시켜서 크리티컬 리스트와 대조 */
296 foreach (var var in ExtractCriticalVariant(line)) 306 foreach (var var in ExtractCriticalVariant(line))
297 { 307 {
298 /* 크리티컬 리스트에 추출한 변수가 들어있다면 추가 */ 308 /* 크리티컬 리스트에 추출한 변수가 들어있다면 추가 */
299 if (criticalList.Contains(var)) 309 if (criticalList.Contains(var))
300 { 310 {
301 - builder.AppendLine(line); 311 + criticalBlock = true;
302 break; 312 break;
303 } 313 }
304 } 314 }
305 315
316 + builder.AppendLine(line);
317 +
306 } 318 }
319 +
320 + /* 마지막 남은게 있을 수 있으니 추가 */
321 + string fs = builder.ToString();
322 + if (!string.IsNullOrWhiteSpace(fs))
323 + {
324 + blockList.Add(new Block() { HasCritical = criticalBlock, Code = fs, Num = blockNum });
325 + blockNum++;
326 + criticalBlock = false;
327 + builder.Clear();
328 + }
329 +
307 return blockList; 330 return blockList;
308 } 331 }
309 } 332 }
......
...@@ -71,7 +71,7 @@ namespace VulnCrawler ...@@ -71,7 +71,7 @@ namespace VulnCrawler
71 throw new NotImplementedException(); 71 throw new NotImplementedException();
72 } 72 }
73 73
74 - protected override IList<string> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList) 74 + protected override IList<Block> GetCriticalBlocks(string srcCode, IEnumerable<string> criticalList)
75 { 75 {
76 throw new NotImplementedException(); 76 throw new NotImplementedException();
77 } 77 }
......
...@@ -89,15 +89,26 @@ namespace VulnCrawler ...@@ -89,15 +89,26 @@ namespace VulnCrawler
89 Console.ResetColor(); 89 Console.ResetColor();
90 90
91 var table = self.ExtractGitCriticalMethodTable(entry.Patch); 91 var table = self.ExtractGitCriticalMethodTable(entry.Patch);
92 - string originalFunc = string.Empty, md5 = string.Empty; 92 +
93 foreach (var tuple in self.Process(oldBlob, table)) 93 foreach (var tuple in self.Process(oldBlob, table))
94 { 94 {
95 - Console.WriteLine("===z"); 95 + (var methodName, var blocks) = tuple;
96 - (originalFunc, md5) = tuple; 96 +
97 - // 패치 전 원본 함수 97 + foreach (var block in blocks)
98 - Console.WriteLine($"Original Func: {originalFunc}"); 98 + {
99 - // 해쉬 후 99 + if (block.HasCritical)
100 - Console.WriteLine($"Original Func MD5: {md5}"); 100 + {
101 + Console.BackgroundColor = ConsoleColor.DarkMagenta;
102 + }
103 + else
104 + {
105 + Console.BackgroundColor = ConsoleColor.DarkGreen;
106 + }
107 + Console.WriteLine($"=====block({block.Num}, {block.HasCritical.ToString()})");
108 + Console.WriteLine(block.Code);
109 + Console.ResetColor();
110 + Console.WriteLine($"MD5 = {block.Hash}");
111 + }
101 112
102 } 113 }
103 114
......