git-svn: trunk@1694
aCaB authored on 2005/08/16 01:21:05... | ... |
@@ -186,7 +186,7 @@ static int unfsg(char *source, char *dest, int ssize, int dsize, char **endsrc, |
186 | 186 |
} |
187 | 187 |
lostbit = 0; |
188 | 188 |
} |
189 |
- if ((backsize >= dest + dsize - cdst) || (backbytes > cdst - dest)) |
|
189 |
+ if ((backsize > dest + dsize - cdst) || (backbytes > cdst - dest)) |
|
190 | 190 |
return -1; |
191 | 191 |
while(backsize--) { |
192 | 192 |
*cdst=*(cdst-backbytes); |
... | ... |
@@ -207,12 +207,28 @@ static int unfsg(char *source, char *dest, int ssize, int dsize, char **endsrc, |
207 | 207 |
return 0; |
208 | 208 |
} |
209 | 209 |
|
210 |
-int unfsg_200(char *source, char *dest, int ssize, int dsize) { |
|
211 |
- char *fake; |
|
212 | 210 |
|
213 |
- return unfsg(source, dest, ssize, dsize, &fake, &fake); |
|
211 |
+int unfsg_200(char *source, char *dest, int ssize, int dsize, uint32_t rva, uint32_t base, uint32_t ep, int file) { |
|
212 |
+ char *fake, *tsrc; |
|
213 |
+ struct SECTION section; // Yup, just one ;) |
|
214 |
+ |
|
215 |
+ if ( unfsg(source, dest, ssize, dsize, &fake, &fake) ) return -1; |
|
216 |
+ |
|
217 |
+ section.raw=0; |
|
218 |
+ section.rsz = dsize; |
|
219 |
+ section.vsz = dsize; |
|
220 |
+ section.rva = rva; |
|
221 |
+ if ( (tsrc = rebuildpe(dest, §ion, 1, base, ep, 0, 0)) ) { |
|
222 |
+ write(file, tsrc, 0x148+0x80+0x28+dsize); |
|
223 |
+ free(tsrc); |
|
224 |
+ } else { |
|
225 |
+ cli_dbgmsg("FSG: Rebuilding failed\n"); |
|
226 |
+ return 0; |
|
227 |
+ } |
|
228 |
+ return 1; |
|
214 | 229 |
} |
215 | 230 |
|
231 |
+ |
|
216 | 232 |
int unfsg_133(char *source, char *dest, int ssize, int dsize, struct SECTION *sections, int sectcount, uint32_t base, uint32_t ep, int file) { |
217 | 233 |
char *tsrc=source, *tdst=dest; |
218 | 234 |
int i, upd=1, offs=0, lastsz=dsize; |
... | ... |
@@ -266,7 +282,6 @@ int unfsg_133(char *source, char *dest, int ssize, int dsize, struct SECTION *se |
266 | 266 |
write(file, tsrc, 0x148+0x80+0x28*(sectcount+1)+offs); |
267 | 267 |
free(tsrc); |
268 | 268 |
} else { |
269 |
- free(tsrc); |
|
270 | 269 |
cli_dbgmsg("FSG: Rebuilding failed\n"); |
271 | 270 |
return 0; |
272 | 271 |
} |
... | ... |
@@ -22,7 +22,7 @@ |
22 | 22 |
#include "cltypes.h" |
23 | 23 |
#include "rebuildpe.h" |
24 | 24 |
|
25 |
-int unfsg_200(char *, char *, int, int); |
|
25 |
+int unfsg_200(char *, char *, int, int, uint32_t, uint32_t, uint32_t, int); |
|
26 | 26 |
int unfsg_133(char *, char *, int , int, struct SECTION *, int, uint32_t, uint32_t, int); |
27 | 27 |
|
28 | 28 |
#endif |
... | ... |
@@ -666,8 +666,8 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
666 | 666 |
break; |
667 | 667 |
} |
668 | 668 |
|
669 |
- /* FIXME: unused atm, needed for pe rebuilding */ |
|
670 |
- cli_dbgmsg("FSG: found old EP @%x\n", cli_readint32(newebx + 12 - EC32(section_hdr[i + 1].VirtualAddress) + src) - EC32(optional_hdr.ImageBase)); |
|
669 |
+ newedx=cli_readint32(newebx + 12 - EC32(section_hdr[i + 1].VirtualAddress) + src) - EC32(optional_hdr.ImageBase); |
|
670 |
+ cli_dbgmsg("FSG: found old EP @%x\n",newedx); |
|
671 | 671 |
|
672 | 672 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
673 | 673 |
free(section_hdr); |
... | ... |
@@ -675,16 +675,60 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
675 | 675 |
return CL_EMEM; |
676 | 676 |
} |
677 | 677 |
|
678 |
- if(unfsg_200(newesi - EC32(section_hdr[i + 1].VirtualAddress) + src, dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize) == -1) { |
|
679 |
- cli_dbgmsg("FSG: Unpacking failed\n"); |
|
678 |
+ tempfile = cli_gentemp(NULL); |
|
679 |
+ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
|
680 |
+ cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
|
681 |
+ free(tempfile); |
|
682 |
+ free(section_hdr); |
|
680 | 683 |
free(src); |
681 | 684 |
free(dest); |
682 |
- break; |
|
685 |
+ return CL_EIO; |
|
686 |
+ } |
|
687 |
+ |
|
688 |
+ switch (unfsg_200(newesi - EC32(section_hdr[i + 1].VirtualAddress) + src, dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize, newedi, EC32(optional_hdr.ImageBase), newedx, ndesc)) { |
|
689 |
+ case 1: /* Everything OK */ |
|
690 |
+ cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile); |
|
691 |
+ free(src); |
|
692 |
+ free(dest); |
|
693 |
+ fsync(ndesc); |
|
694 |
+ lseek(ndesc, 0, SEEK_SET); |
|
695 |
+ |
|
696 |
+ cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
|
697 |
+ if(cli_magic_scandesc(ndesc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS) { |
|
698 |
+ free(section_hdr); |
|
699 |
+ close(ndesc); |
|
700 |
+ if(!cli_leavetemps_flag) |
|
701 |
+ unlink(tempfile); |
|
702 |
+ free(tempfile); |
|
703 |
+ return CL_VIRUS; |
|
704 |
+ } |
|
705 |
+ |
|
706 |
+ close(ndesc); |
|
707 |
+ if(!cli_leavetemps_flag) |
|
708 |
+ unlink(tempfile); |
|
709 |
+ free(tempfile); |
|
710 |
+ free(section_hdr); |
|
711 |
+ return CL_CLEAN; |
|
712 |
+ |
|
713 |
+ case 0: /* We've got an unpacked buffer, no exe though */ |
|
714 |
+ cli_dbgmsg("FSG: FSG: Successfully decompressed\n"); |
|
715 |
+ close(ndesc); |
|
716 |
+ unlink(tempfile); |
|
717 |
+ free(tempfile); |
|
718 |
+ found = 0; |
|
719 |
+ upx_success = 1; |
|
720 |
+ break; /* Go and scan the buffer! */ |
|
721 |
+ |
|
722 |
+ default: /* Everything gone wrong */ |
|
723 |
+ cli_dbgmsg("FSG: Unpacking failed\n"); |
|
724 |
+ close(ndesc); |
|
725 |
+ unlink(tempfile); // It's empty anyway |
|
726 |
+ free(tempfile); |
|
727 |
+ free(src); |
|
728 |
+ free(dest); |
|
729 |
+ break; |
|
683 | 730 |
} |
684 | 731 |
|
685 |
- found = 0; |
|
686 |
- upx_success = 1; |
|
687 |
- cli_dbgmsg("FSG: Successfully decompressed\n"); |
|
688 | 732 |
} |
689 | 733 |
} |
690 | 734 |
|