|
|
|
|
@ -794,60 +794,60 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
|
|
|
|
cli_dbgmsg("in kriz\n"); |
|
|
|
|
lseek(desc, ep, SEEK_SET); |
|
|
|
|
if(cli_readn(desc, buff, 200) == 200) { |
|
|
|
|
while (1) { |
|
|
|
|
char *krizpos=buff+3; |
|
|
|
|
char *krizmov, *krizxor; |
|
|
|
|
int krizleft = 200-3; |
|
|
|
|
int krizrega,krizregb; |
|
|
|
|
|
|
|
|
|
if (buff[1]!='\x9c' || buff[2]!='\x60') break; /* EP+1 */ |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, 8); |
|
|
|
|
if (krizleft < 6 || *krizpos!='\xe8' || krizpos[2] || krizpos[3] || krizpos[4]) break; /* call DELTA */ |
|
|
|
|
krizleft-=5+(unsigned char)krizpos[1]; |
|
|
|
|
if (krizleft < 2) break; |
|
|
|
|
krizpos+=5+(unsigned char)krizpos[1]; |
|
|
|
|
if (*krizpos<'\x58' || *krizpos>'\x5f' || *krizpos=='\x5c') break; /* pop DELTA */ |
|
|
|
|
krizrega=*krizpos-'\x58'; |
|
|
|
|
cli_dbgmsg("kriz: pop delta using %d\n", krizrega); |
|
|
|
|
krizpos+=1; |
|
|
|
|
krizleft-=1; |
|
|
|
|
xckriz(&krizpos, &krizleft, 1, 8); |
|
|
|
|
if (krizleft <6 || *krizpos<'\xb8' || *krizpos>'\xbf' || *krizpos=='\xbc' || cli_readint32(krizpos+1)!=0x0fd2) break; |
|
|
|
|
krizregb=*krizpos-'\xb8'; |
|
|
|
|
if (krizrega==krizregb) break; |
|
|
|
|
cli_dbgmsg("kriz: using %d for size\n", krizregb); |
|
|
|
|
krizpos+=5; |
|
|
|
|
krizleft-=5; |
|
|
|
|
krizmov = krizpos; |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, 8); |
|
|
|
|
krizxor=krizpos; |
|
|
|
|
if (krizleft && *krizpos=='\x3e') { |
|
|
|
|
/* strip ds: */ |
|
|
|
|
krizpos++; |
|
|
|
|
krizleft--; |
|
|
|
|
} |
|
|
|
|
if (krizleft<8 || *krizpos!='\x80' || (char)(krizpos[1]-krizrega)!='\xb0') { |
|
|
|
|
cli_dbgmsg("kriz: bogus opcode or register\n"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
krizpos+=7; |
|
|
|
|
krizleft-=7; |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, krizrega); |
|
|
|
|
if (! krizleft || (char)(*krizpos-krizrega)!='\x48') break; /* dec delta */ |
|
|
|
|
krizpos++; |
|
|
|
|
krizleft--; |
|
|
|
|
cli_dbgmsg("kriz: dec delta found\n"); |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, krizregb); |
|
|
|
|
if (krizleft <4 || (char)(*krizpos-krizregb)!='\x48' || krizpos[1]!='\x75') break; /* dec size + jne loop */ |
|
|
|
|
if (krizpos+3+(int)krizpos[2]<krizmov || krizpos+3+(int)krizpos[2]>krizxor) { |
|
|
|
|
cli_dbgmsg("kriz: jmp back out of range (%d>%d>%d)\n", krizmov-(krizpos+3), (int)krizpos[2], krizxor-(krizpos+3)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
*ctx->virname = "Win32.Kriz"; |
|
|
|
|
free(section_hdr); |
|
|
|
|
free(exe_sections); |
|
|
|
|
return CL_VIRUS; |
|
|
|
|
while (1) { |
|
|
|
|
char *krizpos=buff+3; |
|
|
|
|
char *krizmov, *krizxor; |
|
|
|
|
int krizleft = 200-3; |
|
|
|
|
int krizrega,krizregb; |
|
|
|
|
|
|
|
|
|
if (buff[1]!='\x9c' || buff[2]!='\x60') break; /* EP+1 */ |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, 8); |
|
|
|
|
if (krizleft < 6 || *krizpos!='\xe8' || krizpos[2] || krizpos[3] || krizpos[4]) break; /* call DELTA */ |
|
|
|
|
krizleft-=5+(unsigned char)krizpos[1]; |
|
|
|
|
if (krizleft < 2) break; |
|
|
|
|
krizpos+=5+(unsigned char)krizpos[1]; |
|
|
|
|
if (*krizpos<'\x58' || *krizpos>'\x5f' || *krizpos=='\x5c') break; /* pop DELTA */ |
|
|
|
|
krizrega=*krizpos-'\x58'; |
|
|
|
|
cli_dbgmsg("kriz: pop delta using %d\n", krizrega); |
|
|
|
|
krizpos+=1; |
|
|
|
|
krizleft-=1; |
|
|
|
|
xckriz(&krizpos, &krizleft, 1, 8); |
|
|
|
|
if (krizleft <6 || *krizpos<'\xb8' || *krizpos>'\xbf' || *krizpos=='\xbc' || cli_readint32(krizpos+1)!=0x0fd2) break; |
|
|
|
|
krizregb=*krizpos-'\xb8'; |
|
|
|
|
if (krizrega==krizregb) break; |
|
|
|
|
cli_dbgmsg("kriz: using %d for size\n", krizregb); |
|
|
|
|
krizpos+=5; |
|
|
|
|
krizleft-=5; |
|
|
|
|
krizmov = krizpos; |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, 8); |
|
|
|
|
krizxor=krizpos; |
|
|
|
|
if (krizleft && *krizpos=='\x3e') { |
|
|
|
|
/* strip ds: */ |
|
|
|
|
krizpos++; |
|
|
|
|
krizleft--; |
|
|
|
|
} |
|
|
|
|
if (krizleft<8 || *krizpos!='\x80' || (char)(krizpos[1]-krizrega)!='\xb0') { |
|
|
|
|
cli_dbgmsg("kriz: bogus opcode or register\n"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
krizpos+=7; |
|
|
|
|
krizleft-=7; |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, krizrega); |
|
|
|
|
if (! krizleft || (char)(*krizpos-krizrega)!='\x48') break; /* dec delta */ |
|
|
|
|
krizpos++; |
|
|
|
|
krizleft--; |
|
|
|
|
cli_dbgmsg("kriz: dec delta found\n"); |
|
|
|
|
xckriz(&krizpos, &krizleft, 0, krizregb); |
|
|
|
|
if (krizleft <4 || (char)(*krizpos-krizregb)!='\x48' || krizpos[1]!='\x75') break; /* dec size + jne loop */ |
|
|
|
|
if (krizpos+3+(int)krizpos[2]<krizmov || krizpos+3+(int)krizpos[2]>krizxor) { |
|
|
|
|
cli_dbgmsg("kriz: jmp back out of range (%d>%d>%d)\n", krizmov-(krizpos+3), (int)krizpos[2], krizxor-(krizpos+3)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
*ctx->virname = "Win32.Kriz"; |
|
|
|
|
free(section_hdr); |
|
|
|
|
free(exe_sections); |
|
|
|
|
return CL_VIRUS; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -855,13 +855,13 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
|
|
|
|
if(SCAN_ALGO && !dll && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)) { |
|
|
|
|
uint32_t rsize, vsize; |
|
|
|
|
|
|
|
|
|
rsize = EC32(section_hdr[nsections - 1].SizeOfRawData); |
|
|
|
|
vsize = EC32(section_hdr[nsections - 1].VirtualSize); |
|
|
|
|
rsize = exe_sections[nsections - 1].rsz; |
|
|
|
|
vsize = exe_sections[nsections - 1].vsz; |
|
|
|
|
|
|
|
|
|
if(rsize >= 0x612c && vsize >= 0x612c && ((vsize & 0xff) == 0xec)) { |
|
|
|
|
int bw = rsize < 0x7000 ? rsize : 0x7000; |
|
|
|
|
|
|
|
|
|
lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET); |
|
|
|
|
lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET); |
|
|
|
|
if(cli_readn(desc, buff, 4096) == 4096) { |
|
|
|
|
if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) { |
|
|
|
|
*ctx->virname = "W32.Magistr.A"; |
|
|
|
|
@ -874,7 +874,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
|
|
|
|
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) { |
|
|
|
|
int bw = rsize < 0x8000 ? rsize : 0x8000; |
|
|
|
|
|
|
|
|
|
lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET); |
|
|
|
|
lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET); |
|
|
|
|
if(cli_readn(desc, buff, 4096) == 4096) { |
|
|
|
|
if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) { |
|
|
|
|
*ctx->virname = "W32.Magistr.B"; |
|
|
|
|
|