/// <summary> /// Add first RET in the data block to the return address list. /// </summary> /// <param name="data"></param> /// <param name="baseAddress"></param> /// <param name="returnAddresses"></param> /// <returns></returns> public static void AddFirstRet(byte[] data, int baseAddress, int startOffset, ref oAsmRetList returnAddresses) { // Disassemble all the instructions in the data block int offset = startOffset; while (offset + 10 < data.Length) { // Process this instruction // Decode SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress); // Process switch (instruction.opcode) { case SIMPLE_INSTRUCTION.OP_RET_NULL: if (instruction.size == 1) { returnAddresses.addRet(instruction.address, 0); } return; case SIMPLE_INSTRUCTION.OP_RET_IMM16: if (instruction.size == 3) { returnAddresses.addRet(instruction.address, instruction.immediate); } return; } // Next instruction offset += instruction.size; } }
/// <summary> /// Add first RET in the data block to the return address list. /// </summary> /// <param name="data"></param> /// <param name="baseAddress"></param> /// <param name="returnAddresses"></param> /// <returns></returns> public static void AddFirstRet(byte[] data, int baseAddress, int startOffset, ref oAsmRetList returnAddresses) { // Disassemble all the instructions in the data block int offset = startOffset; while (offset + 10 < data.Length) { // Process this instruction // Decode SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress); // Process switch (instruction.opcode) { case SIMPLE_INSTRUCTION.OP_RET_NULL: if (instruction.size == 1) returnAddresses.addRet(instruction.address, 0); return; case SIMPLE_INSTRUCTION.OP_RET_IMM16: if (instruction.size == 3) returnAddresses.addRet(instruction.address, instruction.immediate); return; } // Next instruction offset += instruction.size; } }
/// <summary> /// Decodes all the call instructions from the block. Return instructions are outputted to returnAddresses. /// </summary> /// <param name="data"></param> /// <param name="baseAddress"></param> /// <param name="returnAddresses"></param> /// <returns></returns> public static List <SIMPLE_INSTRUCTION> DisassembleBlockCallsOnly(byte[] data, int baseAddress, ref oAsmRetList returnAddresses, ref oEbpArgumentList ebpArguments, ref List <jmpInstruction> jumps) { // Disassemble all the instructions in the data block int offset = 0; List <SIMPLE_INSTRUCTION> result = new List <SIMPLE_INSTRUCTION>(data.Length / 100); while (offset + 10 < data.Length) { // Process this instruction // Decode SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress); // Process switch (instruction.opcode) { case SIMPLE_INSTRUCTION.OP_CALL_IMM32: if (instruction.size == 5 && instruction.numPrefix == 0) { result.Add(instruction); } break; case SIMPLE_INSTRUCTION.OP_RET_NULL: if (instruction.size == 1 && instruction.numPrefix == 0) { returnAddresses.addRet(instruction.address, 0); } break; case SIMPLE_INSTRUCTION.OP_RET_IMM16: if (instruction.size == 3 && instruction.numPrefix == 0) { returnAddresses.addRet(instruction.address, instruction.immediate); } break; case SIMPLE_INSTRUCTION.OP_MOV_REG32: if (instruction.size == 3 && (data[offset + 1] == 0x45 || data[offset + 1] == 0x5d || data[offset + 1] == 0x4D || data[offset + 1] == 0x55 || data[offset + 1] == 0x75 || data[offset + 1] == 0x7D) && data[offset + 2] <= 0x7F && data[offset + 2] > 0x04) { // mov reg32, [ebp+imm8] // Save this immediate value, it tells us how many arguments this function has ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4); } break; case SIMPLE_INSTRUCTION.OP_PUSH_DEREF_REG32: if (instruction.size == 3 && data[offset + 1] == 0x75 && data[offset + 2] <= 0x7F && data[offset + 2] > 0x04) { // push [ebp+imm8] // Save this immediate value, it tells us how many arguments this function has ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4); } break; case SIMPLE_INSTRUCTION.OP_JMP_IMM32: if (instruction.size == 5) { // jmp imm32 // Save this jump jumps.Add(new jmpInstruction(instruction.address, instruction.jmp_target)); } break; } // Check to see if it is a mov reg32, [ebp+imm8] instruction. // Next instruction offset += instruction.size; } // Return the resulting call instructions return(result); }
/// <summary> /// Decodes all the call instructions from the block. Return instructions are outputted to returnAddresses. /// </summary> /// <param name="data"></param> /// <param name="baseAddress"></param> /// <param name="returnAddresses"></param> /// <returns></returns> public static List<SIMPLE_INSTRUCTION> DisassembleBlockCallsOnly(byte[] data, int baseAddress, ref oAsmRetList returnAddresses, ref oEbpArgumentList ebpArguments, ref List<jmpInstruction> jumps) { // Disassemble all the instructions in the data block int offset = 0; List<SIMPLE_INSTRUCTION> result = new List<SIMPLE_INSTRUCTION>(data.Length/100); while( offset + 10 < data.Length) { // Process this instruction // Decode SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress); // Process switch(instruction.opcode) { case SIMPLE_INSTRUCTION.OP_CALL_IMM32: if( instruction.size == 5 && instruction.numPrefix == 0 ) result.Add(instruction); break; case SIMPLE_INSTRUCTION.OP_RET_NULL: if (instruction.size == 1 && instruction.numPrefix == 0) returnAddresses.addRet(instruction.address, 0); break; case SIMPLE_INSTRUCTION.OP_RET_IMM16: if (instruction.size == 3 && instruction.numPrefix == 0) returnAddresses.addRet(instruction.address, instruction.immediate); break; case SIMPLE_INSTRUCTION.OP_MOV_REG32: if (instruction.size == 3 && (data[offset+1] == 0x45 || data[offset+1] == 0x5d || data[offset+1] == 0x4D || data[offset+1] == 0x55 || data[offset+1] == 0x75 || data[offset+1] == 0x7D) && data[offset + 2] <= 0x7F && data[offset + 2] > 0x04) { // mov reg32, [ebp+imm8] // Save this immediate value, it tells us how many arguments this function has ebpArguments.addEbpReference(instruction.address, (int) (data[offset + 2]-4)/4); } break; case SIMPLE_INSTRUCTION.OP_PUSH_DEREF_REG32: if (instruction.size == 3 && data[offset + 1] == 0x75 && data[offset + 2] <= 0x7F && data[offset + 2] > 0x04) { // push [ebp+imm8] // Save this immediate value, it tells us how many arguments this function has ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4); } break; case SIMPLE_INSTRUCTION.OP_JMP_IMM32: if (instruction.size == 5) { // jmp imm32 // Save this jump jumps.Add( new jmpInstruction(instruction.address, instruction.jmp_target) ); } break; } // Check to see if it is a mov reg32, [ebp+imm8] instruction. // Next instruction offset += instruction.size; } // Return the resulting call instructions return result; }