/*
* Copyright (c) 2002
- * Politecnico di Torino. All rights reserved.
+ * Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
//
void emit_lenght(binary_stream *stream, ULONG value, UINT len)
{
- (stream->refs)[stream->bpf_pc]+=len;
- stream->cur_ip+=len;
+ (stream->refs)[stream->bpf_pc]+=len;
+ stream->cur_ip+=len;
}
//
//
void emit_code(binary_stream *stream, ULONG value, UINT len)
{
-
- switch (len){
+
+ switch (len){
- case 1:
- stream->ibuf[stream->cur_ip]=(UCHAR)value;
- stream->cur_ip++;
- break;
+ case 1:
+ stream->ibuf[stream->cur_ip]=(UCHAR)value;
+ stream->cur_ip++;
+ break;
- case 2:
- *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value;
- stream->cur_ip+=2;
- break;
+ case 2:
+ *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value;
+ stream->cur_ip+=2;
+ break;
- case 4:
- *((ULONG*)(stream->ibuf+stream->cur_ip))=value;
- stream->cur_ip+=4;
- break;
+ case 4:
+ *((ULONG*)(stream->ibuf+stream->cur_ip))=value;
+ stream->cur_ip+=4;
+ break;
- default:;
-
- }
+ default:;
+
+ }
- return;
+ return;
}
//
BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem)
{
- struct bpf_insn *ins;
- UINT i, pass;
- binary_stream stream;
+ struct bpf_insn *ins;
+ UINT i, pass;
+ binary_stream stream;
- // Allocate the reference table for the jumps
+ // Allocate the reference table for the jumps
#ifdef NTKERNEL
- stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), '0JWA');
+#define NPF_TAG_REFTABLE TAG('0', 'J', 'W', 'A')
+ stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), NPF_TAG_REFTABLE);
#else
- stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT));
+ stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT));
#endif
- if(stream.refs==NULL)
- {
- return NULL;
- }
-
- // Reset the reference table
- for(i=0; i< nins + 1; i++)
- stream.refs[i]=0;
-
- stream.cur_ip=0;
- stream.bpf_pc=0;
-
- // the first pass will emit the lengths of the instructions
- // to create the reference table
- emitm=emit_lenght;
-
- for(pass=0;;){
-
- ins = prog;
-
- /* create the procedure header */
- PUSH(EBP)
- MOVrd(EBP,ESP)
- PUSH(EBX)
- PUSH(ECX)
- PUSH(EDX)
- PUSH(ESI)
- PUSH(EDI)
- MOVodd(EBX, EBP, 8)
-
- for(i=0;i<nins;i++){
-
- stream.bpf_pc++;
-
- switch (ins->code) {
-
- default:
-
- return NULL;
-
- case BPF_RET|BPF_K:
-
- MOVid(EAX,ins->k)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- RET()
-
- break;
-
-
- case BPF_RET|BPF_A:
-
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- RET()
-
- break;
-
-
- case BPF_LD|BPF_W|BPF_ABS:
-
- MOVid(ECX,ins->k)
- MOVrd(ESI,ECX)
- ADDib(ECX,sizeof(INT))
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0) //this can be optimized with xor eax,eax
- RET()
- MOVobd(EAX, EBX, ESI)
- BSWAP(EAX)
-
- break;
-
- case BPF_LD|BPF_H|BPF_ABS:
-
- MOVid(ECX,ins->k)
- MOVrd(ESI,ECX)
- ADDib(ECX,sizeof(SHORT))
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVid(EAX,0)
- MOVobw(AX, EBX, ESI)
- SWAP_AX()
-
- break;
-
- case BPF_LD|BPF_B|BPF_ABS:
-
- MOVid(ECX,ins->k)
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVid(EAX,0)
- MOVobb(AL,EBX,ECX)
-
- break;
-
- case BPF_LD|BPF_W|BPF_LEN:
-
- MOVodd(EAX, EBP, 0xc)
-
- break;
-
- case BPF_LDX|BPF_W|BPF_LEN:
-
- MOVodd(EDX, EBP, 0xc)
-
- break;
-
- case BPF_LD|BPF_W|BPF_IND:
-
- MOVid(ECX,ins->k)
- ADDrd(ECX,EDX)
- MOVrd(ESI,ECX)
- ADDib(ECX,sizeof(INT))
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVobd(EAX, EBX, ESI)
- BSWAP(EAX)
-
- break;
-
- case BPF_LD|BPF_H|BPF_IND:
-
- MOVid(ECX,ins->k)
- ADDrd(ECX,EDX)
- MOVrd(ESI,ECX)
- ADDib(ECX,sizeof(SHORT))
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVid(EAX,0)
- MOVobw(AX, EBX, ESI)
- SWAP_AX()
-
- break;
-
- case BPF_LD|BPF_B|BPF_IND:
-
- MOVid(ECX,ins->k)
- ADDrd(ECX,EDX)
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVid(EAX,0)
- MOVobb(AL,EBX,ECX)
-
- break;
-
- case BPF_LDX|BPF_MSH|BPF_B:
-
- MOVid(ECX,ins->k)
- CMPodd(ECX, EBP, 0x10)
- JLEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVid(EDX,0)
- MOVobb(DL,EBX,ECX)
- ANDib(DL, 0xf)
- SHLib(EDX, 2)
-
- break;
+ if(stream.refs==NULL)
+ {
+ return NULL;
+ }
+
+ // Reset the reference table
+ for(i=0; i< nins + 1; i++)
+ stream.refs[i]=0;
+
+ stream.cur_ip=0;
+ stream.bpf_pc=0;
+
+ // the first pass will emit the lengths of the instructions
+ // to create the reference table
+ emitm=emit_lenght;
+
+ for(pass=0;;){
+
+ ins = prog;
+
+ /* create the procedure header */
+ PUSH(EBP)
+ MOVrd(EBP,ESP)
+ PUSH(EBX)
+ PUSH(ECX)
+ PUSH(EDX)
+ PUSH(ESI)
+ PUSH(EDI)
+ MOVodd(EBX, EBP, 8)
+
+ for(i=0;i<nins;i++){
+
+ stream.bpf_pc++;
+
+ switch (ins->code) {
+
+ default:
+
+ return NULL;
+
+ case BPF_RET|BPF_K:
+
+ MOVid(EAX,ins->k)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ RET()
+
+ break;
+
+
+ case BPF_RET|BPF_A:
+
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ RET()
+
+ break;
+
+
+ case BPF_LD|BPF_W|BPF_ABS:
+
+ MOVid(ECX,ins->k)
+ MOVrd(ESI,ECX)
+ ADDib(ECX,sizeof(INT))
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0) //this can be optimized with xor eax,eax
+ RET()
+ MOVobd(EAX, EBX, ESI)
+ BSWAP(EAX)
+
+ break;
+
+ case BPF_LD|BPF_H|BPF_ABS:
+
+ MOVid(ECX,ins->k)
+ MOVrd(ESI,ECX)
+ ADDib(ECX,sizeof(SHORT))
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVid(EAX,0)
+ MOVobw(AX, EBX, ESI)
+ SWAP_AX()
+
+ break;
+
+ case BPF_LD|BPF_B|BPF_ABS:
+
+ MOVid(ECX,ins->k)
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVid(EAX,0)
+ MOVobb(AL,EBX,ECX)
+
+ break;
+
+ case BPF_LD|BPF_W|BPF_LEN:
+
+ MOVodd(EAX, EBP, 0xc)
+
+ break;
+
+ case BPF_LDX|BPF_W|BPF_LEN:
+
+ MOVodd(EDX, EBP, 0xc)
+
+ break;
+
+ case BPF_LD|BPF_W|BPF_IND:
+
+ MOVid(ECX,ins->k)
+ ADDrd(ECX,EDX)
+ MOVrd(ESI,ECX)
+ ADDib(ECX,sizeof(INT))
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVobd(EAX, EBX, ESI)
+ BSWAP(EAX)
+
+ break;
+
+ case BPF_LD|BPF_H|BPF_IND:
+
+ MOVid(ECX,ins->k)
+ ADDrd(ECX,EDX)
+ MOVrd(ESI,ECX)
+ ADDib(ECX,sizeof(SHORT))
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVid(EAX,0)
+ MOVobw(AX, EBX, ESI)
+ SWAP_AX()
+
+ break;
+
+ case BPF_LD|BPF_B|BPF_IND:
+
+ MOVid(ECX,ins->k)
+ ADDrd(ECX,EDX)
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVid(EAX,0)
+ MOVobb(AL,EBX,ECX)
+
+ break;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+
+ MOVid(ECX,ins->k)
+ CMPodd(ECX, EBP, 0x10)
+ JLEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVid(EDX,0)
+ MOVobb(DL,EBX,ECX)
+ ANDib(DL, 0xf)
+ SHLib(EDX, 2)
+
+ break;
- case BPF_LD|BPF_IMM:
+ case BPF_LD|BPF_IMM:
- MOVid(EAX,ins->k)
+ MOVid(EAX,ins->k)
- break;
+ break;
- case BPF_LDX|BPF_IMM:
-
- MOVid(EDX,ins->k)
+ case BPF_LDX|BPF_IMM:
+
+ MOVid(EDX,ins->k)
- break;
+ break;
- case BPF_LD|BPF_MEM:
+ case BPF_LD|BPF_MEM:
- MOVid(ECX,(INT)mem)
- MOVid(ESI,ins->k*4)
- MOVobd(EAX, ECX, ESI)
+ MOVid(ECX,(INT)mem)
+ MOVid(ESI,ins->k*4)
+ MOVobd(EAX, ECX, ESI)
- break;
+ break;
- case BPF_LDX|BPF_MEM:
+ case BPF_LDX|BPF_MEM:
- MOVid(ECX,(INT)mem)
- MOVid(ESI,ins->k*4)
- MOVobd(EDX, ECX, ESI)
+ MOVid(ECX,(INT)mem)
+ MOVid(ESI,ins->k*4)
+ MOVobd(EDX, ECX, ESI)
- break;
+ break;
- case BPF_ST:
+ case BPF_ST:
- // XXX: this command and the following could be optimized if the previous
- // instruction was already of this type
- MOVid(ECX,(INT)mem)
- MOVid(ESI,ins->k*4)
- MOVomd(ECX, ESI, EAX)
+ // XXX: this command and the following could be optimized if the previous
+ // instruction was already of this type
+ MOVid(ECX,(INT)mem)
+ MOVid(ESI,ins->k*4)
+ MOVomd(ECX, ESI, EAX)
- break;
+ break;
- case BPF_STX:
+ case BPF_STX:
- MOVid(ECX,(INT)mem)
- MOVid(ESI,ins->k*4)
- MOVomd(ECX, ESI, EDX)
- break;
+ MOVid(ECX,(INT)mem)
+ MOVid(ESI,ins->k*4)
+ MOVomd(ECX, ESI, EDX)
+ break;
- case BPF_JMP|BPF_JA:
+ case BPF_JMP|BPF_JA:
- JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc])
+ JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JGT|BPF_K:
+ case BPF_JMP|BPF_JGT|BPF_K:
- CMPid(EAX, ins->k)
- JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ CMPid(EAX, ins->k)
+ JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ break;
- case BPF_JMP|BPF_JGE|BPF_K:
+ case BPF_JMP|BPF_JGE|BPF_K:
- CMPid(EAX, ins->k)
- JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ CMPid(EAX, ins->k)
+ JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JEQ|BPF_K:
+ case BPF_JMP|BPF_JEQ|BPF_K:
- CMPid(EAX, ins->k)
- JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ CMPid(EAX, ins->k)
+ JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JSET|BPF_K:
+ case BPF_JMP|BPF_JSET|BPF_K:
- MOVrd(ECX,EAX)
- ANDid(ECX,ins->k)
- JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
+ MOVrd(ECX,EAX)
+ ANDid(ECX,ins->k)
+ JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JGT|BPF_X:
+ case BPF_JMP|BPF_JGT|BPF_X:
- CMPrd(EAX, EDX)
- JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ CMPrd(EAX, EDX)
+ JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ break;
- case BPF_JMP|BPF_JGE|BPF_X:
+ case BPF_JMP|BPF_JGE|BPF_X:
- CMPrd(EAX, EDX)
- JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ CMPrd(EAX, EDX)
+ JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JEQ|BPF_X:
+ case BPF_JMP|BPF_JEQ|BPF_X:
- CMPrd(EAX, EDX)
- JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
+ CMPrd(EAX, EDX)
+ JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
- break;
+ break;
- case BPF_JMP|BPF_JSET|BPF_X:
+ case BPF_JMP|BPF_JSET|BPF_X:
- MOVrd(ECX,EAX)
- ANDrd(ECX,EDX)
- JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
- JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
-
- break;
+ MOVrd(ECX,EAX)
+ ANDrd(ECX,EDX)
+ JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
+ JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
+
+ break;
- case BPF_ALU|BPF_ADD|BPF_X:
+ case BPF_ALU|BPF_ADD|BPF_X:
- ADDrd(EAX,EDX)
-
- break;
+ ADDrd(EAX,EDX)
+
+ break;
- case BPF_ALU|BPF_SUB|BPF_X:
+ case BPF_ALU|BPF_SUB|BPF_X:
- SUBrd(EAX,EDX)
+ SUBrd(EAX,EDX)
- break;
+ break;
- case BPF_ALU|BPF_MUL|BPF_X:
+ case BPF_ALU|BPF_MUL|BPF_X:
- MOVrd(ECX,EDX)
- MULrd(EDX)
- MOVrd(EDX,ECX)
- break;
+ MOVrd(ECX,EDX)
+ MULrd(EDX)
+ MOVrd(EDX,ECX)
+ break;
- case BPF_ALU|BPF_DIV|BPF_X:
+ case BPF_ALU|BPF_DIV|BPF_X:
- CMPid(EDX, 0)
- JNEb(12)
- POP(EDI)
- POP(ESI)
- POP(EDX)
- POP(ECX)
- POP(EBX)
- POP(EBP)
- MOVid(EAX,0)
- RET()
- MOVrd(ECX,EDX)
- MOVid(EDX,0)
- DIVrd(ECX)
- MOVrd(EDX,ECX)
+ CMPid(EDX, 0)
+ JNEb(12)
+ POP(EDI)
+ POP(ESI)
+ POP(EDX)
+ POP(ECX)
+ POP(EBX)
+ POP(EBP)
+ MOVid(EAX,0)
+ RET()
+ MOVrd(ECX,EDX)
+ MOVid(EDX,0)
+ DIVrd(ECX)
+ MOVrd(EDX,ECX)
- break;
+ break;
- case BPF_ALU|BPF_AND|BPF_X:
+ case BPF_ALU|BPF_AND|BPF_X:
- ANDrd(EAX,EDX)
-
- break;
+ ANDrd(EAX,EDX)
+
+ break;
- case BPF_ALU|BPF_OR|BPF_X:
+ case BPF_ALU|BPF_OR|BPF_X:
- ORrd(EAX,EDX)
+ ORrd(EAX,EDX)
- break;
+ break;
- case BPF_ALU|BPF_LSH|BPF_X:
+ case BPF_ALU|BPF_LSH|BPF_X:
- MOVrd(ECX,EDX)
- SHL_CLrb(EAX)
+ MOVrd(ECX,EDX)
+ SHL_CLrb(EAX)
- break;
+ break;
- case BPF_ALU|BPF_RSH|BPF_X:
+ case BPF_ALU|BPF_RSH|BPF_X:
- MOVrd(ECX,EDX)
- SHR_CLrb(EAX)
+ MOVrd(ECX,EDX)
+ SHR_CLrb(EAX)
- break;
+ break;
- case BPF_ALU|BPF_ADD|BPF_K:
+ case BPF_ALU|BPF_ADD|BPF_K:
- ADD_EAXi(ins->k)
+ ADD_EAXi(ins->k)
- break;
+ break;
- case BPF_ALU|BPF_SUB|BPF_K:
+ case BPF_ALU|BPF_SUB|BPF_K:
- SUB_EAXi(ins->k)
-
- break;
+ SUB_EAXi(ins->k)
+
+ break;
- case BPF_ALU|BPF_MUL|BPF_K:
+ case BPF_ALU|BPF_MUL|BPF_K:
- MOVrd(ECX,EDX)
- MOVid(EDX,ins->k)
- MULrd(EDX)
- MOVrd(EDX,ECX)
+ MOVrd(ECX,EDX)
+ MOVid(EDX,ins->k)
+ MULrd(EDX)
+ MOVrd(EDX,ECX)
- break;
+ break;
- case BPF_ALU|BPF_DIV|BPF_K:
+ case BPF_ALU|BPF_DIV|BPF_K:
- MOVrd(ECX,EDX)
- MOVid(EDX,0)
- MOVid(ESI,ins->k)
- DIVrd(ESI)
- MOVrd(EDX,ECX)
+ MOVrd(ECX,EDX)
+ MOVid(EDX,0)
+ MOVid(ESI,ins->k)
+ DIVrd(ESI)
+ MOVrd(EDX,ECX)
- break;
+ break;
- case BPF_ALU|BPF_AND|BPF_K:
+ case BPF_ALU|BPF_AND|BPF_K:
- ANDid(EAX, ins->k)
+ ANDid(EAX, ins->k)
- break;
+ break;
- case BPF_ALU|BPF_OR|BPF_K:
+ case BPF_ALU|BPF_OR|BPF_K:
- ORid(EAX, ins->k)
-
- break;
+ ORid(EAX, ins->k)
+
+ break;
- case BPF_ALU|BPF_LSH|BPF_K:
+ case BPF_ALU|BPF_LSH|BPF_K:
- SHLib(EAX, (ins->k) & 255)
+ SHLib(EAX, (ins->k) & 255)
- break;
+ break;
- case BPF_ALU|BPF_RSH|BPF_K:
+ case BPF_ALU|BPF_RSH|BPF_K:
- SHRib(EAX, (ins->k) & 255)
+ SHRib(EAX, (ins->k) & 255)
- break;
+ break;
- case BPF_ALU|BPF_NEG:
+ case BPF_ALU|BPF_NEG:
- NEGd(EAX)
+ NEGd(EAX)
- break;
+ break;
- case BPF_MISC|BPF_TAX:
+ case BPF_MISC|BPF_TAX:
- MOVrd(EDX,EAX)
+ MOVrd(EDX,EAX)
- break;
+ break;
- case BPF_MISC|BPF_TXA:
+ case BPF_MISC|BPF_TXA:
- MOVrd(EAX,EDX)
+ MOVrd(EAX,EDX)
- break;
+ break;
- }
-
- ins++;
- }
+ }
+
+ ins++;
+ }
- pass++;
- if(pass == 2) break;
-
+ pass++;
+ if(pass == 2) break;
+
#ifdef NTKERNEL
- stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, '1JWA');
+#define NPF_TAG_STREAMBUF TAG('1', 'J', 'W', 'A')
+ stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, NPF_TAG_STREAMBUF);
#else
- stream.ibuf=(CHAR*)malloc(stream.cur_ip);
+ stream.ibuf=(CHAR*)malloc(stream.cur_ip);
#endif
- if(stream.ibuf==NULL)
- {
+ if(stream.ibuf==NULL)
+ {
#ifdef NTKERNEL
- ExFreePool(stream.refs);
+ ExFreePool(stream.refs);
#else
- free(stream.refs);
+ free(stream.refs);
#endif
- return NULL;
- }
-
- // modify the reference table to contain the offsets and not the lengths of the instructions
- for(i=1; i< nins + 1; i++)
- stream.refs[i]+=stream.refs[i-1];
-
- // Reset the counters
- stream.cur_ip=0;
- stream.bpf_pc=0;
- // the second pass creates the actual code
- emitm=emit_code;
-
- }
-
- // the reference table is needed only during compilation, now we can free it
+ return NULL;
+ }
+
+ // modify the reference table to contain the offsets and not the lengths of the instructions
+ for(i=1; i< nins + 1; i++)
+ stream.refs[i]+=stream.refs[i-1];
+
+ // Reset the counters
+ stream.cur_ip=0;
+ stream.bpf_pc=0;
+ // the second pass creates the actual code
+ emitm=emit_code;
+
+ }
+
+ // the reference table is needed only during compilation, now we can free it
#ifdef NTKERNEL
- ExFreePool(stream.refs);
+ ExFreePool(stream.refs);
#else
- free(stream.refs);
+ free(stream.refs);
#endif
- return (BPF_filter_function)stream.ibuf;
+ return (BPF_filter_function)stream.ibuf;
}
JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins)
{
- JIT_BPF_Filter *Filter;
+ JIT_BPF_Filter *Filter;
- // Allocate the filter structure
+ // Allocate the filter structure
#ifdef NTKERNEL
- Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), '2JWA');
+#define NPF_TAG_FILTSTRUCT TAG('2', 'J', 'W', 'A')
+ Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), NPF_TAG_FILTSTRUCT);
#else
- Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter));
+ Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter));
#endif
- if(Filter==NULL)
- {
- return NULL;
- }
+ if(Filter==NULL)
+ {
+ return NULL;
+ }
- // Allocate the filter's memory
+ // Allocate the filter's memory
#ifdef NTKERNEL
- Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), '3JWA');
+#define NPF_TAG_FILTMEM TAG('3', 'J', 'W', 'A')
+ Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), NPF_TAG_FILTMEM);
#else
- Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT));
+ Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT));
#endif
- if(Filter->mem==NULL)
- {
+ if(Filter->mem==NULL)
+ {
#ifdef NTKERNEL
- ExFreePool(Filter);
+ ExFreePool(Filter);
#else
- free(Filter);
+ free(Filter);
#endif
- return NULL;
- }
+ return NULL;
+ }
- // Create the binary
- if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL)
- {
+ // Create the binary
+ if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL)
+ {
#ifdef NTKERNEL
- ExFreePool(Filter->mem);
- ExFreePool(Filter);
+ ExFreePool(Filter->mem);
+ ExFreePool(Filter);
#else
- free(Filter->mem);
- free(Filter);
+ free(Filter->mem);
+ free(Filter);
- return NULL;
+ return NULL;
#endif
- }
+ }
- return Filter;
+ return Filter;
}
//////////////////////////////////////////////////////////////
void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter){
-
+
#ifdef NTKERNEL
- ExFreePool(Filter->mem);
- ExFreePool(Filter->Function);
- ExFreePool(Filter);
+ ExFreePool(Filter->mem);
+ ExFreePool(Filter->Function);
+ ExFreePool(Filter);
#else
- free(Filter->mem);
- free(Filter->Function);
- free(Filter);
+ free(Filter->mem);
+ free(Filter->Function);
+ free(Filter);
#endif
}