노현종

Vuln 템플릿 메서드 패턴화, 클래스 정리

VulnC, VulnPython 분리
VulnAbstractCrawler 클래스에서 VulnWorker 클래스로 템플릿 메서드 패턴화를 위해 분리하였음.
작업 진행은 이제 VulnWorker의 Run을 실행하면 됨.
...@@ -8,7 +8,7 @@ using System.Text; ...@@ -8,7 +8,7 @@ using System.Text;
8 using System.Text.RegularExpressions; 8 using System.Text.RegularExpressions;
9 using System.Threading.Tasks; 9 using System.Threading.Tasks;
10 10
11 -using MySql.Data.MySqlClient; 11 +//using MySql.Data.MySqlClient;
12 using AESENC; 12 using AESENC;
13 using System.Security; 13 using System.Security;
14 using System.Runtime.InteropServices; 14 using System.Runtime.InteropServices;
...@@ -32,7 +32,7 @@ namespace VulnCrawler ...@@ -32,7 +32,7 @@ namespace VulnCrawler
32 //AWS.Account account = AWS.account; 32 //AWS.Account account = AWS.account;
33 33
34 //Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}"); 34 //Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}");
35 - 35 +
36 //MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder { 36 //MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder {
37 // Server = "", 37 // Server = "",
38 // UserID = id, 38 // UserID = id,
...@@ -44,9 +44,9 @@ namespace VulnCrawler ...@@ -44,9 +44,9 @@ namespace VulnCrawler
44 //string strConn = builder.ToString(); 44 //string strConn = builder.ToString();
45 //builder = null; 45 //builder = null;
46 //MySqlConnection conn = new MySqlConnection(strConn); 46 //MySqlConnection conn = new MySqlConnection(strConn);
47 - 47 +
48 //try { 48 //try {
49 - 49 +
50 // String sql = "INSERT INTO members (id, pwd, name) " + 50 // String sql = "INSERT INTO members (id, pwd, name) " +
51 // "VALUES ('gon', '111', '김삿갓')"; 51 // "VALUES ('gon', '111', '김삿갓')";
52 52
...@@ -59,10 +59,24 @@ namespace VulnCrawler ...@@ -59,10 +59,24 @@ namespace VulnCrawler
59 //} catch (Exception e) { 59 //} catch (Exception e) {
60 // Console.WriteLine(e.ToString()); 60 // Console.WriteLine(e.ToString());
61 //} 61 //}
62 - 62 +
63 Run(); 63 Run();
64 64
65 } 65 }
66 + public static void Run() {
67 + // Repository 폴더들이 있는 주소를 지정하면 하위 폴더 목록을 가져옴(Repository 목록)
68 + var directorys = Directory.GetDirectories(@"c:\VulnPy");
69 + if (directorys.Length == 0) {
70 + Console.WriteLine("Repository 목록 찾기 실패");
71 + return;
72 + }
73 + // Repository 목록 만큼 반복함.
74 + foreach (var directory in directorys) {
75 + VulnWorker.Run<VulnPython>(directory);
76 + }
77 + }
78 +
79 +
66 static String SecureStringToString(SecureString value) { 80 static String SecureStringToString(SecureString value) {
67 IntPtr valuePtr = IntPtr.Zero; 81 IntPtr valuePtr = IntPtr.Zero;
68 try { 82 try {
...@@ -90,106 +104,7 @@ namespace VulnCrawler ...@@ -90,106 +104,7 @@ namespace VulnCrawler
90 } 104 }
91 return pwd; 105 return pwd;
92 } 106 }
93 - public static void Run() { 107 +
94 - // Repository 폴더들이 있는 주소를 지정하면 하위 폴더 목록을 가져옴(Repository 목록)
95 - var directorys = Directory.GetDirectories(@"c:\VulnPy");
96 - if (directorys.Length == 0) {
97 - Console.WriteLine("Repository 목록 찾기 실패");
98 - return;
99 - }
100 - // Repository 목록 만큼 반복함.
101 - foreach (var directory in directorys) {
102 - var pyCrawl = new VulnPython(directory);
103 - var commits = pyCrawl.Commits;
104 -
105 -
106 - foreach (var commit in commits) {
107 - // 커밋 메시지
108 - string message = commit.Message;
109 - Console.ForegroundColor = ConsoleColor.Yellow;
110 - Console.WriteLine($"Commit Message: {message}");
111 - Console.ResetColor();
112 -
113 - foreach (var parent in commit.Parents) {
114 - // 부모 커밋과 현재 커밋을 Compare 하여 패치 내역을 가져옴
115 - var patch = pyCrawl.Repository.Diff.Compare<Patch>(parent.Tree, commit.Tree);
116 - // 패치 엔트리 파일 배열 중에 파일 확장자가 .py인 것만 가져옴
117 - // (실질적인 코드 변경 커밋만 보기 위해서)
118 - var entrys = pyCrawl.GetPatchEntryChanges(patch);
119 - // 현재 커밋에 대한 패치 엔트리 배열을 출력함
120 - PrintPatchEntrys(entrys, pyCrawl);
121 -
122 -
123 - }
124 - }
125 - }
126 - }
127 -
128 - public static void PrintPatchEntrys(IEnumerable<PatchEntryChanges> entrys, VulnAbstractCrawler pyCrawl) {
129 -
130 - foreach (var entry in entrys) {
131 -
132 - // 현재 패치 엔트리 정보 출력(추가된 줄 수, 삭제된 줄 수, 패치 이전 경로, 패치 후 경로)
133 - Console.ForegroundColor = ConsoleColor.Blue;
134 - Console.WriteLine($"status: {entry.Status.ToString()}");
135 - Console.WriteLine($"added: {entry.LinesAdded.ToString()}, deleted: {entry.LinesDeleted.ToString()}");
136 - Console.WriteLine($"old path: {entry.OldPath.ToString()}, new path: {entry.Path.ToString()}");
137 - Console.ResetColor();
138 -
139 - // 기존 소스코드
140 - var oldOid = entry.OldOid;
141 - Blob oldBlob = pyCrawl.Repository.Lookup<Blob>(oldOid);
142 - string oldContent = oldBlob.GetContentText();
143 -
144 - // 변경된 소스코드
145 - var newOid = entry.Oid;
146 - Blob newBlob = pyCrawl.Repository.Lookup<Blob>(newOid);
147 - string newContent = newBlob.GetContentText();
148 -
149 - var regs = pyCrawl.GetMatches(entry.Patch);
150 - // 패치 전 코드 (oldContent)
151 - // 패치 후 코드 (newContent)
152 - // 패치 코드 (entry.Patch)
153 - // 출력
154 - //if (regs.Count > 0) {
155 - // Console.BackgroundColor = ConsoleColor.DarkBlue;
156 - // Console.WriteLine($"Old Content: \n{oldContent}");
157 - // Console.ResetColor();
158 -
159 - // Console.BackgroundColor = ConsoleColor.DarkMagenta;
160 - // Console.WriteLine($"New Content: \n{newContent}");
161 - // Console.ResetColor();
162 - // Console.BackgroundColor = ConsoleColor.DarkRed;
163 - // Console.WriteLine($"Patched: \n{entry.Patch}");
164 -
165 - // Console.ResetColor();
166 - // Console.WriteLine("-----------");
167 - // Console.WriteLine(regs.Count);
168 -
169 - //}
170 -
171 - // 패치 코드에서 매칭된 파이썬 함수들로부터
172 - // 패치 전 코드 파일(oldBlob)을 탐색하여 원본 파이썬 함수 가져오고(originalFunc)
173 - //
174 - foreach (var reg in regs) {
175 - var match = reg as Match;
176 - string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value;
177 -
178 - string originalFunc, md5;
179 -
180 - (originalFunc, md5) = pyCrawl.GetPatchResult(oldBlob.GetContentStream(),
181 - match.Groups[VulnAbstractCrawler.MethodName].Value);
182 -
183 - // 패치 전 원본 함수
184 - Console.WriteLine($"Original Func: {originalFunc}");
185 - // 해쉬 후
186 - Console.WriteLine($"Original Func MD5: {md5}");
187 -
188 -
189 -
190 - }
191 - }
192 - }
193 108
194 /// <summary> 109 /// <summary>
195 /// 디렉토리 삭제 함수 110 /// 디렉토리 삭제 함수
...@@ -213,26 +128,7 @@ namespace VulnCrawler ...@@ -213,26 +128,7 @@ namespace VulnCrawler
213 Directory.Delete(targetDir, false); 128 Directory.Delete(targetDir, false);
214 } 129 }
215 130
216 - /// <summary>
217 - /// Clone 콜백 함수
218 - /// </summary>
219 - /// <param name="progress"></param>
220 - /// <returns></returns>
221 - public static bool TransferProgress(TransferProgress progress) {
222 - int totalBytes = progress.TotalObjects;
223 - int receivedBytes = progress.ReceivedObjects;
224 - long receivedTotal = progress.ReceivedBytes;
225 - double received = progress.ReceivedBytes / 1000000;
226 - double percent = ((double)receivedBytes / (double)totalBytes) * 10;
227 -
228 - Console.WriteLine($"진행률: {percent.ToString("P2")}, 남은 파일: {receivedBytes} of {totalBytes}"); //, 받은 용량: {received.ToString()}MB");
229 - Console.ForegroundColor = ConsoleColor.DarkGreen;
230 - return true;
231 - }
232 131
233 - public static void CheckoutProcess(string path, int completedSteps, int totalSteps) {
234 - Console.WriteLine($"{completedSteps}, {totalSteps}, {path}");
235 - }
236 132
237 133
238 } 134 }
......
1 +using LibGit2Sharp;
2 +using System;
3 +using System.Collections.Generic;
4 +using System.IO;
5 +using System.Linq;
6 +using System.Security.Cryptography;
7 +using System.Text;
8 +using System.Text.RegularExpressions;
9 +using System.Threading.Tasks;
10 +
11 +namespace VulnCrawler
12 +{
13 + // 추상 클래스
14 + public abstract class VulnAbstractCrawler
15 + {
16 + /// <summary>
17 + /// 생성자
18 + /// 경로를 입력받아서(path)
19 + /// 레파지토리를 초기화하고
20 + /// 커밋 목록을 검색함
21 + /// </summary>
22 + /// <param name="path"></param>
23 + public VulnAbstractCrawler() {
24 +
25 + }
26 +
27 + // 소멸자
28 + ~VulnAbstractCrawler() {
29 +
30 + Repository.Dispose();
31 + }
32 +
33 + #region 메서드 패턴 정규식 그룹
34 + // 정규식 그룹화
35 + // @@ -oldStart,oldLines +newStart,newLines @@ MethodName():
36 + public static string OldStart => "oldStart";
37 + public static string OldLines => "oldLines";
38 + public static string NewStart => "newStart";
39 + public static string NewLines => "newLines";
40 + public static string MethodName => "methodName";
41 + #endregion
42 +
43 + public void Init(string path) {
44 + Repository = new Repository(path);
45 + Commits = SearchCommits();
46 + }
47 + /// <summary>
48 + /// 레파지토리
49 + /// </summary>
50 + public Repository Repository { get; private set; }
51 +
52 + /// <summary>
53 + /// 커밋 목록
54 + /// </summary>
55 + public IEnumerable<Commit> Commits { get; private set; }
56 + /// <summary>
57 + /// 커밋에서 검색할 정규식 문자열
58 + /// </summary>
59 + public string SearchCommitPattern => @"CVE-20\d\d-\d{4}";
60 + /// <summary>
61 + /// 패치 코드에서 함수 찾을 정규식 패턴 문자열
62 + /// </summary>
63 + protected abstract string RegexFuncPattern { get; }
64 + protected abstract string Extension { get; }
65 + public virtual IEnumerable<PatchEntryChanges> GetPatchEntryChanges(Patch patch) {
66 + return patch.Where(e => e.Path.EndsWith(Extension)).ToList();
67 + }
68 + /// <summary>
69 + /// 정규식을 이용하여 @@ -\d,\d +\d,\d @@ MethodName(): 이런 패턴을 찾고
70 + /// 그룹화 하여 반환함 (OldStart, OldLines, NewStart, NewLines, MethodName
71 + /// </summary>
72 + /// <param name="patchCode">찾을 코드</param>
73 + /// <returns>정규식 그룹 컬렉션</returns>
74 + public abstract MatchCollection GetMatches(string patchCode);
75 + /// <summary>
76 + /// 파일스트림으로 부터 원본 함수 구하는 함수
77 + /// </summary>
78 + /// <param name="oldStream">파일 스트림</param>
79 + /// <param name="methodName">찾을 메서드 이름</param>
80 + /// <returns>함수 문자열</returns>
81 + protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
82 +
83 +
84 + /// <summary>
85 + /// 실제 프로세스
86 + /// </summary>
87 + /// <param name="oldStream"></param>
88 + /// <param name="methodName"></param>
89 + /// <returns></returns>
90 + public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName) {
91 + // 패치 전 원본 함수 구하고
92 + string func = GetOriginalFunc(oldStream, methodName);
93 + // 주석 제거하고
94 + func = RemoveComment(func);
95 + // 해쉬하고
96 + string md5 = MD5HashFunc(func);
97 + return (func, md5);
98 + }
99 + /// <summary>
100 + /// 주석 제거 함수
101 + /// </summary>
102 + /// <param name="original">제거할 문자열</param>
103 + /// <returns>결과 문자열</returns>
104 + public abstract string RemoveComment(string original);
105 +
106 + /// <summary>
107 + /// 커밋 검색 함수(정규식 사용)
108 + /// 정규식은 SearchKeyword 사용함
109 + /// </summary>
110 + /// <returns>커밋 목록</returns>
111 + public virtual IEnumerable<Commit> SearchCommits() {
112 + // where => 조건에 맞는 것을 찾음(CVE-20\d\d-\d{4}로 시작하는 커밋만 골라냄)
113 + var commits = Repository.Commits
114 + .Where(c => Regex.Match(c.Message, SearchCommitPattern, RegexOptions.IgnoreCase).Success)
115 + .ToList();
116 +
117 + return commits;
118 + }
119 +
120 + /// <summary>
121 + /// 커밋 메시지로부터 CVE 코드 추출
122 + /// </summary>
123 + /// <param name="msg"></param>
124 + /// <returns></returns>
125 + public string GetCVE(string msg) {
126 + var match = Regex.Match(msg, SearchCommitPattern, RegexOptions.IgnoreCase);
127 +
128 + if (match.Success) {
129 + return match.Value;
130 + }
131 + return string.Empty;
132 + }
133 + /// <summary>
134 + /// MD5 함수
135 + /// </summary>
136 + /// <param name="str">INPUT 문자열</param>
137 + /// <returns>결과 문자열</returns>
138 + protected static string MD5HashFunc(string str) {
139 + StringBuilder MD5Str = new StringBuilder();
140 + byte[] byteArr = Encoding.ASCII.GetBytes(str);
141 + byte[] resultArr = (new MD5CryptoServiceProvider()).ComputeHash(byteArr);
142 + for (int cnti = 0; cnti < resultArr.Length; cnti++) {
143 + MD5Str.Append(resultArr[cnti].ToString("X2"));
144 + }
145 + return MD5Str.ToString();
146 + }
147 +
148 + }
149 +}
1 +using System;
2 +using System.Collections.Generic;
3 +using System.IO;
4 +using System.Linq;
5 +using System.Text;
6 +using System.Text.RegularExpressions;
7 +using System.Threading.Tasks;
8 +
9 +namespace VulnCrawler
10 +{
11 + public class VulnC : VulnAbstractCrawler
12 + {
13 +
14 + protected override string RegexFuncPattern => throw new NotImplementedException();
15 +
16 + protected override string Extension => throw new NotImplementedException();
17 +
18 + public override MatchCollection GetMatches(string patchCode) {
19 + throw new NotImplementedException();
20 + }
21 +
22 + public override string RemoveComment(string original) {
23 + throw new NotImplementedException();
24 + }
25 +
26 + protected override string GetOriginalFunc(Stream oldStream, string methodName) {
27 + throw new NotImplementedException();
28 + }
29 + }
30 +}
...@@ -57,7 +57,10 @@ ...@@ -57,7 +57,10 @@
57 <Compile Include="AWS.cs" /> 57 <Compile Include="AWS.cs" />
58 <Compile Include="Program.cs" /> 58 <Compile Include="Program.cs" />
59 <Compile Include="Properties\AssemblyInfo.cs" /> 59 <Compile Include="Properties\AssemblyInfo.cs" />
60 + <Compile Include="VulnAbstractCrawler.cs" />
61 + <Compile Include="VulnC.cs" />
60 <Compile Include="VulnPython.cs" /> 62 <Compile Include="VulnPython.cs" />
63 + <Compile Include="VulnWorker.cs" />
61 </ItemGroup> 64 </ItemGroup>
62 <ItemGroup> 65 <ItemGroup>
63 <None Include="App.config" /> 66 <None Include="App.config" />
......
1 -using LibGit2Sharp; 1 +
2 using System; 2 using System;
3 using System.Collections.Generic; 3 using System.Collections.Generic;
4 using System.IO; 4 using System.IO;
5 using System.Linq; 5 using System.Linq;
6 -using System.Security.Cryptography;
7 using System.Text; 6 using System.Text;
8 using System.Text.RegularExpressions; 7 using System.Text.RegularExpressions;
9 using System.Threading.Tasks; 8 using System.Threading.Tasks;
10 -
11 namespace VulnCrawler 9 namespace VulnCrawler
12 { 10 {
13 - // 추상 클래스
14 - public abstract class VulnAbstractCrawler {
15 - /// <summary>
16 - /// 생성자
17 - /// 경로를 입력받아서(path)
18 - /// 레파지토리를 초기화하고
19 - /// 커밋 목록을 검색함
20 - /// </summary>
21 - /// <param name="path"></param>
22 - public VulnAbstractCrawler(string path) {
23 - Repository = new Repository(path);
24 - Commits = SearchCommits();
25 - }
26 -
27 - // 소멸자
28 - ~VulnAbstractCrawler() {
29 -
30 - Repository.Dispose();
31 - }
32 -
33 - // 정규식 그룹화
34 - // @@ -oldStart,oldLines +newStart,newLines @@ MethodName():
35 - public static string OldStart => "oldStart";
36 - public static string OldLines => "oldLines";
37 - public static string NewStart => "newStart";
38 - public static string NewLines => "newLines";
39 - public static string MethodName => "methodName";
40 -
41 -
42 - /// <summary>
43 - /// 레파지토리
44 - /// </summary>
45 - public Repository Repository { get; private set; }
46 -
47 - /// <summary>
48 - /// 커밋 목록
49 - /// </summary>
50 - public IEnumerable<Commit> Commits { get; private set; }
51 - /// <summary>
52 - /// 커밋에서 검색할 정규식 문자열
53 - /// </summary>
54 - protected string SearchKeyword => @"CVE-20\d\d-\d{4}";
55 - /// <summary>
56 - /// 패치 코드에서 함수 찾을 정규식 패턴 문자열
57 - /// </summary>
58 - protected abstract string RegexFuncPattern { get; }
59 - protected abstract string Extension { get; }
60 - public abstract IEnumerable<PatchEntryChanges> GetPatchEntryChanges(Patch patch);
61 - /// <summary>
62 - /// 정규식을 이용하여 @@ -\d,\d +\d,\d @@ MethodName(): 이런 패턴을 찾고
63 - /// 그룹화 하여 반환함 (OldStart, OldLines, NewStart, NewLines, MethodName
64 - /// </summary>
65 - /// <param name="patchCode">찾을 코드</param>
66 - /// <returns>정규식 그룹 컬렉션</returns>
67 - public abstract MatchCollection GetMatches(string patchCode);
68 - /// <summary>
69 - /// 파일스트림으로 부터 원본 함수 구하는 함수
70 - /// </summary>
71 - /// <param name="oldStream">파일 스트림</param>
72 - /// <param name="methodName">찾을 메서드 이름</param>
73 - /// <returns>함수 문자열</returns>
74 - protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
75 - public virtual (string originalFunc, string hash) GetPatchResult(Stream oldStream, string methodName) {
76 - // 패치 전 원본 함수 구하고
77 - string func = GetOriginalFunc(oldStream, methodName);
78 - // 주석 제거하고
79 - func = RemoveComment(func);
80 - Console.WriteLine(func);
81 - // 해쉬하고
82 - string md5 = MD5HashFunc(func);
83 - return (func, md5);
84 - }
85 - /// <summary>
86 - /// 주석 제거 함수
87 - /// </summary>
88 - /// <param name="original">제거할 문자열</param>
89 - /// <returns>결과 문자열</returns>
90 - public abstract string RemoveComment(string original);
91 -
92 - /// <summary>
93 - /// 커밋 검색 함수(정규식 사용)
94 - /// 정규식은 SearchKeyword 사용함
95 - /// </summary>
96 - /// <returns>커밋 목록</returns>
97 - public virtual IEnumerable<Commit> SearchCommits() {
98 - // where => 조건에 맞는 것을 찾음(CVE-20\d\d-\d{4}로 시작하는 커밋만 골라냄)
99 - var commits = Repository.Commits
100 - .Where(c => Regex.Match(c.Message, SearchKeyword, RegexOptions.IgnoreCase).Success)
101 - .ToList();
102 11
103 - return commits;
104 - }
105 -
106 - /// <summary>
107 - /// MD5 함수
108 - /// </summary>
109 - /// <param name="str">INPUT 문자열</param>
110 - /// <returns>결과 문자열</returns>
111 - protected static string MD5HashFunc(string str) {
112 - StringBuilder MD5Str = new StringBuilder();
113 - byte[] byteArr = Encoding.ASCII.GetBytes(str);
114 - byte[] resultArr = (new MD5CryptoServiceProvider()).ComputeHash(byteArr);
115 - for (int cnti = 0; cnti < resultArr.Length; cnti++) {
116 - MD5Str.Append(resultArr[cnti].ToString("X2"));
117 - }
118 - return MD5Str.ToString();
119 - }
120 -
121 - }
122 -
123 - public class VulnC : VulnAbstractCrawler
124 - {
125 - public VulnC(string path) : base(path) {
126 -
127 - }
128 12
129 - protected override string RegexFuncPattern => throw new NotImplementedException(); 13 +
130 -
131 - protected override string Extension => ".c";
132 -
133 - public override MatchCollection GetMatches(string patchCode) {
134 - throw new NotImplementedException();
135 - }
136 -
137 - public override IEnumerable<PatchEntryChanges> GetPatchEntryChanges(Patch patch) {
138 - throw new NotImplementedException();
139 - }
140 -
141 - public override string RemoveComment(string original) {
142 - throw new NotImplementedException();
143 - }
144 -
145 - protected override string GetOriginalFunc(Stream oldStream, string methodName) {
146 - throw new NotImplementedException();
147 - }
148 - }
149 /// <summary> 14 /// <summary>
150 /// 파이썬 크롤러 15 /// 파이썬 크롤러
151 /// </summary> 16 /// </summary>
152 public class VulnPython : VulnAbstractCrawler 17 public class VulnPython : VulnAbstractCrawler
153 { 18 {
154 - public VulnPython(string path) : base(path) { 19 +
155 - }
156 -
157 protected override string Extension => ".py"; 20 protected override string Extension => ".py";
158 protected override string RegexFuncPattern => $@"@@ \-(?<{OldStart}>\d+),(?<{OldLines}>\d+) \+(?<{NewStart}>\d+),(?<{NewLines}>\d+) @@ def (?<{MethodName}>\w+)"; 21 protected override string RegexFuncPattern => $@"@@ \-(?<{OldStart}>\d+),(?<{OldLines}>\d+) \+(?<{NewStart}>\d+),(?<{NewLines}>\d+) @@ def (?<{MethodName}>\w+)";
159 22
...@@ -195,12 +58,7 @@ namespace VulnCrawler ...@@ -195,12 +58,7 @@ namespace VulnCrawler
195 } 58 }
196 return oldBuilder.ToString(); 59 return oldBuilder.ToString();
197 } 60 }
198 - 61 +
199 - public override IEnumerable<PatchEntryChanges> GetPatchEntryChanges(Patch patch) {
200 -
201 - return patch.Where(e => e.Path.EndsWith(Extension)).ToList();
202 -
203 - }
204 62
205 public override string RemoveComment(string original) { 63 public override string RemoveComment(string original) {
206 64
......
1 +
2 +using LibGit2Sharp;
3 +using System;
4 +using System.Collections.Generic;
5 +using System.Linq;
6 +using System.Text;
7 +using System.Text.RegularExpressions;
8 +using System.Threading.Tasks;
9 +
10 +namespace VulnCrawler
11 +{
12 +
13 + public static class VulnWorker
14 + {
15 + public static void Run<T>(string dirPath) where T : VulnAbstractCrawler, new() {
16 + var self = new T();
17 + self.Init(dirPath);
18 + var commits = self.Commits;
19 + foreach (var commit in commits) {
20 + // 커밋 메시지
21 + string message = commit.Message;
22 + string cve = self.GetCVE(message);
23 + if (string.IsNullOrEmpty(cve)) {
24 + continue;
25 + }
26 + foreach (var parent in commit.Parents) {
27 + // 부모 커밋과 현재 커밋을 Compare 하여 패치 내역을 가져옴
28 + var patch = self.Repository.Diff.Compare<Patch>(parent.Tree, commit.Tree);
29 + // 패치 엔트리 파일 배열 중에 파일 확장자가 .py인 것만 가져옴
30 + // (실질적인 코드 변경 커밋만 보기 위해서)
31 + var entrys = self.GetPatchEntryChanges(patch);
32 + // 현재 커밋에 대한 패치 엔트리 배열을 출력함
33 + PrintPatchEntrys(entrys, self, message, cve);
34 + }
35 + }
36 + }
37 +
38 +
39 + private static void PrintPatchEntrys(IEnumerable<PatchEntryChanges> entrys, VulnAbstractCrawler self, string commitMsg, string cve) {
40 +
41 + foreach (var entry in entrys) {
42 +
43 +
44 +
45 + // 기존 소스코드
46 + var oldOid = entry.OldOid;
47 + Blob oldBlob = self.Repository.Lookup<Blob>(oldOid);
48 + string oldContent = oldBlob.GetContentText();
49 +
50 + // 변경된 소스코드
51 + var newOid = entry.Oid;
52 + Blob newBlob = self.Repository.Lookup<Blob>(newOid);
53 + string newContent = newBlob.GetContentText();
54 +
55 + var regs = self.GetMatches(entry.Patch);
56 + // 패치 전 코드 (oldContent)
57 + // 패치 후 코드 (newContent)
58 + // 패치 코드 (entry.Patch)
59 + // 출력
60 + //if (regs.Count > 0) {
61 + // Console.BackgroundColor = ConsoleColor.DarkBlue;
62 + // Console.WriteLine($"Old Content: \n{oldContent}");
63 + // Console.ResetColor();
64 +
65 + // Console.BackgroundColor = ConsoleColor.DarkMagenta;
66 + // Console.WriteLine($"New Content: \n{newContent}");
67 + // Console.ResetColor();
68 + // Console.BackgroundColor = ConsoleColor.DarkRed;
69 + // Console.WriteLine($"Patched: \n{entry.Patch}");
70 +
71 + // Console.ResetColor();
72 + // Console.WriteLine("-----------");
73 + // Console.WriteLine(regs.Count);
74 +
75 + //}
76 +
77 + // 패치 코드에서 매칭된 파이썬 함수들로부터
78 + // 패치 전 코드 파일(oldBlob)을 탐색하여 원본 파이썬 함수 가져오고(originalFunc)
79 + //
80 + foreach (var reg in regs) {
81 + var match = reg as Match;
82 + string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value;
83 +
84 + string originalFunc, md5;
85 +
86 + (originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
87 + match.Groups[VulnAbstractCrawler.MethodName].Value);
88 +
89 + // 현재 패치 엔트리 정보 출력(추가된 줄 수, 삭제된 줄 수, 패치 이전 경로, 패치 후 경로)
90 + Console.ForegroundColor = ConsoleColor.Blue;
91 + Console.WriteLine($"status: {entry.Status.ToString()}");
92 + Console.WriteLine($"added: {entry.LinesAdded.ToString()}, deleted: {entry.LinesDeleted.ToString()}");
93 + Console.WriteLine($"old path: {entry.OldPath.ToString()}, new path: {entry.Path.ToString()}");
94 + Console.ResetColor();
95 +
96 +
97 + Console.Write($"CVE: ");
98 + Console.ForegroundColor = ConsoleColor.Red;
99 + Console.Write($"{cve}");
100 + Console.WriteLine("");
101 + Console.ResetColor();
102 + Console.ForegroundColor = ConsoleColor.Yellow;
103 + Console.WriteLine($"Commit Message: {commitMsg}");
104 + Console.ResetColor();
105 +
106 + // 패치 전 원본 함수
107 + Console.WriteLine($"Original Func: {originalFunc}");
108 + // 해쉬 후
109 + Console.WriteLine($"Original Func MD5: {md5}");
110 + Console.WriteLine("==============================");
111 +
112 +
113 +
114 + }
115 + }
116 + }
117 +
118 + }
119 +}