| ... | ... |
@@ -139,8 +139,6 @@ int main(int argc, char *argv[]) |
| 139 | 139 |
exit(1); |
| 140 | 140 |
} |
| 141 | 141 |
if(optget(opts, "version")->enabled) {
|
| 142 |
- char versions[] = "--version"; |
|
| 143 |
- char* argvx[] = {argv[0], versions,NULL};
|
|
| 144 | 142 |
printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version());
|
| 145 | 143 |
cl_init(CL_INIT_DEFAULT); |
| 146 | 144 |
cli_bytecode_printversion(); |
| ... | ... |
@@ -265,7 +263,6 @@ int main(int argc, char *argv[]) |
| 265 | 265 |
funmap(map); |
| 266 | 266 |
} |
| 267 | 267 |
|
| 268 |
- |
|
| 269 | 268 |
rc = cli_bytecode_run(&bcs, bc, ctx); |
| 270 | 269 |
if (rc != CL_SUCCESS) {
|
| 271 | 270 |
fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc)); |
| ... | ... |
@@ -1081,10 +1081,16 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char |
| 1081 | 1081 |
(1ull<<inst.u.cast.mask)-1 : |
| 1082 | 1082 |
~0ull; |
| 1083 | 1083 |
break; |
| 1084 |
+ case OP_BC_GEP1: |
|
| 1085 |
+ case OP_BC_GEPZ: |
|
| 1086 |
+ inst.u.three[0] = readNumber(buffer, &offset, len, &ok); |
|
| 1087 |
+ inst.u.three[1] = readOperand(bcfunc, buffer, &offset, len, &ok); |
|
| 1088 |
+ inst.u.three[2] = readOperand(bcfunc, buffer, &offset, len, &ok); |
|
| 1089 |
+ break; |
|
| 1084 | 1090 |
case OP_BC_GEPN: |
| 1085 | 1091 |
numOp = readFixedNumber(buffer, &offset, len, &ok, 1); |
| 1086 | 1092 |
if (ok) {
|
| 1087 |
- inst.u.ops.numOps = numOp+1; |
|
| 1093 |
+ inst.u.ops.numOps = numOp+2; |
|
| 1088 | 1094 |
inst.u.ops.opsizes = NULL; |
| 1089 | 1095 |
inst.u.ops.ops = cli_calloc(numOp, sizeof(*inst.u.ops.ops)); |
| 1090 | 1096 |
if (!inst.u.ops.ops) {
|
| ... | ... |
@@ -1092,7 +1098,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char |
| 1092 | 1092 |
return CL_EMEM; |
| 1093 | 1093 |
} |
| 1094 | 1094 |
inst.u.ops.ops[0] = readNumber(buffer, &offset, len, &ok); |
| 1095 |
- for (i=1;i<numOp+1;i++) |
|
| 1095 |
+ for (i=1;i<numOp+2;i++) |
|
| 1096 | 1096 |
inst.u.ops.ops[i] = readOperand(bcfunc, buffer, &offset, len, &ok); |
| 1097 | 1097 |
} |
| 1098 | 1098 |
break; |
| ... | ... |
@@ -1548,6 +1554,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
| 1548 | 1548 |
MAP(inst->u.unaryop); |
| 1549 | 1549 |
break; |
| 1550 | 1550 |
case OP_BC_GEP1: |
| 1551 |
+ case OP_BC_GEPZ: |
|
| 1551 | 1552 |
//three[0] is the type |
| 1552 | 1553 |
MAP(inst->u.three[1]); |
| 1553 | 1554 |
MAP(inst->u.three[2]); |
| ... | ... |
@@ -76,15 +76,23 @@ |
| 76 | 76 |
#include "bytecode.h" |
| 77 | 77 |
#include "bytecode_priv.h" |
| 78 | 78 |
#include "type_desc.h" |
| 79 |
+extern "C" {
|
|
| 80 |
+#include "md5.h" |
|
| 81 |
+} |
|
| 79 | 82 |
|
| 80 | 83 |
#define MODULE "libclamav JIT: " |
| 81 | 84 |
|
| 85 |
+extern "C" unsigned int cli_rndnum(unsigned int max); |
|
| 82 | 86 |
using namespace llvm; |
| 83 | 87 |
typedef DenseMap<const struct cli_bc_func*, void*> FunctionMapTy; |
| 84 | 88 |
struct cli_bcengine {
|
| 85 | 89 |
ExecutionEngine *EE; |
| 86 | 90 |
LLVMContext Context; |
| 87 | 91 |
FunctionMapTy compiledFunctions; |
| 92 |
+ union {
|
|
| 93 |
+ unsigned char b[16]; |
|
| 94 |
+ void* align;/* just to align field to ptr */ |
|
| 95 |
+ } guard; |
|
| 88 | 96 |
}; |
| 89 | 97 |
|
| 90 | 98 |
namespace {
|
| ... | ... |
@@ -101,6 +109,12 @@ static void NORETURN jit_exception_handler(void) |
| 101 | 101 |
longjmp(*const_cast<jmp_buf*>(ExceptionReturn.get()), 1); |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 |
+static void NORETURN jit_ssp_handler(void) |
|
| 105 |
+{
|
|
| 106 |
+ errs() << "Bytecode JIT: *** stack smashing detected, bytecode aborted\n"; |
|
| 107 |
+ jit_exception_handler(); |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 104 | 110 |
void llvm_error_handler(void *user_data, const std::string &reason) |
| 105 | 111 |
{
|
| 106 | 112 |
// Output it to stderr, it might exceed the 1k/4k limit of cli_errmsg |
| ... | ... |
@@ -471,6 +485,18 @@ public: |
| 471 | 471 |
return N; |
| 472 | 472 |
} |
| 473 | 473 |
|
| 474 |
+ void AddStackProtect(Function *F) |
|
| 475 |
+ {
|
|
| 476 |
+ BasicBlock &BB = F->getEntryBlock(); |
|
| 477 |
+ if (isa<AllocaInst>(BB.begin())) {
|
|
| 478 |
+ // Have an alloca -> some instruction uses its address otherwise |
|
| 479 |
+ // mem2reg would have converted it to an SSA register. |
|
| 480 |
+ // Enable stack protector for this function. |
|
| 481 |
+ F->addFnAttr(Attribute::StackProtect); |
|
| 482 |
+ F->addFnAttr(Attribute::StackProtectReq); |
|
| 483 |
+ } |
|
| 484 |
+ } |
|
| 485 |
+ |
|
| 474 | 486 |
bool generate() {
|
| 475 | 487 |
TypeMap = new LLVMTypeMapper(Context, bc->types + 4, bc->num_types - 5); |
| 476 | 488 |
for (unsigned i=0;i<bc->dbgnode_cnt;i++) {
|
| ... | ... |
@@ -493,6 +519,7 @@ public: |
| 493 | 493 |
FHandler->addFnAttr(Attribute::NoInline); |
| 494 | 494 |
EE->addGlobalMapping(FHandler, (void*)(intptr_t)jit_exception_handler); |
| 495 | 495 |
|
| 496 |
+ |
|
| 496 | 497 |
std::vector<const Type*> args; |
| 497 | 498 |
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
| 498 | 499 |
args.push_back(Type::getInt8Ty(Context)); |
| ... | ... |
@@ -683,6 +710,7 @@ public: |
| 683 | 683 |
case OP_BC_SEXT: |
| 684 | 684 |
case OP_BC_TRUNC: |
| 685 | 685 |
case OP_BC_GEP1: |
| 686 |
+ case OP_BC_GEPZ: |
|
| 686 | 687 |
case OP_BC_GEPN: |
| 687 | 688 |
case OP_BC_STORE: |
| 688 | 689 |
case OP_BC_COPY: |
| ... | ... |
@@ -892,6 +920,17 @@ public: |
| 892 | 892 |
return false; |
| 893 | 893 |
break; |
| 894 | 894 |
} |
| 895 |
+ case OP_BC_GEPZ: |
|
| 896 |
+ {
|
|
| 897 |
+ Value *Ops[2]; |
|
| 898 |
+ Ops[0] = ConstantInt::get(Type::getInt32Ty(Context), 0); |
|
| 899 |
+ const Type *SrcTy = mapType(inst->u.three[0]); |
|
| 900 |
+ Value *V = convertOperand(func, SrcTy, inst->u.three[1]); |
|
| 901 |
+ Ops[1] = convertOperand(func, I32Ty, inst->u.three[2]); |
|
| 902 |
+ if (!createGEP(inst->dest, V, Ops, Ops+2)) |
|
| 903 |
+ return false; |
|
| 904 |
+ break; |
|
| 905 |
+ } |
|
| 895 | 906 |
case OP_BC_GEPN: |
| 896 | 907 |
{
|
| 897 | 908 |
std::vector<Value*> Idxs; |
| ... | ... |
@@ -995,6 +1034,7 @@ public: |
| 995 | 995 |
return false; |
| 996 | 996 |
} |
| 997 | 997 |
PM.run(*F); |
| 998 |
+ AddStackProtect(F); |
|
| 998 | 999 |
delete [] Values; |
| 999 | 1000 |
delete [] BB; |
| 1000 | 1001 |
} |
| ... | ... |
@@ -1068,6 +1108,20 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx, |
| 1068 | 1068 |
return CL_EBYTECODE; |
| 1069 | 1069 |
} |
| 1070 | 1070 |
|
| 1071 |
+static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
|
|
| 1072 |
+static void setGuard(unsigned char* guardbuf) |
|
| 1073 |
+{
|
|
| 1074 |
+ cli_md5_ctx ctx; |
|
| 1075 |
+ char salt[48]; |
|
| 1076 |
+ memcpy(salt, name_salt, 16); |
|
| 1077 |
+ for(unsigned i = 16; i < 48; i++) |
|
| 1078 |
+ salt[i] = cli_rndnum(255); |
|
| 1079 |
+ |
|
| 1080 |
+ cli_md5_init(&ctx); |
|
| 1081 |
+ cli_md5_update(&ctx, salt, 48); |
|
| 1082 |
+ cli_md5_final(guardbuf, &ctx); |
|
| 1083 |
+} |
|
| 1084 |
+ |
|
| 1071 | 1085 |
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
| 1072 | 1086 |
{
|
| 1073 | 1087 |
if (!bcs->engine) |
| ... | ... |
@@ -1092,7 +1146,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
| 1092 | 1092 |
EngineBuilder builder(MP); |
| 1093 | 1093 |
builder.setErrorStr(&ErrorMsg); |
| 1094 | 1094 |
builder.setEngineKind(EngineKind::JIT); |
| 1095 |
- builder.setOptLevel(CodeGenOpt::Aggressive); |
|
| 1095 |
+ builder.setOptLevel(CodeGenOpt::Default); |
|
| 1096 | 1096 |
ExecutionEngine *EE = bcs->engine->EE = builder.create(); |
| 1097 | 1097 |
if (!EE) {
|
| 1098 | 1098 |
if (!ErrorMsg.empty()) |
| ... | ... |
@@ -1141,6 +1195,23 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
| 1141 | 1141 |
apiFuncs[i] = F; |
| 1142 | 1142 |
} |
| 1143 | 1143 |
|
| 1144 |
+ // stack protector |
|
| 1145 |
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(M->getContext()), |
|
| 1146 |
+ false); |
|
| 1147 |
+ GlobalVariable *Guard = new GlobalVariable(*M, PointerType::getUnqual(Type::getInt8Ty(M->getContext())), |
|
| 1148 |
+ true, GlobalValue::InternalLinkage, 0, "__stack_chk_guard"); |
|
| 1149 |
+ unsigned plus = 0; |
|
| 1150 |
+ if (2*sizeof(void*) <= 16 && cli_rndnum(2)==2) {
|
|
| 1151 |
+ plus = sizeof(void*); |
|
| 1152 |
+ } |
|
| 1153 |
+ EE->addGlobalMapping(Guard, (void*)(&bcs->engine->guard.b[plus])); |
|
| 1154 |
+ setGuard(bcs->engine->guard.b); |
|
| 1155 |
+ bcs->engine->guard.b[plus+sizeof(void*)-1] = 0x00; |
|
| 1156 |
+// printf("%p\n", *(void**)(&bcs->engine->guard.b[plus]));
|
|
| 1157 |
+ Function *SFail = Function::Create(FTy, Function::ExternalLinkage, |
|
| 1158 |
+ "__stack_chk_fail", M); |
|
| 1159 |
+ EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler); |
|
| 1160 |
+ |
|
| 1144 | 1161 |
for (unsigned i=0;i<bcs->count;i++) {
|
| 1145 | 1162 |
const struct cli_bc *bc = &bcs->all_bcs[i]; |
| 1146 | 1163 |
if (bc->state == bc_skip) |
| ... | ... |
@@ -28,7 +28,7 @@ struct bytecode_metadata {
|
| 28 | 28 |
char *targetExclude; |
| 29 | 29 |
}; |
| 30 | 30 |
|
| 31 |
-#define BC_FUNC_LEVEL 3 |
|
| 31 |
+#define BC_FUNC_LEVEL 4 |
|
| 32 | 32 |
#define BC_HEADER "ClamBC" |
| 33 | 33 |
|
| 34 | 34 |
enum bc_opcode {
|
| ... | ... |
@@ -70,6 +70,7 @@ enum bc_opcode {
|
| 70 | 70 |
OP_BC_CALL_API, |
| 71 | 71 |
OP_BC_COPY, |
| 72 | 72 |
OP_BC_GEP1, |
| 73 |
+ OP_BC_GEPZ, |
|
| 73 | 74 |
OP_BC_GEPN, |
| 74 | 75 |
OP_BC_STORE, |
| 75 | 76 |
OP_BC_LOAD, |
| ... | ... |
@@ -98,8 +99,8 @@ static const unsigned char operand_counts[] = {
|
| 98 | 98 |
0, 0, |
| 99 | 99 |
/* OP_BC_COPY */ |
| 100 | 100 |
2, |
| 101 |
- /* OP_BC_GEP1, OP_BC_GEPN, OP_BC_STORE, OP_BC_LOAD*/ |
|
| 102 |
- 3, 0, 2, 1, |
|
| 101 |
+ /* OP_BC_GEP1, OP_BC_GEPZ, OP_BC_GEPN, OP_BC_STORE, OP_BC_LOAD*/ |
|
| 102 |
+ 3, 3, 0, 2, 1, |
|
| 103 | 103 |
/* OP_MEM* */ |
| 104 | 104 |
3, 3, 3, 3, |
| 105 | 105 |
/* OP_BC_ISBIGENDIAN */ |
| ... | ... |
@@ -1984,7 +1984,7 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset) |
| 1984 | 1984 |
|
| 1985 | 1985 |
|
| 1986 | 1986 |
/* yC 1.3 & variants */ |
| 1987 |
- if((DCONF & PE_CONF_YC) && nsections > 1 && |
|
| 1987 |
+ if((0 & DCONF & PE_CONF_YC) && nsections > 1 && |
|
| 1988 | 1988 |
(EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60)) {
|
| 1989 | 1989 |
|
| 1990 | 1990 |
uint32_t ecx = 0; |
| ... | ... |
@@ -1,10 +1,10 @@ |
| 1 |
-ClamBCac`|``````|`akafp`clamcoincidencejb:86 |
|
| 1 |
+ClamBCad`|``````|`akafp`clamcoincidencejb:83 |
|
| 2 | 2 |
|
| 3 | 3 |
Tedcaabfdebedebfdaaa`aacb`bbfdb`baacb`bb`bb`b |
| 4 | 4 |
Eababaabid|afdgefcgdg`c``abbjd|afdgefcgdgac`` |
| 5 | 5 |
G`aa`@` |
| 6 | 6 |
A`b`bLahbedabgd```b`b`aa`b`b`aa`b`b`Fajac |
| 7 |
-Bbgdaadbcbfd`@d@d``eb`aab`bacabbabHonnkm``odHm``oonnkdaaadeab`bacHhgfedcbadTaaadaaab |
|
| 7 |
+Bbgdaadbbfd`@d``fb`aab`bacabbabHonnkm``odHm``oonnkdaaadeab`bacHhgfedcbadTaaadaaab |
|
| 8 | 8 |
Bb`baeabbaa`Honnkmjnmdaaafeab`baeHhgfedcbadb`bagoaafDm``odDmjnmdTcab`bag |
| 9 | 9 |
BTcab`bDmjnmdE |
| 10 | 10 |
Aab`bLabah`aa`b`b`Facaa |
| ... | ... |
@@ -1,11 +1,11 @@ |
| 1 |
-ClamBCac`|``c``a```|`bjaabp`clamcoincidencejb:326 |
|
| 1 |
+ClamBCad`|``c``a```|`bjaabp`clamcoincidencejb:326 |
|
| 2 | 2 |
Trojan.Foo.{A,B};Target:1;(((0|1|2)=42,2)|(3=10));EP+0:aabb;ffff;aaccee;f00d;dead
|
| 3 | 3 |
Tedebieebheebgeebfeebeeebdeebbeebaeebadebcdaaa`aacb`bbadb`bdb`db`bcajbadbcebadbcebadbcebadbcebadbcecaab`bdagahdaeahdajahdabbaddabahdakah |
| 4 | 4 |
Eafaaafb`e|amcgefdgfgifbgegcgnfafmfef`` |
| 5 | 5 |
Gd```hbia`@`bieBdeBbgBofBjfBafBnfBnbBfdBofBof@`bheBad@`bheBbd@`bge@Ab@Ac`b`aAa`b`aC``a`bfeBedB`eBkbB`cBjcBafBafBbfBbf@`beeBffBffBffBff@`beeBffB`cB`cBdf@`bdeBafBafBcfBcfBefBef@`beeBdfBefBafBdf@`bbe@Ag@@AhAa@AiAc@AjAb@AkAd`bad@Ab`bad@Ac`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bcdAdD```h`bcdAcD```h`bcdAbD```h`bcdAaD```h`bcd@D```h` |
| 6 | 6 |
A`b`bLaeb`b`aa`aa`bad`b`b`Fahac |
| 7 |
-Bb`b`fbBda`aaaagab`b`AadTaaaaaaab |
|
| 7 |
+Bb`b`gbBda`aaaagab`b`AadTaaaaaaab |
|
| 8 | 8 |
Baaabeab`b`AbdbadacoaabAm`An`b`badabbafac@dTcab`b@d |
| 9 | 9 |
BTcab`b@dE |
| 10 | 10 |
A`aaLbcab`b`b`b`b`b`b`b`b`b`aa`aa`aa`aa`b`b`b`b`b`b`b`b`b`b`aa`aa`b`b`aa`aa`Fbdaaa |
| 11 |
-Bb`b`fbBha`b`baafbBga`b`babfbBfa`b`baca`aa`b`bada`acabaaaeeab`badBjbdaaaffab`bab@daaagfab`baa@daaahfab`b`@db`bai`aafb`baj`aagb`bak`aahb`bala`ajakb`bama`alaiaaaneab`bamAbdaaaok`anaeb`bb`afbBea`aabaaeab`bb`aAjdaabbal`aobaaTcaaabbaE |
|
| 11 |
+Bb`b`gbBha`b`baagbBga`b`babgbBfa`b`baca`aa`b`bada`acabaaaeeab`badBjbdaaaffab`bab@daaagfab`baa@daaahfab`b`@db`bai`aafb`baj`aagb`bak`aahb`bala`ajakb`bama`alaiaaaneab`bamAbdaaaok`anaeb`bb`agbBea`aabaaeab`bb`aAjdaabbal`aobaaTcaaabbaE |