Stack protector support.

0.96
Török Edvin 16 years ago
parent a9fe8977e7
commit 9463f9fd90
  1. 3
      clambc/bcrun.c
  2. 11
      libclamav/bytecode.c
  3. 73
      libclamav/c++/bytecode2llvm.cpp
  4. 7
      libclamav/clambc.h
  5. 2
      libclamav/pe.c
  6. 2
      unit_tests/input/apicalls.cbc
  7. 4
      unit_tests/input/apicalls2.cbc
  8. 2
      unit_tests/input/arith.cbc
  9. 2
      unit_tests/input/div0.cbc
  10. 6
      unit_tests/input/lsig.cbc
  11. 2
      unit_tests/input/retmagic.cbc

@ -139,8 +139,6 @@ int main(int argc, char *argv[])
exit(1);
}
if(optget(opts, "version")->enabled) {
char versions[] = "--version";
char* argvx[] = {argv[0], versions,NULL};
printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version());
cl_init(CL_INIT_DEFAULT);
cli_bytecode_printversion();
@ -265,7 +263,6 @@ int main(int argc, char *argv[])
funmap(map);
}
rc = cli_bytecode_run(&bcs, bc, ctx);
if (rc != CL_SUCCESS) {
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
(1ull<<inst.u.cast.mask)-1 :
~0ull;
break;
case OP_BC_GEP1:
case OP_BC_GEPZ:
inst.u.three[0] = readNumber(buffer, &offset, len, &ok);
inst.u.three[1] = readOperand(bcfunc, buffer, &offset, len, &ok);
inst.u.three[2] = readOperand(bcfunc, buffer, &offset, len, &ok);
break;
case OP_BC_GEPN:
numOp = readFixedNumber(buffer, &offset, len, &ok, 1);
if (ok) {
inst.u.ops.numOps = numOp+1;
inst.u.ops.numOps = numOp+2;
inst.u.ops.opsizes = NULL;
inst.u.ops.ops = cli_calloc(numOp, sizeof(*inst.u.ops.ops));
if (!inst.u.ops.ops) {
@ -1092,7 +1098,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
return CL_EMEM;
}
inst.u.ops.ops[0] = readNumber(buffer, &offset, len, &ok);
for (i=1;i<numOp+1;i++)
for (i=1;i<numOp+2;i++)
inst.u.ops.ops[i] = readOperand(bcfunc, buffer, &offset, len, &ok);
}
break;
@ -1548,6 +1554,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
MAP(inst->u.unaryop);
break;
case OP_BC_GEP1:
case OP_BC_GEPZ:
//three[0] is the type
MAP(inst->u.three[1]);
MAP(inst->u.three[2]);

@ -76,15 +76,23 @@
#include "bytecode.h"
#include "bytecode_priv.h"
#include "type_desc.h"
extern "C" {
#include "md5.h"
}
#define MODULE "libclamav JIT: "
extern "C" unsigned int cli_rndnum(unsigned int max);
using namespace llvm;
typedef DenseMap<const struct cli_bc_func*, void*> FunctionMapTy;
struct cli_bcengine {
ExecutionEngine *EE;
LLVMContext Context;
FunctionMapTy compiledFunctions;
union {
unsigned char b[16];
void* align;/* just to align field to ptr */
} guard;
};
namespace {
@ -101,6 +109,12 @@ static void NORETURN jit_exception_handler(void)
longjmp(*const_cast<jmp_buf*>(ExceptionReturn.get()), 1);
}
static void NORETURN jit_ssp_handler(void)
{
errs() << "Bytecode JIT: *** stack smashing detected, bytecode aborted\n";
jit_exception_handler();
}
void llvm_error_handler(void *user_data, const std::string &reason)
{
// Output it to stderr, it might exceed the 1k/4k limit of cli_errmsg
@ -471,6 +485,18 @@ public:
return N;
}
void AddStackProtect(Function *F)
{
BasicBlock &BB = F->getEntryBlock();
if (isa<AllocaInst>(BB.begin())) {
// Have an alloca -> some instruction uses its address otherwise
// mem2reg would have converted it to an SSA register.
// Enable stack protector for this function.
F->addFnAttr(Attribute::StackProtect);
F->addFnAttr(Attribute::StackProtectReq);
}
}
bool generate() {
TypeMap = new LLVMTypeMapper(Context, bc->types + 4, bc->num_types - 5);
for (unsigned i=0;i<bc->dbgnode_cnt;i++) {
@ -493,6 +519,7 @@ public:
FHandler->addFnAttr(Attribute::NoInline);
EE->addGlobalMapping(FHandler, (void*)(intptr_t)jit_exception_handler);
std::vector<const Type*> args;
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
args.push_back(Type::getInt8Ty(Context));
@ -683,6 +710,7 @@ public:
case OP_BC_SEXT:
case OP_BC_TRUNC:
case OP_BC_GEP1:
case OP_BC_GEPZ:
case OP_BC_GEPN:
case OP_BC_STORE:
case OP_BC_COPY:
@ -892,6 +920,17 @@ public:
return false;
break;
}
case OP_BC_GEPZ:
{
Value *Ops[2];
Ops[0] = ConstantInt::get(Type::getInt32Ty(Context), 0);
const Type *SrcTy = mapType(inst->u.three[0]);
Value *V = convertOperand(func, SrcTy, inst->u.three[1]);
Ops[1] = convertOperand(func, I32Ty, inst->u.three[2]);
if (!createGEP(inst->dest, V, Ops, Ops+2))
return false;
break;
}
case OP_BC_GEPN:
{
std::vector<Value*> Idxs;
@ -995,6 +1034,7 @@ public:
return false;
}
PM.run(*F);
AddStackProtect(F);
delete [] Values;
delete [] BB;
}
@ -1068,6 +1108,20 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
return CL_EBYTECODE;
}
static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
static void setGuard(unsigned char* guardbuf)
{
cli_md5_ctx ctx;
char salt[48];
memcpy(salt, name_salt, 16);
for(unsigned i = 16; i < 48; i++)
salt[i] = cli_rndnum(255);
cli_md5_init(&ctx);
cli_md5_update(&ctx, salt, 48);
cli_md5_final(guardbuf, &ctx);
}
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
{
if (!bcs->engine)
@ -1092,7 +1146,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
EngineBuilder builder(MP);
builder.setErrorStr(&ErrorMsg);
builder.setEngineKind(EngineKind::JIT);
builder.setOptLevel(CodeGenOpt::Aggressive);
builder.setOptLevel(CodeGenOpt::Default);
ExecutionEngine *EE = bcs->engine->EE = builder.create();
if (!EE) {
if (!ErrorMsg.empty())
@ -1141,6 +1195,23 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
apiFuncs[i] = F;
}
// stack protector
FunctionType *FTy = FunctionType::get(Type::getVoidTy(M->getContext()),
false);
GlobalVariable *Guard = new GlobalVariable(*M, PointerType::getUnqual(Type::getInt8Ty(M->getContext())),
true, GlobalValue::InternalLinkage, 0, "__stack_chk_guard");
unsigned plus = 0;
if (2*sizeof(void*) <= 16 && cli_rndnum(2)==2) {
plus = sizeof(void*);
}
EE->addGlobalMapping(Guard, (void*)(&bcs->engine->guard.b[plus]));
setGuard(bcs->engine->guard.b);
bcs->engine->guard.b[plus+sizeof(void*)-1] = 0x00;
// printf("%p\n", *(void**)(&bcs->engine->guard.b[plus]));
Function *SFail = Function::Create(FTy, Function::ExternalLinkage,
"__stack_chk_fail", M);
EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler);
for (unsigned i=0;i<bcs->count;i++) {
const struct cli_bc *bc = &bcs->all_bcs[i];
if (bc->state == bc_skip)

@ -28,7 +28,7 @@ struct bytecode_metadata {
char *targetExclude;
};
#define BC_FUNC_LEVEL 3
#define BC_FUNC_LEVEL 4
#define BC_HEADER "ClamBC"
enum bc_opcode {
@ -70,6 +70,7 @@ enum bc_opcode {
OP_BC_CALL_API,
OP_BC_COPY,
OP_BC_GEP1,
OP_BC_GEPZ,
OP_BC_GEPN,
OP_BC_STORE,
OP_BC_LOAD,
@ -98,8 +99,8 @@ static const unsigned char operand_counts[] = {
0, 0,
/* OP_BC_COPY */
2,
/* OP_BC_GEP1, OP_BC_GEPN, OP_BC_STORE, OP_BC_LOAD*/
3, 0, 2, 1,
/* OP_BC_GEP1, OP_BC_GEPZ, OP_BC_GEPN, OP_BC_STORE, OP_BC_LOAD*/
3, 3, 0, 2, 1,
/* OP_MEM* */
3, 3, 3, 3,
/* OP_BC_ISBIGENDIAN */

@ -1984,7 +1984,7 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset)
/* yC 1.3 & variants */
if((DCONF & PE_CONF_YC) && nsections > 1 &&
if((0 & DCONF & PE_CONF_YC) && nsections > 1 &&
(EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60)) {
uint32_t ecx = 0;

@ -1,4 +1,4 @@
ClamBCac`|``````|`agafp`clamcoincidencejb:82
ClamBCad`|``````|`agafp`clamcoincidencejb:82
Tedaaa`aacb`bb`bb`b
Eabaaabbfd|afdgefcgdgac``

@ -1,10 +1,10 @@
ClamBCac`|``````|`akafp`clamcoincidencejb:86
ClamBCad`|``````|`akafp`clamcoincidencejb:83
Tedcaabfdebedebfdaaa`aacb`bbfdb`baacb`bb`bb`b
Eababaabid|afdgefcgdg`c``abbjd|afdgefcgdgac``
G`aa`@`
A`b`bLahbedabgd```b`b`aa`b`b`aa`b`b`Fajac
Bbgdaadbcbfd`@d@d``eb`aab`bacabbabHonnkm``odHm``oonnkdaaadeab`bacHhgfedcbadTaaadaaab
Bbgdaadbbfd`@d``fb`aab`bacabbabHonnkm``odHm``oonnkdaaadeab`bacHhgfedcbadTaaadaaab
Bb`baeabbaa`Honnkmjnmdaaafeab`baeHhgfedcbadb`bagoaafDm``odDmjnmdTcab`bag
BTcab`bDmjnmdE
Aab`bLabah`aa`b`b`Facaa

@ -1,4 +1,4 @@
ClamBCac`|``````|`afbbep`clamcoincidencejb:418
ClamBCad`|``````|`afbbep`clamcoincidencejb:418
Tedaaa`
E``

@ -1,4 +1,4 @@
ClamBCac`|``````|`afabp`clamcoincidencejb:23
ClamBCad`|``````|`afabp`clamcoincidencejb:23
Tedaaa`
E``

@ -1,11 +1,11 @@
ClamBCac`|``c``a```|`bjaabp`clamcoincidencejb:326
ClamBCad`|``c``a```|`bjaabp`clamcoincidencejb:326
Trojan.Foo.{A,B};Target:1;(((0|1|2)=42,2)|(3=10));EP+0:aabb;ffff;aaccee;f00d;dead
Tedebieebheebgeebfeebeeebdeebbeebaeebadebcdaaa`aacb`bbadb`bdb`db`bcajbadbcebadbcebadbcebadbcebadbcecaab`bdagahdaeahdajahdabbaddabahdakah
Eafaaafb`e|amcgefdgfgifbgegcgnfafmfef``
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`
A`b`bLaeb`b`aa`aa`bad`b`b`Fahac
Bb`b`fbBda`aaaagab`b`AadTaaaaaaab
Bb`b`gbBda`aaaagab`b`AadTaaaaaaab
Baaabeab`b`AbdbadacoaabAm`An`b`badabbafac@dTcab`b@d
BTcab`b@dE
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
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
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

@ -1,4 +1,4 @@
ClamBCac`|``````|`afaap`clamcoincidencejb:20
ClamBCad`|``````|`afaap`clamcoincidencejb:20
Tedaaa`
E``

Loading…
Cancel
Save