... | ... |
@@ -2570,9 +2570,26 @@ int cli_scanpe(cli_ctx *ctx) |
2570 | 2570 |
cli_jsonstr(pe_json, "Packer", "yC"); |
2571 | 2571 |
#endif |
2572 | 2572 |
|
2573 |
- cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset); |
|
2574 |
- CLI_UNPTEMP("yC",(spinned,exe_sections,0)); |
|
2575 |
- CLI_UNPRESULTS("yC",(yc_decrypt(ctx, spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0)); |
|
2573 |
+ do { |
|
2574 |
+ unsigned int yc_unp_num_viruses = ctx->num_viruses; |
|
2575 |
+ const char *yc_unp_virname = NULL; |
|
2576 |
+ |
|
2577 |
+ if (ctx->virname) |
|
2578 |
+ yc_unp_virname = ctx->virname[0]; |
|
2579 |
+ |
|
2580 |
+ cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset); |
|
2581 |
+ CLI_UNPTEMP("yC",(spinned,exe_sections,0)); |
|
2582 |
+ CLI_UNPRESULTS("yC",(yc_decrypt(ctx, spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0)); |
|
2583 |
+ |
|
2584 |
+ if (SCAN_ALL && yc_unp_num_viruses != ctx->num_viruses) { |
|
2585 |
+ free(exe_sections); |
|
2586 |
+ return CL_VIRUS; |
|
2587 |
+ } |
|
2588 |
+ else if (ctx->virname && yc_unp_virname != ctx->virname[0]) { |
|
2589 |
+ free(exe_sections); |
|
2590 |
+ return CL_VIRUS; |
|
2591 |
+ } |
|
2592 |
+ } while(0); |
|
2576 | 2593 |
} |
2577 | 2594 |
} |
2578 | 2595 |
|
... | ... |
@@ -44,6 +44,7 @@ |
44 | 44 |
static int yc_bounds_check(cli_ctx *ctx, char *base, unsigned int filesize, char *offset, unsigned int bound) |
45 | 45 |
{ |
46 | 46 |
if ((unsigned int)((offset+bound)-base) > filesize) { |
47 |
+ cli_dbgmsg("%s: Bounds check assertion.\n", __func__); |
|
47 | 48 |
#if DO_HEURISTIC |
48 | 49 |
cli_append_virus(ctx, "Heuristics.BoundsCheck"); |
49 | 50 |
#endif |
... | ... |
@@ -84,14 +85,14 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
84 | 84 |
for(i=0;i<ecx&&i<max_emu;i++) /* Byte looper - Decrypts every byte and write it back */ |
85 | 85 |
{ |
86 | 86 |
if (yc_bounds_check(ctx, base, filesize, code, i)) { |
87 |
- return 1; |
|
87 |
+ return 2; |
|
88 | 88 |
} |
89 | 89 |
al = code[i]; |
90 | 90 |
|
91 | 91 |
for(j=0;j<0x30;j++) /* Poly Decryptor "Emulator" */ |
92 | 92 |
{ |
93 | 93 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
94 |
- return 1; |
|
94 |
+ return 2; |
|
95 | 95 |
} |
96 | 96 |
|
97 | 97 |
switch(decryptor_offset[j]) |
... | ... |
@@ -100,7 +101,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
100 | 100 |
case '\xEB': /* JMP short */ |
101 | 101 |
j++; |
102 | 102 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
103 |
- return 1; |
|
103 |
+ return 2; |
|
104 | 104 |
} |
105 | 105 |
j = j + decryptor_offset[j]; |
106 | 106 |
break; |
... | ... |
@@ -128,7 +129,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
128 | 128 |
case '\x04': /* ADD AL,num */ |
129 | 129 |
j++; |
130 | 130 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
131 |
- return 1; |
|
131 |
+ return 2; |
|
132 | 132 |
} |
133 | 133 |
al = al + decryptor_offset[j]; |
134 | 134 |
break; |
... | ... |
@@ -136,7 +137,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
136 | 136 |
case '\x34': /* XOR AL,num */ |
137 | 137 |
j++; |
138 | 138 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
139 |
- return 1; |
|
139 |
+ return 2; |
|
140 | 140 |
} |
141 | 141 |
al = al ^ decryptor_offset[j]; |
142 | 142 |
break; |
... | ... |
@@ -144,7 +145,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
144 | 144 |
case '\x2C': /* SUB AL,num */ |
145 | 145 |
j++; |
146 | 146 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
147 |
- return 1; |
|
147 |
+ return 2; |
|
148 | 148 |
} |
149 | 149 |
al = al - decryptor_offset[j]; |
150 | 150 |
break; |
... | ... |
@@ -153,13 +154,13 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
153 | 153 |
case '\xC0': |
154 | 154 |
j++; |
155 | 155 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
156 |
- return 1; |
|
156 |
+ return 2; |
|
157 | 157 |
} |
158 | 158 |
if(decryptor_offset[j]=='\xC0') /* ROL AL,num */ |
159 | 159 |
{ |
160 | 160 |
j++; |
161 | 161 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
162 |
- return 1; |
|
162 |
+ return 2; |
|
163 | 163 |
} |
164 | 164 |
CLI_ROL(al,decryptor_offset[j]); |
165 | 165 |
} |
... | ... |
@@ -167,7 +168,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
167 | 167 |
{ |
168 | 168 |
j++; |
169 | 169 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
170 |
- return 1; |
|
170 |
+ return 2; |
|
171 | 171 |
} |
172 | 172 |
CLI_ROR(al,decryptor_offset[j]); |
173 | 173 |
} |
... | ... |
@@ -176,7 +177,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
176 | 176 |
case '\xD2': |
177 | 177 |
j++; |
178 | 178 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
179 |
- return 1; |
|
179 |
+ return 2; |
|
180 | 180 |
} |
181 | 181 |
if(decryptor_offset[j]=='\xC8') /* ROR AL,CL */ |
182 | 182 |
{ |
... | ... |
@@ -197,7 +198,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
197 | 197 |
|
198 | 198 |
default: |
199 | 199 |
if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) { |
200 |
- return 1; |
|
200 |
+ return 2; |
|
201 | 201 |
} |
202 | 202 |
cli_dbgmsg("yC: Unhandled opcode %x\n", (unsigned char)decryptor_offset[j]); |
203 | 203 |
return 1; |
... | ... |
@@ -205,7 +206,7 @@ static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, cha |
205 | 205 |
} |
206 | 206 |
cl--; |
207 | 207 |
if (yc_bounds_check(ctx, base, filesize, code, i)) |
208 |
- return 1; |
|
208 |
+ return 2; |
|
209 | 209 |
code[i] = al; |
210 | 210 |
} |
211 | 211 |
return 0; |
... | ... |
@@ -233,8 +234,12 @@ int yc_decrypt(cli_ctx *ctx, char *fbuf, unsigned int filesize, struct cli_exe_s |
233 | 233 |
*/ |
234 | 234 |
cli_dbgmsg("yC: offset: %x, length: %x\n", offset, ecx); |
235 | 235 |
cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount); |
236 |
- if (yc_poly_emulator(ctx, fbuf, filesize, fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx)) |
|
237 |
- return 1; |
|
236 |
+ switch (yc_poly_emulator(ctx, fbuf, filesize, fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx)) { |
|
237 |
+ case 2: |
|
238 |
+ return CL_VIRUS; |
|
239 |
+ case 1: |
|
240 |
+ return CL_EUNPACK; |
|
241 |
+ } |
|
238 | 242 |
filesize-=sections[sectcount].ursz; |
239 | 243 |
|
240 | 244 |
/* |
... | ... |
@@ -269,11 +274,15 @@ int yc_decrypt(cli_ctx *ctx, char *fbuf, unsigned int filesize, struct cli_exe_s |
269 | 269 |
cli_dbgmsg("yC: bad emulation length limit %u\n", max_emu); |
270 | 270 |
return 1; |
271 | 271 |
} |
272 |
- if (yc_poly_emulator(ctx, fbuf, filesize, fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), |
|
272 |
+ switch (yc_poly_emulator(ctx, fbuf, filesize, fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), |
|
273 | 273 |
fbuf + sections[i].raw, |
274 | 274 |
sections[i].ursz, |
275 |
- max_emu)) |
|
276 |
- return 1; |
|
275 |
+ max_emu)) { |
|
276 |
+ case 2: |
|
277 |
+ return CL_VIRUS; |
|
278 |
+ case 1: |
|
279 |
+ return CL_EUNPACK; |
|
280 |
+ } |
|
277 | 281 |
} |
278 | 282 |
|
279 | 283 |
/* Remove yC section */ |
... | ... |
@@ -291,7 +300,7 @@ int yc_decrypt(cli_ctx *ctx, char *fbuf, unsigned int filesize, struct cli_exe_s |
291 | 291 |
|
292 | 292 |
if (cli_writen(desc, fbuf, filesize)==-1) { |
293 | 293 |
cli_dbgmsg("yC: Cannot write unpacked file\n"); |
294 |
- return 1; |
|
294 |
+ return CL_EUNPACK; |
|
295 | 295 |
} |
296 |
- return 0; |
|
296 |
+ return CL_SUCCESS; |
|
297 | 297 |
} |