git-svn: trunk@1815
Tomasz Kojm authored on 2006/01/15 03:21:36... | ... |
@@ -171,6 +171,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
171 | 171 |
int (*upxfn)(char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL; |
172 | 172 |
char *src = NULL, *dest = NULL; |
173 | 173 |
int ndesc, ret; |
174 |
+ size_t fsize; |
|
174 | 175 |
|
175 | 176 |
|
176 | 177 |
if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) { |
... | ... |
@@ -473,6 +474,8 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
473 | 473 |
return CL_EIO; |
474 | 474 |
} |
475 | 475 |
|
476 |
+ fsize = sb.st_size; |
|
477 |
+ |
|
476 | 478 |
section_hdr = (struct pe_image_section_hdr *) cli_calloc(nsections, sizeof(struct pe_image_section_hdr)); |
477 | 479 |
|
478 | 480 |
if(!section_hdr) { |
... | ... |
@@ -524,8 +527,8 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
524 | 524 |
|
525 | 525 |
cli_dbgmsg("------------------------------------\n"); |
526 | 526 |
|
527 |
- if(EC32(section_hdr[i].PointerToRawData) + EC32(section_hdr[i].SizeOfRawData) > (unsigned long int) sb.st_size) { |
|
528 |
- cli_dbgmsg("Possibly broken PE file - Section %d out of file (Offset@ %d, Rsize %d, Total filesize %d)\n", i, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData), sb.st_size); |
|
527 |
+ if(!CLI_ISCONTAINED(0, (uint32_t) fsize, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData)) || EC32(section_hdr[i].PointerToRawData) >= fsize) { |
|
528 |
+ cli_dbgmsg("Possibly broken PE file - Section %d out of file (Offset@ %d, Rsize %d, Total filesize %d)\n", i, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData), fsize); |
|
529 | 529 |
if(DETECT_BROKEN) { |
530 | 530 |
if(virname) |
531 | 531 |
*virname = "Broken.Executable"; |
... | ... |
@@ -753,7 +756,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
753 | 753 |
return CL_EMEM; |
754 | 754 |
} |
755 | 755 |
|
756 |
- tempfile = cli_gentemp(NULL); |
|
756 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
757 |
+ return CL_EMEM; |
|
758 |
+ |
|
757 | 759 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
758 | 760 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
759 | 761 |
free(tempfile); |
... | ... |
@@ -951,7 +956,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
951 | 951 |
oldep = EC32(optional_hdr32.AddressOfEntryPoint) + 161 + 6 + cli_readint32(buff+163); |
952 | 952 |
cli_dbgmsg("FSG: found old EP @%x\n", oldep); |
953 | 953 |
|
954 |
- tempfile = cli_gentemp(NULL); |
|
954 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
955 |
+ return CL_EMEM; |
|
956 |
+ |
|
955 | 957 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
956 | 958 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
957 | 959 |
free(tempfile); |
... | ... |
@@ -1154,7 +1161,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1154 | 1154 |
oldep = EC32(optional_hdr32.AddressOfEntryPoint) + gp + 6 + cli_readint32(src+gp+2+oldep); |
1155 | 1155 |
cli_dbgmsg("FSG: found old EP @%x\n", oldep); |
1156 | 1156 |
|
1157 |
- tempfile = cli_gentemp(NULL); |
|
1157 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
1158 |
+ return CL_EMEM; |
|
1159 |
+ |
|
1158 | 1160 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1159 | 1161 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
1160 | 1162 |
free(tempfile); |
... | ... |
@@ -1363,7 +1372,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1363 | 1363 |
free(src); |
1364 | 1364 |
free(section_hdr); |
1365 | 1365 |
|
1366 |
- tempfile = cli_gentemp(NULL); |
|
1366 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
1367 |
+ return CL_EMEM; |
|
1368 |
+ |
|
1367 | 1369 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1368 | 1370 |
cli_dbgmsg("UPX/FSG: Can't create file %s\n", tempfile); |
1369 | 1371 |
free(tempfile); |
... | ... |
@@ -1458,7 +1469,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1458 | 1458 |
} |
1459 | 1459 |
} |
1460 | 1460 |
|
1461 |
- tempfile = cli_gentemp(NULL); |
|
1461 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
1462 |
+ return CL_EMEM; |
|
1463 |
+ |
|
1462 | 1464 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1463 | 1465 |
cli_dbgmsg("Petite: Can't create file %s\n", tempfile); |
1464 | 1466 |
free(tempfile); |
... | ... |
@@ -1520,28 +1533,24 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1520 | 1520 |
EC32(optional_hdr32.AddressOfEntryPoint) < EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(section_hdr[nsections - 1].SizeOfRawData) - 0x3217 - 4 && |
1521 | 1521 |
memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0) { |
1522 | 1522 |
|
1523 |
- struct stat fstats; |
|
1524 | 1523 |
char *spinned; |
1525 | 1524 |
|
1526 |
- if(fstat(desc, &fstats) == -1) { |
|
1527 |
- free(section_hdr); |
|
1528 |
- return CL_EIO; |
|
1529 |
- } |
|
1530 |
- |
|
1531 |
- if((spinned = (char *) cli_malloc(fstats.st_size)) == NULL) { |
|
1525 |
+ if((spinned = (char *) cli_malloc(fsize)) == NULL) { |
|
1532 | 1526 |
free(section_hdr); |
1533 | 1527 |
return CL_EMEM; |
1534 | 1528 |
} |
1535 | 1529 |
|
1536 | 1530 |
lseek(desc, 0, SEEK_SET); |
1537 |
- if(read(desc, spinned, fstats.st_size) != fstats.st_size) { |
|
1538 |
- cli_dbgmsg("PESpin: Can't read %d bytes\n", fstats.st_size); |
|
1531 |
+ if(read(desc, spinned, fsize) != fsize) { |
|
1532 |
+ cli_dbgmsg("PESpin: Can't read %d bytes\n", fsize); |
|
1539 | 1533 |
free(spinned); |
1540 | 1534 |
free(section_hdr); |
1541 | 1535 |
return CL_EIO; |
1542 | 1536 |
} |
1543 | 1537 |
|
1544 |
- tempfile = cli_gentemp(NULL); |
|
1538 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
1539 |
+ return CL_EMEM; |
|
1540 |
+ |
|
1545 | 1541 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1546 | 1542 |
cli_dbgmsg("PESpin: Can't create file %s\n", tempfile); |
1547 | 1543 |
free(tempfile); |
... | ... |
@@ -1550,7 +1559,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1550 | 1550 |
return CL_EIO; |
1551 | 1551 |
} |
1552 | 1552 |
|
1553 |
- if(!unspin(spinned, fstats.st_size, section_hdr, nsections - 1, EC32(optional_hdr32.AddressOfEntryPoint), ndesc)) { |
|
1553 |
+ if(!unspin(spinned, fsize, section_hdr, nsections - 1, EC32(optional_hdr32.AddressOfEntryPoint), ndesc)) { |
|
1554 | 1554 |
free(spinned); |
1555 | 1555 |
cli_dbgmsg("PESpin: Unpacked and rebuilt executable saved in %s\n", tempfile); |
1556 | 1556 |
fsync(ndesc); |
... | ... |
@@ -1589,29 +1598,25 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1589 | 1589 |
EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) + 0x60 && |
1590 | 1590 |
memcmp(buff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0) { |
1591 | 1591 |
|
1592 |
- struct stat fstats; |
|
1593 | 1592 |
char *spinned; |
1594 | 1593 |
|
1595 |
- if(fstat(desc, &fstats) == -1) { |
|
1596 |
- free(section_hdr); |
|
1597 |
- return CL_EIO; |
|
1598 |
- } |
|
1599 |
- |
|
1600 |
- if ( fstats.st_size >= EC32(section_hdr[nsections - 1].PointerToRawData) + 0xC6 + 0xb97 ) { /* size check on yC sect */ |
|
1601 |
- if((spinned = (char *) cli_malloc(fstats.st_size)) == NULL) { |
|
1594 |
+ if ( fsize >= EC32(section_hdr[nsections - 1].PointerToRawData) + 0xC6 + 0xb97 ) { /* size check on yC sect */ |
|
1595 |
+ if((spinned = (char *) cli_malloc(fsize)) == NULL) { |
|
1602 | 1596 |
free(section_hdr); |
1603 | 1597 |
return CL_EMEM; |
1604 | 1598 |
} |
1605 | 1599 |
|
1606 | 1600 |
lseek(desc, 0, SEEK_SET); |
1607 |
- if(read(desc, spinned, fstats.st_size) != fstats.st_size) { |
|
1608 |
- cli_dbgmsg("yC: Can't read %d bytes\n", fstats.st_size); |
|
1601 |
+ if(read(desc, spinned, fsize) != fsize) { |
|
1602 |
+ cli_dbgmsg("yC: Can't read %d bytes\n", fsize); |
|
1609 | 1603 |
free(spinned); |
1610 | 1604 |
free(section_hdr); |
1611 | 1605 |
return CL_EIO; |
1612 | 1606 |
} |
1613 |
- |
|
1614 |
- tempfile = cli_gentemp(NULL); |
|
1607 |
+ |
|
1608 |
+ if(!(tempfile = cli_gentemp(NULL))) |
|
1609 |
+ return CL_EMEM; |
|
1610 |
+ |
|
1615 | 1611 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1616 | 1612 |
cli_dbgmsg("yC: Can't create file %s\n", tempfile); |
1617 | 1613 |
free(tempfile); |
... | ... |
@@ -1619,8 +1624,8 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1619 | 1619 |
free(section_hdr); |
1620 | 1620 |
return CL_EIO; |
1621 | 1621 |
} |
1622 |
- |
|
1623 |
- if(!yc_decrypt(spinned, fstats.st_size, section_hdr, nsections-1, e_lfanew, ndesc)) { |
|
1622 |
+ |
|
1623 |
+ if(!yc_decrypt(spinned, fsize, section_hdr, nsections-1, e_lfanew, ndesc)) { |
|
1624 | 1624 |
free(spinned); |
1625 | 1625 |
cli_dbgmsg("yC: Unpacked and rebuilt executable saved in %s\n", tempfile); |
1626 | 1626 |
fsync(ndesc); |
... | ... |
@@ -1651,7 +1656,6 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
1651 | 1651 |
free(tempfile); |
1652 | 1652 |
} |
1653 | 1653 |
|
1654 |
- |
|
1655 | 1654 |
} |
1656 | 1655 |
} |
1657 | 1656 |
|
... | ... |
@@ -35,7 +35,7 @@ |
35 | 35 |
#include "others.h" |
36 | 36 |
|
37 | 37 |
|
38 |
-// Macros were created by aCaB |
|
38 |
+/* Macros were created by aCaB */ |
|
39 | 39 |
#define ROL(a,b) a = ( a << (b % (sizeof(a)<<3) )) | (a >> ( (sizeof(a)<<3) - (b % (sizeof(a)<<3 )) ) ) |
40 | 40 |
#define ROR(a,b) a = ( a >> (b % (sizeof(a)<<3) )) | (a << ( (sizeof(a)<<3) - (b % (sizeof(a)<<3 )) ) ) |
41 | 41 |
|
... | ... |
@@ -54,9 +54,9 @@ static inline uint32_t EC32(uint32_t v) |
54 | 54 |
} |
55 | 55 |
#endif |
56 | 56 |
|
57 |
-//================================================================================== |
|
58 |
-// "Emulates" the poly decryptors |
|
59 |
-// |
|
57 |
+/* ========================================================================== */ |
|
58 |
+/* "Emulates" the poly decryptors */ |
|
59 |
+ |
|
60 | 60 |
static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx) |
61 | 61 |
{ |
62 | 62 |
|
... | ... |
@@ -77,56 +77,55 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx |
77 | 77 |
D2C0 ROL AL,CL |
78 | 78 |
|
79 | 79 |
*/ |
80 |
- // unsigned int ecx = len2decrypt; |
|
81 | 80 |
unsigned char al; |
82 | 81 |
unsigned char cl = ecx & 0xff; |
83 | 82 |
unsigned int j=0,i=0; |
84 | 83 |
|
85 |
- for(i;i<ecx;i++) // Byte looper - Decrypts every byte and write it back |
|
84 |
+ for(i;i<ecx;i++) /* Byte looper - Decrypts every byte and write it back */ |
|
86 | 85 |
{ |
87 | 86 |
al = code[i]; |
88 | 87 |
|
89 |
- for(j=0;j<0x30;j++) // Poly Decryptor "Emulator" |
|
88 |
+ for(j=0;j<0x30;j++) /* Poly Decryptor "Emulator" */ |
|
90 | 89 |
{ |
91 | 90 |
switch(decryptor_offset[j]) |
92 | 91 |
{ |
93 | 92 |
|
94 |
- case '\xEB': // JMP short |
|
93 |
+ case '\xEB': /* JMP short */ |
|
95 | 94 |
j++; |
96 | 95 |
j = j + decryptor_offset[j]; |
97 | 96 |
break; |
98 | 97 |
|
99 |
- case '\xFE': // DEC AL |
|
98 |
+ case '\xFE': /* DEC AL */ |
|
100 | 99 |
al--; |
101 | 100 |
j++; |
102 | 101 |
break; |
103 | 102 |
|
104 |
- case '\x2A': // SUB AL,CL |
|
103 |
+ case '\x2A': /* SUB AL,CL */ |
|
105 | 104 |
al = al - cl; |
106 | 105 |
j++; |
107 | 106 |
break; |
108 | 107 |
|
109 |
- case '\x02': // ADD AL,CL |
|
108 |
+ case '\x02': /* ADD AL,CL */ |
|
110 | 109 |
al = al + cl; |
111 | 110 |
j++; |
112 | 111 |
break |
113 | 112 |
; |
114 |
- case '\x32': // XOR AL,CL |
|
113 |
+ case '\x32': /* XOR AL,CL */ |
|
115 | 114 |
al = al ^ cl; |
116 | 115 |
j++; |
117 | 116 |
break; |
118 | 117 |
; |
119 |
- case '\x04': // ADD AL,num |
|
118 |
+ case '\x04': /* ADD AL,num */ |
|
120 | 119 |
j++; |
121 | 120 |
al = al + decryptor_offset[j]; |
122 | 121 |
break; |
123 | 122 |
; |
124 |
- case '\x34': // XOR AL,num |
|
123 |
+ case '\x34': /* XOR AL,num */ |
|
125 | 124 |
j++; |
126 | 125 |
al = al ^ decryptor_offset[j]; |
127 | 126 |
break; |
128 | 127 |
|
129 |
- case '\x2C': // SUB AL,num |
|
128 |
+ case '\x2C': /* SUB AL,num */ |
|
130 | 129 |
j++; |
131 | 130 |
al = al - decryptor_offset[j]; |
132 | 131 |
break; |
... | ... |
@@ -134,12 +133,12 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx |
134 | 134 |
|
135 | 135 |
case '\xC0': |
136 | 136 |
j++; |
137 |
- if(decryptor_offset[j]=='\xC0') // ROL AL,num |
|
137 |
+ if(decryptor_offset[j]=='\xC0') /* ROL AL,num */ |
|
138 | 138 |
{ |
139 | 139 |
j++; |
140 | 140 |
al = ROL(al,decryptor_offset[j]); |
141 | 141 |
} |
142 |
- else // ROR AL,num |
|
142 |
+ else /* ROR AL,num */ |
|
143 | 143 |
{ |
144 | 144 |
j++; |
145 | 145 |
ROR(al,decryptor_offset[j]); |
... | ... |
@@ -148,12 +147,12 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx |
148 | 148 |
|
149 | 149 |
case '\xD2': |
150 | 150 |
j++; |
151 |
- if(decryptor_offset[j]=='\xC8') // ROR AL,CL |
|
151 |
+ if(decryptor_offset[j]=='\xC8') /* ROR AL,CL */ |
|
152 | 152 |
{ |
153 | 153 |
j++; |
154 | 154 |
ROR(al,cl); |
155 | 155 |
} |
156 |
- else // ROL AL,CL |
|
156 |
+ else /* ROL AL,CL */ |
|
157 | 157 |
{ |
158 | 158 |
j++; |
159 | 159 |
ROL(al,cl); |
... | ... |
@@ -177,9 +176,9 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx |
177 | 177 |
} |
178 | 178 |
|
179 | 179 |
|
180 |
-//================================================================================== |
|
181 |
-// Main routine which calls all others |
|
182 |
-// |
|
180 |
+/* ========================================================================== */ |
|
181 |
+/* Main routine which calls all others */ |
|
182 |
+ |
|
183 | 183 |
int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *sections, unsigned int sectcount, uint32_t peoffset, int desc) |
184 | 184 |
{ |
185 | 185 |
uint32_t ycsect = EC32(sections[sectcount].PointerToRawData); |
... | ... |
@@ -211,19 +210,19 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
211 | 211 |
*/ |
212 | 212 |
|
213 | 213 |
|
214 |
- // Loop through all sections and decrypt them... |
|
214 |
+ /* Loop through all sections and decrypt them... */ |
|
215 | 215 |
for(i;i<sectcount;i++) |
216 | 216 |
{ |
217 | 217 |
uint32_t name = (uint32_t) cli_readint32((char *)sections[i].Name); |
218 |
- if ( name == 0x63727372 || // rsrc |
|
219 |
- name == 0x7273722E || // .rsr |
|
220 |
- name == 0x6F6C6572 || // relo |
|
221 |
- name == 0x6C65722E || // .rel |
|
222 |
- name == 0x6164652E || // .eda |
|
223 |
- name == 0x6164722E || // .rda |
|
224 |
- name == 0x6164692E || // .ida |
|
225 |
- name == 0x736C742E || // .tls |
|
226 |
- name&0xffff == 0x4379 || // yC |
|
218 |
+ if ( name == 0x63727372 || /* rsrc */ |
|
219 |
+ name == 0x7273722E || /* .rsr */ |
|
220 |
+ name == 0x6F6C6572 || /* relo */ |
|
221 |
+ name == 0x6C65722E || /* .rel */ |
|
222 |
+ name == 0x6164652E || /* .eda */ |
|
223 |
+ name == 0x6164722E || /* .rda */ |
|
224 |
+ name == 0x6164692E || /* .ida */ |
|
225 |
+ name == 0x736C742E || /* .tls */ |
|
226 |
+ name&0xffff == 0x4379 || /* yC */ |
|
227 | 227 |
EC32(sections[i].PointerToRawData) == 0 || |
228 | 228 |
EC32(sections[i].SizeOfRawData) == 0 ) continue; |
229 | 229 |
cli_dbgmsg("yC: decrypting sect%d\n",i); |
... | ... |
@@ -231,23 +230,22 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
231 | 231 |
return 1; |
232 | 232 |
} |
233 | 233 |
|
234 |
- // Remove yC section |
|
235 |
- pe->NumberOfSections=EC16(EC16(pe->NumberOfSections)-1); |
|
234 |
+ /* Remove yC section */ |
|
235 |
+ pe->NumberOfSections=EC16(pe->NumberOfSections)-1; |
|
236 | 236 |
|
237 |
- // Remove IMPORT_DIRECTORY information |
|
237 |
+ /* Remove IMPORT_DIRECTORY information */ |
|
238 | 238 |
memset((char *)pe + sizeof(struct pe_image_file_hdr) + 0x68, 0, 8); |
239 | 239 |
|
240 |
- // OEP resolving |
|
241 |
- // OEP = DWORD PTR [ Start of yC section+ A0F] |
|
240 |
+ /* OEP resolving */ |
|
241 |
+ /* OEP = DWORD PTR [ Start of yC section+ A0F] */ |
|
242 | 242 |
cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 16, cli_readint32(fbuf + ycsect + 0xa0f)); |
243 | 243 |
|
244 |
- // Fix SizeOfImage |
|
244 |
+ /* Fix SizeOfImage */ |
|
245 | 245 |
cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38, cli_readint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38) - EC32(sections[sectcount].VirtualSize)); |
246 | 246 |
|
247 | 247 |
if (cli_writen(desc, fbuf, filesize)==-1) { |
248 |
- cli_dbgmsg("yc: Cannot write unpacked file\n"); |
|
248 |
+ cli_dbgmsg("yC: Cannot write unpacked file\n"); |
|
249 | 249 |
return 1; |
250 | 250 |
} |
251 | 251 |
return 0; |
252 | 252 |
} |
253 |
- |