노현종

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

...@@ -114,14 +114,126 @@ namespace VulnCrawler ...@@ -114,14 +114,126 @@ namespace VulnCrawler
114 /// <returns>함수 문자열</returns> 114 /// <returns>함수 문자열</returns>
115 protected abstract string GetOriginalFunc(Stream oldStream, string methodName); 115 protected abstract string GetOriginalFunc(Stream oldStream, string methodName);
116 116
117 + // 테스트용 함수 곧 삭제될 운명
118 + public string GetOriginalFuncTest(Stream oldStream, string methodName, int start)
119 + {
120 + StringBuilder oldBuilder = new StringBuilder();
121 +
122 + using (var reader = new StreamReader(oldStream))
123 + {
124 +
125 +
126 + bool found = false;
127 + bool found2 = false;
128 + bool commentLine = false;
129 + int bracketCount = -1;
130 + string stringPattern = @"[""].*[""]";
131 + string commentPattern = @"\/\*.+\*\/";
132 + string commentPattern2 = @"\/\*";
133 + string commentPattern3 = @"\*\/";
134 + int readCount = 0;
135 + Queue<string> tempQ = new Queue<string>();
136 + while (!reader.EndOfStream)
137 + {
138 + string line = reader.ReadLine();
139 +
140 +
141 + if (readCount++ < start)
142 + {
143 + tempQ.Enqueue(line);
144 + continue;
145 + }
146 + Stack<string> tempStack = new Stack<string>();
147 + while (tempQ.Count > 0)
148 + {
149 + string s = tempQ.Dequeue();
150 + tempStack.Push(s);
151 + string method = Regex.Escape(methodName);
152 + if (Regex.Match(s, $"{method}").Success)
153 + {
154 +
155 + break;
156 + }
157 + }
158 +
159 + while (tempStack.Count > 0)
160 + {
161 + string s = tempStack.Pop();
162 + string trim = s.Trim();
117 163
164 + if (commentLine)
165 + {
166 + if (Regex.IsMatch(trim, commentPattern3))
167 + {
168 + commentLine = false;
169 + trim = Regex.Split(trim, commentPattern3)[1];
170 + }
171 + continue;
172 + }
173 +
174 +
175 + string removeString = Regex.Replace(trim, stringPattern, "");
176 +
177 + // /* ~ 패턴
178 + if (Regex.IsMatch(trim, commentPattern2))
179 + {
180 +
181 + // /* ~ */ 패턴이 아닌 경우
182 + if (!Regex.IsMatch(trim, commentPattern))
183 + {
184 + commentLine = true;
185 + }
186 + trim = Regex.Split(trim, "/*")[0];
187 +
188 + }
189 + if (string.IsNullOrWhiteSpace(trim))
190 + {
191 + continue;
192 + }
193 +
194 + int openBracketCount = removeString.Count(c => c == '{');
195 + int closeBracketCount = removeString.Count(c => c == '}');
196 + int subtract = openBracketCount - closeBracketCount;
197 + bracketCount += subtract;
198 + // 메서드 시작 괄호 찾은 경우
199 + if (found2)
200 + {
201 + // 괄호가 모두 닫혔으니 종료
202 + if (bracketCount < 0)
203 + {
204 + Console.WriteLine("괄호끝");
205 + break;
206 + }
207 + // oldBuilder.AppendLine(line);
208 + }
209 + else
210 + {
211 + if (openBracketCount > 0)
212 + {
213 + found2 = true;
214 + }
215 +
216 + }
217 + oldBuilder.AppendLine(s);
218 + }
219 +
220 +
221 + }
222 +
223 + }
224 + Console.WriteLine("찾음");
225 + Console.WriteLine(oldBuilder.ToString());
226 + Console.ReadLine();
227 +
228 + return oldBuilder.ToString();
229 + }
118 /// <summary> 230 /// <summary>
119 /// 실제 프로세스 231 /// 실제 프로세스
120 /// </summary> 232 /// </summary>
121 /// <param name="oldStream"></param> 233 /// <param name="oldStream"></param>
122 /// <param name="methodName"></param> 234 /// <param name="methodName"></param>
123 /// <returns></returns> 235 /// <returns></returns>
124 - public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName) { 236 + public virtual (string originalFunc, string hash) Process(Stream oldStream, string methodName, int start) {
125 // 패치 전 원본 함수 구하고 237 // 패치 전 원본 함수 구하고
126 string func = GetOriginalFunc(oldStream, methodName); 238 string func = GetOriginalFunc(oldStream, methodName);
127 // 주석 제거하고 239 // 주석 제거하고
......
...@@ -52,34 +52,44 @@ namespace VulnCrawler ...@@ -52,34 +52,44 @@ namespace VulnCrawler
52 // 메서드를 찾은 경우 52 // 메서드를 찾은 경우
53 if (found) 53 if (found)
54 { 54 {
55 - Console.WriteLine("찾았었음");
56 string trim = line.Trim(); 55 string trim = line.Trim();
57 56
57 + // 범위 주석 진행되고 있으면 넘어감
58 if (commentLine) 58 if (commentLine)
59 { 59 {
60 + // 혹시 범위 주석이 끝났는지 체크
60 if (Regex.IsMatch(trim, commentPattern3)) 61 if (Regex.IsMatch(trim, commentPattern3))
61 { 62 {
62 commentLine = false; 63 commentLine = false;
63 trim = Regex.Split(trim, commentPattern3)[1]; 64 trim = Regex.Split(trim, commentPattern3)[1];
64 } 65 }
66 + else
67 + {
68 + continue;
69 + }
65 } 70 }
66 71
67 - if (string.IsNullOrWhiteSpace(trim)) 72 + // "" 문자열 제거
68 - {
69 - continue;
70 - }
71 string removeString = Regex.Replace(trim, stringPattern, ""); 73 string removeString = Regex.Replace(trim, stringPattern, "");
72 74
73 // /* ~ 패턴 75 // /* ~ 패턴
74 if (Regex.IsMatch(trim, commentPattern2)) 76 if (Regex.IsMatch(trim, commentPattern2))
75 { 77 {
76 - trim = Regex.Split(trim, "/*")[0]; 78 +
77 // /* ~ */ 패턴이 아닌 경우 79 // /* ~ */ 패턴이 아닌 경우
78 if (!Regex.IsMatch(trim, commentPattern)) 80 if (!Regex.IsMatch(trim, commentPattern))
79 { 81 {
80 commentLine = true; 82 commentLine = true;
81 } 83 }
84 + trim = Regex.Split(trim, "/*")[0];
85 +
86 + }
87 + // 비어있는 경우 넘어감
88 + if (string.IsNullOrWhiteSpace(trim))
89 + {
90 + continue;
82 } 91 }
92 +
83 int openBracketCount = removeString.Count(c => c == '{'); 93 int openBracketCount = removeString.Count(c => c == '{');
84 int closeBracketCount = removeString.Count(c => c == '}'); 94 int closeBracketCount = removeString.Count(c => c == '}');
85 int subtract = openBracketCount - closeBracketCount; 95 int subtract = openBracketCount - closeBracketCount;
...@@ -87,31 +97,44 @@ namespace VulnCrawler ...@@ -87,31 +97,44 @@ namespace VulnCrawler
87 // 메서드 시작 괄호 찾은 경우 97 // 메서드 시작 괄호 찾은 경우
88 if (found2) 98 if (found2)
89 { 99 {
100 + oldBuilder.AppendLine(line);
90 // 괄호가 모두 닫혔으니 종료 101 // 괄호가 모두 닫혔으니 종료
91 if (bracketCount < 0) 102 if (bracketCount < 0)
92 { 103 {
93 - Console.WriteLine("괄호끝");
94 break; 104 break;
95 } 105 }
96 - oldBuilder.AppendLine(line); 106 +
97 } 107 }
98 - else 108 + else // 메서드는 찾았으나 아직 시작 괄호를 못찾은 경우
99 { 109 {
110 + oldBuilder.AppendLine(line);
100 if (openBracketCount > 0) 111 if (openBracketCount > 0)
101 { 112 {
102 found2 = true; 113 found2 = true;
103 } 114 }
115 + else
116 + {
117 + //아직 { 괄호를 못찾았는데 );를 만났다면 메서드 선언 부분이니 넘어감
118 + if (trim.EndsWith(");"))
119 + {
120 + found = false;
121 + oldBuilder.Clear();
122 + continue;
123 + }
124 + }
104 125
105 } 126 }
106 127
107 128
108 } 129 }
130 + // 아직 메서드를 못찾은 경우
109 else 131 else
110 { 132 {
133 + // 메서드 찾았는지 확인
111 if (Regex.Match(line, $"{methodName}").Success) 134 if (Regex.Match(line, $"{methodName}").Success)
112 { 135 {
113 -
114 string trim = line.Trim(); 136 string trim = line.Trim();
137 + // 주석으로 시작했다면 넘어감
115 if (trim.StartsWith("//")) 138 if (trim.StartsWith("//"))
116 { 139 {
117 continue; 140 continue;
...@@ -121,16 +144,20 @@ namespace VulnCrawler ...@@ -121,16 +144,20 @@ namespace VulnCrawler
121 { 144 {
122 continue; 145 continue;
123 } 146 }
124 - 147 +
125 - if (Regex.Match(trim, $@"""[\s]*({methodName})").Success) 148 + // 혹시 메서드가 문자열 사이에 있다면 넘어감..
149 + if (Regex.Match(trim, $@"""[.]*({methodName})").Success)
126 { 150 {
127 continue; 151 continue;
128 } 152 }
129 153
154 + // 만약 찾은 메서드 라인에서 중괄호 {가 시작된 경우
130 if (Regex.Match(trim, $@"{methodName}\s*" + @"\{").Success) 155 if (Regex.Match(trim, $@"{methodName}\s*" + @"\{").Success)
131 { 156 {
157 + // 동시에 } 닫히기까지 한 경우 드물겠지만..
132 if (trim.EndsWith("}")) 158 if (trim.EndsWith("}"))
133 { 159 {
160 + oldBuilder.AppendLine(line);
134 break; 161 break;
135 } 162 }
136 found2 = true; 163 found2 = true;
...@@ -143,11 +170,13 @@ namespace VulnCrawler ...@@ -143,11 +170,13 @@ namespace VulnCrawler
143 } 170 }
144 171
145 } 172 }
146 - Console.WriteLine("찾음");
147 Console.WriteLine(oldBuilder.ToString()); 173 Console.WriteLine(oldBuilder.ToString());
148 Console.ReadLine(); 174 Console.ReadLine();
149 175
150 return oldBuilder.ToString(); 176 return oldBuilder.ToString();
151 } 177 }
178 +
179 +
180 +
152 } 181 }
153 } 182 }
......
...@@ -108,10 +108,13 @@ namespace VulnCrawler ...@@ -108,10 +108,13 @@ namespace VulnCrawler
108 { 108 {
109 var match = reg as Match; 109 var match = reg as Match;
110 string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim(); 110 string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
111 + int start = int.Parse(match.Groups[VulnAbstractCrawler.OldStart].Value);
111 Console.WriteLine("methodName = " + methodName); 112 Console.WriteLine("methodName = " + methodName);
112 string originalFunc, md5; 113 string originalFunc, md5;
113 (originalFunc, md5) = self.Process(oldBlob.GetContentStream(), 114 (originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
114 - methodName); 115 + methodName, start);
116 +
117 +
115 118
116 #region 현재 패치 엔트리 정보 출력(추가된 , 삭제된 , 패치 이전 경로, 패치 경로) 119 #region 현재 패치 엔트리 정보 출력(추가된 , 삭제된 , 패치 이전 경로, 패치 경로)
117 120
......