bool EmitProlog(CxProgram program) { bool rc = true; switch (PrologOrder[program.GetRandom() % 3]) { case 2: // MOV EAX, (Random() & 0x3ff) // MOV EAX, EncryptionControlBlock[EAX] rc = program.EmitNop(5) && // 0xbe program.Emit(CxByteCode.MOV_EAX_IMMED, 2) && // 0x8b 0x86 program.EmitUInt32(program.GetRandom() & 0x3ff) && program.Emit(CxByteCode.MOV_EAX_INDIRECT, 0); break; case 1: rc = program.Emit(CxByteCode.MOV_EAX_EDI, 2); // 0x8b 0xc7 break; case 0: // MOV EAX, Random() rc = program.Emit(CxByteCode.MOV_EAX_IMMED) && // 0xb8 program.EmitRandom(); break; } return(rc); }
bool EmitBody(CxProgram program, int stage) { if (1 == stage) { return(EmitProlog(program)); } if (!program.Emit(CxByteCode.PUSH_EBX)) // 0x53 { return(false); } if (0 != (program.GetRandom() & 1)) { if (!EmitBody(program, stage - 1)) { return(false); } } else if (!EmitBody2(program, stage - 1)) { return(false); } if (!program.Emit(CxByteCode.MOV_EBX_EAX, 2)) // 0x89 0xc3 { return(false); } if (0 != (program.GetRandom() & 1)) { if (!EmitBody(program, stage - 1)) { return(false); } } else if (!EmitBody2(program, stage - 1)) { return(false); } return(EmitOddBranch(program) && program.Emit(CxByteCode.POP_EBX)); // 0x5b }
bool EmitBody2(CxProgram program, int stage) { if (1 == stage) { return(EmitProlog(program)); } bool rc = true; if (0 != (program.GetRandom() & 1)) { rc = EmitBody(program, stage - 1); } else { rc = EmitBody2(program, stage - 1); } return(rc && EmitEvenBranch(program)); }
bool EmitOddBranch(CxProgram program) { bool rc = true; switch (OddBranchOrder[program.GetRandom() % 6]) { case 0: rc = program.Emit(CxByteCode.PUSH_ECX) && // 0x51 program.Emit(CxByteCode.MOV_ECX_EBX, 2) && // 0x89 0xd9 program.Emit(CxByteCode.AND_ECX_0F, 3) && // 0x83 0xe1 0x0f program.Emit(CxByteCode.SHR_EAX_CL, 2) && // 0xd3 0xe8 program.Emit(CxByteCode.POP_ECX); // 0x59 break; case 1: rc = program.Emit(CxByteCode.PUSH_ECX) && // 0x51 program.Emit(CxByteCode.MOV_ECX_EBX, 2) && // 0x89 0xd9 program.Emit(CxByteCode.AND_ECX_0F, 3) && // 0x83 0xe1 0x0f program.Emit(CxByteCode.SHL_EAX_CL, 2) && // 0xd3 0xe0 program.Emit(CxByteCode.POP_ECX); // 0x59 break; case 2: rc = program.Emit(CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8 break; case 3: rc = program.Emit(CxByteCode.NEG_EAX, 2) && // 0xf7 0xd8 program.Emit(CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8 break; case 4: rc = program.Emit(CxByteCode.IMUL_EAX_EBX, 3); // 0x0f 0xaf 0xc3 break; case 5: rc = program.Emit(CxByteCode.SUB_EAX_EBX, 2); // 0x29 0xd8 break; } return(rc); }
bool EmitEvenBranch(CxProgram program) { bool rc = true; switch (EvenBranchOrder[program.GetRandom() & 7]) { case 0: rc = program.Emit(CxByteCode.NOT_EAX, 2); // 0xf7 0xd0 break; case 1: rc = program.Emit(CxByteCode.DEC_EAX); // 0x48 break; case 2: rc = program.Emit(CxByteCode.NEG_EAX, 2); // 0xf7 0xd8 break; case 3: rc = program.Emit(CxByteCode.INC_EAX); // 0x40 break; case 4: rc = program.EmitNop(5) && // 0xbe program.Emit(CxByteCode.AND_EAX_IMMED) && // 0x25 program.EmitUInt32(0x3ff) && program.Emit(CxByteCode.MOV_EAX_INDIRECT, 3); // 0x8b 0x04 0x86 break; case 5: rc = program.Emit(CxByteCode.PUSH_EBX) && // 0x53 program.Emit(CxByteCode.MOV_EBX_EAX, 2) && // 0x89 0xc3 program.Emit(CxByteCode.AND_EBX_IMMED, 2) && // 0x81 0xe3 program.EmitUInt32(0xaaaaaaaa) && program.Emit(CxByteCode.AND_EAX_IMMED) && // 0x25 program.EmitUInt32(0x55555555) && program.Emit(CxByteCode.SHR_EBX_1, 2) && // 0xd1 0xeb program.Emit(CxByteCode.SHL_EAX_1, 2) && // 0xd1 0xe0 program.Emit(CxByteCode.OR_EAX_EBX, 2) && // 0x09 0xd8 program.Emit(CxByteCode.POP_EBX); // 0x5b break; case 6: rc = program.Emit(CxByteCode.XOR_EAX_IMMED) && // 0x35 program.EmitRandom(); break; case 7: if (0 != (program.GetRandom() & 1)) { rc = program.Emit(CxByteCode.ADD_EAX_IMMED); // 0x05 } else { rc = program.Emit(CxByteCode.SUB_EAX_IMMED); // 0x2d } rc = rc && program.EmitRandom(); break; } return(rc); }
bool EmitProlog(CxProgram program) { bool rc = true; switch (PrologOrder[program.GetRandom() % 3]) { case 2: // MOV EAX, (Random() & 0x3ff) // MOV EAX, EncryptionControlBlock[EAX] rc = program.EmitNop (5) // 0xbe && program.Emit (CxByteCode.MOV_EAX_IMMED, 2) // 0x8b 0x86 && program.EmitUInt32 (program.GetRandom() & 0x3ff) && program.Emit (CxByteCode.MOV_EAX_INDIRECT, 0); break; case 1: rc = program.Emit (CxByteCode.MOV_EAX_EDI, 2); // 0x8b 0xc7 break; case 0: // MOV EAX, Random() rc = program.Emit (CxByteCode.MOV_EAX_IMMED) // 0xb8 && program.EmitRandom(); break; } return rc; }
bool EmitOddBranch(CxProgram program) { bool rc = true; switch (OddBranchOrder[program.GetRandom() % 6]) { case 0: rc = program.Emit (CxByteCode.PUSH_ECX) // 0x51 && program.Emit (CxByteCode.MOV_ECX_EBX, 2) // 0x89 0xd9 && program.Emit (CxByteCode.AND_ECX_0F, 3) // 0x83 0xe1 0x0f && program.Emit (CxByteCode.SHR_EAX_CL, 2) // 0xd3 0xe8 && program.Emit (CxByteCode.POP_ECX); // 0x59 break; case 1: rc = program.Emit (CxByteCode.PUSH_ECX) // 0x51 && program.Emit (CxByteCode.MOV_ECX_EBX, 2) // 0x89 0xd9 && program.Emit (CxByteCode.AND_ECX_0F, 3) // 0x83 0xe1 0x0f && program.Emit (CxByteCode.SHL_EAX_CL, 2) // 0xd3 0xe0 && program.Emit (CxByteCode.POP_ECX); // 0x59 break; case 2: rc = program.Emit (CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8 break; case 3: rc = program.Emit (CxByteCode.NEG_EAX, 2) // 0xf7 0xd8 && program.Emit (CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8 break; case 4: rc = program.Emit (CxByteCode.IMUL_EAX_EBX, 3); // 0x0f 0xaf 0xc3 break; case 5: rc = program.Emit (CxByteCode.SUB_EAX_EBX, 2); // 0x29 0xd8 break; } return rc; }
bool EmitEvenBranch(CxProgram program) { bool rc = true; switch (EvenBranchOrder[program.GetRandom() & 7]) { case 0: rc = program.Emit (CxByteCode.NOT_EAX, 2); // 0xf7 0xd0 break; case 1: rc = program.Emit (CxByteCode.DEC_EAX); // 0x48 break; case 2: rc = program.Emit (CxByteCode.NEG_EAX, 2); // 0xf7 0xd8 break; case 3: rc = program.Emit (CxByteCode.INC_EAX); // 0x40 break; case 4: rc = program.EmitNop (5) // 0xbe && program.Emit (CxByteCode.AND_EAX_IMMED) // 0x25 && program.EmitUInt32 (0x3ff) && program.Emit (CxByteCode.MOV_EAX_INDIRECT, 3); // 0x8b 0x04 0x86 break; case 5: rc = program.Emit (CxByteCode.PUSH_EBX) // 0x53 && program.Emit (CxByteCode.MOV_EBX_EAX, 2) // 0x89 0xc3 && program.Emit (CxByteCode.AND_EBX_IMMED, 2) // 0x81 0xe3 && program.EmitUInt32 (0xaaaaaaaa) && program.Emit (CxByteCode.AND_EAX_IMMED) // 0x25 && program.EmitUInt32 (0x55555555) && program.Emit (CxByteCode.SHR_EBX_1, 2) // 0xd1 0xeb && program.Emit (CxByteCode.SHL_EAX_1, 2) // 0xd1 0xe0 && program.Emit (CxByteCode.OR_EAX_EBX, 2) // 0x09 0xd8 && program.Emit (CxByteCode.POP_EBX); // 0x5b break; case 6: rc = program.Emit (CxByteCode.XOR_EAX_IMMED) // 0x35 && program.EmitRandom(); break; case 7: if (0 != (program.GetRandom() & 1)) rc = program.Emit (CxByteCode.ADD_EAX_IMMED); // 0x05 else rc = program.Emit (CxByteCode.SUB_EAX_IMMED); // 0x2d rc = rc && program.EmitRandom(); break; } return rc; }
bool EmitBody2(CxProgram program, int stage) { if (1 == stage) return EmitProlog (program); bool rc = true; if (0 != (program.GetRandom() & 1)) rc = EmitBody (program, stage - 1); else rc = EmitBody2 (program, stage - 1); return rc && EmitEvenBranch (program); }
bool EmitBody(CxProgram program, int stage) { if (1 == stage) return EmitProlog (program); if (!program.Emit (CxByteCode.PUSH_EBX)) // 0x53 return false; if (0 != (program.GetRandom() & 1)) { if (!EmitBody (program, stage - 1)) return false; } else if (!EmitBody2 (program, stage - 1)) return false; if (!program.Emit (CxByteCode.MOV_EBX_EAX, 2)) // 0x89 0xc3 return false; if (0 != (program.GetRandom() & 1)) { if (!EmitBody (program, stage - 1)) return false; } else if (!EmitBody2 (program, stage - 1)) return false; return EmitOddBranch (program) && program.Emit (CxByteCode.POP_EBX); // 0x5b }